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",
|
"imageproc",
|
||||||
"paste",
|
"paste",
|
||||||
"pid",
|
"pid",
|
||||||
|
"rand 0.8.5",
|
||||||
"rusttype",
|
"rusttype",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
@ -357,7 +358,7 @@ dependencies = [
|
|||||||
"itertools",
|
"itertools",
|
||||||
"nalgebra",
|
"nalgebra",
|
||||||
"num",
|
"num",
|
||||||
"rand",
|
"rand 0.7.3",
|
||||||
"rand_distr",
|
"rand_distr",
|
||||||
"rayon",
|
"rayon",
|
||||||
"rusttype",
|
"rusttype",
|
||||||
@ -662,11 +663,22 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.1.16",
|
"getrandom 0.1.16",
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.2.2",
|
||||||
"rand_core",
|
"rand_core 0.5.1",
|
||||||
"rand_hc",
|
"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]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rand_chacha"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@ -674,7 +686,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"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]]
|
[[package]]
|
||||||
@ -686,13 +708,22 @@ dependencies = [
|
|||||||
"getrandom 0.1.16",
|
"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]]
|
[[package]]
|
||||||
name = "rand_distr"
|
name = "rand_distr"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
|
checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand",
|
"rand 0.7.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -701,7 +732,7 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -11,6 +11,7 @@ rusttype = "0.9"
|
|||||||
paste = "1.0"
|
paste = "1.0"
|
||||||
pid = "4.0"
|
pid = "4.0"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
rand = "0.8"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
@ -143,6 +143,10 @@ fn draw_setting(
|
|||||||
font: &Font,
|
font: &Font,
|
||||||
) {
|
) {
|
||||||
let text_scale = Scale::uniform(screen.yres() as f32 / 4.0 - 8.0);
|
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;
|
let x = screen.xres() as i32 / 8 + screen.xres() as i32 * i32::from(index) / 4;
|
||||||
draw_centered_text(
|
draw_centered_text(
|
||||||
screen,
|
screen,
|
||||||
@ -156,9 +160,9 @@ fn draw_setting(
|
|||||||
screen,
|
screen,
|
||||||
x,
|
x,
|
||||||
screen.yres() as i32 * 5 / 8 + 4,
|
screen.yres() as i32 * 5 / 8 + 4,
|
||||||
text_scale,
|
value_scale,
|
||||||
font,
|
font,
|
||||||
format!("{value}").as_str(),
|
format!("{value:.2}").as_str(),
|
||||||
);
|
);
|
||||||
let top_triangle = [
|
let top_triangle = [
|
||||||
Point::new(x, screen.yres() as i32 / 2),
|
Point::new(x, screen.yres() as i32 / 2),
|
||||||
|
115
src/main.rs
115
src/main.rs
@ -2,17 +2,17 @@ mod buttons;
|
|||||||
mod display;
|
mod display;
|
||||||
|
|
||||||
use buttons::SmartEv3Buttons;
|
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::{
|
use ev3dev_lang_rust::{
|
||||||
motors::{LargeMotor, MotorPort},
|
motors::{LargeMotor, MotorPort},
|
||||||
sensors::{ColorSensor, SensorPort},
|
sensors::{ColorSensor, SensorPort},
|
||||||
Ev3Error, Ev3Result, Screen,
|
Ev3Error, Ev3Result, Screen,
|
||||||
};
|
};
|
||||||
use pid::Pid;
|
use pid::Pid;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
use rusttype::Font;
|
use rusttype::Font;
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
error::Error,
|
||||||
hint,
|
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
time::{Duration, Instant},
|
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 white = calibrate_gray(&mut screen, &sensor, &mut buttons, "Weiß", &font)?;
|
||||||
let setpoint = (black + white) / 2.0;
|
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);
|
draw_driving(&mut screen, &font);
|
||||||
|
|
||||||
let result = follow_line(
|
let result = follow_line(
|
||||||
@ -44,13 +46,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
&sensor,
|
&sensor,
|
||||||
&mut buttons,
|
&mut buttons,
|
||||||
setpoint,
|
setpoint,
|
||||||
(0.3, 0.0, 0.0),
|
(k_p / 10.0, k_i, k_d),
|
||||||
20,
|
v,
|
||||||
);
|
);
|
||||||
left_motor.stop().and(right_motor.stop())?;
|
left_motor.stop().and(right_motor.stop())?;
|
||||||
let time = match result {
|
let time = match result {
|
||||||
Ok(time) => time,
|
Ok(time) => time,
|
||||||
Err(LineFollowError::UserAbort) => return Ok(()),
|
Err(ProgramError::UserAbort) => return Ok(()),
|
||||||
e => e?,
|
e => e?,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,6 +65,103 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(())
|
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(
|
fn calibrate_gray(
|
||||||
screen: &mut Screen,
|
screen: &mut Screen,
|
||||||
sensor: &ColorSensor,
|
sensor: &ColorSensor,
|
||||||
@ -81,7 +180,7 @@ fn calibrate_gray(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
enum LineFollowError {
|
enum ProgramError {
|
||||||
#[error("working with EV3 peripheral")]
|
#[error("working with EV3 peripheral")]
|
||||||
Ev3(#[from] Ev3Error),
|
Ev3(#[from] Ev3Error),
|
||||||
#[error("the user abortet the run")]
|
#[error("the user abortet the run")]
|
||||||
@ -102,7 +201,7 @@ fn follow_line(
|
|||||||
setpoint: f32,
|
setpoint: f32,
|
||||||
(k_p, k_i, k_d): (f32, f32, f32),
|
(k_p, k_i, k_d): (f32, f32, f32),
|
||||||
v: i32,
|
v: i32,
|
||||||
) -> Result<Duration, LineFollowError> {
|
) -> Result<Duration, ProgramError> {
|
||||||
let mut controller = Pid::new(setpoint, f32::INFINITY);
|
let mut controller = Pid::new(setpoint, f32::INFINITY);
|
||||||
controller
|
controller
|
||||||
.p(k_p, f32::INFINITY)
|
.p(k_p, f32::INFINITY)
|
||||||
@ -140,7 +239,7 @@ fn follow_line(
|
|||||||
if let LineFollowState::Finish(time) = state {
|
if let LineFollowState::Finish(time) = state {
|
||||||
Ok(time)
|
Ok(time)
|
||||||
} else {
|
} else {
|
||||||
Err(LineFollowError::UserAbort)
|
Err(ProgramError::UserAbort)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user