Expand description
Target tracking from radar plots and AIS reports, collision assessment and avoidance.
An observation gives a numbered target’s position at an instant. A
TargetTrack derives course and speed (least-squares over recent fixes,
or as reported by the target), an extrapolated position and an age.
Traffic holds the tracks, ingests observations, drops silent targets and
produces a TrafficView plus events: TrafficEvent::TargetAcquired,
TrafficEvent::TargetLost, TrafficEvent::ObservationRejected (out of
order or implausible speed).
Thresholds are vessel settings in a TrackingPolicy: fixes to acquire,
stale and lost timeouts, maximum plausible speed.
Collision assessment: assess for one encounter (CPA/TCPA, bearing at
CPA, bearing rate, bow crossing range, CollisionRisk against a
CpaPolicy); assess_track for a tracked target; assess_traffic
for the whole picture against own ship’s snapshot, raising
TrafficEvent::CpaAlarm. Give-way rules live in kinavis-colregs; their
permitted manoeuvre comes back as ManoeuvreConstraints, within which
avoid and avoid_all find the smallest course alteration that opens
one or all targets to the requested passing distance.
use kinavis_kernel::{Instant, Position, Speed, TargetId, Utc};
use kinavis_traffic::{TargetObservation, Traffic, TrackingPolicy, TrafficEvent, WhenFull};
use core::time::Duration;
// Three plots to acquire, stale after half a minute, dropped after three,
// nothing faster than sixty knots; and when the picture is full, the
// target that has gone quietest makes way for the newcomer.
let policy = TrackingPolicy::new(
3,
Duration::from_secs(30),
Duration::from_secs(180),
Speed::from_knots(60.0)?,
)?
.when_full(WhenFull::EvictStalest);
let mut traffic = Traffic::new(policy);
// Three radar plots of one target, a minute apart, heading north at
// twelve knots: a fifth of a mile a minute.
let start = Instant::<Utc>::from_unix_seconds(1_789_000_000);
let target = TargetId::new(7);
let mut acquired = false;
for minute in 0_u32..3 {
let position = Position::from_degrees(50.0 + 0.2 * f64::from(minute) / 60.0, -1.0)?;
let at = start.checked_add(Duration::from_secs(60 * u64::from(minute))).unwrap();
let events = traffic.ingest(TargetObservation::new(target, position, at))?;
acquired |= events
.iter()
.any(|event| matches!(event, TrafficEvent::TargetAcquired { .. }));
}
assert!(acquired);
// Two and a half minutes in, the picture has it half a mile up the track.
let now = start.checked_add(Duration::from_secs(150)).unwrap();
let view = traffic.view(now);
let seen = &view.targets()[0];
let motion = seen.motion.unwrap();
assert_eq!(format!("{:.0}", motion.course_over_ground), "000°T");
assert_eq!(format!("{:.1}", motion.speed_over_ground.knots()), "12.0");
assert_eq!(format!("{:.3}", seen.position.latitude().degrees()), "50.008");
assert!(!seen.stale);
// Ten minutes of silence and it is gone.
let later = now.checked_add(Duration::from_secs(600)).unwrap();
let events = traffic.sweep(later);
assert!(matches!(events[0], TrafficEvent::TargetLost { target, .. } if target == TargetId::new(7)));
assert!(traffic.is_empty());§Feature flags
std(default) — standard library maths in the kernel.libm— forno_stdtargets:--no-default-features --features libm.serde— serialisation of observations, policies and view entries.
No allocation; builds for bare-metal targets. The picture is stored inline
(MAX_TARGETS tracks × MAX_TRACK_HISTORY fixes), so Traffic is
large: keep it behind a reference or in a static.
Structs§
- Avoidance
Manoeuvre - Manoeuvre result.
- Collision
Assessment - Assessed encounter.
- Collision
Picture - All tracked targets assessed against own ship at one instant.
- CpaPolicy
- CPA and TCPA limits: vessel settings.
- Manoeuvre
Constraints - Manoeuvre constraints.
- Target
Assessment - One target’s assessment.
- Target
Observation - One sighting of a target: radar bearing and range, AIS position report, or any other position source.
- Target
Track - Target track held by the traffic picture.
- Target
View - One target in the view.
- Tracking
Policy - Track acquisition and loss thresholds: vessel settings.
- Traffic
- Traffic picture: up to
Ntracked targets. - Traffic
View - Traffic picture at one instant: read model built by
Traffic::view, with the source picture’s capacity.
Enums§
- Collision
Risk - Risk level of an encounter.
- Permitted
Sides - Permitted alteration side.
- Track
Status - Track acquisition status.
- Traffic
Event - Traffic picture event.
- When
Full - Behaviour for a new target when the picture is full.
Constants§
- ALTERATION_
STEP_ DEG - Search step for permitted alterations, degrees.
- MAX_
ALTERATION_ DEG - Maximum alteration: a reversal.
- MAX_
TARGETS - Default picture capacity.
- MAX_
TRACK_ HISTORY - Maximum fixes per track.
Functions§
- assess
- Assesses one encounter from own course and speed, the contact’s bearing and range, and the target’s course and speed.
- assess_
track - Assesses a tracked target against own ship at
now, using the track’s extrapolated position and motion. - assess_
traffic - Assesses every target against own ship from the snapshot, reporting
TrafficEvent::CpaAlarmfor each dangerous one. - avoid
- Smallest permitted alteration giving
targeta CPA of at leastdesired. - avoid_
all - Smallest permitted alteration giving every target a CPA of at least
desired, or leaving it opening.