3 Commits

Author SHA1 Message Date
Oleg Kalachev
f8f746b0cd Add level calibration 2026-01-30 07:49:26 +03:00
Oleg Kalachev
3dde380bb7 Add parameters for list of modes bound to rc switch
Parameters: CTL_FLT_MODE_0, CTL_FLT_MODE_1, CTL_FLT_MODE_2.
Also fix a bug with incorrect choosing the mode from controlMode.
2026-01-27 16:38:20 +03:00
Oleg Kalachev
377b21429b Fix error when launching the sim
Also make the parameters WIFI_LOC_PORT and WIFI_REM_PORT work in the sim.
2026-01-27 16:32:52 +03:00
6 changed files with 30 additions and 11 deletions

View File

@@ -46,6 +46,7 @@ const char* motd =
"log [dump] - print log header [and data]\n" "log [dump] - print log header [and data]\n"
"cr - calibrate RC\n" "cr - calibrate RC\n"
"ca - calibrate accel\n" "ca - calibrate accel\n"
"cl - calibrate level\n"
"mfr, mfl, mrr, mrl - test motor (remove props)\n" "mfr, mfl, mrr, mrl - test motor (remove props)\n"
"sys - show system info\n" "sys - show system info\n"
"reset - reset drone's state\n" "reset - reset drone's state\n"
@@ -151,6 +152,8 @@ void doCommand(String str, bool echo = false) {
calibrateRC(); calibrateRC();
} else if (command == "ca") { } else if (command == "ca") {
calibrateAccel(); calibrateAccel();
} else if (command == "cl") {
calibrateLevel();
} else if (command == "mfr") { } else if (command == "mfr") {
testMotor(MOTOR_FRONT_RIGHT); testMotor(MOTOR_FRONT_RIGHT);
} else if (command == "mfl") { } else if (command == "mfl") {

View File

@@ -52,6 +52,7 @@ PID pitchPID(PITCH_P, PITCH_I, PITCH_D);
PID yawPID(YAW_P, 0, 0); PID yawPID(YAW_P, 0, 0);
Vector maxRate(ROLLRATE_MAX, PITCHRATE_MAX, YAWRATE_MAX); Vector maxRate(ROLLRATE_MAX, PITCHRATE_MAX, YAWRATE_MAX);
float tiltMax = TILT_MAX; float tiltMax = TILT_MAX;
int flightModes[] = {STAB, STAB, STAB}; // map for rc mode switch
extern const int MOTOR_REAR_LEFT, MOTOR_REAR_RIGHT, MOTOR_FRONT_RIGHT, MOTOR_FRONT_LEFT; extern const int MOTOR_REAR_LEFT, MOTOR_REAR_RIGHT, MOTOR_FRONT_RIGHT, MOTOR_FRONT_LEFT;
extern float controlRoll, controlPitch, controlThrottle, controlYaw, controlMode; extern float controlRoll, controlPitch, controlThrottle, controlYaw, controlMode;
@@ -65,9 +66,9 @@ void control() {
} }
void interpretControls() { void interpretControls() {
if (controlMode < 0.25) mode = STAB; if (controlMode < 0.25) mode = flightModes[0];
if (controlMode < 0.75) mode = STAB; else if (controlMode < 0.75) mode = flightModes[1];
if (controlMode > 0.75) mode = STAB; else if (controlMode > 0.75) mode = flightModes[2];
if (mode == AUTO) return; // pilot is not effective in AUTO mode if (mode == AUTO) return; // pilot is not effective in AUTO mode

View File

@@ -110,6 +110,14 @@ void calibrateAccelOnce() {
accBias = (accMax + accMin) / 2; accBias = (accMax + accMin) / 2;
} }
void calibrateLevel() {
print("Place perfectly level [1 sec]\n");
pause(1);
Quaternion correction = Quaternion::fromBetweenVectors(Quaternion::rotateVector(Vector(0, 0, 1), attitude), Vector(0, 0, 1));
imuRotation = Quaternion::rotate(correction, Quaternion::fromEuler(imuRotation)).toEuler();
print("✓ Done: %.3f %.3f %.3f\n", degrees(imuRotation.x), degrees(imuRotation.y), degrees(imuRotation.z));
}
void printIMUCalibration() { void printIMUCalibration() {
print("gyro bias: %f %f %f\n", gyroBias.x, gyroBias.y, gyroBias.z); print("gyro bias: %f %f %f\n", gyroBias.x, gyroBias.y, gyroBias.z);
print("accel bias: %f %f %f\n", accBias.x, accBias.y, accBias.z); print("accel bias: %f %f %f\n", accBias.x, accBias.y, accBias.z);

View File

@@ -49,6 +49,9 @@ Parameter parameters[] = {
{"CTL_R_RATE_MAX", &maxRate.x}, {"CTL_R_RATE_MAX", &maxRate.x},
{"CTL_Y_RATE_MAX", &maxRate.z}, {"CTL_Y_RATE_MAX", &maxRate.z},
{"CTL_TILT_MAX", &tiltMax}, {"CTL_TILT_MAX", &tiltMax},
{"CTL_FLT_MODE_0", &flightModes[0]},
{"CTL_FLT_MODE_1", &flightModes[1]},
{"CTL_FLT_MODE_2", &flightModes[2]},
// imu // imu
{"IMU_ROT_ROLL", &imuRotation.x}, {"IMU_ROT_ROLL", &imuRotation.x},
{"IMU_ROT_PITCH", &imuRotation.y}, {"IMU_ROT_PITCH", &imuRotation.y},

View File

@@ -9,6 +9,7 @@
#include "quaternion.h" #include "quaternion.h"
#include "Arduino.h" #include "Arduino.h"
#include "wifi.h" #include "wifi.h"
#include "lpf.h"
extern float t, dt; extern float t, dt;
extern float controlRoll, controlPitch, controlYaw, controlThrottle, controlMode; extern float controlRoll, controlPitch, controlYaw, controlThrottle, controlMode;
@@ -19,6 +20,7 @@ extern float motors[4];
Vector gyro, acc, imuRotation; Vector gyro, acc, imuRotation;
Vector accBias, gyroBias, accScale(1, 1, 1); Vector accBias, gyroBias, accScale(1, 1, 1);
LowPassFilter<Vector> gyroBiasFilter(0);
// declarations // declarations
void step(); void step();
@@ -69,6 +71,7 @@ void resetParameters();
void setLED(bool on) {}; void setLED(bool on) {};
void calibrateGyro() { print("Skip gyro calibrating\n"); }; void calibrateGyro() { print("Skip gyro calibrating\n"); };
void calibrateAccel() { print("Skip accel calibrating\n"); }; void calibrateAccel() { print("Skip accel calibrating\n"); };
void calibrateLevel() { print("Skip level calibrating\n"); };
void printIMUCalibration() { print("cal: N/A\n"); }; void printIMUCalibration() { print("cal: N/A\n"); };
void printIMUInfo() {}; void printIMUInfo() {};
void printWiFiInfo() {}; void printWiFiInfo() {};

View File

@@ -11,9 +11,10 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <gazebo/gazebo.hh> #include <gazebo/gazebo.hh>
#define WIFI_UDP_PORT 14580 int wifiMode = 1; // mock
#define WIFI_UDP_REMOTE_PORT 14550 int udpLocalPort = 14580;
#define WIFI_UDP_REMOTE_ADDR "255.255.255.255" int udpRemotePort = 14550;
const char *udpRemoteIP = "255.255.255.255";
int wifiSocket; int wifiSocket;
@@ -22,22 +23,22 @@ void setupWiFi() {
sockaddr_in addr; // local address sockaddr_in addr; // local address
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY; addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(WIFI_UDP_PORT); addr.sin_port = htons(udpLocalPort);
if (bind(wifiSocket, (sockaddr *)&addr, sizeof(addr))) { if (bind(wifiSocket, (sockaddr *)&addr, sizeof(addr))) {
gzerr << "Failed to bind WiFi UDP socket on port " << WIFI_UDP_PORT << std::endl; gzerr << "Failed to bind WiFi UDP socket on port " << udpLocalPort << std::endl;
return; return;
} }
int broadcast = 1; int broadcast = 1;
setsockopt(wifiSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); // enable broadcast setsockopt(wifiSocket, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)); // enable broadcast
gzmsg << "WiFi UDP socket initialized on port " << WIFI_UDP_PORT << " (remote port " << WIFI_UDP_REMOTE_PORT << ")" << std::endl; gzmsg << "WiFi UDP socket initialized on port " << udpLocalPort << " (remote port " << udpRemotePort << ")" << std::endl;
} }
void sendWiFi(const uint8_t *buf, int len) { void sendWiFi(const uint8_t *buf, int len) {
if (wifiSocket == 0) setupWiFi(); if (wifiSocket == 0) setupWiFi();
sockaddr_in addr; // remote address sockaddr_in addr; // remote address
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(WIFI_UDP_REMOTE_ADDR); addr.sin_addr.s_addr = inet_addr(udpRemoteIP);
addr.sin_port = htons(WIFI_UDP_REMOTE_PORT); addr.sin_port = htons(udpRemotePort);
sendto(wifiSocket, buf, len, 0, (sockaddr *)&addr, sizeof(addr)); sendto(wifiSocket, buf, len, 0, (sockaddr *)&addr, sizeof(addr));
} }