|
| 1 | +#include "../flags.h" |
1 | 2 | #include "FOCMotor.h" |
2 | 3 | #include "../../communication/SimpleFOCDebug.h" |
3 | 4 |
|
@@ -25,9 +26,11 @@ FOCMotor::FOCMotor() |
25 | 26 |
|
26 | 27 | // default target value |
27 | 28 | target = 0; |
| 29 | + #ifndef SIMPLEFOC_NO_PROFILING |
28 | 30 | profile_state.position = 0; |
29 | 31 | profile_state.velocity = 0; |
30 | 32 | profile_state.initialized = false; |
| 33 | + #endif |
31 | 34 | open_loop_velocity = 0; |
32 | 35 | voltage.d = 0; |
33 | 36 | voltage.q = 0; |
@@ -189,7 +192,7 @@ int FOCMotor::characteriseMotor(float voltage, float correction_factor=1.0f){ |
189 | 192 | unsigned int iterations = 40; // how often the algorithm gets repeated. |
190 | 193 | unsigned int cycles = 3; // averaged measurements for each iteration |
191 | 194 | unsigned int risetime_us = 200; // initially short for worst case scenario with low inductance |
192 | | - unsigned int settle_us = 100000; // initially long for worst case scenario with high inductance |
| 195 | + uint32_t settle_us = 100000; // initially long for worst case scenario with high inductance |
193 | 196 |
|
194 | 197 | // Pre-rotate the angle to the q-axis (only useful with sensor, else no harm in doing it) |
195 | 198 | current_electric_angle += 0.5f * _PI; |
@@ -421,11 +424,9 @@ float FOCMotor::velocityOpenloop(float target_velocity){ |
421 | 424 | if(Ts <= 0 || Ts > 0.5f) Ts = 1e-3f; |
422 | 425 |
|
423 | 426 | // if acceleration limit is set, use it to calculate the target velocity |
424 | | - if (_isset(acceleration_limit) && acceleration_limit > 0.0f) { |
| 427 | + if (acceleration_limit > 0.0f) { |
425 | 428 | // limit the change in velocity to the acceleration limit |
426 | | - float dv_max = acceleration_limit * Ts; |
427 | | - float dv = _constrain(target_velocity - open_loop_velocity, -dv_max, dv_max); |
428 | | - open_loop_velocity += dv; |
| 429 | + open_loop_velocity += _constrain(target_velocity - open_loop_velocity, -acceleration_limit * Ts, acceleration_limit * Ts); |
429 | 430 | } else { |
430 | 431 | open_loop_velocity = target_velocity; |
431 | 432 | } |
@@ -454,34 +455,31 @@ float FOCMotor::angleOpenloop(float target_angle){ |
454 | 455 | // calculate the sample time from last call |
455 | 456 | float Ts = (now_us - open_loop_timestamp) * 1e-6f; |
456 | 457 | // quick fix for strange cases (micros overflow + timestamp not defined) |
457 | | - if(Ts <= 0 || Ts > 0.5f) Ts = 1e-3f; |
| 458 | + if(Ts <= 0.0f || Ts > 0.5f) Ts = 1e-3f; |
458 | 459 |
|
459 | | - float err = target_angle - shaft_angle; |
460 | | - float target_velocity = 0.0f; |
461 | 460 | // if acceleration limit is set, use it to calculate the target velocity |
462 | 461 | if (acceleration_limit > 0.0f) { |
463 | 462 | // calculate the necessary velocity to stop at the target angle with the given acceleration limit |
464 | | - float stop_vel = sqrtf(2.0f * acceleration_limit * fabsf(err)); |
| 463 | + float stop_vel = sqrtf(2.0f * acceleration_limit * fabsf(target_angle - shaft_angle)); |
465 | 464 | // limit the target velocity to the velocity limit |
466 | | - target_velocity = _sign(err) * _constrain(stop_vel, 0.0f, velocity_limit); |
| 465 | + float target_velocity = _sign(target_angle - shaft_angle) * _constrain(stop_vel, 0.0f, velocity_limit); |
467 | 466 |
|
468 | 467 | // limit the change in velocity to the acceleration limit |
469 | | - float dv_max = acceleration_limit * Ts; |
470 | | - float dv = _constrain(target_velocity - open_loop_velocity, -dv_max, dv_max); |
471 | | - |
472 | | - // update the open loop velocity |
473 | | - open_loop_velocity += dv; |
| 468 | + open_loop_velocity += _constrain(target_velocity - open_loop_velocity, -acceleration_limit * Ts, acceleration_limit * Ts); |
474 | 469 |
|
475 | 470 | // integrate the open loop velocity to get the new shaft angle |
476 | 471 | float step = open_loop_velocity * Ts; |
477 | | - if ((fabsf(err) <= fabsf(step)) || (fabsf(err) < 1e-6f && fabsf(open_loop_velocity) <= dv_max)) { |
| 472 | + if ((fabsf(target_angle - shaft_angle) <= fabsf(step)) || |
| 473 | + (fabsf(target_angle - shaft_angle) < 1e-6f && |
| 474 | + fabsf(open_loop_velocity) <= (acceleration_limit * Ts))) { |
478 | 475 | shaft_angle = target_angle; |
479 | 476 | open_loop_velocity = 0.0f; |
480 | 477 | } else { |
481 | 478 | shaft_angle += step; |
482 | 479 | } |
483 | 480 | shaft_velocity = open_loop_velocity; |
484 | | - } else { |
| 481 | + } |
| 482 | + else { |
485 | 483 | // if no acceleration limit is set, use the velocity limit to calculate the target velocity |
486 | 484 | // calculate the necessary angle to move from current position towards target angle |
487 | 485 | // with maximal velocity (velocity_limit) |
@@ -599,13 +597,15 @@ void FOCMotor::updateMotionControlType(MotionControlType new_motion_controller) |
599 | 597 | break; |
600 | 598 | } |
601 | 599 |
|
| 600 | + #ifndef SIMPLEFOC_NO_PROFILING |
602 | 601 | if (new_motion_controller == MotionControlType::angle_profile) { |
603 | 602 | trajectoryResetTrapezoidal(profile_state, shaft_angle, 0.0f, target); |
604 | 603 | profile_state.initialized = false; |
605 | 604 | } else if (controller == MotionControlType::angle_profile) { |
606 | 605 | profile_state.velocity = 0.0f; |
607 | 606 | profile_state.initialized = false; |
608 | 607 | } |
| 608 | + #endif |
609 | 609 |
|
610 | 610 | if (new_motion_controller == MotionControlType::angle_openloop || new_motion_controller == MotionControlType::velocity_openloop) { |
611 | 611 | open_loop_velocity = 0.0f; |
@@ -813,7 +813,9 @@ void FOCMotor::move(float new_target) { |
813 | 813 | current_sp = P_angle(shaft_angle_sp - LPF_angle(shaft_angle)); |
814 | 814 | break; |
815 | 815 | } |
816 | | - case MotionControlType::angle_profile: { |
| 816 | + case MotionControlType::angle_profile: |
| 817 | + #ifndef SIMPLEFOC_NO_PROFILING |
| 818 | + { |
817 | 819 | // TODO sensor precision: this calculation is not numerically precise. The target value cannot express precise positions when |
818 | 820 | // the angles are large. This results in not being able to command small changes at high position values. |
819 | 821 | // to solve this, the delta-angle has to be calculated in a numerically precise way. |
@@ -853,6 +855,7 @@ void FOCMotor::move(float new_target) { |
853 | 855 | current_sp = PID_velocity(shaft_velocity_sp - shaft_velocity); |
854 | 856 | break; |
855 | 857 | } |
| 858 | + #endif |
856 | 859 | case MotionControlType::angle: |
857 | 860 | // TODO sensor precision: this calculation is not numerically precise. The target value cannot express precise positions when |
858 | 861 | // the angles are large. This results in not being able to command small changes at high position values. |
|
0 commit comments