1use super::{DELTA_T, JOINT_VELOCITY_LIMITS_TOLERANCE};
8use crate::error::{FrankaError, FrankaResult};
9use crate::math_utils::{cmax, cmin};
10
11pub fn compute_upper_limits_joint_velocity(q: &[f64; 7]) -> [f64; 7] {
20 [
21 cmin(
22 2.62,
23 cmax(0.0, -0.30 + cmax(0.0, 12.0 * (2.75010 - q[0])).sqrt()),
24 ) - JOINT_VELOCITY_LIMITS_TOLERANCE[0],
25 cmin(
26 2.62,
27 cmax(0.0, -0.20 + cmax(0.0, 5.17 * (1.79180 - q[1])).sqrt()),
28 ) - JOINT_VELOCITY_LIMITS_TOLERANCE[1],
29 cmin(
30 2.62,
31 cmax(0.0, -0.20 + cmax(0.0, 7.00 * (2.90650 - q[2])).sqrt()),
32 ) - JOINT_VELOCITY_LIMITS_TOLERANCE[2],
33 cmin(
34 2.62,
35 cmax(0.0, -0.30 + cmax(0.0, 8.00 * (-0.1458 - q[3])).sqrt()),
36 ) - JOINT_VELOCITY_LIMITS_TOLERANCE[3],
37 cmin(
38 5.26,
39 cmax(0.0, -0.35 + cmax(0.0, 34.0 * (2.81010 - q[4])).sqrt()),
40 ) - JOINT_VELOCITY_LIMITS_TOLERANCE[4],
41 cmin(
42 4.18,
43 cmax(0.0, -0.35 + cmax(0.0, 11.0 * (4.52050 - q[5])).sqrt()),
44 ) - JOINT_VELOCITY_LIMITS_TOLERANCE[5],
45 cmin(
46 5.26,
47 cmax(0.0, -0.35 + cmax(0.0, 34.0 * (3.01960 - q[6])).sqrt()),
48 ) - JOINT_VELOCITY_LIMITS_TOLERANCE[6],
49 ]
50}
51
52pub fn compute_lower_limits_joint_velocity(q: &[f64; 7]) -> [f64; 7] {
59 [
60 cmax(
61 -2.62,
62 cmin(0.0, 0.30 - cmax(0.0, 12.0 * (2.750100 + q[0])).sqrt()),
63 ) + JOINT_VELOCITY_LIMITS_TOLERANCE[0],
64 cmax(
65 -2.62,
66 cmin(0.0, 0.20 - cmax(0.0, 5.17 * (1.791800 + q[1])).sqrt()),
67 ) + JOINT_VELOCITY_LIMITS_TOLERANCE[1],
68 cmax(
69 -2.62,
70 cmin(0.0, 0.20 - cmax(0.0, 7.00 * (2.906500 + q[2])).sqrt()),
71 ) + JOINT_VELOCITY_LIMITS_TOLERANCE[2],
72 cmax(
73 -2.62,
74 cmin(0.0, 0.30 - cmax(0.0, 8.00 * (3.048100 + q[3])).sqrt()),
75 ) + JOINT_VELOCITY_LIMITS_TOLERANCE[3],
76 cmax(
77 -5.26,
78 cmin(0.0, 0.35 - cmax(0.0, 34.0 * (2.810100 + q[4])).sqrt()),
79 ) + JOINT_VELOCITY_LIMITS_TOLERANCE[4],
80 cmax(
81 -4.18,
82 cmin(0.0, 0.35 - cmax(0.0, 11.0 * (-0.54092 + q[5])).sqrt()),
83 ) + JOINT_VELOCITY_LIMITS_TOLERANCE[5],
84 cmax(
85 -5.26,
86 cmin(0.0, 0.35 - cmax(0.0, 34.0 * (3.019600 + q[6])).sqrt()),
87 ) + JOINT_VELOCITY_LIMITS_TOLERANCE[6],
88 ]
89}
90
91#[allow(clippy::too_many_arguments)]
103pub fn limit_rate_joint_velocity(
104 upper_limits_velocity: f64,
105 lower_limits_velocity: f64,
106 max_acceleration: f64,
107 max_jerk: f64,
108 commanded_velocity: f64,
109 last_commanded_velocity: f64,
110 last_commanded_acceleration: f64,
111) -> f64 {
112 let commanded_jerk = (((commanded_velocity - last_commanded_velocity) / DELTA_T)
114 - last_commanded_acceleration)
115 / DELTA_T;
116
117 let commanded_acceleration =
119 last_commanded_acceleration + cmax(cmin(commanded_jerk, max_jerk), -max_jerk) * DELTA_T;
120
121 let safe_max_acceleration = cmin(
123 (max_jerk / max_acceleration) * (upper_limits_velocity - last_commanded_velocity),
124 max_acceleration,
125 );
126 let safe_min_acceleration = cmax(
127 (max_jerk / max_acceleration) * (lower_limits_velocity - last_commanded_velocity),
128 -max_acceleration,
129 );
130
131 last_commanded_velocity
133 + cmax(
134 cmin(commanded_acceleration, safe_max_acceleration),
135 safe_min_acceleration,
136 ) * DELTA_T
137}
138
139#[allow(clippy::too_many_arguments)]
151pub fn limit_rate_joint_position(
152 upper_limits_velocity: f64,
153 lower_limits_velocity: f64,
154 max_acceleration: f64,
155 max_jerk: f64,
156 commanded_position: f64,
157 last_commanded_position: f64,
158 last_commanded_velocity: f64,
159 last_commanded_acceleration: f64,
160) -> f64 {
161 last_commanded_position
162 + limit_rate_joint_velocity(
163 upper_limits_velocity,
164 lower_limits_velocity,
165 max_acceleration,
166 max_jerk,
167 (commanded_position - last_commanded_position) / DELTA_T,
168 last_commanded_velocity,
169 last_commanded_acceleration,
170 ) * DELTA_T
171}
172
173#[allow(clippy::too_many_arguments)]
183pub fn limit_rate_joint_velocities(
184 upper_limits_velocity: &[f64; 7],
185 lower_limits_velocity: &[f64; 7],
186 max_acceleration: &[f64; 7],
187 max_jerk: &[f64; 7],
188 commanded_velocities: &[f64; 7],
189 last_commanded_velocities: &[f64; 7],
190 last_commanded_accelerations: &[f64; 7],
191) -> FrankaResult<[f64; 7]> {
192 if !commanded_velocities.iter().all(|v| v.is_finite()) {
193 return Err(FrankaError::InvalidArgument(
194 "commanded_velocities is infinite or NaN.".to_string(),
195 ));
196 }
197 let mut limited = [0.0; 7];
198 for i in 0..7 {
199 limited[i] = limit_rate_joint_velocity(
200 upper_limits_velocity[i],
201 lower_limits_velocity[i],
202 max_acceleration[i],
203 max_jerk[i],
204 commanded_velocities[i],
205 last_commanded_velocities[i],
206 last_commanded_accelerations[i],
207 );
208 }
209 Ok(limited)
210}
211
212#[allow(clippy::too_many_arguments)]
222pub fn limit_rate_joint_positions(
223 upper_limits_velocity: &[f64; 7],
224 lower_limits_velocity: &[f64; 7],
225 max_acceleration: &[f64; 7],
226 max_jerk: &[f64; 7],
227 commanded_positions: &[f64; 7],
228 last_commanded_positions: &[f64; 7],
229 last_commanded_velocities: &[f64; 7],
230 last_commanded_accelerations: &[f64; 7],
231) -> FrankaResult<[f64; 7]> {
232 if !commanded_positions.iter().all(|v| v.is_finite()) {
233 return Err(FrankaError::InvalidArgument(
234 "commanded_positions is infinite or NaN.".to_string(),
235 ));
236 }
237 let mut limited = [0.0; 7];
238 for i in 0..7 {
239 limited[i] = limit_rate_joint_position(
240 upper_limits_velocity[i],
241 lower_limits_velocity[i],
242 max_acceleration[i],
243 max_jerk[i],
244 commanded_positions[i],
245 last_commanded_positions[i],
246 last_commanded_velocities[i],
247 last_commanded_accelerations[i],
248 );
249 }
250 Ok(limited)
251}