@@ -206,12 +206,42 @@ void SmartServoClass::setPosition(uint8_t const id, float const angle)
206206 if (!isValidId (id))
207207 return ;
208208
209- _targetPosition[idToArrayIndex (id)] = angleToPosition (angle);
209+ float const MAX_ANGULAR_VELOCITY_deg_per_sec = 10 .0f ;
210+
211+ float const target_position_deg = angleToPosition (angle);
212+ float const actual_position_deg = getPosition (id);
213+ if (actual_position_deg < 0 .0f )
214+ {
215+ char msg[64 ] = {0 };
216+ snprintf (msg, sizeof (msg), " error obtaining position for servo %d" , (int )id);
217+ Serial.println (msg);
218+ return ;
219+ }
220+
221+ float const abs_position_diff_deg = fabs (target_position_deg - actual_position_deg);
222+ float const runtime_sec = static_cast <float >(getTime (id)) / 1000 .0f ;
223+ float const angular_velocity_deg_per_sec = abs_position_diff_deg / runtime_sec;
224+
225+ /* Check whether or not the maximum allowed angular velocity is exceeded,
226+ * if it is indeed exceeded increase the runtime accordingly.
227+ */
228+ if (angular_velocity_deg_per_sec > MAX_ANGULAR_VELOCITY_deg_per_sec)
229+ {
230+ float const limited_runtime_sec = abs_position_diff_deg / MAX_ANGULAR_VELOCITY_deg_per_sec;
231+ setTime (id, static_cast <uint16_t >(limited_runtime_sec));
232+
233+ char msg[64 ] = {0 };
234+ snprintf (msg, sizeof (msg), " targed = %0.2f, actual = %0.2f, diff = %0.2f, omega_vel = %0.2f" ,
235+ target_position_deg, actual_position_deg, abs_position_diff_deg, angular_velocity_deg_per_sec);
236+ Serial.println (msg);
237+ }
238+
239+ _targetPosition[idToArrayIndex (id)] = target_position_deg;
210240
211241 if (_positionMode == PositionMode::IMMEDIATE)
212242 {
213243 mbed::ScopedLock<rtos::Mutex> lock (_mtx);
214- writeWordCmd (id, REG (SmartServoRegister::TARGET_POSITION_H), angleToPosition (angle) );
244+ writeWordCmd (id, REG (SmartServoRegister::TARGET_POSITION_H), target_position_deg );
215245 }
216246}
217247
0 commit comments