From aaba6c8927b0cdd0de7739b37f2bdfe267074dbb Mon Sep 17 00:00:00 2001 From: Crozet Sébastien Date: Mon, 22 Feb 2021 12:12:24 +0100 Subject: Add motors to prismatic joints. --- src/dynamics/joint/prismatic_joint.rs | 72 ++++++++++++++++++++++++++++------- src/dynamics/joint/revolute_joint.rs | 2 + 2 files changed, 61 insertions(+), 13 deletions(-) (limited to 'src/dynamics/joint') diff --git a/src/dynamics/joint/prismatic_joint.rs b/src/dynamics/joint/prismatic_joint.rs index 6e32a01..4f5c984 100644 --- a/src/dynamics/joint/prismatic_joint.rs +++ b/src/dynamics/joint/prismatic_joint.rs @@ -1,3 +1,4 @@ +use crate::dynamics::SpringModel; use crate::math::{Isometry, Point, Real, Vector, DIM}; use crate::utils::WBasis; use na::Unit; @@ -36,10 +37,23 @@ pub struct PrismaticJoint { /// /// The impulse applied to the second body is given by `-impulse`. pub limits_impulse: Real, - // pub motor_enabled: bool, - // pub target_motor_vel: Real, - // pub max_motor_impulse: Real, - // pub motor_impulse: Real, + + /// The target relative angular velocity the motor will attempt to reach. + pub motor_target_vel: Real, + /// The target relative angle along the joint axis the motor will attempt to reach. + pub motor_target_pos: Real, + /// The motor's stiffness. + /// See the documentation of `SpringModel` for more information on this parameter. + pub motor_stiffness: Real, + /// The motor's damping. + /// See the documentation of `SpringModel` for more information on this parameter. + pub motor_damping: Real, + /// The maximal impulse the motor is able to deliver. + pub motor_max_impulse: Real, + /// The angular impulse applied by the motor. + pub motor_impulse: Real, + /// The spring-like model used by the motor to reach the target velocity and . + pub motor_model: SpringModel, } impl PrismaticJoint { @@ -63,10 +77,13 @@ impl PrismaticJoint { limits_enabled: false, limits: [-Real::MAX, Real::MAX], limits_impulse: 0.0, - // motor_enabled: false, - // target_motor_vel: 0.0, - // max_motor_impulse: Real::MAX, - // motor_impulse: 0.0, + motor_target_vel: 0.0, + motor_target_pos: 0.0, + motor_stiffness: 0.0, + motor_damping: 0.0, + motor_max_impulse: Real::MAX, + motor_impulse: 0.0, + motor_model: SpringModel::VelocityBased, } } @@ -118,10 +135,13 @@ impl PrismaticJoint { limits_enabled: false, limits: [-Real::MAX, Real::MAX], limits_impulse: 0.0, - // motor_enabled: false, - // target_motor_vel: 0.0, - // max_motor_impulse: Real::MAX, - // motor_impulse: 0.0, + motor_target_vel: 0.0, + motor_target_pos: 0.0, + motor_stiffness: 0.0, + motor_damping: 0.0, + motor_max_impulse: Real::MAX, + motor_impulse: 0.0, + motor_model: SpringModel::VelocityBased, } } @@ -137,7 +157,8 @@ impl PrismaticJoint { /// Can a SIMD constraint be used for resolving this joint? pub fn supports_simd_constraints(&self) -> bool { - true + // SIMD revolute constraints don't support motors right now. + self.motor_max_impulse == 0.0 || (self.motor_stiffness == 0.0 && self.motor_damping == 0.0) } // FIXME: precompute this? @@ -195,4 +216,29 @@ impl PrismaticJoint { let translation = self.local_anchor2.coords.into(); Isometry::from_parts(translation, rotation) } + + pub fn configure_motor_model(&mut self, model: SpringModel) { + self.motor_model = model; + } + + pub fn configure_motor_velocity(&mut self, target_vel: Real, factor: Real) { + self.configure_motor(self.motor_target_pos, target_vel, 0.0, factor) + } + + pub fn configure_motor_position(&mut self, target_pos: Real, stiffness: Real, damping: Real) { + self.configure_motor(target_pos, 0.0, stiffness, damping) + } + + pub fn configure_motor( + &mut self, + target_pos: Real, + target_vel: Real, + stiffness: Real, + damping: Real, + ) { + self.motor_target_vel = target_vel; + self.motor_target_pos = target_pos; + self.motor_stiffness = stiffness; + self.motor_damping = damping; + } } diff --git a/src/dynamics/joint/revolute_joint.rs b/src/dynamics/joint/revolute_joint.rs index e1e1441..6895d3d 100644 --- a/src/dynamics/joint/revolute_joint.rs +++ b/src/dynamics/joint/revolute_joint.rs @@ -23,6 +23,7 @@ pub struct RevoluteJoint { /// /// The impulse applied to the second body is given by `-impulse`. pub impulse: Vector5, + /// The target relative angular velocity the motor will attempt to reach. pub motor_target_vel: Real, /// The target relative angle along the joint axis the motor will attempt to reach. @@ -39,6 +40,7 @@ pub struct RevoluteJoint { pub motor_impulse: Real, /// The spring-like model used by the motor to reach the target velocity and . pub motor_model: SpringModel, + // Used to handle cases where the position target ends up being more than pi radians away. pub(crate) motor_last_angle: Real, // The angular impulse expressed in world-space. -- cgit