Skip to content

Commit a917406

Browse files
committed
FEAT new communication protocol
1 parent 232dcce commit a917406

File tree

15 files changed

+400
-356
lines changed

15 files changed

+400
-356
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ Therefore this is an attempt to:
3838
> - align sensor: direction + zero offset + pole pair check
3939
> - align current sense
4040
> - sensor offset supported (`motor.sensor_offset`)
41+
> - **refactored motor commands interface**
42+
> - much more flexible and easy to extend
43+
> - very easy to add new commands and function callbacks
44+
> - implemented motor+pid+lpf commands of-the-shelf
4145
>
4246
> BEWARE 📢 slight API changes included
4347
> - `ControlType` renamed into `MotionControlType`

keywords.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ PIDController KEYWORD1
1818
LowPassFilter KEYWORD1
1919
InlineCurrentSense KEYWORD1
2020
CurrentSense KEYWORD1
21+
Commander KEYWORD1
2122

2223

2324
initFOC KEYWORD2
@@ -44,6 +45,7 @@ LPF_velocity KEYWORD2
4445
LPF_current_q KEYWORD2
4546
LPF_current_d KEYWORD2
4647
P_angle KEYWORD2
48+
LPF_angle KEYWORD2
4749

4850
MotionControlType KEYWORD1
4951
TorqueControlType KEYWORD1
@@ -79,6 +81,8 @@ getCurrent KEYWORD2
7981
setPwm KEYWORD2
8082
driverAlign KEYWORD2
8183
driverSync KEYWORD2
84+
add KEYWORD2
85+
run KEYWORD2
8286

8387

8488
current KEYWORD2

src/BLDCMotor.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "common/base_classes/FOCMotor.h"
66
#include "common/base_classes/Sensor.h"
77
#include "common/base_classes/BLDCDriver.h"
8-
#include "common/base_classes/CommunicationNode.h"
98
#include "common/foc_utils.h"
109
#include "common/time_utils.h"
1110
#include "common/defaults.h"

src/SimpleFOC.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,6 @@ void loop() {
108108
#include "drivers/StepperDriver4PWM.h"
109109
#include "drivers/StepperDriver2PWM.h"
110110
#include "current_sense/InlineCurrentSense.h"
111-
#include "communication/Communicator.h"
111+
#include "communication/Commander.h"
112112

113113
#endif

src/common/base_classes/FOCMotor.cpp

Lines changed: 0 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -109,171 +109,3 @@ void FOCMotor::monitor() {
109109
}
110110
}
111111

112-
String FOCMotor::communicate(String user_command) {
113-
// error flag
114-
String ret = "";
115-
// if empty string
116-
if(user_command.length() < 1) return ret;
117-
118-
// parse command letter
119-
char cmd = user_command.charAt(0);
120-
char sub_cmd = user_command.charAt(1);
121-
int value_index = (sub_cmd >= 'A' && sub_cmd <= 'Z') ? 2 : 1;
122-
// check if get command
123-
char GET = user_command.charAt(value_index) == '\n';
124-
// parse command values
125-
float value = user_command.substring(value_index).toFloat();
126-
127-
// a bit of optimisation of variable memory for Arduino UNO (atmega328)
128-
switch(cmd){
129-
case 'Q': //
130-
ret = ret + F("PID curr q| ");
131-
if(sub_cmd == 'F') ret = ret + LPF_current_q.communicate(user_command.substring(1));
132-
else ret = ret + PID_current_q.communicate(user_command.substring(1));
133-
break;
134-
case 'D': //
135-
ret = ret + F("PID curr d| ");
136-
if(sub_cmd == 'F') ret = ret + LPF_current_d.communicate(user_command.substring(1));
137-
else ret = ret + PID_current_d.communicate(user_command.substring(1));
138-
break;
139-
case 'V': //
140-
ret = ret + F("PID vel| ");
141-
if(sub_cmd == 'F') ret = ret + LPF_velocity.communicate(user_command.substring(1));
142-
else ret = ret + PID_velocity.communicate(user_command.substring(1));
143-
break;
144-
case 'A': //
145-
ret = ret + F("PID angle| ");
146-
if(sub_cmd == 'F') ret = ret + LPF_angle.communicate(user_command.substring(1));
147-
else ret = ret + P_angle.communicate(user_command.substring(1));
148-
break;
149-
case 'L': //
150-
ret = ret + F("Limits| ");
151-
switch (sub_cmd){
152-
case 'U': // voltage limit change
153-
ret = ret + F("voltage: ");
154-
if(!GET) {
155-
voltage_limit = value;
156-
PID_current_d.limit = value;
157-
PID_current_q.limit = value;
158-
// change velocity pid limit if in voltage mode and no phase resistance set
159-
if( !_isset(phase_resistance) && torque_controller==TorqueControlType::voltage) PID_velocity.limit = value;
160-
}
161-
ret = ret + voltage_limit;
162-
break;
163-
case 'C': // current limit
164-
ret = ret + F("current: ");
165-
if(!GET){
166-
current_limit = value;
167-
// if phase resistance is set, change the voltage limit as well.
168-
if(_isset(phase_resistance)) voltage_limit = value*phase_resistance;
169-
// if phase resistance specified or the current control is on set the current limit to the velocity PID
170-
if(_isset(phase_resistance) || torque_controller != TorqueControlType::voltage ) PID_velocity.limit = value;
171-
}
172-
ret = ret + current_limit;
173-
break;
174-
case 'V': // velocity limit
175-
ret = ret + F("velocity: ");
176-
if(!GET){
177-
velocity_limit = value;
178-
P_angle.limit = value;
179-
}
180-
ret = ret + velocity_limit;
181-
break;
182-
default:
183-
ret = ret + F("error");
184-
break;
185-
}
186-
break;
187-
case 'C':
188-
ret = ret + F("Control: ");
189-
// change control type
190-
if(!GET && value >= 0 && (int)value < 5)// if set command
191-
controller = (MotionControlType)value;
192-
switch(controller){
193-
case MotionControlType::torque:
194-
ret = ret + F("torque");
195-
break;
196-
case MotionControlType::velocity:
197-
ret = ret + F("velocity");
198-
break;
199-
case MotionControlType::angle:
200-
ret = ret + F("angle");
201-
break;
202-
case MotionControlType::velocity_openloop:
203-
ret = ret + F("velocity openloop");
204-
break;
205-
case MotionControlType::angle_openloop:
206-
ret = ret + F("angle openloop");
207-
break;
208-
}
209-
break;
210-
case 'T':
211-
// change control type
212-
ret = ret + F("Torque: ");
213-
if(!GET && value >= 0 && (int)value < 3)// if set command
214-
torque_controller = (TorqueControlType)value;
215-
switch(torque_controller){
216-
case TorqueControlType::voltage:
217-
ret = ret + F("voltage");
218-
break;
219-
case TorqueControlType::current:
220-
ret = ret + F("current");
221-
break;
222-
case TorqueControlType::foc_current:
223-
ret = ret + F("foc current");
224-
break;
225-
}
226-
break;
227-
case 'E':
228-
// enable/disable
229-
ret = ret + F("Status: ");
230-
if(!GET) (bool)value ? enable() : disable();
231-
ret = ret + enabled;
232-
break;
233-
case 'S':
234-
// Sensor zero offset
235-
ret = ret + F("Sensor | ");
236-
switch (sub_cmd){
237-
case 'M': // zero offset
238-
ret = ret + F("offset: ");
239-
if(!GET) sensor_offset = value;
240-
ret = ret + sensor_offset;
241-
break;
242-
case 'E': // electrical zero offset - not suggested to touch
243-
ret = ret + F("el. offset: ");
244-
if(!GET) zero_electric_angle = value;
245-
ret = ret + zero_electric_angle;
246-
break;
247-
default:
248-
ret = ret + F("error");
249-
break;
250-
}
251-
break;
252-
case 'M': // get current values of the state variables
253-
switch((int)value){
254-
case 0: // get voltage
255-
ret = ret + F("Uq: ");
256-
ret = ret + voltage.q;
257-
break;
258-
case 1: // get velocity
259-
ret = ret + F("Velocity: ");
260-
ret = ret + shaft_velocity;
261-
break;
262-
case 2: // get angle
263-
ret = ret + F("Angle: ");
264-
ret = ret + shaft_angle;
265-
break;
266-
case 3: // get angle
267-
ret = ret + F("Target: ");
268-
ret = ret + target;
269-
break;
270-
}
271-
break;
272-
default: // target change
273-
ret = ret + F("Target: ");
274-
target = user_command.toFloat();
275-
ret = ret + target;
276-
}
277-
278-
return ret;
279-
}

src/common/base_classes/FOCMotor.h

Lines changed: 2 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
#include "Arduino.h"
55
#include "Sensor.h"
66
#include "CurrentSense.h"
7-
#include "CommunicationNode.h"
87

98
#include "../time_utils.h"
109
#include "../foc_utils.h"
@@ -45,7 +44,7 @@ enum FOCModulationType{
4544
/**
4645
Generic motor class
4746
*/
48-
class FOCMotor: public CommunicationNode
47+
class FOCMotor
4948
{
5049
public:
5150
/**
@@ -182,52 +181,7 @@ class FOCMotor: public CommunicationNode
182181
* significantly slowing the execution down!!!!
183182
*/
184183
void monitor();
185-
186-
/**
187-
* Function setting the configuration parameters of the motor, target value of the control loop
188-
* and outputing them to the monitoring port( if available ) :
189-
* - configure PID controller constants
190-
* - change motion control loops
191-
* - monitor motor variabels
192-
* - set target values
193-
* - check all the configuration values
194-
*
195-
* To check the config value just enter the command letter.
196-
* For example:
197-
* - to read velocity PI controller P gain run: P
198-
* - to set velocity PI controller P gain to 1.2 run: P1.2
199-
*
200-
* To change the target value just enter a number in the terminal:
201-
* For example:
202-
* - to change the target value to -0.1453 enter: -0.1453
203-
* - to get the current target value enter: V3
204-
*
205-
* List of commands:
206-
* - P: velocity PI controller P gain
207-
* - I: velocity PI controller I gain
208-
* - L: velocity PI controller voltage limit
209-
* - R: velocity PI controller voltage ramp
210-
* - F: velocity Low pass filter time constant
211-
* - K: angle P controller P gain
212-
* - N: angle P controller velocity limit
213-
* - C: control loop
214-
* - 0: voltage
215-
* - 1: velocity
216-
* - 2: angle
217-
* - V: get motor variables
218-
* - 0: currently set voltage
219-
* - 1: current velocity
220-
* - 2: current angle
221-
* - 3: current target value
222-
*
223-
* - Look into the documentation (docs.simplefoc.com) for more information.
224-
*
225-
* @param command String containing the user command
226-
*
227-
* returns 0 for error or 1 for executed command
228-
*/
229-
String communicate(String command) override;
230-
184+
231185
/**
232186
* Sensor link:
233187
* - Encoder

src/common/lowpass_filter.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,3 @@ float LowPassFilter::operator() (float x)
2323
timestamp_prev = timestamp;
2424
return y;
2525
}
26-
27-
String LowPassFilter::communicate(String user_cmd){
28-
String ret = "";
29-
char cmd = user_cmd.charAt(0);
30-
char GET = user_cmd.charAt(1) == '\n';
31-
float value = user_cmd.substring(1).toFloat();
32-
33-
switch (cmd){
34-
case 'F': // Tf value change
35-
ret = ret + "Tf: ";
36-
if(!GET) Tf = value;
37-
ret = ret + Tf;
38-
break;
39-
default:
40-
ret = ret + F("error");
41-
break;
42-
}
43-
return ret;
44-
}

src/common/lowpass_filter.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44

55
#include "time_utils.h"
66
#include "foc_utils.h"
7-
#include "base_classes/CommunicationNode.h"
87

98
/**
109
* Low pass filter class
1110
*/
12-
class LowPassFilter: public CommunicationNode
11+
class LowPassFilter
1312
{
1413
public:
1514
/**
@@ -21,8 +20,6 @@ class LowPassFilter: public CommunicationNode
2120
float operator() (float x);
2221
float Tf; //!< Low pass filter time constant
2322

24-
String communicate(String user_command) override;
25-
2623
protected:
2724
unsigned long timestamp_prev; //!< Last execution timestamp
2825
float y_prev; //!< filtered value in previous execution step

src/common/pid.cpp

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -55,42 +55,3 @@ float PIDController::operator() (float error){
5555
return output;
5656
}
5757

58-
59-
String PIDController::communicate(String user_cmd){
60-
String ret = "";
61-
char cmd = user_cmd.charAt(0);
62-
char GET = user_cmd.charAt(1) == '\n';
63-
float value = user_cmd.substring(1).toFloat();
64-
65-
switch (cmd){
66-
case 'P': // P gain change
67-
ret = ret + "P: ";
68-
if(!GET) P = value;
69-
ret = ret + P;
70-
break;
71-
case 'I': // I gain change
72-
ret = ret + "I: ";
73-
if(!GET) I = value;
74-
ret = ret + I;
75-
break;
76-
case 'D': // D gain change
77-
ret = ret + "D: ";
78-
if(!GET) D = value;
79-
ret = ret + D;
80-
break;
81-
case 'R': // ramp change
82-
ret = ret + "ramp: ";
83-
if(!GET) output_ramp = value;
84-
ret = ret + output_ramp;
85-
break;
86-
case 'L': // limit change
87-
ret = ret + "limit: ";
88-
if(!GET) limit = value;
89-
ret = ret + limit;
90-
break;
91-
default:
92-
ret = ret + F("error");
93-
break;
94-
}
95-
return ret; // not well handled
96-
}

0 commit comments

Comments
 (0)