use crazyflie_lib::Crazyflie;
use crazyflie_lib::crazyflie_link::LinkContext;
use std::convert::TryInto;
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let context = LinkContext::new();
let cf = Crazyflie::connect_from_uri(
&context,
"radio://0/80/2M/E7E7E7E7E7",
crazyflie_lib::NoTocCache
)
.await?;
println!("Connected!");
cf.param.set("stabilizer.estimator", 2u8).await?;
cf.param.set("locSrv.extQuatStdDev", 8.0e-3f32).await?;
cf.param.set("kalman.resetEstimation", 1u8).await?;
sleep(Duration::from_millis(100)).await;
cf.param.set("kalman.resetEstimation", 0u8).await?;
sleep(Duration::from_secs(2)).await;
let mut quat_block = cf.log.create_block().await?;
quat_block.add_variable("stateEstimate.qx").await?;
quat_block.add_variable("stateEstimate.qy").await?;
quat_block.add_variable("stateEstimate.qz").await?;
quat_block.add_variable("stateEstimate.qw").await?;
let mut pos_block = cf.log.create_block().await?;
pos_block.add_variable("stateEstimate.x").await?;
pos_block.add_variable("stateEstimate.y").await?;
pos_block.add_variable("stateEstimate.z").await?;
let log_period_ms = 100;
let update_period_ms = 5; let log_every_n_iterations = log_period_ms / update_period_ms;
let quat_stream = quat_block.start(Duration::from_millis(log_period_ms).try_into()?).await?;
let pos_stream = pos_block.start(Duration::from_millis(log_period_ms).try_into()?).await?;
println!("Sending external pose data...");
for i in 0..5000 {
let t = i as f32 * 0.01;
let x = (t).cos() * 0.5;
let y = (t).sin() * 0.5;
let z = 0.0;
let roll = (t * 50.0).sin() * 0.2; let pitch = (t * 50.0).cos() * 0.15; let yaw = 1.2f32;
let roll_rad = roll;
let pitch_rad = -pitch;
let yaw_rad = yaw;
let cr = (roll_rad / 2.0).cos();
let sr = (roll_rad / 2.0).sin();
let cp = (pitch_rad / 2.0).cos();
let sp = (pitch_rad / 2.0).sin();
let cy = (yaw_rad / 2.0).cos();
let sy = (yaw_rad / 2.0).sin();
let quat = [
sr * cp * cy - cr * sp * sy, cr * sp * cy + sr * cp * sy, cr * cp * sy - sr * sp * cy, cr * cp * cy + sr * sp * sy ];
cf.localization.external_pose.send_external_pose([x, y, z], quat).await?;
if i % log_every_n_iterations == 0 {
let quat_data = quat_stream.next().await?;
let pos_data = pos_stream.next().await?;
let state_x = pos_data.data.get("stateEstimate.x").unwrap();
let state_y = pos_data.data.get("stateEstimate.y").unwrap();
let state_z = pos_data.data.get("stateEstimate.z").unwrap();
let state_qx = quat_data.data.get("stateEstimate.qx").unwrap();
let state_qy = quat_data.data.get("stateEstimate.qy").unwrap();
let state_qz = quat_data.data.get("stateEstimate.qz").unwrap();
let state_qw = quat_data.data.get("stateEstimate.qw").unwrap();
println!("Sent: pos=[{:.2}, {:.2}, {:.2}] quat=[{:.3}, {:.3}, {:.3}, {:.3}]",
x, y, z, quat[0], quat[1], quat[2], quat[3]);
println!("State: pos=[{:.2}, {:.2}, {:.2}] quat=[{:.3}, {:.3}, {:.3}, {:.3}]",
state_x.to_f64_lossy(), state_y.to_f64_lossy(), state_z.to_f64_lossy(),
state_qx.to_f64_lossy(), state_qy.to_f64_lossy(), state_qz.to_f64_lossy(), state_qw.to_f64_lossy());
}
sleep(Duration::from_millis(update_period_ms as u64)).await;
}
Ok(())
}