franka/robot/control_loop/
mod.rs1mod motion;
13mod runner;
14mod torque;
15
16pub(crate) use runner::{control_torques, ControlLoop};
17pub(crate) use torque::convert_torques;
18#[cfg(test)]
19pub(crate) use torque::torque_rate_margin;
20
21use crate::control_types::{MotionGenerator, MotionGeneratorKind, Torques};
22use crate::duration::Duration;
23use crate::error::FrankaResult;
24use crate::lowpass_filter::MAX_CUTOFF_FREQUENCY;
25use crate::rate_limiting;
26use crate::robot::robot_impl::RobotImpl;
27use crate::robot_state::RobotState;
28use crate::wire::robot::codec::FciVersion;
29use crate::wire::robot::{MotionGeneratorCommand, MoveMotionGeneratorMode};
30
31#[derive(Debug, Clone, Copy)]
39pub(crate) struct RateLimits {
40 pub max_joint_acceleration: [f64; 7],
41 pub max_joint_jerk: [f64; 7],
42 pub max_translational_velocity: f64,
43 pub max_translational_acceleration: f64,
44 pub max_translational_jerk: f64,
45 pub max_rotational_velocity: f64,
46 pub max_rotational_acceleration: f64,
47 pub max_rotational_jerk: f64,
48 pub max_elbow_velocity: f64,
49 pub min_elbow_velocity: f64,
50 pub max_elbow_acceleration: f64,
51 pub max_elbow_jerk: f64,
52 pub max_torque_rate: [f64; 7],
53 pub torque_f32_margin: bool,
60}
61
62pub(crate) const fn rate_limits(version: FciVersion) -> RateLimits {
64 match version {
65 FciVersion::V5 => RateLimits {
66 max_joint_acceleration: rate_limiting::fer::MAX_JOINT_ACCELERATION,
67 max_joint_jerk: rate_limiting::fer::MAX_JOINT_JERK,
68 max_translational_velocity: rate_limiting::fer::MAX_TRANSLATIONAL_VELOCITY,
69 max_translational_acceleration: rate_limiting::fer::MAX_TRANSLATIONAL_ACCELERATION,
70 max_translational_jerk: rate_limiting::fer::MAX_TRANSLATIONAL_JERK,
71 max_rotational_velocity: rate_limiting::fer::MAX_ROTATIONAL_VELOCITY,
72 max_rotational_acceleration: rate_limiting::fer::MAX_ROTATIONAL_ACCELERATION,
73 max_rotational_jerk: rate_limiting::fer::MAX_ROTATIONAL_JERK,
74 max_elbow_velocity: rate_limiting::fer::MAX_ELBOW_VELOCITY,
75 min_elbow_velocity: rate_limiting::fer::MIN_ELBOW_VELOCITY,
76 max_elbow_acceleration: rate_limiting::fer::MAX_ELBOW_ACCELERATION,
77 max_elbow_jerk: rate_limiting::fer::MAX_ELBOW_JERK,
78 max_torque_rate: rate_limiting::fer::MAX_TORQUE_RATE,
79 torque_f32_margin: false,
80 },
81 FciVersion::V10 => RateLimits {
82 max_joint_acceleration: rate_limiting::MAX_JOINT_ACCELERATION,
83 max_joint_jerk: rate_limiting::MAX_JOINT_JERK,
84 max_translational_velocity: rate_limiting::MAX_TRANSLATIONAL_VELOCITY,
85 max_translational_acceleration: rate_limiting::MAX_TRANSLATIONAL_ACCELERATION,
86 max_translational_jerk: rate_limiting::MAX_TRANSLATIONAL_JERK,
87 max_rotational_velocity: rate_limiting::MAX_ROTATIONAL_VELOCITY,
88 max_rotational_acceleration: rate_limiting::MAX_ROTATIONAL_ACCELERATION,
89 max_rotational_jerk: rate_limiting::MAX_ROTATIONAL_JERK,
90 max_elbow_velocity: rate_limiting::MAX_ELBOW_VELOCITY,
91 min_elbow_velocity: rate_limiting::MIN_ELBOW_VELOCITY,
92 max_elbow_acceleration: rate_limiting::MAX_ELBOW_ACCELERATION,
93 max_elbow_jerk: rate_limiting::MAX_ELBOW_JERK,
94 max_torque_rate: rate_limiting::MAX_TORQUE_RATE,
95 torque_f32_margin: true,
96 },
97 }
98}
99
100pub(crate) trait JointVelocityLimitsSource {
106 fn upper_joint_velocity_limits(&self, q: &[f64; 7]) -> [f64; 7];
108 fn lower_joint_velocity_limits(&self, q: &[f64; 7]) -> [f64; 7];
110}
111
112impl JointVelocityLimitsSource for RobotImpl {
113 fn upper_joint_velocity_limits(&self, q: &[f64; 7]) -> [f64; 7] {
114 RobotImpl::upper_joint_velocity_limits(self, q)
115 }
116
117 fn lower_joint_velocity_limits(&self, q: &[f64; 7]) -> [f64; 7] {
118 RobotImpl::lower_joint_velocity_limits(self, q)
119 }
120}
121
122pub(crate) struct ConvertContext<'a> {
124 pub limits: &'a dyn JointVelocityLimitsSource,
126 pub rate: RateLimits,
128 pub limit_rate: bool,
130 pub cutoff_frequency: f64,
132 pub initialized_filter: bool,
135 pub first_command_is_its_own_reference: bool,
146}
147
148impl ConvertContext<'_> {
149 fn filtering(&self) -> bool {
150 self.cutoff_frequency < MAX_CUTOFF_FREQUENCY
151 }
152}
153
154pub(crate) trait ControlLoopMotion: MotionGenerator {
158 const MOVE_MODE: MoveMotionGeneratorMode;
160
161 fn convert(
163 &self,
164 context: &mut ConvertContext<'_>,
165 state: &RobotState,
166 command: &mut MotionGeneratorCommand,
167 ) -> FrankaResult<()>;
168}
169
170pub(crate) const fn move_mode(kind: MotionGeneratorKind) -> MoveMotionGeneratorMode {
172 match kind {
173 MotionGeneratorKind::JointPosition => MoveMotionGeneratorMode::JointPosition,
174 MotionGeneratorKind::JointVelocity => MoveMotionGeneratorMode::JointVelocity,
175 MotionGeneratorKind::CartesianPosition => MoveMotionGeneratorMode::CartesianPosition,
176 MotionGeneratorKind::CartesianVelocity => MoveMotionGeneratorMode::CartesianVelocity,
177 }
178}
179
180pub(crate) type MotionCallback<'a, M> = &'a mut dyn FnMut(&RobotState, Duration) -> M;
182
183pub(crate) type ControlCallback<'a> = &'a mut dyn FnMut(&RobotState, Duration) -> Torques;
185
186#[cfg(test)]
187mod tests;