#![allow(dead_code, clippy::unwrap_used)]
use std::time::{Duration, Instant};
use m0601::protocol::{drive_floor, frame_velocity};
use m0601::{Bus, M0601, MockTransport, Mode, PositionAccumulator, PositionMirror, bus_period};
fn query_example() -> m0601::Result<()> {
let mut motor = M0601::open("/dev/ttyUSB0", 0x01, Duration::from_millis(150))?;
match motor.query()? {
Some(fb) => println!(
"{:+} RPM, {:.1}°, {:?} °C, faults: {}",
fb.speed_rpm, fb.position_deg, fb.temp_c, fb.faults
),
None => println!("no reply — check power, wiring, --id"),
}
Ok(())
}
fn drive_example() -> m0601::Result<()> {
let mut motor = M0601::open("/dev/ttyUSB0", 0x01, Duration::from_millis(150))?;
let deadline = Instant::now() + Duration::from_secs(3);
while Instant::now() < deadline {
motor.drive_velocity(100)?;
std::thread::sleep(Duration::from_millis(20));
}
motor.safe_stop();
Ok(())
}
fn transact_example(motor: &mut M0601) -> m0601::Result<()> {
let frame = frame_velocity(motor.id(), 100, 1);
if let Some(fb) = motor.transact(&frame, Duration::from_millis(6))? {
assert!(fb.temp_c.is_none());
println!("{:+} RPM at {:.2}°", fb.speed_rpm, fb.position_deg);
}
Ok(())
}
fn modes_example(motor: &mut M0601) -> m0601::Result<()> {
motor.set_mode(Mode::Current)?;
motor.drive_current(4096)?;
motor.set_mode(Mode::Position)?;
motor.drive_position(16384)?;
Ok(())
}
fn bus_example() -> m0601::Result<()> {
let bus = Bus::open("/dev/ttyUSB0", Duration::from_millis(150))?;
let mut left = bus.motor(0x01)?.mirrored(true);
let mut right = bus.motor(0x02)?;
left.drive_velocity(100)?;
right.drive_velocity(100)?;
Ok(())
}
fn multi_motor_example() -> m0601::Result<()> {
let ids = [0x01, 0x02, 0x03, 0x04];
let bus = Bus::open("/dev/ttyUSB0", Duration::from_millis(150))?
.with_min_gap(Duration::from_micros(2500));
assert!(bus.min_gap() > Duration::ZERO);
bus.set_mode_all(&ids, Mode::Velocity)?;
let mut wheels = Vec::new();
for id in ids {
wheels.push(bus.motor(id)?);
}
for wheel in &mut wheels {
wheel.drive_velocity(60)?; }
let guard = bus.clone(); guard.safe_stop_all(&ids);
Ok(())
}
fn timing_example() -> m0601::Result<()> {
let bus = Bus::open("/dev/ttyUSB0", Duration::from_millis(150))?
.with_timing(m0601::BusTiming {
stop_accel: 5,
..m0601::BusTiming::default()
})
.with_default_accel(10); let mut motor = bus.motor(0x01)?.with_default_accel(20); motor.drive_velocity(200)?; Ok(())
}
fn strict_crc_example() -> m0601::Result<()> {
let timeout = Duration::from_millis(150);
let bus = Bus::open("/dev/ttyUSB0", timeout)?.with_strict_crc(true);
let motor = bus.motor(0x01)?;
assert!(motor.strict_crc());
let mut other = bus.motor(0x02)?.with_strict_crc(false); other.set_strict_crc(true); Ok(())
}
fn position_mirror_example() -> m0601::Result<()> {
let bus = Bus::open("/dev/ttyUSB0", Duration::from_millis(150))?;
let _right = bus
.motor(0x02)?
.mirrored(true)
.position_mirror(PositionMirror::Reflect); Ok(())
}
fn odometry_example(motor: &mut M0601, reply_wait: Duration) -> m0601::Result<()> {
let mut odo = PositionAccumulator::new();
if let Some(fb) = motor.query_with(reply_wait)? {
let travelled_deg = odo.update(fb.position_deg);
println!("{travelled_deg:.1}° ({:.2} rev)", odo.revolutions());
}
let ceiling = PositionAccumulator::max_unaliased_rpm(Duration::from_millis(20));
assert!(ceiling > 330.0);
Ok(())
}
fn budgeting_example(bus: &Bus, reply_wait: Duration) {
let cycle = Duration::from_millis(18);
let need = bus_period(4, 1, bus.min_gap(), reply_wait);
assert!(
need < cycle && cycle <= drive_floor(),
"cycle {cycle:?} cannot carry {need:?} of bus traffic under the {:?} floor",
drive_floor()
);
}
fn slew_example() -> m0601::Result<()> {
let cycle = Duration::from_millis(20);
let mut ramp = m0601::SlewLimiter::new(300.0)?; let target = 250.0;
let rpm = ramp.step(target, cycle).round() as i16;
assert_eq!(rpm, 6);
ramp.reset_to(0.0);
assert_eq!(ramp.current_setpoint(), 0.0);
Ok(())
}
fn low_latency_example() -> m0601::Result<()> {
let transport = m0601::SerialTransport::open("/dev/ttyUSB0", Duration::from_millis(150))?;
if !transport.low_latency() {
eprintln!("[!] low-latency not set; see docs/content/docs/concepts/latency.md");
}
Ok(())
}
fn mock_example() -> m0601::Result<()> {
let mock = MockTransport::with_replies([vec![
0x01, 0x02, 0x00, 0x00, 0x00, 0x64, 0x28, 0x00, 0x00, 0x00,
]]);
let mut motor = M0601::with_transport(mock, 0x01, Duration::from_millis(150))?;
let fb = motor.query()?.unwrap();
assert_eq!(fb.speed_rpm, 100);
let mock = motor.into_transport().unwrap();
assert_eq!(mock.sent.len(), 1);
Ok(())
}
fn main() {}