Skip to content

Commit 247cae3

Browse files
committed
more g4 filtering for cs + second sensor added
1 parent 6c36005 commit 247cae3

3 files changed

Lines changed: 52 additions & 11 deletions

File tree

src/common/base_classes/FOCMotor.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ FOCMotor::FOCMotor()
4242
//sensor
4343
sensor_offset = 0.0f;
4444
sensor = nullptr;
45+
position_loop_sensor = nullptr;
4546
//current sensor
4647
current_sense = nullptr;
4748
}
@@ -52,8 +53,19 @@ FOCMotor::FOCMotor()
5253
*/
5354
void FOCMotor::linkSensor(Sensor* _sensor) {
5455
sensor = _sensor;
56+
if (!position_loop_sensor) position_loop_sensor = _sensor; // if position sensor not linked use the same sensor for position control as well
5557
}
5658

59+
60+
/**
61+
Sensor linking method
62+
*/
63+
void FOCMotor::linkPositionLoopSensor(Sensor* _sensor, Direction direction) {
64+
position_loop_sensor = _sensor;
65+
position_loop_sensor_direction = direction;
66+
}
67+
68+
5769
/**
5870
CurrentSense linking method
5971
*/
@@ -64,8 +76,8 @@ void FOCMotor::linkCurrentSense(CurrentSense* _current_sense) {
6476
// shaft angle calculation
6577
float FOCMotor::shaftAngle() {
6678
// if no sensor linked return previous value ( for open loop )
67-
if(!sensor) return shaft_angle;
68-
return sensor_direction*sensor->getAngle() - sensor_offset;
79+
if(!position_loop_sensor) return shaft_angle;
80+
return position_loop_sensor_direction*position_loop_sensor->getAngle();
6981
}
7082
// shaft velocity calculation
7183
float FOCMotor::shaftVelocity() {
@@ -355,8 +367,8 @@ void FOCMotor::monitor() {
355367
DQCurrent_s c = current;
356368
if( current_sense && torque_controller != TorqueControlType::foc_current ){
357369
c = current_sense->getFOCCurrents(electrical_angle);
358-
c.q = LPF_current_q(c.q);
359-
c.d = LPF_current_d(c.d);
370+
// c.q = LPF_current_q(c.q);
371+
// c.d = LPF_current_d(c.d);
360372
}
361373
if(monitor_variables & _MON_CURR_Q) {
362374
if(!printed && monitor_start_char) monitor_port->print(monitor_start_char);
@@ -381,7 +393,7 @@ void FOCMotor::monitor() {
381393
if(monitor_variables & _MON_ANGLE) {
382394
if(!printed && monitor_start_char) monitor_port->print(monitor_start_char);
383395
else if(printed) monitor_port->print(monitor_separator);
384-
monitor_port->print(shaft_angle,monitor_decimals);
396+
monitor_port->print(shaft_angle, monitor_decimals);
385397
printed= true;
386398
}
387399
if(printed){
@@ -624,7 +636,8 @@ void FOCMotor::loopFOC() {
624636
// constrain current setpoint
625637
current_sp = _constrain(current_sp, -current_limit, current_limit) + feed_forward_current.q; // desired current is the setpoint
626638
// calculate the back-emf voltage if KV_rating available U_bemf = vel*(1/KV)
627-
if (_isset(KV_rating)) voltage_bemf = estimateBEMF(shaft_velocity);
639+
if (KV_rating &&_isset(KV_rating)) voltage_bemf = estimateBEMF(shaft_velocity);
640+
else voltage_bemf = 0;
628641
// filter the value values
629642
current.q = LPF_current_q(current_sp);
630643
// calculate the phase voltage
@@ -700,6 +713,9 @@ void FOCMotor::move(float new_target) {
700713
// a specific frequency (or almost)
701714
updateMotionControlTime();
702715

716+
// update the additional sensor values
717+
if (position_loop_sensor) position_loop_sensor->update();
718+
703719
// read value even if motor is disabled to keep the monitoring updated
704720
// except for the open loop modes where the values are updated within angle/velocityOpenLoop functions
705721

@@ -712,7 +728,7 @@ void FOCMotor::move(float new_target) {
712728
if( controller!=MotionControlType::angle_openloop && controller!=MotionControlType::velocity_openloop ){
713729
// read the values only if the motor is not in open loop
714730
// because in open loop the shaft angle/velocity is updated within angle/velocityOpenLoop functions
715-
shaft_angle = shaftAngle();
731+
shaft_angle = shaftAngle() - sensor_offset;
716732
shaft_velocity = shaftVelocity();
717733
}
718734

@@ -797,6 +813,10 @@ int FOCMotor::initFOC() {
797813
exit_flag *= alignSensor();
798814
// added the shaft_angle update
799815
sensor->update();
816+
//if(position_loop_sensor_direction == Direction::UNKNOWN) position_loop_sensor_direction = sensor_direction;
817+
SIMPLEFOC_MOTOR_DEBUG("Sensor aligned.");
818+
position_loop_sensor->update();
819+
SIMPLEFOC_MOTOR_DEBUG("Sensor aligned1.");
800820
shaft_angle = shaftAngle();
801821
} else {
802822
SIMPLEFOC_MOTOR_DEBUG("No sensor.");

src/common/base_classes/FOCMotor.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,20 @@ class FOCMotor
160160
/**
161161
* Function linking a motor and a sensor
162162
*
163-
* @param sensor Sensor class wrapper for the FOC algorihtm to read the motor angle and velocity
163+
* @param sensor Sensor class wrapper for the FOC algorithm to read the motor angle and velocity
164164
*/
165165
void linkSensor(Sensor* sensor);
166166

167+
168+
169+
/**
170+
* Function linking a motor and a second sensor used only for position control
171+
* If not provided, the motor will use the sensor linked with the linkSensor function for position control as well
172+
*
173+
* @param sensor Sensor class wrapper for the FOC algorithm to read the motor angle and velocity
174+
*/
175+
void linkPositionLoopSensor(Sensor* sensor, Direction direction = Direction::CW);
176+
167177
/**
168178
* Function linking a motor and current sensing
169179
*
@@ -265,12 +275,15 @@ class FOCMotor
265275
unsigned int motion_downsample = DEF_MOTION_DOWNSMAPLE; //!< parameter defining the ratio of downsampling for move commad
266276
unsigned int motion_cnt = 0; //!< counting variable for downsampling for move commad
267277

268-
// sensor related variabels
278+
// sensor related variables
269279
float sensor_offset; //!< user defined sensor zero offset
280+
float position_loop_sensor_direction = Direction::UNKNOWN; //!< direction of the position loop sensor compared to the sensor linked with linkSensor function - default is 1, if set to -1 the direction will be flipped
270281
float zero_electric_angle = NOT_SET;//!< absolute zero electric angle - if available
271282
Direction sensor_direction = Direction::UNKNOWN; //!< default is CW. if sensor_direction == Direction::CCW then direction will be flipped compared to CW. Set to UNKNOWN to set by calibration
272283
bool pp_check_result = false; //!< the result of the PP check, if run during loopFOC
273284

285+
286+
274287
/**
275288
* Function providing BLDCMotor class with the
276289
* Serial interface and enabling monitoring mode
@@ -299,6 +312,8 @@ class FOCMotor
299312
* - HallSensor
300313
*/
301314
Sensor* sensor;
315+
Sensor* position_loop_sensor; //!< optional second sensor used only for position control - if not provided the sensor linked with linkSensor will be used for position control as well
316+
302317
//!< CurrentSense link
303318
CurrentSense* current_sense;
304319

src/current_sense/hardware_specific/stm32/stm32g4/stm32g4_hal.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#include "../../../../communication/SimpleFOCDebug.h"
66

77
#define SIMPLEFOC_STM32_DEBUG
8+
#define SIMPLEFOC_STM32G4_CS_SAMPLING_TIME ADC_SAMPLETIME_24CYCLES_5
9+
#define SIMPLEFOC_STM32G4_CS_OVERSAMPLING_RATIO ADC_OVERSAMPLING_RATIO_8
10+
#define SIMPLEFOC_STM32G4_CS_OVERSAMPLING_SHIFT ADC_RIGHTBITSHIFT_3
811

912

1013
// pointer to the ADC handles used in the project
@@ -105,6 +108,7 @@ int _adc_init_regular(ADC_TypeDef* adc_instance){
105108
hadc[adc_num].Init.DMAContinuousRequests = DISABLE;
106109
hadc[adc_num].Init.EOCSelection = ADC_EOC_SINGLE_CONV;
107110
hadc[adc_num].Init.Overrun = ADC_OVR_DATA_PRESERVED;
111+
hadc[adc_num].Init.OversamplingMode = DISABLE;
108112
if ( HAL_ADC_Init(&hadc[adc_num]) != HAL_OK){
109113
#ifdef SIMPLEFOC_STM32_DEBUG
110114
SIMPLEFOC_DEBUG("STM32-CS: ERR: cannot init ADC!");
@@ -149,14 +153,16 @@ int _adc_init(Stm32CurrentSenseParams* cs_params, const STM32DriverParams* drive
149153
sConfigInjected.InjectedNbrOfConversion++;
150154
}
151155
}
152-
sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_2CYCLES_5;
156+
sConfigInjected.InjectedSamplingTime = SIMPLEFOC_STM32G4_CS_SAMPLING_TIME;
153157
sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_RISING;
154158
sConfigInjected.AutoInjectedConv = DISABLE;
155159
sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;
156160
sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;
157161
sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;
158162
sConfigInjected.InjectedOffset = 0;
159-
sConfigInjected.InjecOversamplingMode = DISABLE;
163+
sConfigInjected.InjecOversamplingMode = ENABLE;
164+
sConfigInjected.InjecOversampling.Ratio = SIMPLEFOC_STM32G4_CS_OVERSAMPLING_RATIO;
165+
sConfigInjected.InjecOversampling.RightBitShift = SIMPLEFOC_STM32G4_CS_OVERSAMPLING_SHIFT;
160166
sConfigInjected.QueueInjectedContext = DISABLE;
161167

162168
// automating TRGO flag finding - hardware specific

0 commit comments

Comments
 (0)