calibrating_steering/
calibrating_steering.rs1use std::{
8 str::FromStr,
9 time::Duration
10};
11
12use tokio::time;
13
14use anyhow::{Result};
15use btleplug::api::BDAddr;
16use rust_powered_lego::{
17 hub::{
18 Hub
19 },
20 connection_manager::ConnectionManager,
21 HubType,
22 MotorType,
23 lego::message_parameters::{
24 StartupAndCompletionInfo,
25 },
26 lego::{
27 consts::{
28 TechnicHubPorts,
29 EndState,
30 Profile,
31 MotorModes,
32 },
33 },
34};
35
36
37#[tokio::main]
38async fn main() -> Result<()> {
39 let hub_mac_address = "90:84:2b:4e:5b:96";
42 let port_id = TechnicHubPorts::B;
43 let hub = get_hub(hub_mac_address).await?;
44 let motor = hub.get_motor(port_id as u8).await?;
45
46 _ = hub.setup_port_input_format(port_id as u8, MotorModes::Pos as u8, 1, true).await?;
48
49 let mut width = get_degree_width_avg(&hub, port_id as u8, &motor).await?;
50
51 width = (width + get_degree_width_avg(&hub, port_id as u8, &motor).await?) / 2;
53
54 width /= 2;
56
57 move_motor_to_extreme(&motor, 1).await?;
58
59 _ = motor.set_abs_position(width as i32, StartupAndCompletionInfo::BufferAndNoAction).await?;
60
61 println!("Done! Calibrated!");
62
63 motor.go_to_abs_position(
66 -(width as i32),
67 10,
68 15,
69 EndState::HOLD,
70 Profile::AccDec,
71 StartupAndCompletionInfo::ExecuteImmediatelyAndNoAction
72 ).await?;
73
74 time::sleep(Duration::from_secs(5)).await;
75
76 motor.go_to_abs_position(
77 0,
78 10,
79 15,
80 EndState::HOLD,
81 Profile::AccDec,
82 StartupAndCompletionInfo::ExecuteImmediatelyAndNoAction
83 ).await?;
84
85 time::sleep(Duration::from_secs(5)).await;
86
87 Ok(())
88}
89
90async fn get_hub(address: &str) -> Result<Hub> {
91
92 let address = BDAddr::from_str(address)?;
94
95 let cm = ConnectionManager::new();
97
98 let hub = cm.get_hub(None, Some(address), 5).await?;
101
102 Ok(hub)
104}
105
106
107async fn get_degree_width_avg<T, U>(hub: &U, port_id: u8, motor: &T) -> Result<u32>
112where
113 T: MotorType,
114 U: HubType,
115{
116 move_motor_to_extreme(motor, 1).await?;
117
118 _ = motor.set_abs_position(0, StartupAndCompletionInfo::BufferAndNoAction).await?;
119
120 move_motor_to_extreme(motor, -1).await?;
121
122 let mut width = hub.get_port_info_raw_value(port_id).await?.abs() as u32;
123
124 _ = motor.set_abs_position(0, StartupAndCompletionInfo::BufferAndNoAction).await?;
125
126 move_motor_to_extreme(motor, 1).await?;
127
128 width += width;
129
130 Ok(width / 2)
131}
132
133async fn move_motor_to_extreme<T>(motor: &T, sign: i8) -> Result<()>
134where
135 T: MotorType,
136{
137 let speed = sign.signum() * 10;
138 let max_power = 15;
139 let end_state = EndState::HOLD;
140 let use_profile = Profile::AccDec;
141 let start_up_info = StartupAndCompletionInfo::ExecuteImmediatelyAndNoAction;
142 let degrees: i32 = 200;
143 let sleep_time = 5;
144
145 motor.start_speed_for_deg(
146 degrees,
147 speed,
148 max_power,
149 end_state,
150 use_profile,
151 start_up_info).await?;
152
153 time::sleep(Duration::from_secs(sleep_time)).await;
154
155 Ok(())
156}