Add examples showing usage of sim time
This commit is contained in:
parent
951db6caae
commit
62897e2afe
|
|
@ -57,3 +57,7 @@ features = ["doc-only"]
|
|||
[[bench]]
|
||||
name = "deserialization"
|
||||
harness = false
|
||||
|
||||
[[example]]
|
||||
name = "timer_sim_time"
|
||||
required-features = ["sim-time"]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
use r2r::rosgraph_msgs::msg;
|
||||
use r2r::ClockType::SystemTime;
|
||||
use r2r::{Clock, QosProfile};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Simple publisher publishing time starting at time 0 every `SENDING_PERIOD`
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let ctx = r2r::Context::create()?;
|
||||
let mut node = r2r::Node::create(ctx, "clock_publisher", "")?;
|
||||
let qos = QosProfile::default().keep_last(1);
|
||||
let publisher = node.create_publisher("/clock", qos)?;
|
||||
|
||||
const SENDING_PERIOD: Duration = Duration::from_millis(100);
|
||||
const SIM_TIME_MULTIPLIER: f64 = 0.1;
|
||||
|
||||
let mut clock = Clock::create(SystemTime)?;
|
||||
let zero_time = clock.get_now()?;
|
||||
let mut msg = msg::Clock::default();
|
||||
|
||||
loop {
|
||||
let time_diff = clock.get_now()? - zero_time;
|
||||
let time = time_diff.mul_f64(SIM_TIME_MULTIPLIER);
|
||||
msg.clock = Clock::to_builtin_time(&time);
|
||||
|
||||
publisher.publish(&msg)?;
|
||||
println!("Publishing time {}.{:9} s", time.as_secs(), time.subsec_nanos());
|
||||
|
||||
std::thread::sleep(SENDING_PERIOD);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
use futures::executor::LocalPool;
|
||||
use futures::task::LocalSpawnExt;
|
||||
|
||||
use r2r::{Clock, ClockType};
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
async fn timer_task(
|
||||
mut t: r2r::Timer, ros_clock: Arc<Mutex<Clock>>, mut system_clock: Clock,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut iteration: i32 = 0;
|
||||
loop {
|
||||
let elapsed = t.tick().await?;
|
||||
|
||||
let ros_time = ros_clock.lock().unwrap().get_now()?;
|
||||
let system_time = system_clock.get_now()?;
|
||||
|
||||
println!("Timer called ({}), {}us since last call", iteration, elapsed.as_micros());
|
||||
println!(
|
||||
"\tcurrent time ros={:.3}s, system={:.3}s",
|
||||
ros_time.as_secs_f64(),
|
||||
system_time.as_secs_f64()
|
||||
);
|
||||
|
||||
iteration += 1;
|
||||
if iteration == 10 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Publication of time can be done either using the example `sim_time_publisher`
|
||||
/// or with `ros2 bag play --clock <clock_frequency> <the_bag>`
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let ctx = r2r::Context::create()?;
|
||||
let mut node = r2r::Node::create(ctx, "testnode", "")?;
|
||||
|
||||
let mut pool = LocalPool::new();
|
||||
let spawner = pool.spawner();
|
||||
|
||||
// Simulated time can be enabled by registering parameter handler
|
||||
// and starting the program this ros param 'use_sim_time:=true'
|
||||
// ```shell
|
||||
// cargo run --features=sim-time --example=timer_sim_time -- --ros-args -p use_sim_time:=true
|
||||
// ```
|
||||
// this does not work if the parameter is changed during the runtime
|
||||
let (paramater_handler, _parameter_events) = node.make_parameter_handler()?;
|
||||
spawner.spawn_local(paramater_handler)?;
|
||||
|
||||
// or simulated time can be enabled/disabled directly by calling these functions:
|
||||
// let time_source = node.get_time_source();
|
||||
// time_source.enable_sim_time(&mut node)?;
|
||||
// time_source.disable_sim_time();
|
||||
|
||||
// Note: Wall timer does not use sim time
|
||||
let timer = node.create_timer(std::time::Duration::from_millis(1000))?;
|
||||
|
||||
let is_done = Rc::new(RefCell::new(false));
|
||||
|
||||
let task_is_done = is_done.clone();
|
||||
let ros_clock = node.get_ros_clock();
|
||||
let system_clock = Clock::create(ClockType::SystemTime)?;
|
||||
spawner.spawn_local(async move {
|
||||
match timer_task(timer, ros_clock, system_clock).await {
|
||||
Ok(()) => {
|
||||
*task_is_done.borrow_mut() = true;
|
||||
println!("exiting");
|
||||
}
|
||||
Err(e) => println!("error: {}", e),
|
||||
}
|
||||
})?;
|
||||
|
||||
while !*is_done.borrow() {
|
||||
node.spin_once(std::time::Duration::from_millis(100));
|
||||
|
||||
pool.run_until_stalled();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -86,6 +86,8 @@ impl TimeSource {
|
|||
/// Enables usage of simulated time
|
||||
///
|
||||
/// Simulated time is provided on topic `"/clock"` in the message [rosgraph_msgs::msg::Clock].
|
||||
///
|
||||
/// See example: sim_time_publisher.rs
|
||||
pub fn enable_sim_time(&self, node: &mut Node) -> Result<()> {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
if inner.simulated_time_enabled {
|
||||
|
|
|
|||
Loading…
Reference in New Issue