(* calculate arctan(y/x) *) open TypeBase open TypeTracks node myarctan(y, x : float) returns (atan : float) var l6 : float; l4 : bool; l1 : float; let atan = if l4 then if x <. 0.0 then CstPhysics.pi +. l1 else l1 else CstPhysics.pi /. 2.0 *. Math.sign(y); (* l6 = (activate div every l4 initial default 0.0)(y, x); *) l6 = if l4 then y /. x else 0.0 -> pre l6; l4 = Math.abs(x) >. 0.1; l1 = Mathext.atanr(l6); tel (* compute if a given track is equal to one of the mission tracks belonging to the mission track array at the previous tick *) fun missiontrackequalsprevious(previousone, actualone : TypeTracks.tmissiontrack) returns (equal : bool) let equal = 0 <> previousone.m_id & previousone.m_id = actualone.m_id or Math.abs(previousone.m_pos.x -. actualone.m_pos.x) <. 100.0 & Math.abs(previousone.m_pos.y -. actualone.m_pos.y) <. 100.0 & not (Math.abs(previousone.m_pos.x) <. 0.1 & Math.abs(previousone.m_pos.y) <. 0.1 & Math.abs(actualone.m_pos.x) <. 0.1 & Math.abs(actualone.m_pos.y) <. 0.1 ) tel (* compute track visibility (appearance on radar screen) according to track position and speed *) fun calctrackvisible1(position : TypeBase.tposition; speed : TypeBase.tspeed) returns (trackvisible : bool) let trackvisible = not (Math.abs(position.x) <. 0.001 & Math.abs(position.y) <. 0.001 & Math.abs(speed.sx) <. 0.001 & Math.abs(speed.sy) <. 0.001); tel fun missiontrackexist1(acc_tracknumber : int; missiontrack, previousmissiontrack : TypeTracks.tmissiontrack) returns (tracknumbertoset : int) let tracknumbertoset = if missiontrackequalsprevious(missiontrack, previousmissiontrack) & 0 <> previousmissiontrack.m_tracknumber then previousmissiontrack.m_tracknumber else acc_tracknumber; tel (* compute if a given track is equal to one of the mission tracks belonging to the mission track array at the previous tick *) fun missiontrackequalsprevious_orig(previousone, actualone : TypeTracks.tmissiontrack) returns (equal : bool) var l43 : bool; let l43 = previousone.m_tracknumber <> 0; equal = l43 & (l43 & 0 <> previousone.m_id & previousone.m_id = actualone.m_id or Math.abs(previousone.m_pos.x -. actualone.m_pos.x) <. 100.0 & Math.abs(previousone.m_pos.y -. actualone.m_pos.y) <. 100.0 & not (Math.abs(previousone.m_pos.x) <. 0.1 & Math.abs(previousone.m_pos.y) <. 0.1 & Math.abs(actualone.m_pos.x) <. 0.1 & Math.abs(actualone.m_pos.y) <. 0.1)); tel fun util_radtodeg(input1 : float) returns (output1 : float) let output1 = input1 /. (2.0 *. CstPhysics.pi) *. 360.0; tel fun util_degtorad(input1 : float) returns (output1 : float) let output1 = 2.0 *. CstPhysics.pi *. input1 /. 360.0; tel (* if speedabs is small (speed.x and speed.y are also small), trackangle is set to 0. otherwise, trackangle is computed to be in the range [-180, 180] degrees thanks to the acosr; sign is given, from the asinr. *) fun calctrackangle(speed : TypeBase.tspeed; speedabs : TypeBase.tmetresseconde) returns (trackangle : float) var l51 : bool; l48, l47 : float; let trackangle = util_radtodeg(if l51 then 0.0 else Mathext.acosr(l47) *. l48) *. (l48 *. Math.sign(Mathext.asinr(speed.sy /. (if l51 then 1.0 else speedabs)))); l51 = speedabs <. 0.01; l48 = Math.sign(l47); l47 = speed.sx /. (if l51 then 1.0 else speedabs); tel (* compute track visibility (appearance on radar screen) according to track position *) fun calctrackvisible(position : TypeBase.tposition) returns (trackvisible : bool) let trackvisible = not (Math.abs(position.x) <. 0.001 & Math.abs(position.y) <. 0.001); tel fun missiontrackexist( missiontrack, previousmissiontrack : TypeTracks.tmissiontrack; acc_tracknumber : int) returns (tracknumbertoset : int) let tracknumbertoset = if missiontrackequalsprevious(missiontrack, previousmissiontrack) then previousmissiontrack.m_tracknumber else acc_tracknumber; tel (* calculate: result = rate of closing / distance *) node calculatevrdivd(vr, d : float) returns (result : float) var l13 : float; l11 : bool; let result = if l11 then l13 else 0.0; (* l13 = (activate div every l11 initial default 0.0)(vr, d); *) l13 = if l11 then vr /. d else 0.0 -> pre l13; l11 = d >. 0.1; tel (* sort two mission tracks according to: 1) their (rate of closing / distance) ratio 2) target type 3) detection or not by the radar *) node trackalowerprioritythanb(a, b : TypeTracks.tmissiontrack) returns (prioritary : bool) let prioritary = a.m_targettype = TypeBase.Ttargettype_friend or not a.m_detectedbyradar or a.m_detectedbyradar & calculatevrdivd(a.m_sr, a.m_d) <. calculatevrdivd(b.m_sr, b.m_d) & b.m_detectedbyradar; tel (* compute if two tracks speeds are equal *) fun comparespeeds(speed1, speed2 : TypeBase.tspeed) returns (equal : bool) let equal = Math.abs(speed1.sx -. speed2.sx) <. 1.0 & Math.abs(speed1.sy -. speed2.sy) <. 1.0; tel (* compute a "prioritized" track number according to its priority and target type *) fun calculateprioritizedtracknb(missiontrack : TypeTracks.tmissiontrack) returns (prioritizedtracknb : int) let prioritizedtracknb = if missiontrack.m_targettype <> TypeBase.Ttargettype_friend & missiontrack.m_priority <> 0 then missiontrack.m_tracknumber else 0; tel (* sort two real inputs *) fun sortreals(a, b : float) returns (newa, newb : float) var l2 : bool; let l2 = a <. b; newb = if l2 then a else b; newa = if l2 then b else a; tel (* compute if two tracks positions are equal *) fun comparepositions(pos1, pos2 : TypeBase.tposition) returns (equal : bool) let equal = Math.abs(pos1.x -. pos2.x) <. 0.1 & Math.abs(pos1.y -. pos2.y) <. 0.1; tel (* compute if two tracks are equal (according to their position and speed) *) fun comparetracks(pos1, pos2 : TypeBase.tposition; v1, v2 : TypeBase.tspeed) returns (equal : bool) let equal = comparepositions(pos1, pos2) & comparespeeds(v1, v2); tel (* set the track number of a mission track *) fun setmissiontracknumber(missiontrack : TypeTracks.tmissiontrack at r; number : int) returns (newmissiontrack : TypeTracks.tmissiontrack at r) let newmissiontrack = { missiontrack with .m_tracknumber = number }; tel (* compute if a mission track is null (or empty) according to its position and speed *) fun missiontrackisnull(missiontrack : TypeTracks.tmissiontrack) returns (isnull : bool) let isnull = comparetracks(missiontrack.m_pos, CstBaseInit.kInitPosition, missiontrack.m_speed, CstBaseInit.kInitSpeed); tel (* calculate the new track number for a mission track, according to: 1) the mission track data 2) the previous mission tracks array 3) the current (highest) track number *) fun calculatemissiontracknumber( previousmissiontracks : TypeArray.tmissiontracksarray; missiontrack : TypeTracks.tmissiontrack at r; currenttracknumber : int) returns (newmissiontrack : TypeTracks.tmissiontrack at r; newtracknumber : int) var setnewtracknumber : bool; previoustracknumber : int; let setnewtracknumber = previoustracknumber = 0 & not missiontrackisnull(missiontrack); newtracknumber = if setnewtracknumber then currenttracknumber + 1 else currenttracknumber; previoustracknumber = fold <> missiontrackexist <(missiontrack)> (previousmissiontracks, 0); newmissiontrack = setmissiontracknumber(missiontrack, if setnewtracknumber then newtracknumber else previoustracknumber); tel (* compute a mission track target type according to its identifier *) fun calculatetracktargettypefromid(id : int) returns (targettype : TypeBase.ttargettype) let targettype = if 0 = id then TypeBase.Ttargettype_unknown else if id <= 500 then TypeBase.Ttargettype_friend else TypeBase.Ttargettype_foe; tel (* calculate the derivative of a value x(n) according to its ante-previous value x(n-2) *) node myderivative(inv, period : float) returns (o : float) var l2 : float; let (* l2 = fby (inv; 2; 0.0); *) l2 = 0.0 fby (0.0 fby inv); o = if Math.abs(l2) <. 0.1 or Math.abs(inv) <. 0.1 then 0.0 else 0.0 -> (inv -. l2) /. (2.0 *. period); tel (* calculate a track speed vector according to the position vector *) node calculatetrackspeedfrompos(position : TypeBase.tposition) returns (speed : TypeBase.tspeed) let speed = { sx = myderivative(position.x, CstPhysics.t); sy = myderivative(position.y, CstPhysics.t) }; tel (* generate the (up to 2) tracks detected by a sensor (radar or iff) from the environment (made of 4 tracks) *) fun selectdetectedtrack(index : int; tracks : TypeArray.ttracksarray; defaulttrack : TypeTracks.ttrack) returns (trackselected : TypeTracks.ttrack) let trackselected = tracks.[index] default defaulttrack; tel (* set the priority of a mission track *) fun setmissiontrackpriority(missiontrack : TypeTracks.tmissiontrack at r; priority : int) returns (newmissiontrack : TypeTracks.tmissiontrack at r) let newmissiontrack = { missiontrack with .m_priority = if missiontrack.m_detectedbyradar then priority else 0 } tel (* invert two mission tracks if the first one is null (or empty) *) fun sortblockmissiontrack(a, b : TypeTracks.tmissiontrack) returns (newa, newb : TypeTracks.tmissiontrack) var l7 : bool; let l7 = missiontrackisnull(a); newb = if l7 then a else b; newa = if l7 then b else a; tel (* sort two mission tracks according to: 1) their (rate of closing / distance) ratio 2) target type 3) detection or not by the radar *) node sortblockpriorities(a, b : TypeTracks.tmissiontrack) returns (newa, newb : TypeTracks.tmissiontrack) var l25 : bool; let l25 = trackalowerprioritythanb(a, b); newb = if l25 then a else b; newa = if l25 then b else a; tel fun position_equal(p1, p2 : TypeBase.tposition) returns (res:bool) let res = (p1.x = p2.x) & (p1.y = p2.y) tel fun speed_equal(s1, s2 : TypeBase.tspeed) returns (res:bool) let res = (s1.sx = s2.sx) & (s1.sy = s2.sy) tel (* convert an iff track (position + identifier) into a mission track (position + speed + distance + rate of closing + detected by radar/iff + tracknumber + target type) *) node convertifftracktomissiontrack(ifftrack : TypeTracks.tifftrack) returns (missiontrack : TypeTracks.tmissiontrack) let missiontrack = { m_pos = ifftrack.i_pos; m_speed = if position_equal(CstBaseInit.kInitPosition, ifftrack.i_pos) then CstBaseInit.kInitSpeed else calculatetrackspeedfrompos(ifftrack.i_pos); m_id = ifftrack.i_id; m_priority = 0; m_d = 0.0; m_sabs = 0.0; m_sr = 0.0; m_detectedbyradar = false; m_detectedbyiff = not (position_equal(ifftrack.i_pos, CstBaseInit.kInitPosition) & ifftrack.i_id = 0); m_tracknumber = 0; m_targettype = calculatetracktargettypefromid(ifftrack.i_id); m_isvisible = calctrackvisible(ifftrack.i_pos); m_angle = 0.0 }; tel (* convert an radar track (position + speed + distance + rate of closing) into a mission track (position + speed + distance + rate of closing + detected by radar/iff + tracknumber + target type) *) fun convertrdrtracktomissiontrack(rdrtrack : TypeTracks.trdrtrack) returns (missiontrack : TypeTracks.tmissiontrack) let missiontrack = { m_pos = rdrtrack.r_pos; m_speed = rdrtrack.r_s; m_id = 0; m_priority = 0; m_d = rdrtrack.r_d; m_sabs = rdrtrack.r_sabs; m_sr = rdrtrack.r_sr; m_detectedbyradar = not (position_equal(rdrtrack.r_pos, CstBaseInit.kInitPosition) & speed_equal(rdrtrack.r_s, CstBaseInit.kInitSpeed) & rdrtrack.r_d = 0.0 & rdrtrack.r_sabs = 0.0 & rdrtrack.r_sr = 0.0); m_detectedbyiff = false; m_tracknumber = 0; m_targettype = TypeBase.Ttargettype_unknown; m_isvisible = calctrackvisible(rdrtrack.r_pos); m_angle = calctrackangle(rdrtrack.r_s, rdrtrack.r_sabs) }; tel (* calculate the magnitude of a vector (2d) *) fun vectnorme(a, b : float) returns (c : float) let c = Mathext.sqrtr(a *. a +. b *. b); tel (* extract the x and y (position) values from a track (ttrack type) *) fun extracttrackposxy(track : TypeTracks.ttrack) returns (x, y : TypeBase.tmetres) let y = track.t_pos.y; x = track.t_pos.x; tel (* elaborate radar track data (position, speed, distance, rate of closing) according to an environment track (position only) *) node elaboraterdrtrack(track : TypeTracks.ttrack) returns (rdrtrack : TypeTracks.trdrtrack) var d, v, vr, vx, vy, x, y : float; l142 : TypeBase.tspeed; let (*activate ifblock1 if d = 0.0 then vr = 0.0; else var xnorm, ynorm : real; let ynorm = y / d; xnorm = x / d; vr = - (vx * xnorm + vy * ynorm); tel returns vr;*) switch d = 0.0 | true do vr = 0.0 | false var xnorm, ynorm : float; do ynorm = y /. d; xnorm = x /. d; vr = -. (vx *. xnorm +. vy *. ynorm); end; (x, y) = extracttrackposxy(track); rdrtrack = { r_pos = { x = x; y = y }; r_s = { sx = vx; sy = vy }; r_d = d; r_sabs = v; r_sr = vr }; v = vectnorme(vx, vy); d = vectnorme(x, y); vy = l142.sy; vx = l142.sx; l142 = calculatetrackspeedfrompos({ x = x; y = y }); tel