2#include "../../communication/SimpleFOCDebug.h"
89 #ifndef SIMPLEFOC_DISABLE_DEBUG
103 if (voltage <= 0.0f){
124 for(
int i=0; i < 100; i++){
136 if (fabsf(r_currents.
d - zerocurrent.
d) < 0.2f)
142 float resistance =
voltage / (correction_factor * (r_currents.
d - zerocurrent.
d));
143 if (resistance <= 0.0f)
156 unsigned long t0 = 0;
157 unsigned long t1 = 0;
161 float d_electrical_angle = 0;
163 unsigned int iterations = 40;
164 unsigned int cycles = 3;
165 unsigned int risetime_us = 200;
166 unsigned int settle_us = 100000;
169 current_electric_angle += 0.5f *
_PI;
172 for (
size_t axis = 0; axis < 2; axis++)
174 for (
size_t i = 0; i < iterations; i++)
177 float inductanced = 0.0f;
179 float qcurrent = 0.0f;
180 float dcurrent = 0.0f;
181 for (
size_t j = 0; j < cycles; j++)
190 delayMicroseconds(risetime_us);
197 delayMicroseconds(settle_us);
199 if (t0 > t1)
continue;
202 float dt = (t1 - t0)/1000000.0f;
203 if (l_currents.
d - zerocurrent.
d <= 0 || (
voltage - resistance * (l_currents.
d - zerocurrent.
d)) <= 0)
208 inductanced += fabsf(- (resistance * dt) / log((
voltage - resistance * (l_currents.
d - zerocurrent.
d)) /
voltage))/correction_factor;
210 qcurrent+= l_currents.
q - zerocurrent.
q;
211 dcurrent+= l_currents.
d - zerocurrent.
d;
216 float delta = qcurrent / (fabsf(dcurrent) + fabsf(qcurrent));
219 inductanced /= cycles;
220 Ltemp = i < 2 ? inductanced : Ltemp * 0.6 + inductanced * 0.4;
222 float timeconstant = fabsf(Ltemp / resistance);
226 risetime_us =
_constrain(risetime_us * 0.6f + 0.4f * 1000000 * 0.6f * timeconstant, 100, 10000);
227 settle_us = 10 * risetime_us;
246 current_electric_angle+=fabsf(delta);
249 current_electric_angle-=fabsf(delta);
257 d_electrical_angle = i < 2 ? current_electric_angle : d_electrical_angle * 0.9 + current_electric_angle * 0.1;
263 current_electric_angle += 0.5f *
_PI;
286 float estimated_zero_electric_angle = 0.0f;
289 estimated_zero_electric_angle = estimated_zero_electric_angle_A;
292 estimated_zero_electric_angle = estimated_zero_electric_angle_B;
391 unsigned long now_us =
_micros();
393 float Ts = (now_us - open_loop_timestamp) * 1e-6f;
395 if(Ts <= 0 || Ts > 0.5f) Ts = 1e-3f;
403 open_loop_timestamp = now_us;
416 unsigned long now_us =
_micros();
418 float Ts = (now_us - open_loop_timestamp) * 1e-6f;
420 if(Ts <= 0 || Ts > 0.5f) Ts = 1e-3f;
436 open_loop_timestamp = now_us;
497 if (
controller == new_motion_controller)
return;
499 switch(new_motion_controller)
539 if (bandwidth <= 0.0f) {
766 if(customMotionControlCallback)
767 current_sp = customMotionControlCallback(
this);
843 return exit_flag > 0;
854 if(!exit_flag)
return exit_flag;
865 for (
int i = 0; i <=500; i++ ) {
875 for (
int i = 500; i >=0; i-- ) {
886 float moved = fabs(mid_angle - end_angle);
890 }
else if (mid_angle < end_angle) {
@ velocity
Velocity motion control.
@ custom
Custom control method - control method added by user.
@ angle_nocascade
Position/angle motion control without velocity cascade.
@ angle
Position/angle motion control.
#define SIMPLEFOC_MOTOR_DEBUG(msg,...)
@ SinePWM
Sinusoidal PWM modulation.
@ motor_ready
Motor is initialized and calibrated (closed loop possible)
@ motor_calibrating
Motor calibration in progress.
@ motor_calib_failed
Motor calibration failed (possibly recoverable)
#define SIMPLEFOC_MOTOR_ERROR(msg,...)
#define SIMPLEFOC_MOTOR_WARN(msg,...)
@ estimated_current
torque control using estimated current (provided motor parameters)
@ voltage
Torque control using voltage.
@ dc_current
Torque control using DC current (one current magnitude)
@ foc_current
torque control using dq currents
virtual int driverAlign(float align_voltage, bool modulation_centered=false)
PhaseCurrent_s readAverageCurrents(int N=100)
DQCurrent_s getDQCurrents(ABCurrent_s current, float angle_el)
virtual PhaseCurrent_s getPhaseCurrents()=0
virtual float getDCCurrent(float angle_el=0)
ABCurrent_s getABCurrents(PhaseCurrent_s current)
DQCurrent_s getFOCCurrents(float angle_el)
int characteriseMotor(float voltage, float correction_factor)
int8_t enabled
enabled or disabled motor flag
void updateCurrentLimit(float new_current_limit)
void linkSensor(Sensor *sensor)
int8_t modulation_centered
flag (1) centered modulation around driver limit /2 or (0) pulled to 0
DQ_s axis_inductance
motor direct axis phase inductance
void useMonitoring(Print &serial)
char monitor_separator
monitor outputs separation character
PIDController PID_current_q
parameter determining the q current PID config
virtual void setPhaseVoltage(float Uq, float Ud, float angle_el)=0
void updateVoltageLimit(float new_voltage_limit)
float sensor_offset
user defined sensor zero offset
LowPassFilter LPF_angle
parameter determining the angle low pass filter configuration
DQVoltage_s voltage
current d and q voltage set to the motor
LowPassFilter LPF_velocity
parameter determining the velocity Low pass filter configuration
uint8_t monitor_variables
Bit array holding the map of variables the user wants to monitor.
MotionControlType controller
parameter determining the control loop to be used
float phase_resistance
motor phase resistance
uint32_t loopfoc_time_us
filtered loop times
void updateTorqueControlType(TorqueControlType new_torque_controller)
float velocityOpenloop(float target_velocity)
float angleOpenloop(float target_angle)
PIDController PID_current_d
parameter determining the d current PID config
Sensor * sensor
CurrentSense link.
DQVoltage_s feed_forward_voltage
current d and q voltage set to the motor
CurrentSense * current_sense
void linkCurrentSense(CurrentSense *current_sense)
virtual void move(float target=NOT_SET)
float current_sp
target current ( q current )
float voltage_limit
Voltage limiting variable - global limit.
float velocity_limit
Velocity limiting variable - global limit.
bool pp_check_result
the result of the PP check, if run during loopFOC
PIDController P_angle
parameter determining the position PID configuration
unsigned int monitor_decimals
monitor outputs decimal places
unsigned int monitor_downsample
show monitor outputs each monitor_downsample calls
virtual float estimateBEMF(float velocity)
LowPassFilter LPF_current_q
parameter determining the current Low pass filter configuration
unsigned int motion_cnt
counting variable for downsampling for move commad
char monitor_end_char
monitor outputs ending character
Print * monitor_port
Serial terminal variable if provided.
FOCMotorStatus motor_status
motor status
float velocity_index_search
target velocity for index search
float feed_forward_velocity
current feed forward velocity
char monitor_start_char
monitor starting character
LowPassFilter LPF_current_d
parameter determining the current Low pass filter configuration
float Ubeta
Phase voltages U alpha and U beta used for inverse Park and Clarke transform.
float shaft_angle_sp
current target angle
float shaft_velocity
current motor velocity
float KV_rating
motor KV rating
float voltage_bemf
estimated backemf voltage (if provided KV constant)
float shaft_angle
current motor angle
int tuneCurrentController(float bandwidth)
float voltage_sensor_align
sensor and motor align voltage parameter
Direction sensor_direction
default is CW. if sensor_direction == Direction::CCW then direction will be flipped compared to CW....
void updateMotionControlTime()
float target
current target value - depends of the controller
float current_limit
Current limiting variable - global limit.
float electrical_angle
current electrical angle
DQCurrent_s feed_forward_current
current d and q current measured
TorqueControlType torque_controller
parameter determining the torque control type
PIDController PID_velocity
parameter determining the velocity PID configuration
float phase_inductance
motor phase inductance q axis - FOR BACKWARDS COMPATIBILITY
float zero_electric_angle
absolute zero electric angle - if available
DQCurrent_s current
current d and q current measured
int pole_pairs
motor pole pairs number
void updateVelocityLimit(float new_velocity_limit)
FOCModulationType foc_modulation
parameter determining modulation algorithm
unsigned int motion_downsample
parameter defining the ratio of downsampling for move commad
void updateMotionControlType(MotionControlType new_motion_controller)
float shaft_velocity_sp
current target velocity
float Tf
Low pass filter time constant.
float limit
Maximum output value.
float P
Proportional gain.
virtual int needsSearch()
virtual float getMechanicalAngle()
virtual float getVelocity()
static void enable(Print *debugPrint=&Serial)
#define DEF_VEL_LIM
angle velocity limit default
#define DEF_CURRENT_LIM
2Amps current limit by default
#define DEF_VOLTAGE_SENSOR_ALIGN
default voltage for sensor and motor zero alignemt
#define DEF_POWER_SUPPLY
default power supply voltage
#define DEF_INDEX_SEARCH_TARGET_VELOCITY
default index search velocity
float _electricalAngle(float shaft_angle, int pole_pairs)
float _normalizeAngle(float angle)
#define MIN_ANGLE_DETECT_MOVEMENT
#define _constrain(amt, low, high)
void _delay(unsigned long ms)