SimpleFOClibrary 2.4.0
Loading...
Searching...
No Matches
Commander.cpp
Go to the documentation of this file.
1#include "Commander.h"
2
3Commander::Commander(Stream& serial, char eol, bool echo){
4 com_port = &serial;
5 this->eol = eol;
6 this->echo = echo;
7}
8Commander::Commander(char eol, bool echo){
9 this->eol = eol;
10 this->echo = echo;
11}
12
13
14void Commander::add(char id, CommandCallback onCommand, const char* label ){
15 call_list[call_count] = onCommand;
16 call_ids[call_count] = id;
17 call_label[call_count] = (char*)label;
18 call_count++;
19}
20
21
23 if(!com_port) return;
24 run(*com_port, eol);
25}
26
27void Commander::run(Stream& serial, char eol){
28 Stream* tmp = com_port; // save the serial instance
29 char eol_tmp = this->eol;
30 this->eol = eol;
31 com_port = &serial;
32
33 // a string to hold incoming data
34 while (serial.available()) {
35 // get the new byte:
36 int ch = serial.read();
37 received_chars[rec_cnt++] = (char)ch;
38 // end of user input
39 if(echo)
40 print((char)ch);
41 if (isSentinel(ch)) {
42 // execute the user command
43 run(received_chars);
44
45 // reset the command buffer
46 memset(received_chars, 0, MAX_COMMAND_LENGTH);
47 rec_cnt=0;
48 }
49 if (rec_cnt>=MAX_COMMAND_LENGTH) { // prevent buffer overrun if message is too long
50 memset(received_chars, 0, MAX_COMMAND_LENGTH);
51 rec_cnt=0;
52 }
53 }
54
55 com_port = tmp; // reset the instance to the internal value
56 this->eol = eol_tmp;
57}
58
59void Commander::run(char* user_input){
60 // execute the user command
61 char id = user_input[0];
62 switch(id){
63 case CMD_SCAN:
64 for(int i=0; i < call_count; i++){
65 printMachineReadable(CMD_SCAN);
66 print(call_ids[i]);
67 print(":");
68 if(call_label[i]) println(call_label[i]);
69 else println("");
70 }
71 break;
72 case CMD_VERBOSE:
73 if(!isSentinel(user_input[1])) verbose = (VerboseMode)atoi(&user_input[1]);
74 printVerbose(F("Verb:"));
75 printMachineReadable(CMD_VERBOSE);
76 switch (verbose){
78 println(F("off!"));
79 break;
82 println(F("on!"));
83 break;
85 printlnMachineReadable(F("machine"));
86 break;
87 }
88 break;
89 case CMD_DECIMAL:
90 if(!isSentinel(user_input[1])) decimal_places = atoi(&user_input[1]);
91 printVerbose(F("Decimal:"));
92 printMachineReadable(CMD_DECIMAL);
93 println(decimal_places);
94 break;
95 default:
96 for(int i=0; i < call_count; i++){
97 if(id == call_ids[i]){
98 printMachineReadable(user_input[0]);
99 call_list[i](&user_input[1]);
100 break;
101 }
102 }
103 break;
104 }
105}
106
107void Commander::motor(FOCMotor* motor, char* user_command) {
108
109 // if target setting
110 if(isDigit(user_command[0]) || user_command[0] == '-' || user_command[0] == '+' || isSentinel(user_command[0])){
111 target(motor, user_command);
112 return;
113 }
114
115 // parse command letter
116 char cmd = user_command[0];
117 char sub_cmd = user_command[1];
118 // check if there is a subcommand or not
119 int value_index = (sub_cmd >= 'A' && sub_cmd <= 'Z') || (sub_cmd == '#') ? 2 : 1;
120 // check if get command
121 bool GET = isSentinel(user_command[value_index]);
122 // parse command values
123 float value = atof(&user_command[value_index]);
124 printMachineReadable(cmd);
125 if (sub_cmd >= 'A' && sub_cmd <= 'Z') {
126 printMachineReadable(sub_cmd);
127 }
128
129 // a bit of optimisation of variable memory for Arduino UNO (atmega328)
130 switch(cmd){
131 case CMD_C_Q_PID: //
132 printVerbose(F("PID curr q| "));
133 if(sub_cmd == SCMD_LPF_TF) lpf(&motor->LPF_current_q, &user_command[1]);
134 else pid(&motor->PID_current_q,&user_command[1]);
135 break;
136 case CMD_C_D_PID: //
137 printVerbose(F("PID curr d| "));
138 if(sub_cmd == SCMD_LPF_TF) lpf(&motor->LPF_current_d, &user_command[1]);
139 else pid(&motor->PID_current_d, &user_command[1]);
140 break;
141 case CMD_V_PID: //
142 printVerbose(F("PID vel| "));
143 if(sub_cmd == SCMD_LPF_TF) lpf(&motor->LPF_velocity, &user_command[1]);
144 else pid(&motor->PID_velocity, &user_command[1]);
145 break;
146 case CMD_A_PID: //
147 printVerbose(F("PID angle| "));
148 if(sub_cmd == SCMD_LPF_TF) lpf(&motor->LPF_angle, &user_command[1]);
149 else pid(&motor->P_angle, &user_command[1]);
150 break;
151 case CMD_LIMITS: //
152 printVerbose(F("Limits| "));
153 switch (sub_cmd){
154 case SCMD_LIM_VOLT: // voltage limit change
155 printVerbose(F("volt: "));
156 if(!GET) {
157 motor->updateVoltageLimit(value);
158 }
159 println(motor->voltage_limit);
160 break;
161 case SCMD_LIM_CURR: // current limit
162 printVerbose(F("curr: "));
163 if(!GET){
164 motor->updateCurrentLimit(value);
165 }
166 println(motor->current_limit);
167 break;
168 case SCMD_LIM_VEL: // velocity limit
169 printVerbose(F("vel: "));
170 if(!GET){
171 motor->updateVelocityLimit(value);
172 }
173 println(motor->velocity_limit);
174 break;
175 default:
176 printError();
177 break;
178 }
179 break;
180 case CMD_MOTION_TYPE:
181 case CMD_TORQUE_TYPE:
182 case CMD_STATUS:
183 motion(motor, &user_command[0]);
184 break;
185 case CMD_PWMMOD:
186 // PWM modulation change
187 printVerbose(F("PWM Mod | "));
188 switch (sub_cmd){
189 case SCMD_PWMMOD_TYPE: // zero offset
190 printVerbose(F("type: "));
191 if(!GET) motor->foc_modulation = (FOCModulationType)value;
192 switch(motor->foc_modulation){
194 println(F("SinePWM"));
195 break;
197 println(F("SVPWM"));
198 break;
200 println(F("Trap 120"));
201 break;
203 println(F("Trap 150"));
204 break;
205 }
206 break;
207 case SCMD_PWMMOD_CENTER: // centered modulation
208 printVerbose(F("center: "));
209 if(!GET) motor->modulation_centered = value;
210 println(motor->modulation_centered);
211 break;
212 default:
213 printError();
214 break;
215 }
216 break;
217 case CMD_RESIST:
218 printVerbose(F("R phase: "));
219 if(!GET){
220 motor->phase_resistance = value;
221 }
222 if(_isset(motor->phase_resistance)) println(motor->phase_resistance);
223 else println(0);
224 break;
225 case CMD_INDUCTANCE:
226 printVerbose(F("L phase: "));
227 switch (sub_cmd){
228 case SCMD_INDUCT_D:
229 printVerbose(F("d: "));
230 if(!GET){
231 motor->axis_inductance.d = value;
232 motor->phase_inductance = value;
233 }
234 if(_isset(motor->axis_inductance.d)) println(motor->axis_inductance.d);
235 else println(0);
236 break;
237 case SCMD_INDUCT_Q:
238 printVerbose(F("q: "));
239 if(!GET){
240 motor->axis_inductance.q = value;
241 }
242 if(_isset(motor->axis_inductance.q)) println(motor->axis_inductance.q);
243 else println(0);
244 break;
245 default:
246 if(!GET){
247 motor->phase_inductance = value;
248 motor->axis_inductance.d = value;
249 motor->axis_inductance.q = value;
250 }
251 if(_isset(motor->phase_inductance)) println(motor->phase_inductance);
252 else println(0);
253 break;
254 }
255 break;
256 case CMD_KV_RATING:
257 printVerbose(F("Motor KV: "));
258 if(!GET){
259 motor->KV_rating = value;
260 }
261 if(_isset(motor->KV_rating)) println(motor->KV_rating);
262 else println(0);
263 break;
264 case CMD_SENSOR:
265 // Sensor zero offset
266 printVerbose(F("Sensor | "));
267 switch (sub_cmd){
268 case SCMD_SENS_MECH_OFFSET: // zero offset
269 printVerbose(F("offset: "));
270 if(!GET) motor->sensor_offset = value;
271 println(motor->sensor_offset);
272 break;
273 case SCMD_SENS_ELEC_OFFSET: // electrical zero offset - not suggested to touch
274 printVerbose(F("el. offset: "));
275 if(!GET) motor->zero_electric_angle = value;
276 println(motor->zero_electric_angle);
277 break;
278 default:
279 printError();
280 break;
281 }
282 break;
283 case CMD_FOC_PARAMS:
284 printVerbose(F("MOT | "));
285 switch (sub_cmd){
286 case SCMD_REINIT_FOC:
287 printVerbose(F("Reinit!"));
288 motor->sensor_direction = Direction::UNKNOWN; // reset sensor direction estimation
289 motor->zero_electric_angle = NOT_SET; // reset zero electric angle
290 motor->target = 0; // reset target
291 motor->initFOC();
292 println(F("done"));
293 break;
294 case SCMD_MEAS_PARAMS:
295 printVerbose(F("Meas motor params!"));
296 {
297 int res = motor->characteriseMotor(value, 1.5f);
298 if(res == 0){
299 println(F("done"));
300 } else {
301 printVerbose(F("failed, err code: "));
302 println(res);
303 }
304 }
305 break;
306 case SCMD_TUNE_CURR:
307 printVerbose(F("PI tune curr.| "));
308 {
309 int res = motor->tuneCurrentController(value);
310 if(res == 0){
311 println(F("done"));
312 } else {
313 printVerbose(F("failed, err code: "));
314 println(res);
315 }
316 }
317 break;
318 default:
319 printError();
320 break;
321 }
322 break;
323 case CMD_MONITOR: // get current values of the state variables
324 printVerbose(F("Monitor | "));
325 switch (sub_cmd){
326 case SCMD_GET: // get command
327 switch((uint8_t)value){
328 case 0: // get target
329 printVerbose(F("target: "));
330 println(motor->target);
331 break;
332 case 1: // get voltage q
333 printVerbose(F("Vq: "));
334 println(motor->voltage.q);
335 break;
336 case 2: // get voltage d
337 printVerbose(F("Vd: "));
338 println(motor->voltage.d);
339 break;
340 case 3: // get current q
341 printVerbose(F("Cq: "));
342 println(motor->current.q);
343 break;
344 case 4: // get current d
345 printVerbose(F("Cd: "));
346 println(motor->current.d);
347 break;
348 case 5: // get velocity
349 printVerbose(F("vel: "));
350 println(motor->shaft_velocity);
351 break;
352 case 6: // get angle
353 printVerbose(F("angle: "));
354 println(motor->shaft_angle);
355 break;
356 case 7: // get all states
357 printVerbose(F("all: "));
358 print(motor->target);
359 print(";");
360 print(motor->voltage.q);
361 print(";");
362 print(motor->voltage.d);
363 print(";");
364 print(motor->current.q);
365 print(";");
366 print(motor->current.d);
367 print(";");
368 print(motor->shaft_velocity);
369 print(";");
370 println(motor->shaft_angle);
371 break;
372 default:
373 printError();
374 break;
375 }
376 break;
377 case SCMD_DOWNSAMPLE:
378 printVerbose(F("downsample: "));
379 if(!GET) motor->monitor_downsample = value;
380 println((int)motor->monitor_downsample);
381 break;
382 case SCMD_CLEAR:
383 motor->monitor_variables = (uint8_t) 0;
384 println(F("clear"));
385 break;
386 case CMD_DECIMAL:
387 printVerbose(F("decimal: "));
388 motor->monitor_decimals = value;
389 println((int)motor->monitor_decimals);
390 break;
391 case SCMD_SET:
392 if(!GET){
393 // set the variables
394 motor->monitor_variables = (uint8_t) 0;
395 for(int i = 0; i < 7; i++){
396 if(isSentinel(user_command[value_index+i])) break;
397 motor->monitor_variables |= (user_command[value_index+i] - '0') << (6-i);
398 }
399 }
400 // print the variables
401 for(int i = 0; i < 7; i++){
402 print( (motor->monitor_variables & (1 << (6-i))) >> (6-i));
403 }
404 println("");
405 break;
406 default:
407 printError();
408 break;
409 }
410 break;
411 default: // unknown cmd
412 printVerbose(F("unknown cmd "));
413 printError();
414 }
415}
416
417void Commander::motion(FOCMotor* motor, char* user_cmd, char* separator){
418 char cmd = user_cmd[0];
419 char sub_cmd = user_cmd[1];
420 int value_index = (sub_cmd == SCMD_DOWNSAMPLE) ? 2 : 1;
421 bool GET = isSentinel(user_cmd[value_index]);
422 float value = atof(&user_cmd[(sub_cmd >= 'A' && sub_cmd <= 'Z') ? 2 : 1]);
423
424 switch(cmd){
425 case CMD_MOTION_TYPE:
426 printVerbose(F("Motion:"));
427 switch(sub_cmd){
428 case SCMD_TIME:
429 printVerbose(F(" time: "));
430 println((int)motor->move_time_us);
431 break;
432 case SCMD_DOWNSAMPLE:
433 printVerbose(F(" downsample: "));
434 if(!GET) motor->motion_downsample = value;
435 println((int)motor->motion_downsample);
436 break;
437 default:
438 // change control type
439 if(!GET && value >= 0 && (int)value < 7) // if set command
440 motor->updateMotionControlType((MotionControlType)value); // update motion control type
441 switch(motor->controller){
443 println(F("torque"));
444 break;
446 println(F("vel"));
447 break;
449 println(F("angle"));
450 break;
452 println(F("vel open"));
453 break;
455 println(F("angle open"));
456 break;
458 println(F("angle nocascade"));
459 break;
461 println(F("custom"));
462 break;
463 }
464 break;
465 }
466 break;
467 case CMD_TORQUE_TYPE:
468 // change control type
469 printVerbose(F("Torque: "));
470 switch(sub_cmd){
471 case SCMD_TIME:
472 printVerbose(F(" time: "));
473 println((int)motor->move_time_us);
474 break;
475 default:
476 if(!GET && (int8_t)value >= 0 && (int8_t)value < 4) // if set command
477 motor->updateTorqueControlType((TorqueControlType)value); // update torque control type
478 switch(motor->torque_controller){
480 println(F("volt"));
481 break;
483 println(F("dc curr"));
484 break;
486 println(F("foc curr"));
487 break;
489 println(F("est. curr"));
490 break;
491 default:
492 printError();
493 }
494 break;
495 }
496 break;
497 case CMD_STATUS:
498 // enable/disable
499 printVerbose(F("Status: "));
500 if(!GET) (bool)value ? motor->enable() : motor->disable();
501 println(motor->enabled);
502 break;
503 default:
504 target(motor, user_cmd, separator);
505 break;
506 }
507}
508
509void Commander::pid(PIDController* pid, char* user_cmd){
510 char cmd = user_cmd[0];
511 bool GET = isSentinel(user_cmd[1]);
512 float value = atof(&user_cmd[1]);
513
514 switch (cmd){
515 case SCMD_PID_P: // P gain change
516 printVerbose("P: ");
517 if(!GET) pid->P = value;
518 println(pid->P);
519 break;
520 case SCMD_PID_I: // I gain change
521 printVerbose("I: ");
522 if(!GET) pid->I = value;
523 println(pid->I);
524 break;
525 case SCMD_PID_D: // D gain change
526 printVerbose("D: ");
527 if(!GET) pid->D = value;
528 println(pid->D);
529 break;
530 case SCMD_PID_RAMP: // ramp change
531 printVerbose("ramp: ");
532 if(!GET) pid->output_ramp = value;
533 println(pid->output_ramp);
534 break;
535 case SCMD_PID_LIM: // limit change
536 printVerbose("limit: ");
537 if(!GET) pid->limit = value;
538 println(pid->limit);
539 break;
540 default:
541 printError();
542 break;
543 }
544}
545
546void Commander::lpf(LowPassFilter* lpf, char* user_cmd){
547 char cmd = user_cmd[0];
548 bool GET = isSentinel(user_cmd[1]);
549 float value = atof(&user_cmd[1]);
550
551 switch (cmd){
552 case SCMD_LPF_TF: // Tf value change
553 printVerbose(F("Tf: "));
554 if(!GET) lpf->Tf = value;
555 println(lpf->Tf);
556 break;
557 default:
558 printError();
559 break;
560 }
561}
562
563void Commander::scalar(float* value, char* user_cmd){
564 bool GET = isSentinel(user_cmd[0]);
565 if(!GET) *value = atof(user_cmd);
566 println(*value);
567}
568
569
570void Commander::target(FOCMotor* motor, char* user_cmd, char* separator){
571 // if no values sent
572 if(isSentinel(user_cmd[0])) {
573 printlnMachineReadable(motor->target);
574 return;
575 };
576
577 float pos, vel, torque;
578 char* next_value;
579 switch(motor->controller){
581 case MotionControlType::torque: // setting torque target
582 torque = atof(strtok (user_cmd, separator));
583 motor->target = torque;
584 break;
585 case MotionControlType::velocity: // setting velocity target + torque limit
586 // set the target
587 vel= atof(strtok (user_cmd, separator));
588 motor->target = vel;
589
590 // allow for setting only the target velocity without chaning the torque limit
591 next_value = strtok (NULL, separator);
592 if (next_value){
593 torque = atof(next_value);
594 // torque command can be voltage or current
595 if(motor->torque_controller == TorqueControlType::voltage) motor->updateVoltageLimit(torque);
596 else motor->updateCurrentLimit(torque);
597 }
598 break;
599 case MotionControlType::angle: // setting angle target + torque, velocity limit
600 // setting the target position
601 pos= atof(strtok (user_cmd, separator));
602 motor->target = pos;
603
604 // allow for setting only the target position without chaning the velocity/torque limits
605 next_value = strtok (NULL, separator);
606 if( next_value ){
607 vel = atof(next_value);
608 motor->updateVelocityLimit(vel);
609
610 // allow for setting only the target position and velocity limit without the torque limit
611 next_value = strtok (NULL, separator);
612 if( next_value ){
613 torque= atof(next_value);
614 // torque command can be voltage or current
615 if(motor->torque_controller == TorqueControlType::voltage) motor->updateVoltageLimit(torque);
616 else motor->updateCurrentLimit(torque);
617 }
618 }
619 break;
620 case MotionControlType::velocity_openloop: // setting velocity target + torque limit
621 // set the target
622 vel= atof(strtok (user_cmd, separator));
623 motor->target = vel;
624 // allow for setting only the target velocity without chaning the torque limit
625 next_value = strtok (NULL, separator);
626 if (next_value ){
627 torque = atof(next_value);
628 // torque command can be voltage or current
629 if(motor->torque_controller == TorqueControlType::voltage) motor->updateVoltageLimit(torque);
630 else motor->updateCurrentLimit(torque);
631 }
632 break;
633 case MotionControlType::angle_openloop: // setting angle target + torque, velocity limit
634 // set the target
635 pos= atof(strtok (user_cmd, separator));
636 motor->target = pos;
637
638 // allow for setting only the target position without chaning the velocity/torque limits
639 next_value = strtok (NULL, separator);
640 if( next_value ){
641 vel = atof(next_value);
642 motor->updateVelocityLimit(vel);
643 // allow for setting only the target velocity without chaning the torque limit
644 next_value = strtok (NULL, separator);
645 if (next_value ){
646 torque = atof(next_value);
647 // torque command can be voltage or current
648 if(motor->torque_controller == TorqueControlType::voltage) motor->updateVoltageLimit(torque);
649 else motor->updateCurrentLimit(torque);
650 }
651 }
652 break;
653 }
654 printVerbose(F("Target: "));
655 println(motor->target);
656}
657
658
660{
661 if(ch == eol)
662 return true;
663 else if (ch == '\r')
664 {
665 printVerbose(F("Warn: \\r detected! \n"));
666 return true; // lets still consider it to end the line...
667 }
668 return false;
669}
670
671void Commander::print(const int number){
672 if( !com_port || verbose == VerboseMode::nothing ) return;
673 com_port->print(number);
674}
675void Commander::print(const float number){
676 if(!com_port || verbose == VerboseMode::nothing ) return;
677 com_port->print((float)number,(int)decimal_places);
678}
679void Commander::print(const char* message){
680 if(!com_port || verbose == VerboseMode::nothing ) return;
681 com_port->print(message);
682}
683void Commander::print(const __FlashStringHelper *message){
684 if(!com_port || verbose == VerboseMode::nothing ) return;
685 com_port->print(message);
686}
687void Commander::print(const char message){
688 if(!com_port || verbose == VerboseMode::nothing ) return;
689 com_port->print(message);
690}
691
692void Commander::println(const int number){
693 if(!com_port || verbose == VerboseMode::nothing ) return;
694 com_port->println(number);
695}
696void Commander::println(const float number){
697 if(!com_port || verbose == VerboseMode::nothing ) return;
698 com_port->println((float)number, (int)decimal_places);
699}
700void Commander::println(const char* message){
701 if(!com_port || verbose == VerboseMode::nothing ) return;
702 com_port->println(message);
703}
704void Commander::println(const __FlashStringHelper *message){
705 if(!com_port || verbose == VerboseMode::nothing ) return;
706 com_port->println(message);
707}
708void Commander::println(const char message){
709 if(!com_port || verbose == VerboseMode::nothing ) return;
710 com_port->println(message);
711}
712
713
714void Commander::printVerbose(const char* message){
715 if(verbose == VerboseMode::user_friendly) print(message);
716}
717void Commander::printVerbose(const __FlashStringHelper *message){
718 if(verbose == VerboseMode::user_friendly) print(message);
719}
720
721void Commander::printMachineReadable(const int number){
722 if(verbose == VerboseMode::machine_readable) print(number);
723}
724void Commander::printMachineReadable(const float number){
725 if(verbose == VerboseMode::machine_readable) print(number);
726}
727void Commander::printMachineReadable(const char* message){
728 if(verbose == VerboseMode::machine_readable) print(message);
729}
730void Commander::printMachineReadable(const __FlashStringHelper *message){
731 if(verbose == VerboseMode::machine_readable) print(message);
732}
733void Commander::printMachineReadable(const char message){
734 if(verbose == VerboseMode::machine_readable) print(message);
735}
736
737void Commander::printlnMachineReadable(const int number){
738 if(verbose == VerboseMode::machine_readable) println(number);
739}
740void Commander::printlnMachineReadable(const float number){
741 if(verbose == VerboseMode::machine_readable) println(number);
742}
743void Commander::printlnMachineReadable(const char* message){
744 if(verbose == VerboseMode::machine_readable) println(message);
745}
746void Commander::printlnMachineReadable(const __FlashStringHelper *message){
747 if(verbose == VerboseMode::machine_readable) println(message);
748}
749void Commander::printlnMachineReadable(const char message){
750 if(verbose == VerboseMode::machine_readable) println(message);
751}
752
753void Commander::printError(){
754 println(F("err"));
755}
VerboseMode
Definition Commander.h:15
@ machine_readable
Definition Commander.h:19
@ on_request
Definition Commander.h:17
@ user_friendly
Definition Commander.h:18
@ nothing
Definition Commander.h:16
void(* CommandCallback)(char *)
command callback function pointer
Definition Commander.h:24
#define MAX_COMMAND_LENGTH
Definition Commander.h:11
MotionControlType
Definition FOCMotor.h:49
@ velocity_openloop
Definition FOCMotor.h:53
@ velocity
Velocity motion control.
Definition FOCMotor.h:51
@ angle_openloop
Definition FOCMotor.h:54
@ custom
Custom control method - control method added by user.
Definition FOCMotor.h:56
@ torque
Torque control.
Definition FOCMotor.h:50
@ angle_nocascade
Position/angle motion control without velocity cascade.
Definition FOCMotor.h:55
@ angle
Position/angle motion control.
Definition FOCMotor.h:52
FOCModulationType
Definition FOCMotor.h:72
@ Trapezoid_120
Definition FOCMotor.h:75
@ SpaceVectorPWM
Space vector modulation method.
Definition FOCMotor.h:74
@ Trapezoid_150
Definition FOCMotor.h:76
@ SinePWM
Sinusoidal PWM modulation.
Definition FOCMotor.h:73
TorqueControlType
Definition FOCMotor.h:62
@ estimated_current
torque control using estimated current (provided motor parameters)
Definition FOCMotor.h:66
@ voltage
Torque control using voltage.
Definition FOCMotor.h:63
@ dc_current
Torque control using DC current (one current magnitude)
Definition FOCMotor.h:64
@ foc_current
torque control using dq currents
Definition FOCMotor.h:65
@ UNKNOWN
Definition Sensor.h:12
void target(FOCMotor *motor, char *user_cmd, char *separator=(char *)" ")
Stream * com_port
Serial terminal variable if provided.
Definition Commander.h:101
bool isSentinel(char ch)
char eol
end of line sentinel character
Definition Commander.h:102
void motor(FOCMotor *motor, char *user_cmd)
void motion(FOCMotor *motor, char *user_cmd, char *separator=(char *)" ")
VerboseMode verbose
flag signaling that the commands should output user understanable text
Definition Commander.h:97
uint8_t decimal_places
number of decimal places to be used when displaying numbers
Definition Commander.h:98
bool echo
echo last typed character (for command line feedback)
Definition Commander.h:103
void scalar(float *value, char *user_cmd)
void lpf(LowPassFilter *lpf, char *user_cmd)
void run()
Definition Commander.cpp:22
Commander(Stream &serial, char eol='\n', bool echo=false)
Definition Commander.cpp:3
void pid(PIDController *pid, char *user_cmd)
void add(char id, CommandCallback onCommand, const char *label=nullptr)
Definition Commander.cpp:14
#define SCMD_PID_RAMP
PID ramp.
Definition commands.h:33
#define CMD_LIMITS
limits current/voltage/velocity
Definition commands.h:12
#define SCMD_LIM_VOLT
Limit voltage.
Definition commands.h:38
#define CMD_V_PID
velocity PID & LPF
Definition commands.h:9
#define SCMD_GET
Get variable only one value.
Definition commands.h:46
#define CMD_SENSOR
sensor offsets
Definition commands.h:15
#define SCMD_PID_LIM
PID limit.
Definition commands.h:34
#define CMD_KV_RATING
motor kv rating
Definition commands.h:19
#define CMD_MOTION_TYPE
motion control type
Definition commands.h:13
#define CMD_MONITOR
monitoring
Definition commands.h:16
#define SCMD_TIME
Time between executions (filtered)
Definition commands.h:48
#define CMD_STATUS
motor status enable/disable
Definition commands.h:11
#define SCMD_PID_I
PID gain I.
Definition commands.h:31
#define CMD_C_D_PID
current d PID & LPF
Definition commands.h:7
#define CMD_FOC_PARAMS
time parameters
Definition commands.h:21
#define SCMD_PWMMOD_TYPE
< Pwm modulation type
Definition commands.h:51
#define CMD_INDUCTANCE
motor phase inductance
Definition commands.h:18
#define CMD_RESIST
motor phase resistance
Definition commands.h:17
#define SCMD_INDUCT_Q
inductance q axis
Definition commands.h:61
#define SCMD_SENS_MECH_OFFSET
Sensor offset.
Definition commands.h:41
#define SCMD_DOWNSAMPLE
Monitoring downsample value.
Definition commands.h:44
#define CMD_SCAN
command scaning the network - only for commander
Definition commands.h:24
#define CMD_TORQUE_TYPE
torque control type
Definition commands.h:14
#define CMD_VERBOSE
command setting output mode - only for commander
Definition commands.h:25
#define SCMD_LIM_CURR
Limit current.
Definition commands.h:37
#define SCMD_TUNE_CURR
tune current controller
Definition commands.h:56
#define SCMD_INDUCT_D
inductance d axis
Definition commands.h:60
#define SCMD_SET
Set variables to be monitored.
Definition commands.h:47
#define SCMD_CLEAR
Clear all monitored variables.
Definition commands.h:45
#define SCMD_LIM_VEL
Limit velocity.
Definition commands.h:39
#define SCMD_REINIT_FOC
reinitialize FOC
Definition commands.h:55
#define CMD_A_PID
angle PID & LPF
Definition commands.h:10
#define SCMD_MEAS_PARAMS
measure motor parameters (resistance and inductance)
Definition commands.h:57
#define SCMD_PID_D
PID gain D.
Definition commands.h:32
#define CMD_PWMMOD
pwm modulation
Definition commands.h:20
#define SCMD_PID_P
PID gain P.
Definition commands.h:30
#define CMD_DECIMAL
command setting decimal places - only for commander
Definition commands.h:26
#define SCMD_SENS_ELEC_OFFSET
Sensor electrical zero offset.
Definition commands.h:42
#define SCMD_LPF_TF
LPF time constant.
Definition commands.h:35
#define CMD_C_Q_PID
current q PID & LPF
Definition commands.h:8
#define SCMD_PWMMOD_CENTER
< Pwm modulation center flag
Definition commands.h:52
#define NOT_SET
Definition foc_utils.h:34
#define _isset(a)
Definition foc_utils.h:13