mirror of
https://github.com/okalachev/flix.git
synced 2025-07-29 20:38:59 +00:00
Refactor CLI submodule
Move command parsing to doCommand Parse command with splitString instead of stringToken Trim commands Move cliTestMotor to the bottom Rename parseInput to handleInput, which is more clear Move motor test function to motors.ino Remove parameters table functionality to simplify the code
This commit is contained in:
parent
67e4a95697
commit
6058e8ecab
96
flix/cli.ino
96
flix/cli.ino
@ -21,8 +21,6 @@ const char* motd =
|
|||||||
"|__| |_______||__| /__/ \\__\\\n\n"
|
"|__| |_______||__| /__/ \\__\\\n\n"
|
||||||
"Commands:\n\n"
|
"Commands:\n\n"
|
||||||
"help - show help\n"
|
"help - show help\n"
|
||||||
"show - show all parameters\n"
|
|
||||||
"<name> <value> - set parameter\n"
|
|
||||||
"ps - show pitch/roll/yaw\n"
|
"ps - show pitch/roll/yaw\n"
|
||||||
"psq - show attitude quaternion\n"
|
"psq - show attitude quaternion\n"
|
||||||
"imu - show IMU data\n"
|
"imu - show IMU data\n"
|
||||||
@ -35,36 +33,14 @@ const char* motd =
|
|||||||
"mfr, mfl, mrr, mrl - test motor (remove props)\n"
|
"mfr, mfl, mrr, mrl - test motor (remove props)\n"
|
||||||
"reset - reset drone's state\n";
|
"reset - reset drone's state\n";
|
||||||
|
|
||||||
const struct Param {
|
void doCommand(String str) {
|
||||||
const char* name;
|
// parse command
|
||||||
float* value;
|
String command, arg0, arg1;
|
||||||
float* value2;
|
splitString(str, command, arg0, arg1);
|
||||||
} params[] = {
|
|
||||||
{"rp", &rollRatePID.p, &pitchRatePID.p},
|
|
||||||
{"ri", &rollRatePID.i, &pitchRatePID.i},
|
|
||||||
{"rd", &rollRatePID.d, &pitchRatePID.d},
|
|
||||||
|
|
||||||
{"ap", &rollPID.p, &pitchPID.p},
|
// execute command
|
||||||
{"ai", &rollPID.i, &pitchPID.i},
|
|
||||||
{"ad", &rollPID.d, &pitchPID.d},
|
|
||||||
|
|
||||||
{"yp", &yawRatePID.p, nullptr},
|
|
||||||
{"yi", &yawRatePID.i, nullptr},
|
|
||||||
{"yd", &yawRatePID.d, nullptr},
|
|
||||||
|
|
||||||
{"lpr", &ratesFilter.alpha, nullptr},
|
|
||||||
{"lpd", &rollRatePID.lpf.alpha, &pitchRatePID.lpf.alpha},
|
|
||||||
|
|
||||||
{"ss", &loopRate, nullptr},
|
|
||||||
{"dt", &dt, nullptr},
|
|
||||||
{"t", &t, nullptr},
|
|
||||||
};
|
|
||||||
|
|
||||||
void doCommand(String& command, String& value) {
|
|
||||||
if (command == "help" || command == "motd") {
|
if (command == "help" || command == "motd") {
|
||||||
Serial.println(motd);
|
Serial.println(motd);
|
||||||
} else if (command == "show") {
|
|
||||||
showTable();
|
|
||||||
} else if (command == "ps") {
|
} else if (command == "ps") {
|
||||||
Vector a = attitude.toEulerZYX();
|
Vector a = attitude.toEulerZYX();
|
||||||
Serial.printf("roll: %f pitch: %f yaw: %f\n", a.x * RAD_TO_DEG, a.y * RAD_TO_DEG, a.z * RAD_TO_DEG);
|
Serial.printf("roll: %f pitch: %f yaw: %f\n", a.x * RAD_TO_DEG, a.y * RAD_TO_DEG, a.z * RAD_TO_DEG);
|
||||||
@ -96,76 +72,38 @@ void doCommand(String& command, String& value) {
|
|||||||
} else if (command == "ca") {
|
} else if (command == "ca") {
|
||||||
calibrateAccel();
|
calibrateAccel();
|
||||||
} else if (command == "mfr") {
|
} else if (command == "mfr") {
|
||||||
cliTestMotor(MOTOR_FRONT_RIGHT);
|
testMotor(MOTOR_FRONT_RIGHT);
|
||||||
} else if (command == "mfl") {
|
} else if (command == "mfl") {
|
||||||
cliTestMotor(MOTOR_FRONT_LEFT);
|
testMotor(MOTOR_FRONT_LEFT);
|
||||||
} else if (command == "mrr") {
|
} else if (command == "mrr") {
|
||||||
cliTestMotor(MOTOR_REAR_RIGHT);
|
testMotor(MOTOR_REAR_RIGHT);
|
||||||
} else if (command == "mrl") {
|
} else if (command == "mrl") {
|
||||||
cliTestMotor(MOTOR_REAR_LEFT);
|
testMotor(MOTOR_REAR_LEFT);
|
||||||
} else if (command == "reset") {
|
} else if (command == "reset") {
|
||||||
attitude = Quaternion();
|
attitude = Quaternion();
|
||||||
|
} else if (command == "") {
|
||||||
|
// do nothing
|
||||||
} else {
|
} else {
|
||||||
float val = value.toFloat();
|
|
||||||
// TODO: on error returns 0, check invalid value
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < sizeof(params) / sizeof(params[0]); i++) {
|
|
||||||
if (command == params[i].name) {
|
|
||||||
*params[i].value = val;
|
|
||||||
if (params[i].value2 != nullptr) *params[i].value2 = val;
|
|
||||||
Serial.print(command);
|
|
||||||
Serial.print(" = ");
|
|
||||||
Serial.println(val, 4);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Serial.println("Invalid command: " + command);
|
Serial.println("Invalid command: " + command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showTable() {
|
void handleInput() {
|
||||||
for (uint8_t i = 0; i < sizeof(params) / sizeof(params[0]); i++) {
|
|
||||||
Serial.print(params[i].name);
|
|
||||||
Serial.print(" ");
|
|
||||||
Serial.println(*params[i].value, 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cliTestMotor(uint8_t n) {
|
|
||||||
Serial.printf("Testing motor %d\n", n);
|
|
||||||
motors[n] = 1;
|
|
||||||
delay(50); // ESP32 may need to wait until the end of the current cycle to change duty https://github.com/espressif/arduino-esp32/issues/5306
|
|
||||||
sendMotors();
|
|
||||||
delay(3000);
|
|
||||||
motors[n] = 0;
|
|
||||||
sendMotors();
|
|
||||||
Serial.println("Done");
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseInput() {
|
|
||||||
static bool showMotd = true;
|
static bool showMotd = true;
|
||||||
static String command;
|
static String input;
|
||||||
static String value;
|
|
||||||
static bool parsingCommand = true;
|
|
||||||
|
|
||||||
if (showMotd) {
|
if (showMotd) {
|
||||||
Serial.println(motd);
|
Serial.printf("%s\n", motd);
|
||||||
showMotd = false;
|
showMotd = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (Serial.available()) {
|
while (Serial.available()) {
|
||||||
char c = Serial.read();
|
char c = Serial.read();
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
parsingCommand = true;
|
doCommand(input);
|
||||||
if (!command.isEmpty()) {
|
input.clear();
|
||||||
doCommand(command, value);
|
|
||||||
}
|
|
||||||
command.clear();
|
|
||||||
value.clear();
|
|
||||||
} else if (c == ' ') {
|
|
||||||
parsingCommand = false;
|
|
||||||
} else {
|
} else {
|
||||||
(parsingCommand ? command : value) += c;
|
input += c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,10 +165,6 @@ void controlTorque() {
|
|||||||
motors[3] = constrain(motors[3], 0, 1);
|
motors[3] = constrain(motors[3], 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool motorsActive() {
|
|
||||||
return motors[0] > 0 || motors[1] > 0 || motors[2] > 0 || motors[3] > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* getModeName() {
|
const char* getModeName() {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MANUAL: return "MANUAL";
|
case MANUAL: return "MANUAL";
|
||||||
|
@ -50,7 +50,7 @@ void loop() {
|
|||||||
estimate();
|
estimate();
|
||||||
control();
|
control();
|
||||||
sendMotors();
|
sendMotors();
|
||||||
parseInput();
|
handleInput();
|
||||||
#if WIFI_ENABLED
|
#if WIFI_ENABLED
|
||||||
processMavlink();
|
processMavlink();
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,3 +46,18 @@ void sendMotors() {
|
|||||||
ledcWrite(MOTOR_2_PIN, getDutyCycle(motors[2]));
|
ledcWrite(MOTOR_2_PIN, getDutyCycle(motors[2]));
|
||||||
ledcWrite(MOTOR_3_PIN, getDutyCycle(motors[3]));
|
ledcWrite(MOTOR_3_PIN, getDutyCycle(motors[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool motorsActive() {
|
||||||
|
return motors[0] != 0 || motors[1] != 0 || motors[2] != 0 || motors[3] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void testMotor(uint8_t n) {
|
||||||
|
Serial.printf("Testing motor %d\n", n);
|
||||||
|
motors[n] = 1;
|
||||||
|
delay(50); // ESP32 may need to wait until the end of the current cycle to change duty https://github.com/espressif/arduino-esp32/issues/5306
|
||||||
|
sendMotors();
|
||||||
|
delay(3000);
|
||||||
|
motors[n] = 0;
|
||||||
|
sendMotors();
|
||||||
|
Serial.printf("Done\n");
|
||||||
|
}
|
||||||
|
10
flix/util.h
10
flix/util.h
@ -42,3 +42,13 @@ void printArray(T arr[], int size) {
|
|||||||
void disableBrownOut() {
|
void disableBrownOut() {
|
||||||
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ENA);
|
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ENA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trim and split string by spaces
|
||||||
|
void splitString(String& str, String& token0, String& token1, String& token2) {
|
||||||
|
str.trim();
|
||||||
|
char chars[str.length() + 1];
|
||||||
|
str.toCharArray(chars, str.length() + 1);
|
||||||
|
token0 = strtok(chars, " ");
|
||||||
|
token1 = strtok(NULL, " "); // String(NULL) creates empty string
|
||||||
|
token2 = strtok(NULL, "");
|
||||||
|
}
|
||||||
|
@ -33,9 +33,17 @@ class __FlashStringHelper;
|
|||||||
// https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/
|
// https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/
|
||||||
class String: public std::string {
|
class String: public std::string {
|
||||||
public:
|
public:
|
||||||
|
String(const char *str = "") : std::string(str ? str : "") {}
|
||||||
long toInt() const { return atol(this->c_str()); }
|
long toInt() const { return atol(this->c_str()); }
|
||||||
float toFloat() const { return atof(this->c_str()); }
|
float toFloat() const { return atof(this->c_str()); }
|
||||||
bool isEmpty() const { return this->empty(); }
|
bool isEmpty() const { return this->empty(); }
|
||||||
|
void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {
|
||||||
|
strlcpy(buf, this->c_str() + index, bufsize);
|
||||||
|
}
|
||||||
|
void trim() {
|
||||||
|
this->erase(0, this->find_first_not_of(" \t\n\r"));
|
||||||
|
this->erase(this->find_last_not_of(" \t\n\r") + 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Print;
|
class Print;
|
||||||
|
@ -34,7 +34,8 @@ void controlTorque();
|
|||||||
void showTable();
|
void showTable();
|
||||||
void sendMotors();
|
void sendMotors();
|
||||||
bool motorsActive();
|
bool motorsActive();
|
||||||
void cliTestMotor(uint8_t n);
|
void doCommand(String str);
|
||||||
|
void normalizeRC();
|
||||||
void printRCCal();
|
void printRCCal();
|
||||||
void processMavlink();
|
void processMavlink();
|
||||||
void sendMavlink();
|
void sendMavlink();
|
||||||
|
@ -79,7 +79,7 @@ public:
|
|||||||
attitude.setYaw(this->model->WorldPose().Yaw());
|
attitude.setYaw(this->model->WorldPose().Yaw());
|
||||||
|
|
||||||
control();
|
control();
|
||||||
parseInput();
|
handleInput();
|
||||||
processMavlink();
|
processMavlink();
|
||||||
|
|
||||||
applyMotorForces();
|
applyMotorForces();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user