private void CompareNewDMViewWithPrevious(string dm, Dictionary <string, AttributeCollectionValue> singleDMView, ref List <string> recentDiscoveries) { if (!dmViews.ContainsKey(dm)) { return; } ObjectsAttributeCollection prevDMView = dmViews[dm]; List <string> objectsToRemove = new List <string>(); List <string> objectsToAdd = new List <string>(); List <string> previouslyNotVisibleObjects = new List <string>(); foreach (string obj in prevDMView.GetObjectKeys()) { if (!singleDMView.ContainsKey(obj)) { objectsToRemove.Add(obj); } if (prevDMView[obj].attributes.ContainsKey("Location")) { if (!((LocationValue)((DetectedAttributeValue)prevDMView[obj]["Location"]).value).exists) { previouslyNotVisibleObjects.Add(obj); } } } foreach (string obj in singleDMView.Keys) { if (!prevDMView.ContainsObject(obj) && singleDMView[obj].attributes.ContainsKey("Location")) { objectsToAdd.Add(obj); } } AttributeCollectionValue acv = new AttributeCollectionValue(); //acv.attributes.Add("ID", new StringValue() as DataValue); foreach (string obj in objectsToAdd.ToArray()) { // acv = singleDMView[obj]; //singleDMView stores DetectedValues, which need to be //stripped before sending to SendVPIO if (acv.attributes.ContainsKey("Location")) { if (!((LocationValue)((DetectedAttributeValue)acv["Location"]).value).exists) { objectsToRemove.Add(obj); objectsToAdd.Remove(obj); continue; } else { //if (!previouslyNotVisibleObjects.Contains(obj)) // continue; //objectsToAdd.Add(obj); //objectsToRemove.Remove(obj); } } if (!acv.attributes.ContainsKey("ID")) { acv["ID"] = DataValueFactory.BuildDetectedValue(DataValueFactory.BuildString(obj), 100); } if (!acv.attributes.ContainsKey("OwnerID")) { acv["OwnerID"] = DataValueFactory.BuildDetectedValue(objectProxies[obj]["OwnerID"].GetDataValue(), 100); } SendViewProInitializeObject(dm, ExtractDetectedValuesFromACV(acv)); } foreach (string obj in objectsToRemove) { SendRemoveObjectEvent(obj, dm); prevDMView.RemoveObject(obj); } bool anyAttributeChanged = false; acv = null; foreach (string obj in objectsToAdd) { //AttributeCollectionValue atts = new AttributeCollectionValue(); //prevDMView.UpdateObject(obj, singleDMView[obj]); //SendViewProAttributeUpdate(dm, atts); prevDMView.UpdateObject(obj, new AttributeCollectionValue()); if (!movingObjects.Contains(obj)) { continue; } if (!activeDMs.Contains(dm)) { continue; } if (!recentDiscoveries.Contains(obj)) { recentDiscoveries.Add(obj); } //atts["ObjectID"] = DataValueFactory.BuildString(obj);//this is needed as the // //above Update call will // //add "ID", not "ObjectID" //SendViewProMotionUpdate(atts); } foreach (string obj in prevDMView.GetObjectKeys()) { acv = prevDMView.UpdateObject(obj, singleDMView[obj]); //add recent tags if (recentUnitTags != null) { if (recentUnitTags.ContainsKey(obj)) { if (recentUnitTags[obj].ContainsKey(dm)) { if (acv == null) { acv = new AttributeCollectionValue(); } acv.attributes["InitialTag"] = DataValueFactory.BuildString(recentUnitTags[obj][dm]); recentUnitTags[obj].Remove(dm); //remove once the DM has been notified. acv.attributes["ID"] = DataValueFactory.BuildString(obj); acv.attributes["OwnerID"] = prevDMView[obj]["OwnerID"]; } } } String classification = GetChangedClassificationForDM(obj, dm); if (classification != null) { if (acv == null) { acv = new AttributeCollectionValue(); acv.attributes["ID"] = DataValueFactory.BuildString(obj); acv.attributes["OwnerID"] = prevDMView[obj]["OwnerID"]; } acv.attributes["CurrentClassification"] = DataValueFactory.BuildString(classification); } if (acv == null) { continue; } if (acv.attributes.ContainsKey("Location")) { if (((LocationValue)((DetectedAttributeValue)acv["Location"]).value).exists) { //SendViewProInitializeObject(dm, ExtractDetectedValuesFromACV(prevDMView[obj])); } } SendViewProAttributeUpdate(dm, acv); if (acv.attributes.ContainsKey("OwnerID") && acv.attributes.ContainsKey("CurrentAttacks")) { if (((StringValue)((DetectedAttributeValue)acv.attributes["OwnerID"]).value).value == dm) { AttackCollectionValue attacks = (AttackCollectionValue)((DetectedAttributeValue)acv.attributes["CurrentAttacks"]).value; foreach (AttackCollectionValue.AttackValue av in attacks.GetCurrentAttacks()) { foreach (Attack a in currentAttacks) { if (a.attacker == av.attackingObjectId && a.target == av.targetObjectId && a.capabilityName == av.capabilityName) { a.SetTimes(av.attackStartTime, av.attackTimeWindow); } } } } } if (acv.attributes.ContainsKey("DestinationLocation") || acv.attributes.ContainsKey("Throttle")) { if (!recentDiscoveries.Contains(obj)) { recentDiscoveries.Add(obj); } //acv["ObjectID"] = acv["ID"]; //SendViewProMotionUpdate(ExtractDetectedValuesFromACV(acv)); } acv = null; } }
/// <summary> /// /// </summary> /// <param name="allObjectViews"></param> private void SenseAllObjects(ref Dictionary <string, Dictionary <string, AttributeCollectionValue> > allObjectsViews) { SimulationObjectProxy sensingProxy = null; SimulationObjectProxy targetProxy = null; Vec3D sensingLocation = null; Vec3D targetsLocation = null; LocationValue senLocation = null; LocationValue tarLocation = null; double distance = 0.0; SensorArrayValue sav = null; DataValue targetsAttribute = null; string ownerID = null; string objectType = null; DetectedAttributeValue detectedAttribute; AttributeCollectionValue singleAttributeCollection = null; bool isSensed = false; // The dictionary is constantly created in this method // Dictionary <string, AttributeCollectionValue> singleObjectView; //AD to improve this later: // for each object in the visible ObjectDistances collection // for each object after the current index // check for the index object's view of the nested object // check for the nested object's view of the index object //Possible hangup is the "All" emitter. int x = 0; //Each object senses each other object //foreach (string sensorObjectID in listOfObjectIDs) foreach (KeyValuePair <string, List <string> > networks in networkRosters) { if (!activeSensorNetworks[networks.Key]) { continue; } foreach (string sensorObjectID in networkObjects[networks.Key]) { sensingProxy = objectProxies[sensorObjectID]; objectType = sensingProxy.GetObjectType(); senLocation = sensingProxy["Location"].GetDataValue() as LocationValue; if (senLocation.exists) { ownerID = ((StringValue)sensingProxy["OwnerID"].GetDataValue()).value; singleObjectView = new Dictionary <string, AttributeCollectionValue>(); x++; //foreach (string targetObjectID in listOfObjectIDs) foreach (List <string> objects in networkObjects.Values) { if (objects.Contains(sensorObjectID)) { if (((EmitterValue)sensingProxy["Emitters"].GetDataValue()).emitters.ContainsKey("Invisible")) //OR if it's the "master" object for a region?? -lisa { continue; } string target = sensorObjectID; singleAttributeCollection = new AttributeCollectionValue(); foreach (KeyValuePair <string, AttributeInfo> simModelAtt in simModel.objectModel.objects[objectType].attributes) { if (!simModelAtt.Value.ownerObservable == true) { continue; } //if (!sensingProxy.GetKeys().Contains(simModelAtt.Key)) // continue; DataValue t = sensingProxy[simModelAtt.Key].GetDataValue(); if (t.dataType == "CustomAttributesType") { Dictionary <string, DataValue> copiedDict = CopyFromCustomAttributes(((CustomAttributesValue)t).attributes); t = new CustomAttributesValue(); ((CustomAttributesValue)t).attributes = copiedDict; } detectedAttribute = new DetectedAttributeValue(); detectedAttribute.stdDev = 100; detectedAttribute.value = DataValueFactory.BuildFromDataValue(t); AddAttributeToACV(ref singleAttributeCollection, simModelAtt.Key, detectedAttribute); }//end foreach sensable attribute if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary <string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(target, singleAttributeCollection); //if (changedAttributes != null && selectedRangeRingLevel != RangeRingLevels.DISABLED) //{ // CalculateRangeRings(ref changedAttributes, ref sensingProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(target, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(target)) { allObjectsViews[sensorObjectID].Add(target, new AttributeCollectionValue()); } } } else { foreach (string targetObjectID in objects) {//sensing and target objects are not the same targetProxy = objectProxies[targetObjectID]; tarLocation = targetProxy["Location"].GetDataValue() as LocationValue; if (tarLocation.exists) { EmitterValue emitters = targetProxy["Emitters"].GetDataValue() as EmitterValue; if (emitters.emitters.ContainsKey("All")) { //if an object has an all emitter, retrieve all attributes without sensing algorithm AttributeCollectionValue atts = new AttributeCollectionValue(); if (singleObjectView.ContainsKey(targetObjectID)) { atts = singleObjectView[targetObjectID]; } SenseAllAttributes(ref atts, targetProxy); singleObjectView[targetObjectID] = atts; isSensed = true; if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary <string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(targetObjectID, atts); //if (changedAttributes != null && selectedRangeRingLevel == RangeRingLevels.FULL) //{//the only way to sense a "target" here is for FULL ring display // CalculateRangeRings(ref changedAttributes, ref targetProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(targetObjectID, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(targetObjectID)) { allObjectsViews[sensorObjectID].Add(targetObjectID, new AttributeCollectionValue()); } } } else if (emitters.emitters.ContainsKey("Invisible")) //or if object is "master" for moving region -lisa { continue; } else {//object does not have an all emitter, continue to check each emitter value AttributeCollectionValue atts = new AttributeCollectionValue(); if (Omniscience) { if (singleObjectView.ContainsKey(targetObjectID)) { atts = singleObjectView[targetObjectID]; } SenseAllAttributes(ref atts, targetProxy); singleObjectView[targetObjectID] = atts; isSensed = true; if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary <string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(targetObjectID, atts); //if (changedAttributes != null && selectedRangeRingLevel == RangeRingLevels.FULL) //{//the only way to sense a "target" here is for FULL ring display // CalculateRangeRings(ref changedAttributes, ref targetProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(targetObjectID, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(targetObjectID)) { allObjectsViews[sensorObjectID].Add(targetObjectID, new AttributeCollectionValue()); } } continue; } sensingLocation = new Vec3D(senLocation); targetsLocation = new Vec3D(tarLocation); isSensed = false; distance = sensingLocation.ScalerDistanceTo(targetsLocation); sav = sensingProxy["Sensors"].GetDataValue() as SensorArrayValue; foreach (SensorValue sv in sav.sensors) { if (distance < sv.maxRange) { //Find obstructions List <SimulationObjectProxy> obstructions = FindObstructions(sensingLocation, targetsLocation); foreach (KeyValuePair <string, List <ConeValue> > kvp in sv.ranges) { //Key is the attribute being sensed, value is a list of cones if (kvp.Key == "All") { atts = new AttributeCollectionValue(); if (singleObjectView.ContainsKey(targetObjectID)) { atts = singleObjectView[targetObjectID]; } SenseAllAttributes(ref atts, targetProxy); singleObjectView[targetObjectID] = atts; isSensed = true; } else //not an All sensor, so run detection algorithm {//Added in main-line if (!emitters.emitters.ContainsKey(kvp.Key)) { continue; } //Custom attributes fix: DataValue currentDataValue; try { currentDataValue = targetProxy[kvp.Key].GetDataValue(); } catch { currentDataValue = targetProxy["CustomAttributes"].GetDataValue(); currentDataValue = ((CustomAttributesValue)currentDataValue)[kvp.Key]; //will throw an error here if object doesn't contain custom atts, or //if it doesnt contain the specified custom att. } bool isObstructed = false; foreach (SimulationObjectProxy reg in obstructions) { foreach (string attributeBlocked in ((StringListValue)reg["BlocksSensorTypes"].GetDataValue()).strings) { if (kvp.Key == attributeBlocked) { isObstructed = true; } } } if (isObstructed) { detectedAttribute = new DetectedAttributeValue(); detectedAttribute.value = DataValueFactory.BuildValue(currentDataValue.dataType); detectedAttribute.confidence = 0; //continue; } else { targetsAttribute = DataValueFactory.BuildFromDataValue(currentDataValue); //ev is emitters Dictionary <string, double> emitterCollection = emitters.emitters[kvp.Key]; detectedAttribute = new DetectedAttributeValue(); detectedAttribute = ObjectMath.Detection(senLocation, tarLocation, targetsAttribute, kvp.Value, emitterCollection, obstructions, ref randomGenerator); } if (detectedAttribute != null) { singleAttributeCollection = new AttributeCollectionValue(); if (singleObjectView.ContainsKey(targetObjectID)) { singleAttributeCollection = singleObjectView[targetObjectID]; } AddAttributeToACV(ref singleAttributeCollection, kvp.Key, detectedAttribute); isSensed = true; } } }//end foreach attribute in sensor //if the object has any attributes sensed, fill in some other info for the object's view. if (isSensed) { detectedAttribute = new DetectedAttributeValue(); detectedAttribute.stdDev = 100; detectedAttribute.value = targetProxy["ID"].GetDataValue(); if (singleAttributeCollection == null) { singleAttributeCollection = new AttributeCollectionValue(); } if (!singleObjectView.ContainsKey(targetObjectID)) { singleObjectView.Add(targetObjectID, singleAttributeCollection); } singleAttributeCollection = singleObjectView[targetObjectID]; AddAttributeToACV(ref singleAttributeCollection, "ID", detectedAttribute); detectedAttribute = new DetectedAttributeValue(); detectedAttribute.stdDev = 100; detectedAttribute.value = targetProxy["OwnerID"].GetDataValue(); AddAttributeToACV(ref singleAttributeCollection, "OwnerID", detectedAttribute); } //end if isSensed. } } //end foreach sensor in sensor array if (singleObjectView.ContainsKey(targetObjectID)) { AttributeCollectionValue attr = singleObjectView[targetObjectID]; if (!allObjectsViews.ContainsKey(sensorObjectID)) { allObjectsViews.Add(sensorObjectID, new Dictionary <string, AttributeCollectionValue>()); } if (!objectViews.ContainsKey(sensorObjectID)) { objectViews.Add(sensorObjectID, new ObjectsAttributeCollection()); } if (attr.attributes.ContainsKey("CustomAttributes")) { DataValue t = ((DetectedAttributeValue)attr["CustomAttributes"]).value; double conf = ((DetectedAttributeValue)attr["CustomAttributes"]).confidence; Dictionary <string, DataValue> copiedDict = CopyFromCustomAttributes(((CustomAttributesValue)t).attributes); t = new CustomAttributesValue(); ((CustomAttributesValue)t).attributes = copiedDict; attr.attributes.Remove("CustomAttributes"); attr.attributes.Add("CustomAttributes", DataValueFactory.BuildDetectedValue(t, Convert.ToInt32(conf))); } //update the global "allObjectViews". The return from UpdateObject is the collection of attributes //that have changed. These attributes are stored in allObjectsViews and then sent out //to users. AttributeCollectionValue changedAttributes = objectViews[sensorObjectID].UpdateObject(targetObjectID, attr); //if (changedAttributes != null && selectedRangeRingLevel == RangeRingLevels.FULL) //{//the only way to sense a "target" here is for FULL ring display // CalculateRangeRings(ref changedAttributes, ref targetProxy); //} if (changedAttributes != null) { allObjectsViews[sensorObjectID].Add(targetObjectID, changedAttributes); } else//this is so there is at least the empty entry for the detected object so //you still know it is detected. { if (!allObjectsViews[sensorObjectID].ContainsKey(targetObjectID)) { allObjectsViews[sensorObjectID].Add(targetObjectID, new AttributeCollectionValue()); } } } else { if (objectViews.ContainsKey(sensorObjectID)) { if (objectViews[sensorObjectID].ContainsObject(targetObjectID)) { objectViews[sensorObjectID].RemoveObject(targetObjectID); //if you once knew of this object, and now don't, remove it from object's view. } } } } //end emitter detection } //end if target is visible } } } //end foreach target object } //end if sensor is visible } //end of foreach sensing object } //end of Foreach sensor network if (x > 0) { //Console.Out.WriteLine("ViewPro: {0} objects were sensing at time {1}.", x, currentTick / 1000); } }