Initial UI Design
This commit is contained in:
92
src/main.rs
92
src/main.rs
@ -1,28 +1,82 @@
|
||||
extern crate ev3dev_lang_rust;
|
||||
|
||||
use ev3dev_lang_rust::Ev3Result;
|
||||
use ev3dev_lang_rust::motors::{LargeMotor, MotorPort};
|
||||
use ev3dev_lang_rust::sensors::ColorSensor;
|
||||
use ev3dev_lang_rust::{
|
||||
motors::{LargeMotor, MotorPort},
|
||||
sensors::{ColorSensor, SensorPort},
|
||||
Ev3Button, Ev3Result, Screen,
|
||||
};
|
||||
use image::{Rgb, RgbImage};
|
||||
use imageproc::{
|
||||
drawing::{draw_hollow_rect_mut, draw_text_mut},
|
||||
rect::Rect,
|
||||
};
|
||||
use rusttype::{Font, Scale};
|
||||
|
||||
fn main() -> Ev3Result<()> {
|
||||
let left_motor = LargeMotor::get(MotorPort::OutB)?;
|
||||
let right_motor = LargeMotor::get(MotorPort::OutC)?;
|
||||
|
||||
// Get large motor on port outA.
|
||||
let large_motor = LargeMotor::get(MotorPort::OutA)?;
|
||||
let res = mainloop(&left_motor, &right_motor);
|
||||
|
||||
// Set command "run-direct".
|
||||
large_motor.run_direct()?;
|
||||
// Make sure the motors stop
|
||||
left_motor.stop().and(right_motor.stop())?;
|
||||
res
|
||||
}
|
||||
|
||||
// Run motor.
|
||||
large_motor.set_duty_cycle_sp(50)?;
|
||||
fn mainloop(left_motor: &LargeMotor, right_motor: &LargeMotor) -> Ev3Result<()> {
|
||||
let left_sensor = ColorSensor::get(SensorPort::In2)?;
|
||||
let right_sensor = ColorSensor::get(SensorPort::In3)?;
|
||||
left_sensor.set_mode_rgb_raw()?;
|
||||
right_sensor.set_mode_rgb_raw()?;
|
||||
|
||||
// Find color sensor. Always returns the first recognized one.
|
||||
let color_sensor = ColorSensor::find()?;
|
||||
|
||||
// Switch to rgb mode.
|
||||
color_sensor.set_mode_rgb_raw()?;
|
||||
|
||||
// Get current rgb color tuple.
|
||||
println!("Current rgb color: {:?}", color_sensor.get_rgb()?);
|
||||
let buttons = Ev3Button::new()?;
|
||||
println!("waiting for button press");
|
||||
while !buttons.is_enter() {
|
||||
draw_ui(1.0, 0.3, 0.1, 50.0)?;
|
||||
buttons.process();
|
||||
}
|
||||
println!("button pressed");
|
||||
|
||||
left_motor.set_polarity("inversed")?;
|
||||
right_motor.set_polarity("inversed")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_ui(kp: f32, ki: f32, kd: f32, speed: f32) -> Ev3Result<()> {
|
||||
const BACKGROUND: Rgb<u8> = Rgb([255; 3]);
|
||||
const FOREGROUND: Rgb<u8> = Rgb([0; 3]);
|
||||
let mut screen = Screen::new()?;
|
||||
let center = screen.xres() / 2;
|
||||
let quater = screen.yres() / 4;
|
||||
screen.image.fill(BACKGROUND.0[0]);
|
||||
let input_field_width = center;
|
||||
let input_field_height = quater - 4;
|
||||
let input_field_x = (center - 2).try_into().unwrap();
|
||||
for i in 0..4 {
|
||||
draw_hollow_rect_mut(
|
||||
&mut screen.image,
|
||||
Rect::at(input_field_x, (i * quater + 2).try_into().unwrap())
|
||||
.of_size(input_field_width, input_field_height),
|
||||
FOREGROUND,
|
||||
);
|
||||
}
|
||||
draw_value(kp, &mut screen.image, center, quater, 0);
|
||||
draw_value(ki, &mut screen.image, center, quater, 1);
|
||||
draw_value(kd, &mut screen.image, center, quater, 2);
|
||||
draw_value(speed, &mut screen.image, center, quater, 3);
|
||||
screen.update();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw_value(value: f32, canvas: &mut RgbImage, center: u32, quater: u32, index: u8) {
|
||||
const FOREGROUND: Rgb<u8> = Rgb([0; 3]);
|
||||
const FONT_DATA: &[u8] = include_bytes!("../fonts/RobotoMono-Regular.ttf");
|
||||
let font = Font::try_from_bytes(FONT_DATA).unwrap();
|
||||
draw_text_mut(
|
||||
canvas,
|
||||
FOREGROUND,
|
||||
center.try_into().unwrap(),
|
||||
i32::from(index) * i32::try_from(quater).unwrap() + 4,
|
||||
Scale::uniform((quater - 8) as f32),
|
||||
&font,
|
||||
format!("{value:2.2}").as_str(),
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user