use crate::geom::{FfiVector2D, Location, Vector2D};
use autocxx::prelude::*;
use carla_sys::carla_rust::rpc::FfiVehiclePhysicsControl;
#[cfg(carla_version_0100)]
use crate::{geom::Vector3D, rpc::WheelPhysicsControl, utils::IteratorExt};
#[cfg(not(carla_version_0100))]
use crate::utils::IteratorExt;
#[cfg(not(carla_version_0100))]
use carla_sys::carla::rpc::{GearPhysicsControl, WheelPhysicsControl};
#[cfg(carla_version_0100)]
#[derive(Debug, Clone)]
pub struct VehiclePhysicsControl {
pub torque_curve: Vec<Vector2D>,
pub max_torque: f32,
pub max_rpm: f32,
pub idle_rpm: f32,
pub brake_effect: f32,
pub rev_up_moi: f32,
pub rev_down_rate: f32,
pub differential_type: u8,
pub front_rear_split: f32,
pub use_automatic_gears: bool,
pub gear_change_time: f32,
pub final_ratio: f32,
pub forward_gear_ratios: Vec<f32>,
pub reverse_gear_ratios: Vec<f32>,
pub change_up_rpm: f32,
pub change_down_rpm: f32,
pub transmission_efficiency: f32,
pub mass: f32,
pub drag_coefficient: f32,
pub center_of_mass: Location,
pub chassis_width: f32,
pub chassis_height: f32,
pub downforce_coefficient: f32,
pub drag_area: f32,
pub inertia_tensor_scale: Vector3D,
pub sleep_threshold: f32,
pub sleep_slope_limit: f32,
pub steering_curve: Vec<Vector2D>,
pub wheels: Vec<WheelPhysicsControl>,
pub use_sweep_wheel_collision: bool,
}
#[cfg(carla_version_0100)]
impl VehiclePhysicsControl {
pub fn to_cxx(&self) -> UniquePtr<FfiVehiclePhysicsControl> {
let torque_curve = self
.torque_curve
.iter()
.map(|v| unsafe {
std::mem::transmute::<crate::geom::FfiVector2D, carla_sys::carla::geom::Vector2D>(
v.into_ffi(),
)
})
.collect_cxx_vector();
let steering_curve = self
.steering_curve
.iter()
.map(|v| unsafe {
std::mem::transmute::<crate::geom::FfiVector2D, carla_sys::carla::geom::Vector2D>(
v.into_ffi(),
)
})
.collect_cxx_vector();
let forward_gear_ratios = self
.forward_gear_ratios
.iter()
.cloned()
.collect_cxx_vector();
let reverse_gear_ratios = self
.reverse_gear_ratios
.iter()
.cloned()
.collect_cxx_vector();
let mut ctrl = FfiVehiclePhysicsControl::new().within_unique_ptr();
ctrl.pin_mut().set_torque_curve(&torque_curve);
ctrl.pin_mut().set_max_torque(self.max_torque);
ctrl.pin_mut().set_max_rpm(self.max_rpm);
ctrl.pin_mut().set_idle_rpm(self.idle_rpm);
ctrl.pin_mut().set_brake_effect(self.brake_effect);
ctrl.pin_mut().set_rev_up_moi(self.rev_up_moi);
ctrl.pin_mut().set_rev_down_rate(self.rev_down_rate);
ctrl.pin_mut().set_differential_type(self.differential_type);
ctrl.pin_mut().set_front_rear_split(self.front_rear_split);
ctrl.pin_mut()
.set_use_automatic_gears(self.use_automatic_gears);
ctrl.pin_mut().set_gear_change_time(self.gear_change_time);
ctrl.pin_mut().set_final_ratio(self.final_ratio);
ctrl.pin_mut().set_forward_gear_ratios(&forward_gear_ratios);
ctrl.pin_mut().set_reverse_gear_ratios(&reverse_gear_ratios);
ctrl.pin_mut().set_change_up_rpm(self.change_up_rpm);
ctrl.pin_mut().set_change_down_rpm(self.change_down_rpm);
ctrl.pin_mut()
.set_transmission_efficiency(self.transmission_efficiency);
ctrl.pin_mut().set_mass(self.mass);
ctrl.pin_mut().set_drag_coefficient(self.drag_coefficient);
ctrl.pin_mut()
.set_center_of_mass(&self.center_of_mass.into_ffi());
ctrl.pin_mut().set_chassis_width(self.chassis_width);
ctrl.pin_mut().set_chassis_height(self.chassis_height);
ctrl.pin_mut()
.set_downforce_coefficient(self.downforce_coefficient);
ctrl.pin_mut().set_drag_area(self.drag_area);
ctrl.pin_mut()
.set_inertia_tensor_scale(&self.inertia_tensor_scale.into_ffi());
ctrl.pin_mut().set_sleep_threshold(self.sleep_threshold);
ctrl.pin_mut().set_sleep_slope_limit(self.sleep_slope_limit);
ctrl.pin_mut().set_steering_curve(&steering_curve);
ctrl.pin_mut()
.set_use_sweep_wheel_collision(self.use_sweep_wheel_collision);
ctrl.pin_mut().clear_wheels();
for wheel in &self.wheels {
let wheel_cxx = wheel.to_cxx();
ctrl.pin_mut().push_wheel(&wheel_cxx);
}
ctrl
}
pub fn from_cxx(from: &FfiVehiclePhysicsControl) -> Self {
let convert_vec2d = |v: &carla_sys::carla::geom::Vector2D| unsafe {
Vector2D::from_ffi(std::mem::transmute::<
carla_sys::carla::geom::Vector2D,
FfiVector2D,
>(v.clone()))
};
let num_wheels = from.wheels_size();
let wheels: Vec<WheelPhysicsControl> = (0..num_wheels)
.map(|i| {
let ffi_wheel = from.wheel_at(i);
WheelPhysicsControl::from_cxx(&ffi_wheel)
})
.collect();
Self {
torque_curve: from.torque_curve().iter().map(convert_vec2d).collect(),
max_torque: from.max_torque(),
max_rpm: from.max_rpm(),
idle_rpm: from.idle_rpm(),
brake_effect: from.brake_effect(),
rev_up_moi: from.rev_up_moi(),
rev_down_rate: from.rev_down_rate(),
differential_type: from.differential_type(),
front_rear_split: from.front_rear_split(),
use_automatic_gears: from.use_automatic_gears(),
gear_change_time: from.gear_change_time(),
final_ratio: from.final_ratio(),
forward_gear_ratios: from.forward_gear_ratios().iter().cloned().collect(),
reverse_gear_ratios: from.reverse_gear_ratios().iter().cloned().collect(),
change_up_rpm: from.change_up_rpm(),
change_down_rpm: from.change_down_rpm(),
transmission_efficiency: from.transmission_efficiency(),
mass: from.mass(),
drag_coefficient: from.drag_coefficient(),
center_of_mass: Location::from_ffi(from.center_of_mass().clone()),
chassis_width: from.chassis_width(),
chassis_height: from.chassis_height(),
downforce_coefficient: from.downforce_coefficient(),
drag_area: from.drag_area(),
inertia_tensor_scale: Vector3D::from_ffi(from.inertia_tensor_scale()),
sleep_threshold: from.sleep_threshold(),
sleep_slope_limit: from.sleep_slope_limit(),
steering_curve: from.steering_curve().iter().map(convert_vec2d).collect(),
wheels,
use_sweep_wheel_collision: from.use_sweep_wheel_collision(),
}
}
}
#[cfg(not(carla_version_0100))]
#[cfg_attr(carla_version_0916, doc = "")]
#[cfg_attr(
carla_version_0916,
doc = " [`carla.VehiclePhysicsControl`]: https://carla.readthedocs.io/en/0.9.16/python_api/#carla.VehiclePhysicsControl"
)]
#[cfg_attr(carla_version_0915, doc = "")]
#[cfg_attr(
carla_version_0915,
doc = " [`carla.VehiclePhysicsControl`]: https://carla.readthedocs.io/en/0.9.15/python_api/#carla.VehiclePhysicsControl"
)]
#[cfg_attr(carla_version_0914, doc = "")]
#[cfg_attr(
carla_version_0914,
doc = " [`carla.VehiclePhysicsControl`]: https://carla.readthedocs.io/en/0.9.14/python_api/#carla.VehiclePhysicsControl"
)]
#[derive(Debug, Clone)]
pub struct VehiclePhysicsControl {
pub torque_curve: Vec<Vector2D>,
pub max_rpm: f32,
pub moi: f32,
pub damping_rate_full_throttle: f32,
pub damping_rate_zero_throttle_clutch_engaged: f32,
pub damping_rate_zero_throttle_clutch_disengaged: f32,
pub use_gear_autobox: bool,
pub gear_switch_time: f32,
pub clutch_strength: f32,
pub final_ratio: f32,
pub forward_gears: Vec<GearPhysicsControl>,
pub mass: f32,
pub drag_coefficient: f32,
pub center_of_mass: Location,
pub steering_curve: Vec<Vector2D>,
pub wheels: Vec<WheelPhysicsControl>,
pub use_sweep_wheel_collision: bool,
}
#[cfg(not(carla_version_0100))]
impl VehiclePhysicsControl {
pub fn to_cxx(&self) -> UniquePtr<FfiVehiclePhysicsControl> {
let Self {
ref torque_curve,
max_rpm,
moi,
damping_rate_full_throttle,
damping_rate_zero_throttle_clutch_engaged,
damping_rate_zero_throttle_clutch_disengaged,
use_gear_autobox,
gear_switch_time,
clutch_strength,
final_ratio,
ref forward_gears,
mass,
drag_coefficient,
ref center_of_mass,
ref steering_curve,
ref wheels,
use_sweep_wheel_collision,
} = *self;
let torque_curve = torque_curve
.iter()
.map(|v| unsafe {
std::mem::transmute::<crate::geom::FfiVector2D, carla_sys::carla::geom::Vector2D>(
v.into_ffi(),
)
})
.collect_cxx_vector();
let steering_curve = steering_curve
.iter()
.map(|v| unsafe {
std::mem::transmute::<crate::geom::FfiVector2D, carla_sys::carla::geom::Vector2D>(
v.into_ffi(),
)
})
.collect_cxx_vector();
let mut center_of_mass = Box::pin(center_of_mass.into_ffi());
let mut forward_gears = forward_gears.iter().cloned().collect_cxx_vector();
let mut wheels = wheels.iter().cloned().collect_cxx_vector();
FfiVehiclePhysicsControl::new1(
&torque_curve,
max_rpm,
moi,
damping_rate_full_throttle,
damping_rate_zero_throttle_clutch_engaged,
damping_rate_zero_throttle_clutch_disengaged,
use_gear_autobox,
gear_switch_time,
clutch_strength,
final_ratio,
forward_gears.pin_mut(),
mass,
drag_coefficient,
center_of_mass.as_mut(),
&steering_curve,
wheels.pin_mut(),
use_sweep_wheel_collision,
)
.within_unique_ptr()
}
pub fn from_cxx(from: &FfiVehiclePhysicsControl) -> Self {
Self {
torque_curve: from
.torque_curve()
.iter()
.map(|v| unsafe {
Vector2D::from_ffi(std::mem::transmute::<
carla_sys::carla::geom::Vector2D,
FfiVector2D,
>(v.clone()))
})
.collect(),
max_rpm: from.max_rpm(),
moi: from.moi(),
damping_rate_full_throttle: from.damping_rate_full_throttle(),
damping_rate_zero_throttle_clutch_engaged: from
.damping_rate_zero_throttle_clutch_engaged(),
damping_rate_zero_throttle_clutch_disengaged: from
.damping_rate_zero_throttle_clutch_disengaged(),
use_gear_autobox: from.use_gear_autobox(),
gear_switch_time: from.gear_switch_time(),
clutch_strength: from.clutch_strength(),
final_ratio: from.final_ratio(),
forward_gears: from.forward_gears().iter().cloned().collect(),
mass: from.mass(),
drag_coefficient: from.drag_coefficient(),
center_of_mass: Location::from_ffi(from.center_of_mass().clone()),
steering_curve: from
.steering_curve()
.iter()
.map(|v| unsafe {
Vector2D::from_ffi(std::mem::transmute::<
carla_sys::carla::geom::Vector2D,
FfiVector2D,
>(v.clone()))
})
.collect(),
wheels: from.wheels().iter().cloned().collect(),
use_sweep_wheel_collision: from.use_sweep_wheel_collision(),
}
}
}