openrr_plugin_example/
lib.rs

1use std::{sync::Mutex, time::Duration};
2
3use arci::{DummyLocalization, DummyMoveBase, DummyNavigation, Error, TrajectoryPoint, WaitFuture};
4use openrr_client::PrintSpeaker;
5use openrr_plugin::Plugin;
6use serde::Deserialize;
7
8openrr_plugin::export_plugin!(MyPlugin);
9
10#[derive(Debug)]
11pub struct MyPlugin;
12
13impl Plugin for MyPlugin {
14    fn new_joint_trajectory_client(
15        &self,
16        args: String,
17    ) -> Result<Option<Box<dyn arci::JointTrajectoryClient>>, arci::Error> {
18        let config: MyClientConfig =
19            serde_json::from_str(&args).map_err(|e| arci::Error::Other(e.into()))?;
20        let dof = config.joint_names.len();
21        Ok(Some(Box::new(MyJointTrajectoryClient {
22            joint_names: config.joint_names,
23            joint_positions: Mutex::new(vec![0.0; dof]),
24        })))
25    }
26
27    fn new_speaker(&self, _args: String) -> Result<Option<Box<dyn arci::Speaker>>, arci::Error> {
28        Ok(Some(Box::<PrintSpeaker>::default()))
29    }
30
31    fn new_move_base(&self, _args: String) -> Result<Option<Box<dyn arci::MoveBase>>, arci::Error> {
32        Ok(Some(Box::<DummyMoveBase>::default()))
33    }
34
35    fn new_navigation(
36        &self,
37        _args: String,
38    ) -> Result<Option<Box<dyn arci::Navigation>>, arci::Error> {
39        Ok(Some(Box::<DummyNavigation>::default()))
40    }
41
42    fn new_localization(
43        &self,
44        _args: String,
45    ) -> Result<Option<Box<dyn arci::Localization>>, arci::Error> {
46        Ok(Some(Box::<DummyLocalization>::default()))
47    }
48
49    #[cfg(unix)]
50    fn new_gamepad(&self, _args: String) -> Result<Option<Box<dyn arci::Gamepad>>, arci::Error> {
51        Ok(Some(
52            Box::new(arci_gamepad_keyboard::KeyboardGamepad::new()),
53        ))
54    }
55}
56
57#[derive(Deserialize)]
58struct MyClientConfig {
59    joint_names: Vec<String>,
60}
61
62struct MyJointTrajectoryClient {
63    joint_names: Vec<String>,
64    joint_positions: Mutex<Vec<f64>>,
65}
66
67impl arci::JointTrajectoryClient for MyJointTrajectoryClient {
68    fn joint_names(&self) -> Vec<String> {
69        self.joint_names.clone()
70    }
71
72    fn current_joint_positions(&self) -> Result<Vec<f64>, Error> {
73        Ok(self.joint_positions.lock().unwrap().clone())
74    }
75
76    fn send_joint_positions(
77        &self,
78        positions: Vec<f64>,
79        duration: Duration,
80    ) -> Result<WaitFuture, Error> {
81        println!("positions = {positions:?}, duration = {duration:?}");
82        *self.joint_positions.lock().unwrap() = positions;
83        Ok(WaitFuture::new(async { Ok(()) }))
84    }
85
86    fn send_joint_trajectory(
87        &self,
88        _trajectory: Vec<TrajectoryPoint>,
89    ) -> Result<WaitFuture, Error> {
90        // panic across the FFI boundary will be converted to abort by abi_stable.
91        panic!()
92    }
93}