alert
serviceAircraft
: the aircraftFlightPlan
: the FlightPlan, which contains WaypointsWaypoint
: the WaypointsAlarm
: the AlarmsFeature
class, because they have a geometrical position:Aircraft
: the aircraftWaypoint
: the WaypointsAircraft
has:Label
Geometry
(the Aircraft
is a subclass of Feature
), which in this case specify the latitude and longitude of the AircraftFlightPlan
that the Aircraft followsAlarm
sAircraft
refer to a Aircraft in the tacticalEnv model.
Alarm
has:AlarmNumber
: the number of the AlarmAlarmMessage
: the message of the AlarmAlarmType
( WhiteAlarm
, AmberAlarm
, or RedAlarm
). The AlarmType represents the danger of the AlarmFlightPlan
has:Label
, which is the name of the FlightPlanFlightPlan
refer to a FlightPlan in the tacticalEnv model.
Waypoint
has:Label
, which is the name of the WaypointGeometry
(the Waypoint
is a subclass of Feature
), which in this case specify the latitude and longitude of the WaypointWaypointType
( NAV
or ATT
). NAV are navigation points (used for example to define the FlightPlan), and ATT are landing waypointsWaypoint
refer to a Waypoint in the tacticalEnv model.
Aircraft
class in the OntologyWaypoint
class in the Ontologyalert
service to the Alarm
class in the OntologyAircraft
and the Waypoint
will directly come from Java classes, whereas the Alarm
will have to be constructed from the content of a service. The mappings will be specified through a Jena model mapping.
Label
DataProperty on the Thing
classAircraft
class<classTypes> <class path="org.da.protoframework.tacticalenv.common.model.Aircraft" nameMethod="getName"> <type object="track" /> </class> </classTypes> <object name="track" className="Aircraft"> <geometry /> <dataProperty name="label" property="Label" isName="true"/> </object>For the Waypoint:
Label
DataProperty on the Thing
classWaypoint
classhasWaypointType
property on the Waypoint
class. As there is only one Waypoint type of course, this mapping will have a cardinality of one
isWaypointFrom
property on the Waypoint
class. As there is only one Flightplan for one Waypoint in our case, this mapping will have a cardinality of one
<classTypes> <class path="org.da.protoframework.tacticalenv.common.model.Waypoint" nameMethod="getName"> <type object="waypoint" /> </class> </classTypes> <object name="waypoint" className="Waypoint"> <geometry /> <dataProperty name="label" property="Label" isName="true"/> <property name="hasWaypointType" eltRef="WaypointType" property="hasWaypointType" cardinality="one" /> <property name="isWaypointFrom" eltRef="flightplan" property="isWaypointFrom" cardinality="one" /> </object>For the FlightPlan:
Label
DataProperty on the Thing
classhasWaypoint
property on the Flightplan
class. As there are as many Waypoints per one Flightplan, this mapping will have a cardinality of unbound
<classTypes> <class path="org.da.protoframework.tacticalenv.common.model.Flightplan" nameMethod="getName"> <type object="flightplan" /> </class> </classTypes> <object name="flightplan" className="FlightPlan"> <dataProperty name="label" property="Label" isName="true"/> <property name="waypoint" eltRef="waypoint" property="hasWaypoint" inverseProperty="isWaypointFrom" cardinality="unbound" inverseCardinality="one" /> </object>
<object name="alarm" className="Alarm"> <dataProperty name="number" property="AlarmNumber"/> <dataProperty name="message" property="AlarmMessage"/> <property name="type" eltRef="alarmType" property="hasAlarmType" cardinality="one" /> </object>
alert
service<application name="fillOntology"> <deployment> <lib url="FillOntology.jar" /> </deployment> <modules> <module name="fillOntology"> <implementation path="org.da.owl.FillOntology" > <initEntryPoint method="init" /> <defaultReceiveEntryPoint method="subscribe" /> </implementation> <interfaces> <eventReceived service="alert" /> <eventReceived service="flightplansModel" uri="http://dassault-aviation.com/tacticalenv"/> <eventReceived service="waypointsModel" uri="http://dassault-aviation.com/tacticalenv"/> <subscribe service="aircraftsModel" uri="http://dassault-aviation.com/tacticalenv"/> <requestSend service="applyOperations" uri="http://dassault-aviation.com/jena" /> </interfaces> </module> </modules> </application>It will be notified from the following services:
flightplansModel
and waypointsModel
services to set the flightplan and the WaypointsaircraftsModel
service to update the position of the Aircraftalert
service to receive the alerting statusapplyOperations
service[1]
public void init(Module module) { mappings = new ObjectMappings(); URL url = this.getClass().getResource("objectMappings.xml"); mappings.parse(module, url, true); // here we create operations for the Waypoints and the Flightplan, the Aircraft, and the Alerts wptOp = new ElementsOperations(module, mappings); acOp = new ElementsOperations(module, mappings); alertOp = new ElementsOperations(module, mappings); }
flightplansModel
, waypointsModel
, aircraftsModel
, and alert
services.public synchronized void subscribe(ServiceInstance service) { NamespaceKey key = service.getKey(); if (key.equals(ENV_WAYPOINTS)) { this.waypointsReceived = true; if (flightplansReceived) { receiveWaypointsAndFlightPlans(service); } } else if (key.equals(ENV_FLIGHTPLANS)) { this.flightplansReceived = true; if (waypointsReceived) { receiveWaypointsAndFlightPlans(service); } } else if (key.equals(ENV_AIRCRAFTS)) { if (waypointsReceived && flightplansReceived) { receiveAircrafts(service); } } else if (service.getName().equals("alert")) { receiveAlert(service); } }As you can see, we will update the Ontology with the content of both the Waypoints and the Flightplan when both the tacticalEnv model
flightplansModel
and waypointsModel
have been notified.
private void receiveWaypointsAndFlightPlans(ServiceInstance service) { // waypoints Waypoints waypoints = (Waypoints) envWaypointsService.getDataValue("waypoints"); Iterator<Waypoint> it = waypoints.getWaypoints().values().iterator(); while (it.hasNext()) { Waypoint waypoint = it.next(); // this method will ensure that the Waypoint individual will be created // we don't need to set the Label of the Waypoint, because it is already taken care of in the mappings MappedElement elt = wptOp.addElement(waypoint); float latitude = waypoint.getLatitude(); float longitude = waypoint.getLongitude(); // will create the geometry of the Waypoint individual in the Ontology elt.setPosition(latitude, longitude); // specifies the hasWaypointType property, which links to the appropriate WaypointType element String type = waypoint.getType(); if (type.equals("NAV")) { elt.addProperty("hasWaypointType", "NAV"); } else if (type.equals("ATT")) { elt.addProperty("hasWaypointType", "ATT"); } } // flightplans Flightplans flightplans = (Flightplans) envFlightplansService.getDataValue("flightplans"); Iterator<Flightplan> it2 = flightplans.getFlightplans().values().iterator(); while (it2.hasNext()) { Flightplan fp = it2.next(); // this method will ensure that the Flightplan individual will be created // we don't need to set the Label of the Flightplan, because it is already taken care of in the mappings MappedElement flightplanElt = wptOp.addElement(fp); Iterator<String> it3 = fp.getWaypoints().iterator(); while (it3.hasNext()) { String name = it3.next(); // specifies a hasWaypoint property, which links to one Waypoint individual flightplanElt.addProperty("waypoint", name); } } // handle the creation of the operations. All the effective Ontology update will be done in the Jena Module Operations operations = wptOp.create(); applyOperations.setDataValue("operations", operations); applyOperations.invoke(); }As they will only be received once, we only create the indivduals in the Ontology. We don't need to update their position because the position of the Flightplan and the Waypoints won't be updated.
private void receiveAircrafts(ServiceInstance service) { applyOperations.setDataStringValue("reqSchema", SCHEMA); Aircrafts envAircrafts = (Aircrafts) service.getValue("aircrafts"); Iterator<Aircraft> it = envAircrafts.getAircrafts().values().iterator(); while (it.hasNext()) { Aircraft aircraft = it.next(); if (aircraft.getName().equals("falcon")) { float latitude = aircraft.getLatitude(); float longitude = aircraft.getLongitude(); // this method will ensure that the Aircraft individual will be created // we don't need to set the Label of the Aircraft, because it is already taken care of in the mappings MappedElement elt = acOp.addElement(aircraft); if (!acReceived) { // will create the geometry of the Aircraft individual in the Ontology elt.setPosition(latitude, longitude); } else { // will update the geometry of the Aircraft individual in the Ontology acOp.updateElementPosition("track", aircraft.getName(), latitude, longitude); } } } // handle the creation of the operations. All the effective Ontology update will be done in the Jena Module Operations operations = acOp.create(); acOp.clearOperations(); applyOperations.setDataValue("operations", operations); applyOperations.invoke(); acReceived = true; }We will create the
falcon
Aircraft for the first notification, then for further notifications we will just update the existing Individual position.
alert
service contains the alert itself and its status:<event name="alert"> <data name="alert" type="alert" desc="the alert"/> <data name="status" type="alertStatus" desc="the alert status"/> </event>The associated types are:
<enumType name="alertType" > <enumValue name="WARNING" /> <enumValue name="CAUTION" /> <enumValue name="ADVISORY" /> </enumType> <enumType name="alertStatus" > <enumValue name="NEW" /> <enumValue name="REMOVED" /> </enumType> <structType name="alert"> <field name="number" type="int" /> <field name="type" type="alertType" /> <field name="content" type="string" /> </structType>We will use the Alert
number
, type
, and status
:number
field specifies the name of the Alarm
individual to create or removetype
field specifies the AlarmType
individual on which we must link tostatus
data specifies if we need to create the individual or remove an existing oneprivate void receiveAlert(ServiceInstance service) { List<Object> alertObj = service.getData("alert").getValueAsStructure(); int number = alertType.getFieldValueAsInt("number", alertObj); String alarmType = alertType.getFieldValueAsString("type", alertObj); int status = service.getData("status").getValueAsInt(); applyOperations.setDataStringValue("reqSchema", SCHEMA); // create an alarm MappedElement elt = alertOp.addElement("alarm", "alarm" + number); // add the AlarmNumber dataProperty elt.addDataProperty("number", number); // specifies the hasAlarmType property, which links to the appropriate AlarmType element switch (alarmType) { case "WARNING": elt.addProperty("type", "RedAlarm"); break; case "CAUTION": elt.addProperty("type", "AmberAlarm"); break; case "ADVISORY": elt.addProperty("type", "WhiteAlarm"); break; } // if status == 1 the Alarm was removed from the Alarm list if (status == 1) { // in this case, the existing Alarm element will be deleted from the Ontology rather than created elt.setRemoved(true); } // handle the creation of the operations. All the effective Ontology update will be done in the Jena Module Operations operations = alertOp.create(); alertOp.clearOperations(); applyOperations.setDataValue("operations", operations); applyOperations.invoke(); }
Copyright 2017-2020 Dassault Aviation. All Rights Reserved. Documentation and source under the LGPL v3 licence