Skip to content

Commit 60de368

Browse files
committed
apply SeaTalk autopilot datagrams to model
1 parent a801022 commit 60de368

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

modules/seatalk/src/seatalk/seatalk_apply.hpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
11
#pragma once
22

3+
#include <string.h>
34
#include <ship_data_model.hpp>
45

56
#include "seatalk_decoder.hpp"
67

78
namespace seatalk {
89

10+
inline ship_data_model::AutopilotMode seatalk_model_autopilot_mode(SeaTalkAutopilotMode mode) {
11+
switch (mode) {
12+
case SeaTalkAutopilotMode::standby: return ship_data_model::AutopilotMode::compass;
13+
case SeaTalkAutopilotMode::auto_heading: return ship_data_model::AutopilotMode::compass;
14+
case SeaTalkAutopilotMode::vane: return ship_data_model::AutopilotMode::wind;
15+
case SeaTalkAutopilotMode::track: return ship_data_model::AutopilotMode::nav;
16+
}
17+
return ship_data_model::AutopilotMode::compass;
18+
}
19+
20+
inline void seatalk_copy_text(char* dst, size_t dst_len, const char* src) {
21+
if (!dst || dst_len == 0) return;
22+
dst[0] = '\0';
23+
if (!src) return;
24+
strncpy(dst, src, dst_len - 1);
25+
dst[dst_len - 1] = '\0';
26+
}
27+
928
template<typename Real>
1029
bool apply_seatalk_decoded(const SeaTalkDecoded<Real>& decoded,
1130
ship_data_model::DataModel<Real>& model,
@@ -61,6 +80,66 @@ bool apply_seatalk_decoded(const SeaTalkDecoded<Real>& decoded,
6180
}
6281
return true;
6382

83+
case SeaTalkDecodedKind::autopilot_state: {
84+
auto& ap = model.autopilot.controller;
85+
ap.mode.value = seatalk_model_autopilot_mode(decoded.autopilot_mode);
86+
ap.enabled.value = decoded.autopilot_mode != SeaTalkAutopilotMode::standby;
87+
ap.heading_deg.set(decoded.value, now_us);
88+
if (decoded.secondary_valid) ap.heading_command_deg.set(decoded.secondary_value, now_us);
89+
model.ins.imu.heading_deg.set(decoded.value, now_us);
90+
model.ins.imu.heading_magnetic_deg.set(decoded.value, now_us);
91+
if (decoded.third_valid) {
92+
model.steering.rudder.angle_deg.set(decoded.third_value, now_us);
93+
model.steering.rudder.source.value = source;
94+
model.steering.rudder.last_update_us = now_us;
95+
}
96+
if (decoded.alarm) {
97+
model.autopilot.status.warnings.set(decoded.code, now_us);
98+
seatalk_copy_text(model.notifications.messages.event.event_id, sizeof(model.notifications.messages.event.event_id), "seatalk_ap_alarm");
99+
seatalk_copy_text(model.notifications.messages.event.event_source, sizeof(model.notifications.messages.event.event_source), "seatalk");
100+
model.notifications.messages.event.event_state = 'A';
101+
seatalk_copy_text(model.notifications.messages.event.event_text, sizeof(model.notifications.messages.event.event_text), decoded.label);
102+
model.notifications.messages.event.field_count.set(1, now_us);
103+
model.notifications.messages.event.source.value = source;
104+
model.notifications.messages.event.last_update_us = now_us;
105+
}
106+
return true;
107+
}
108+
109+
case SeaTalkDecodedKind::autopilot_key:
110+
seatalk_copy_text(model.notifications.messages.event.event_id, sizeof(model.notifications.messages.event.event_id), "seatalk_ap_key");
111+
seatalk_copy_text(model.notifications.messages.event.event_source, sizeof(model.notifications.messages.event.event_source), "seatalk");
112+
model.notifications.messages.event.event_state = decoded.long_press ? 'L' : 'S';
113+
seatalk_copy_text(model.notifications.messages.event.event_text, sizeof(model.notifications.messages.event.event_text), decoded.label);
114+
model.notifications.messages.event.field_count.set(1, now_us);
115+
model.notifications.messages.event.source.value = source;
116+
model.notifications.messages.event.last_update_us = now_us;
117+
return true;
118+
119+
case SeaTalkDecodedKind::navigation_to_waypoint:
120+
model.route.apb.xte_nmi.set(decoded.value, now_us);
121+
if (decoded.secondary_valid) {
122+
model.route.apb.present_to_destination_bearing_deg.set(decoded.secondary_value, now_us);
123+
model.route.apb.heading_to_steer_deg.set(decoded.secondary_value, now_us);
124+
model.route.waypoint.bearing_magnetic_deg.set(decoded.secondary_value, now_us);
125+
}
126+
if (decoded.third_valid) {
127+
model.route.apb.origin_to_destination_bearing_deg.set(decoded.secondary_value, now_us);
128+
model.route.waypoint.distance_nmi.set(decoded.third_value, now_us);
129+
model.route.rmb.range_nmi.set(decoded.third_value, now_us);
130+
}
131+
model.route.apb.mode_hint.value = ship_data_model::AutopilotMode::nav;
132+
model.route.apb.source.value = source;
133+
model.route.apb.last_update_us = now_us;
134+
model.route.waypoint.source.value = source;
135+
model.route.waypoint.last_update_us = now_us;
136+
return true;
137+
138+
case SeaTalkDecodedKind::compass_variation:
139+
model.ins.imu.magnetic_variation_deg.set(decoded.value, now_us);
140+
model.gnss.fix.declination_deg.set(decoded.value, now_us);
141+
return true;
142+
64143
case SeaTalkDecodedKind::trip_distance:
65144
model.sea.trip_distance_nmi.set(decoded.value, now_us);
66145
model.sea.source.value = source;

0 commit comments

Comments
 (0)