arci_ros2/
ros2_laser_scan.rs1use std::{
2 sync::{Arc, RwLock},
3 time::Duration,
4};
5
6use arci::*;
7use r2r::{sensor_msgs::msg::LaserScan, QosProfile};
8use serde::{Deserialize, Serialize};
9
10use crate::{utils, Node};
11
12pub struct Ros2LaserScan2D {
14 scan: Arc<RwLock<Option<LaserScan>>>,
15 laser_scan_topic_name: String,
16 _node: Node,
18}
19
20impl Ros2LaserScan2D {
21 pub fn new(node: Node, laser_scan_topic_name: &str) -> Result<Self, Error> {
23 let mut scan_subscriber = node
24 .r2r()
25 .subscribe::<LaserScan>(laser_scan_topic_name, QosProfile::default())
26 .map_err(anyhow::Error::from)?;
27 let scan = utils::subscribe_one(&mut scan_subscriber, Duration::from_secs(1));
28 let scan = Arc::new(RwLock::new(scan));
29 utils::subscribe_thread(scan_subscriber, scan.clone(), Some);
30
31 Ok(Self {
32 scan,
33 laser_scan_topic_name: laser_scan_topic_name.to_owned(),
34 _node: node,
35 })
36 }
37}
38
39impl LaserScan2D for Ros2LaserScan2D {
40 fn current_scan(&self) -> Result<arci::Scan2D, arci::Error> {
41 let subscribed_scan = self.scan.read().unwrap();
42 let current_scan = match &*subscribed_scan {
43 Some(msg) => Scan2D {
44 angle_min: msg.angle_min as f64,
45 angle_max: msg.angle_max as f64,
46 angle_increment: msg.angle_increment as f64,
47 time_increment: msg.time_increment as f64,
48 scan_time: msg.scan_time as f64,
49 range_min: msg.range_min as f64,
50 range_max: msg.range_max as f64,
51 ranges: msg.ranges.iter().map(|&v| v as f64).collect::<Vec<f64>>(),
52 intensities: msg
53 .intensities
54 .iter()
55 .map(|&v| v as f64)
56 .collect::<Vec<f64>>(),
57 },
58 None => {
59 return Err(Error::Connection {
60 message: format!("Failed to get scan from {}", self.laser_scan_topic_name),
61 });
62 }
63 };
64 Ok(current_scan)
65 }
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize)]
70#[serde(deny_unknown_fields)]
71pub struct Ros2LaserScan2DConfig {
72 pub topic: String,
74}