Skip to content

Commit

Permalink
Units of .1 working
Browse files Browse the repository at this point in the history
  • Loading branch information
keesverruijt committed Oct 13, 2024
1 parent be7d559 commit 29ab7f4
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 190 deletions.
16 changes: 8 additions & 8 deletions src/furuno/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,23 @@ pub fn new() -> Controls {
ControlType::BearingAlignment,
Control::new_numeric(ControlType::BearingAlignment, -180., 180.)
.unit("Deg")
.wire_scale_factor(1800.)
.wire_scale_factor(1800., true)
.wire_offset(-1.),
);
controls.insert(
ControlType::Gain,
Control::new_auto(ControlType::Gain, 0., 100., HAS_AUTO_NOT_ADJUSTABLE)
.wire_scale_factor(255.),
.wire_scale_factor(255., false),
);
controls.insert(
ControlType::Sea,
Control::new_auto(ControlType::Sea, 0., 100., HAS_AUTO_NOT_ADJUSTABLE)
.wire_scale_factor(255.),
.wire_scale_factor(255., false),
);
controls.insert(
ControlType::Rain,
Control::new_auto(ControlType::Rain, 0., 100., HAS_AUTO_NOT_ADJUSTABLE)
.wire_scale_factor(255.),
.wire_scale_factor(255., false),
);
controls.insert(
ControlType::TargetBoost,
Expand Down Expand Up @@ -80,7 +80,7 @@ pub fn new() -> Controls {
100.,
HAS_AUTO_NOT_ADJUSTABLE,
)
.wire_scale_factor(255.),
.wire_scale_factor(255., false),
);

Controls::new_base(controls)
Expand Down Expand Up @@ -115,7 +115,7 @@ pub fn update_when_model_known(controls: &mut Controls, radar_info: &RadarInfo)
let max_value = 48. * 1852.;
let mut range_control = Control::new_numeric(ControlType::Range, 0., max_value)
.unit("m")
.wire_scale_factor(10. * max_value); // Radar sends and receives in decimeters
.wire_scale_factor(10. * max_value, false); // Radar sends and receives in decimeters
if let Some(range_detection) = &radar_info.range_detection {
if range_detection.complete {
range_control.set_valid_values(range_detection.ranges.clone());
Expand All @@ -126,14 +126,14 @@ pub fn update_when_model_known(controls: &mut Controls, radar_info: &RadarInfo)
controls.insert(
ControlType::NoTransmitStart1,
Control::new_numeric(ControlType::NoTransmitStart1, -180., 180.)
.wire_scale_factor(1800.)
.wire_scale_factor(1800., true)
.wire_offset(-1.),
);
controls.insert(
ControlType::NoTransmitEnd1,
Control::new_numeric(ControlType::NoTransmitEnd1, -180., 180.)
.unit("Deg")
.wire_scale_factor(1800.)
.wire_scale_factor(1800., true)
.wire_offset(-1.),
);

Expand Down
38 changes: 25 additions & 13 deletions src/navico/command.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use log::{debug, trace};
use num_traits::ToPrimitive;
use std::cmp::min;
use std::cmp::{max, min};
use tokio::net::UdpSocket;

use crate::radar::{RadarError, RadarInfo, SharedRadars};
Expand Down Expand Up @@ -69,8 +69,19 @@ impl Command {
Ok(())
}

fn mod_degrees(a: i32) -> i32 {
(a + 720) % 360
fn scale_100_to_byte(a: f32) -> u8 {
// Map range 0..100 to 0..255
let mut r = a * 255.0 / 100.0;
if r > 255.0 {
r = 255.0;
} else if r < 0.0 {
r = 0.0;
}
r as u8
}

fn mod_deci_degrees(a: i32) -> i32 {
(a + 7200) % 3600
}

fn near(a: i32, b: i32) -> bool {
Expand Down Expand Up @@ -121,8 +132,9 @@ impl Command {
pub async fn set_control(&mut self, cv: &ControlValue) -> Result<(), RadarError> {
let value = cv
.value
.parse::<i32>()
.parse::<f32>()
.map_err(|_| RadarError::MissingValue(cv.id))?;
let deci_value = (value * 10.0) as i32;
let auto: u8 = if cv.auto.unwrap_or(false) { 1 } else { 0 };

let mut cmd = Vec::with_capacity(6);
Expand All @@ -136,20 +148,20 @@ impl Command {
}

ControlType::Range => {
let decimeters: i32 = self.valid_range(value) * 10;
let decimeters: i32 = self.valid_range(deci_value / 10) * 10; //TODO
log::trace!("range {value} -> {decimeters}");

cmd.extend_from_slice(&[0x03, 0xc1]);
cmd.extend_from_slice(&decimeters.to_le_bytes());
}
ControlType::BearingAlignment => {
let value: i16 = Self::mod_degrees(value) as i16 * 10;
let value: i16 = Self::mod_deci_degrees(deci_value) as i16;

cmd.extend_from_slice(&[0x05, 0xc1]);
cmd.extend_from_slice(&value.to_le_bytes());
}
ControlType::Gain => {
let v = min((value + 1) * 255 / 100, 255) as u8;
let v = Self::scale_100_to_byte(value);
let auto = auto as u32;

cmd.extend_from_slice(&[0x06, 0xc1, 0x00, 0x00, 0x00, 0x00]);
Expand Down Expand Up @@ -181,7 +193,7 @@ impl Command {
cmd.extend_from_slice(&[0x11, 0xc1, 0x01, 0x00, value as i8 as u8, 0x04]);
}
} else {
let v: i32 = min((value + 1) * 255 / 100, 255);
let v: u32 = Self::scale_100_to_byte(value) as u32;
let auto = auto as u32;

cmd.extend_from_slice(&[0x06, 0xc1, 0x02]);
Expand All @@ -190,11 +202,11 @@ impl Command {
}
}
ControlType::Rain => {
let v = min((value + 1) * 255 / 100, 255) as u8;
let v = Self::scale_100_to_byte(value);
cmd.extend_from_slice(&[0x06, 0xc1, 0x04, 0, 0, 0, 0, 0, 0, 0, v]);
}
ControlType::SideLobeSuppression => {
let v = min((value + 1) * 255 / 100, 255) as u8;
let v = Self::scale_100_to_byte(value);

cmd.extend_from_slice(&[0x06, 0xc1, 0x05, 0, 0, 0, auto, 0, 0, 0, v]);
}
Expand Down Expand Up @@ -256,7 +268,7 @@ impl Command {
cmd.extend_from_slice(&value.to_le_bytes());
}
ControlType::AntennaHeight => {
let value = value as u16 * 10;
let value = deci_value as u16;
cmd.extend_from_slice(&[0x30, 0xc1, 0x01, 0, 0, 0]);
cmd.extend_from_slice(&value.to_le_bytes());
cmd.extend_from_slice(&[0, 0]);
Expand All @@ -272,8 +284,8 @@ impl Command {
log::info!("{}: Send command {:02X?}", self.info.key(), cmd);
self.send(&cmd).await?;

if self.fake_errors && cv.id == ControlType::Rain && value > 10 {
return Self::generate_fake_error(value);
if self.fake_errors && cv.id == ControlType::Rain && value > 10. {
return Self::generate_fake_error(value as i32);
}
Ok(())
}
Expand Down
25 changes: 24 additions & 1 deletion src/navico/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use tokio_graceful_shutdown::{SubsystemBuilder, SubsystemHandle};

use crate::locator::{LocatorId, RadarListenAddress, RadarLocator};
use crate::radar::{DopplerMode, Legend, RadarInfo, SharedRadars};
use crate::settings::ControlValue;
use crate::settings::{ControlType, ControlValue};
use crate::util::c_string;
use crate::util::PrintableSlice;

Expand Down Expand Up @@ -476,3 +476,26 @@ pub fn create_br24_locator() -> Box<dyn RadarLocator + Send> {
let locator = NavicoBR24Locator {};
Box::new(locator)
}

const BLANKING_SETS: [(usize, ControlType, ControlType); 4] = [
(
0,
ControlType::NoTransmitStart1,
ControlType::NoTransmitEnd1,
),
(
1,
ControlType::NoTransmitStart2,
ControlType::NoTransmitEnd2,
),
(
2,
ControlType::NoTransmitStart3,
ControlType::NoTransmitEnd3,
),
(
3,
ControlType::NoTransmitStart4,
ControlType::NoTransmitEnd4,
),
];
89 changes: 26 additions & 63 deletions src/navico/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use tokio::time::{sleep, sleep_until, Instant};
use tokio_graceful_shutdown::SubsystemHandle;

use crate::radar::{DopplerMode, RadarError, RadarInfo, RangeDetection, SharedRadars};
use crate::settings::{ControlMessage, ControlState, ControlType, ControlValue};
use crate::settings::{ControlMessage, ControlType, ControlValue};
use crate::util::{c_string, c_wide_string, create_udp_multicast_listen};

use super::command::Command;
Expand Down Expand Up @@ -430,11 +430,7 @@ impl NavicoReportReceiver {

async fn pass_to_data_receiver(&mut self, cv: &ControlValue) -> Result<(), RadarError> {
let value = cv.value.parse::<f32>().unwrap_or(0.);
if self
.info
.set(&cv.id, value, cv.auto, ControlState::Manual)
.is_err()
{
if self.info.set(&cv.id, value, cv.auto).is_err() {
log::warn!("Cannot set {} to {}", cv.id, value);
}

Expand Down Expand Up @@ -471,26 +467,20 @@ impl NavicoReportReceiver {
}
}

fn set(
&mut self,
control_type: &ControlType,
value: f32,
auto: Option<bool>,
state: ControlState,
) {
match self.info.set(control_type, value, auto, state) {
fn set(&mut self, control_type: &ControlType, value: f32, auto: Option<bool>) {
match self.info.set(control_type, value, auto) {
Err(e) => {
error!("{}: {}", self.key, e.to_string());
}
Ok(Some(())) => {
if log::log_enabled!(log::Level::Debug) {
let control = self.info.controls.get(control_type).unwrap();
log::trace!(
"{}: Control '{}' new value {} state {}",
"{}: Control '{}' new value {} enabled {:?}",
self.key,
control_type,
control.value(),
control.state
control.enabled
);
}
}
Expand All @@ -499,11 +489,11 @@ impl NavicoReportReceiver {
}

fn set_value(&mut self, control_type: &ControlType, value: f32) {
self.set(control_type, value, None, ControlState::Manual)
self.set(control_type, value, None)
}

fn set_auto(&mut self, control_type: &ControlType, value: f32, auto: u8) {
match self.info.set_auto(control_type, auto > 0, value) {
fn set_value_auto(&mut self, control_type: &ControlType, value: f32, auto: u8) {
match self.info.set_value_auto(control_type, auto > 0, value) {
Err(e) => {
error!("{}: {}", self.key, e.to_string());
}
Expand Down Expand Up @@ -817,13 +807,13 @@ impl NavicoReportReceiver {
if self.model == Model::HALO {
self.set_value(&ControlType::Mode, mode as f32);
}
self.set_auto(&ControlType::Gain, gain as f32, gain_auto);
self.set_value_auto(&ControlType::Gain, gain as f32, gain_auto);
if self.model != Model::HALO {
self.set_auto(&ControlType::Sea, sea as f32, sea_auto);
self.set_value_auto(&ControlType::Sea, sea as f32, sea_auto);
} else {
self.info
.set_auto_state(&ControlType::Sea, sea_auto > 0)
.unwrap();
.unwrap(); // Only crashes if control not supported which would be an internal bug
}
self.set_value(&ControlType::Rain, rain as f32);
self.set_value(
Expand Down Expand Up @@ -900,29 +890,6 @@ impl NavicoReportReceiver {
Ok(())
}

const BLANKING_SETS: [(usize, ControlType, ControlType); 4] = [
(
0,
ControlType::NoTransmitStart1,
ControlType::NoTransmitEnd1,
),
(
1,
ControlType::NoTransmitStart2,
ControlType::NoTransmitEnd2,
),
(
2,
ControlType::NoTransmitStart3,
ControlType::NoTransmitEnd3,
),
(
3,
ControlType::NoTransmitStart4,
ControlType::NoTransmitEnd4,
),
];

///
/// Blanking (No Transmit) report as seen on HALO 2006
///
Expand All @@ -934,17 +901,15 @@ impl NavicoReportReceiver {
let name = c_string(&report.name);
self.set_string(&ControlType::ModelName, name.unwrap_or("").to_string());

for (i, start, end) in Self::BLANKING_SETS {
for (i, start, end) in super::BLANKING_SETS {
let blanking = &report.blanking[i];
let start_angle = i16::from_le_bytes(blanking.start_angle);
let end_angle = i16::from_le_bytes(blanking.end_angle);
let state = if blanking.enabled > 0 {
ControlState::Manual
} else {
ControlState::Off
};
self.set(&start, start_angle as f32, None, state);
self.set(&end, end_angle as f32, None, state);
let enabled = Some(blanking.enabled > 0);
self.info
.set_value_auto_enabled(&start, start_angle as f32, None, enabled)?;
self.info
.set_value_auto_enabled(&end, end_angle as f32, None, enabled)?;
}

Ok(())
Expand All @@ -966,17 +931,15 @@ impl NavicoReportReceiver {
self.model
);

for (i, start, end) in Self::BLANKING_SETS {
for (i, start, end) in super::BLANKING_SETS {
let blanking = &report.blanking[i];
let start_angle = i16::from_le_bytes(blanking.start_angle);
let end_angle = i16::from_le_bytes(blanking.end_angle);
let state = if blanking.enabled > 0 {
ControlState::Manual
} else {
ControlState::Off
};
self.set(&start, start_angle as f32, None, state);
self.set(&end, end_angle as f32, None, state);
let enabled = Some(blanking.enabled > 0);
self.info
.set_value_auto_enabled(&start, start_angle as f32, None, enabled)?;
self.info
.set_value_auto_enabled(&end, end_angle as f32, None, enabled)?;
}

Ok(())
Expand Down Expand Up @@ -1041,15 +1004,15 @@ impl NavicoReportReceiver {
self.set_value_with_many_auto(
&ControlType::Sea,
sea_clutter as f32,
auto_sea_clutter.into(),
auto_sea_clutter as f32,
);
}
self.set_value(
&ControlType::LocalInterferenceRejection,
local_interference_rejection as f32,
);
self.set_value(&ControlType::ScanSpeed, scan_speed as f32);
self.set_auto(
self.set_value_auto(
&ControlType::SideLobeSuppression,
sidelobe_suppression as f32,
sidelobe_suppression_auto,
Expand Down
Loading

0 comments on commit 29ab7f4

Please sign in to comment.