Add parameter selection
This commit is contained in:
parent
ce2919580d
commit
63534c7e05
43
Cargo.lock
generated
43
Cargo.lock
generated
@ -209,6 +209,7 @@ dependencies = [
|
||||
"imageproc",
|
||||
"paste",
|
||||
"pid",
|
||||
"rand 0.8.5",
|
||||
"rusttype",
|
||||
"thiserror",
|
||||
]
|
||||
@ -357,7 +358,7 @@ dependencies = [
|
||||
"itertools",
|
||||
"nalgebra",
|
||||
"num",
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
"rand_distr",
|
||||
"rayon",
|
||||
"rusttype",
|
||||
@ -662,11 +663,22 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
"rand_hc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.2"
|
||||
@ -674,7 +686,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -686,13 +708,22 @@ dependencies = [
|
||||
"getrandom 0.1.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_distr"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rand 0.7.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -701,7 +732,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -11,6 +11,7 @@ rusttype = "0.9"
|
||||
paste = "1.0"
|
||||
pid = "4.0"
|
||||
thiserror = "1.0"
|
||||
rand = "0.8"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
@ -143,6 +143,10 @@ fn draw_setting(
|
||||
font: &Font,
|
||||
) {
|
||||
let text_scale = Scale::uniform(screen.yres() as f32 / 4.0 - 8.0);
|
||||
let value_scale = Scale {
|
||||
x: screen.xres() as f32 / 10.0,
|
||||
y: screen.yres() as f32 / 4.0 - 8.0,
|
||||
};
|
||||
let x = screen.xres() as i32 / 8 + screen.xres() as i32 * i32::from(index) / 4;
|
||||
draw_centered_text(
|
||||
screen,
|
||||
@ -156,9 +160,9 @@ fn draw_setting(
|
||||
screen,
|
||||
x,
|
||||
screen.yres() as i32 * 5 / 8 + 4,
|
||||
text_scale,
|
||||
value_scale,
|
||||
font,
|
||||
format!("{value}").as_str(),
|
||||
format!("{value:.2}").as_str(),
|
||||
);
|
||||
let top_triangle = [
|
||||
Point::new(x, screen.yres() as i32 / 2),
|
||||
|
115
src/main.rs
115
src/main.rs
@ -2,17 +2,17 @@ mod buttons;
|
||||
mod display;
|
||||
|
||||
use buttons::SmartEv3Buttons;
|
||||
use display::{draw_calibration, draw_cycles, draw_driving, draw_finished, font};
|
||||
use display::{draw_calibration, draw_driving, draw_finished, draw_settings, font, Parameter};
|
||||
use ev3dev_lang_rust::{
|
||||
motors::{LargeMotor, MotorPort},
|
||||
sensors::{ColorSensor, SensorPort},
|
||||
Ev3Error, Ev3Result, Screen,
|
||||
};
|
||||
use pid::Pid;
|
||||
use rand::{thread_rng, Rng};
|
||||
use rusttype::Font;
|
||||
use std::{
|
||||
error::Error,
|
||||
hint,
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
@ -37,6 +37,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
let white = calibrate_gray(&mut screen, &sensor, &mut buttons, "Weiß", &font)?;
|
||||
let setpoint = (black + white) / 2.0;
|
||||
|
||||
let (k_p, k_i, k_d, v) = select_values(&mut screen, &mut buttons, &font);
|
||||
|
||||
draw_driving(&mut screen, &font);
|
||||
|
||||
let result = follow_line(
|
||||
@ -44,13 +46,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
&sensor,
|
||||
&mut buttons,
|
||||
setpoint,
|
||||
(0.3, 0.0, 0.0),
|
||||
20,
|
||||
(k_p / 10.0, k_i, k_d),
|
||||
v,
|
||||
);
|
||||
left_motor.stop().and(right_motor.stop())?;
|
||||
let time = match result {
|
||||
Ok(time) => time,
|
||||
Err(LineFollowError::UserAbort) => return Ok(()),
|
||||
Err(ProgramError::UserAbort) => return Ok(()),
|
||||
e => e?,
|
||||
};
|
||||
|
||||
@ -63,6 +65,103 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn select_values(
|
||||
screen: &mut Screen,
|
||||
buttons: &mut SmartEv3Buttons,
|
||||
font: &Font,
|
||||
) -> (f32, f32, f32, i32) {
|
||||
use Parameter::{Kd, Ki, Kp, Speed};
|
||||
let mut k_p = thread_rng().gen_range(0.01..=10.0);
|
||||
let mut k_i = thread_rng().gen_range(0.01..=10.0);
|
||||
let mut k_d = thread_rng().gen_range(0.01..=10.0);
|
||||
let mut v = thread_rng().gen_range(1..=100);
|
||||
let mut selected = Kp;
|
||||
draw_settings(screen, k_p, k_i, k_d, v, selected, font);
|
||||
|
||||
loop {
|
||||
buttons.process();
|
||||
if buttons.is_enter_pressed() {
|
||||
break;
|
||||
}
|
||||
if buttons.is_right_pressed() {
|
||||
selected = match selected {
|
||||
Kp => Ki,
|
||||
Ki => Kd,
|
||||
Kd => Speed,
|
||||
Speed => Kp,
|
||||
};
|
||||
}
|
||||
if buttons.is_left_pressed() {
|
||||
selected = match selected {
|
||||
Kp => Speed,
|
||||
Ki => Kp,
|
||||
Kd => Ki,
|
||||
Speed => Kd,
|
||||
};
|
||||
}
|
||||
match selected {
|
||||
Speed => {
|
||||
if buttons.is_up() {
|
||||
v = (v + 1).min(100);
|
||||
}
|
||||
if buttons.is_down() {
|
||||
v = (v - 1).max(0);
|
||||
}
|
||||
}
|
||||
p => {
|
||||
let param = match p {
|
||||
Kp => &mut k_p,
|
||||
Ki => &mut k_i,
|
||||
Kd => &mut k_d,
|
||||
Speed => unreachable!(),
|
||||
};
|
||||
if buttons.is_up() {
|
||||
*param = (*param
|
||||
+ if buttons.is_up_pressed() {
|
||||
0.01f32
|
||||
} else {
|
||||
0.1f32
|
||||
})
|
||||
.min(99.99);
|
||||
}
|
||||
if buttons.is_down() {
|
||||
*param = (*param
|
||||
- if buttons.is_down_pressed() {
|
||||
0.01f32
|
||||
} else {
|
||||
0.1f32
|
||||
})
|
||||
.max(0.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if buttons.is_left_pressed()
|
||||
|| buttons.is_right_pressed()
|
||||
|| buttons.is_up()
|
||||
|| buttons.is_down()
|
||||
{
|
||||
draw_settings(screen, k_p, k_i, k_d, v, selected, font);
|
||||
}
|
||||
if buttons.is_up_pressed() || buttons.is_down_pressed() {
|
||||
sleep(Duration::from_millis(200));
|
||||
} else {
|
||||
sleep(Duration::from_millis(10));
|
||||
}
|
||||
}
|
||||
|
||||
(k_p, k_i, k_d, v)
|
||||
}
|
||||
|
||||
fn increase(parameter: &mut f32) {
|
||||
let change = 0.01;
|
||||
*parameter = (*parameter + change).min(99.99);
|
||||
}
|
||||
|
||||
fn decrease(parameter: &mut f32) {
|
||||
let change = 0.01;
|
||||
*parameter = (*parameter - change).max(0.0);
|
||||
}
|
||||
|
||||
fn calibrate_gray(
|
||||
screen: &mut Screen,
|
||||
sensor: &ColorSensor,
|
||||
@ -81,7 +180,7 @@ fn calibrate_gray(
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
enum LineFollowError {
|
||||
enum ProgramError {
|
||||
#[error("working with EV3 peripheral")]
|
||||
Ev3(#[from] Ev3Error),
|
||||
#[error("the user abortet the run")]
|
||||
@ -102,7 +201,7 @@ fn follow_line(
|
||||
setpoint: f32,
|
||||
(k_p, k_i, k_d): (f32, f32, f32),
|
||||
v: i32,
|
||||
) -> Result<Duration, LineFollowError> {
|
||||
) -> Result<Duration, ProgramError> {
|
||||
let mut controller = Pid::new(setpoint, f32::INFINITY);
|
||||
controller
|
||||
.p(k_p, f32::INFINITY)
|
||||
@ -140,7 +239,7 @@ fn follow_line(
|
||||
if let LineFollowState::Finish(time) = state {
|
||||
Ok(time)
|
||||
} else {
|
||||
Err(LineFollowError::UserAbort)
|
||||
Err(ProgramError::UserAbort)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user