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