Skip to main content

Crate kinavis_traffic

Crate kinavis_traffic 

Source
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 — for no_std targets: --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§

AvoidanceManoeuvre
Manoeuvre result.
CollisionAssessment
Assessed encounter.
CollisionPicture
All tracked targets assessed against own ship at one instant.
CpaPolicy
CPA and TCPA limits: vessel settings.
ManoeuvreConstraints
Manoeuvre constraints.
TargetAssessment
One target’s assessment.
TargetObservation
One sighting of a target: radar bearing and range, AIS position report, or any other position source.
TargetTrack
Target track held by the traffic picture.
TargetView
One target in the view.
TrackingPolicy
Track acquisition and loss thresholds: vessel settings.
Traffic
Traffic picture: up to N tracked targets.
TrafficView
Traffic picture at one instant: read model built by Traffic::view, with the source picture’s capacity.

Enums§

CollisionRisk
Risk level of an encounter.
PermittedSides
Permitted alteration side.
TrackStatus
Track acquisition status.
TrafficEvent
Traffic picture event.
WhenFull
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::CpaAlarm for each dangerous one.
avoid
Smallest permitted alteration giving target a CPA of at least desired.
avoid_all
Smallest permitted alteration giving every target a CPA of at least desired, or leaving it opening.