Files
hexapod-robot/2026-current/robot/RobotIMU.cpp
T
mangavalkandClaude Opus 5.5 ad77b06c36 Initial import: robot firmware + PlatformIO two-env scaffold
Robot-side firmware (Teensy 4.0) imported unchanged as extracted.
platformio.ini defines [env:robot] (teensy40) and [env:remote]
(teensy41); scripts/select_src_dir.py points each env at its own
sketch folder so robot/ and remote/ stay Arduino-style sketches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 15:36:37 +02:00

52 lines
1.8 KiB
C++

#include "RobotIMU.h"
#include <Wire.h>
// MPU6050-style register map, default +/-2g / +/-250deg/s ranges.
// Swap readRaw() if you're using a different IMU part.
static constexpr uint8_t IMU_ADDR = 0x68;
static constexpr uint8_t REG_PWR_MGMT_1 = 0x6B;
static constexpr uint8_t REG_ACCEL_XOUT_H = 0x3B;
bool RobotIMU::begin() {
Wire.begin();
Wire.beginTransmission(IMU_ADDR);
Wire.write(REG_PWR_MGMT_1);
Wire.write(0x00); // wake the IMU out of sleep
ok_ = (Wire.endTransmission() == 0);
return ok_;
}
bool RobotIMU::readRaw(float& ax, float& ay, float& az, float& gx, float& gy, float& gz) {
Wire.beginTransmission(IMU_ADDR);
Wire.write(REG_ACCEL_XOUT_H);
if (Wire.endTransmission(false) != 0) return false;
Wire.requestFrom((int)IMU_ADDR, 14);
if (Wire.available() < 14) return false;
int16_t raw_ax = (Wire.read() << 8) | Wire.read();
int16_t raw_ay = (Wire.read() << 8) | Wire.read();
int16_t raw_az = (Wire.read() << 8) | Wire.read();
Wire.read(); Wire.read(); // skip temperature
int16_t raw_gx = (Wire.read() << 8) | Wire.read();
int16_t raw_gy = (Wire.read() << 8) | Wire.read();
int16_t raw_gz = (Wire.read() << 8) | Wire.read();
ax = raw_ax / 16384.0f; ay = raw_ay / 16384.0f; az = raw_az / 16384.0f;
gx = raw_gx / 131.0f; gy = raw_gy / 131.0f; gz = raw_gz / 131.0f; // deg/s
(void)gz;
return true;
}
void RobotIMU::update(float dt) {
if (!ok_ || !enabled) return;
float ax, ay, az, gx, gy, gz;
if (!readRaw(ax, ay, az, gx, gy, gz)) return;
float accel_roll = degrees(atan2(ay, az));
float accel_pitch = degrees(atan2(-ax, sqrt(ay * ay + az * az)));
constexpr float ALPHA = 0.98f; // trust the gyro short-term, the accelerometer long-term
roll_deg_ = ALPHA * (roll_deg_ + gx * dt) + (1 - ALPHA) * accel_roll;
pitch_deg_ = ALPHA * (pitch_deg_ + gy * dt) + (1 - ALPHA) * accel_pitch;
}