2025-12-09 20:37:03 +00:00
|
|
|
use nalgebra::{self as na, Vector3};
|
|
|
|
|
use rapier3d::prelude as rp;
|
2025-12-10 13:11:51 +00:00
|
|
|
use std::{any::Any, f32, io::PipeReader};
|
2025-12-09 20:37:03 +00:00
|
|
|
|
|
|
|
|
use crate::drone::controller::DroneController;
|
|
|
|
|
pub use crate::drone::controller::JoystickInput;
|
|
|
|
|
use crate::drone::MotorCharacteristics;
|
|
|
|
|
|
|
|
|
|
#[derive(Default)]
|
2025-12-11 18:08:07 +00:00
|
|
|
pub struct PControllerState {
|
2025-12-09 20:37:03 +00:00
|
|
|
last_time: f32,
|
|
|
|
|
current_time: f32,
|
|
|
|
|
last_rotation: na::Unit<na::Quaternion<f32>>,
|
|
|
|
|
current_rotation: na::Unit<na::Quaternion<f32>>,
|
2025-12-11 18:08:07 +00:00
|
|
|
angular_velocity: na::Vector3<f32>,
|
2025-12-09 20:37:03 +00:00
|
|
|
}
|
|
|
|
|
|
2025-12-11 18:08:07 +00:00
|
|
|
impl PControllerState {
|
2025-12-09 20:37:03 +00:00
|
|
|
pub fn dt(&self) -> f32 {
|
2025-12-10 13:11:51 +00:00
|
|
|
return self.current_time - self.last_time;
|
2025-12-09 20:37:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-11 18:08:07 +00:00
|
|
|
pub struct PController {
|
2025-12-09 20:37:03 +00:00
|
|
|
input: JoystickInput,
|
|
|
|
|
pub target_rate: f32,
|
2025-12-11 18:08:07 +00:00
|
|
|
state: PControllerState,
|
2025-12-09 20:37:03 +00:00
|
|
|
}
|
|
|
|
|
|
2025-12-11 18:08:07 +00:00
|
|
|
impl Default for PController {
|
2025-12-09 20:37:03 +00:00
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
input: JoystickInput::default(),
|
|
|
|
|
target_rate: f32::consts::PI,
|
|
|
|
|
state: Default::default(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-11 18:08:07 +00:00
|
|
|
impl PController {
|
2025-12-09 20:37:03 +00:00
|
|
|
pub fn set_input(&mut self, input: JoystickInput) {
|
|
|
|
|
self.input = input;
|
|
|
|
|
}
|
2025-12-10 13:11:51 +00:00
|
|
|
pub fn get_angular_velocity(&self) -> na::Vector3<f32> {
|
2025-12-11 18:08:07 +00:00
|
|
|
return self.state.angular_velocity;
|
2025-12-10 13:11:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn get_desired_angular_velocity(&self) -> na::Vector3<f32> {
|
2025-12-11 18:08:07 +00:00
|
|
|
let coords = na::Vector3::new(
|
2025-12-10 13:11:51 +00:00
|
|
|
self.input.pitch_input,
|
|
|
|
|
self.input.yaw_input,
|
|
|
|
|
self.input.roll_input,
|
|
|
|
|
) * self.target_rate;
|
2025-12-11 18:08:07 +00:00
|
|
|
return coords;
|
2025-12-09 20:37:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-11 18:08:07 +00:00
|
|
|
impl DroneController for PController {
|
|
|
|
|
fn set_rotation(&mut self, rotation: nalgebra::Unit<nalgebra::Quaternion<f32>>) {
|
2025-12-09 20:37:03 +00:00
|
|
|
self.state.last_rotation = self.state.current_rotation;
|
2025-12-11 18:08:07 +00:00
|
|
|
self.state.current_rotation = rotation;
|
|
|
|
|
}
|
|
|
|
|
fn set_angular_velocity(&mut self, angvel: nalgebra::Vector3<f32>) {
|
|
|
|
|
self.state.angular_velocity = angvel;
|
2025-12-09 20:37:03 +00:00
|
|
|
}
|
|
|
|
|
fn set_time(&mut self, time: f32) {
|
|
|
|
|
self.state.last_time = self.state.current_time;
|
|
|
|
|
self.state.current_time = time;
|
|
|
|
|
}
|
|
|
|
|
fn set_motor_characteristics(&self, _motor_characteristics: &MotorCharacteristics) {}
|
2025-12-10 13:11:51 +00:00
|
|
|
fn get_motor_throttles(&mut self) -> [f32; 4] {
|
2025-12-11 18:08:07 +00:00
|
|
|
let rot = self.state.current_rotation;
|
|
|
|
|
let current = rot.inverse().transform_vector(&self.get_angular_velocity());
|
2025-12-10 13:11:51 +00:00
|
|
|
let target = self.get_desired_angular_velocity();
|
2025-12-11 18:08:07 +00:00
|
|
|
|
2025-12-10 13:11:51 +00:00
|
|
|
let diff = target - current;
|
|
|
|
|
println!("Target: {:}", target);
|
|
|
|
|
println!("Current: {:}", current);
|
|
|
|
|
println!("Diff: {:}", diff);
|
|
|
|
|
let throttle = self.input.throttle_input;
|
|
|
|
|
|
|
|
|
|
let roll = diff.z * 0.01;
|
|
|
|
|
|
|
|
|
|
let pitch = diff.x * 0.01;
|
|
|
|
|
|
|
|
|
|
let yaw = diff.y;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Motor position indices
|
|
|
|
|
* ^ - Front
|
|
|
|
|
* |
|
|
|
|
|
* |
|
|
|
|
|
* 1 --- 0
|
|
|
|
|
* | |
|
|
|
|
|
* | |
|
|
|
|
|
* 2 --- 3
|
|
|
|
|
*/
|
|
|
|
|
let mut motors = [
|
2025-12-11 18:08:07 +00:00
|
|
|
throttle + yaw - pitch + roll,
|
|
|
|
|
throttle - yaw - pitch - roll,
|
|
|
|
|
throttle + yaw + pitch - roll,
|
|
|
|
|
throttle - yaw + pitch + roll,
|
2025-12-09 21:47:05 +00:00
|
|
|
];
|
2025-12-10 13:11:51 +00:00
|
|
|
|
|
|
|
|
// motors.max
|
|
|
|
|
let max = motors
|
|
|
|
|
.iter()
|
|
|
|
|
.copied()
|
|
|
|
|
.max_by(|a, b| a.total_cmp(b))
|
|
|
|
|
.unwrap_or(0.0);
|
|
|
|
|
if max > 1.0 {
|
|
|
|
|
for v in motors.iter_mut() {
|
|
|
|
|
*v /= max;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return motors;
|
2025-12-09 20:37:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* These should be implemented like this for all the classes that implement DroneController
|
|
|
|
|
* Works as an example implementation
|
|
|
|
|
*/
|
|
|
|
|
fn as_any(&self) -> &dyn Any {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
fn as_mut_any(&mut self) -> &mut dyn Any {
|
|
|
|
|
self
|
|
|
|
|
}
|
|
|
|
|
}
|