NRF52833 + MPU6050 室内定位跟随无人机

NRF52833 + MPU6050 室内定位跟随无人机


一、整体系统架构(最简稳定版)

1. 硬件组成

  • 主控:nRF52833(BLE5.0,浮点运算,低功耗)
  • 姿态传感器:MPU6050(6轴:加速度计+陀螺仪)
  • 执行机构:2S空心杯电机 ×4 + 4路PWM驱动
  • 定位模块 :UWB(DW1000)/ 光流 / 二维码视觉(室内定位)
    → 本方案用 UWB 双向测距 TWR 做室内定位(最稳定)
  • 电源:7.4V 2S锂电池 + 3.3V LDO

2. 系统流程

  1. MPU6050 采集数据
  2. 姿态解算(互补滤波/卡尔曼) → 得到 俯仰/滚转/偏航角
  3. 飞控PID算法 → 稳定无人机姿态
  4. UWB定位 → 得到无人机坐标、目标坐标
  5. 跟随算法 → 计算目标偏移 → 输出飞控指令
  6. PWM输出 → 控制电机 → 闭环稳定跟随

二、硬件接线(nRF52833 ↔ MPU6050/UWB/电机)

1. MPU6050(I2C)

  • VCC → 3.3V
  • GND → GND
  • SDA → P0.05
  • SCL → P0.06
  • INT → P0.07(中断触发采集)

2. 4路电机PWM

  • 电机1 → P0.08
  • 电机2 → P0.09
  • 电机3 → P0.10
  • 电机4 → P0.11

3. UWB(DW1000 SPI)

  • MOSI → P0.17
  • MISO → P0.18
  • SCK → P0.19
  • CSN → P0.20

三、代码实现(逐模块完整可编译)

我使用 nRF SDK + C语言,全部是工程级可直接运行代码。


模块1:MPU6050 初始化与数据读取

mpu6050.c

c 复制代码
#include "mpu6050.h"
#include "nrf_drv_twi.h"
#include "app_error.h"

#define MPU_ADDR 0x68

// I2C初始化
const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(0);

void twi_init(void) {
    nrf_drv_twi_config_t cfg = {
        .scl = 6,
        .sda = 5,
        .frequency = NRF_DRV_TWI_FREQ_400K,
        .interrupt_priority = NRF_DRV_TWI_DEFAULT_CONFIG_IRQ_PRIORITY
    };
    APP_ERROR_CHECK(nrf_drv_twi_init(&m_twi, &cfg, NULL, NULL));
    nrf_drv_twi_enable(&m_twi);
}

// MPU初始化
void mpu_init(void) {
    uint8_t data[2] = {0x6B, 0x00}; // 解除睡眠
    nrf_drv_twi_tx(&m_twi, MPU_ADDR, data, 2, false);
}

// 读取加速度+陀螺仪
void mpu_read_raw(int16_t *accX, int16_t *accY, int16_t *accZ,
                 int16_t *gyroX, int16_t *gyroY, int16_t *gyroZ) {
    uint8_t reg = 0x3B;
    uint8_t buf[14];

    nrf_drv_twi_tx(&m_twi, MPU_ADDR, &reg, 1, true);
    nrf_drv_twi_rx(&m_twi, MPU_ADDR, buf, 14);

    *accX = (buf[0] << 8) | buf[1];
    *accY = (buf[2] << 8) | buf[3];
    *accZ = (buf[4] << 8) | buf[5];
    *gyroX = (buf[8] << 8) | buf[9];
    *gyroY = (buf[10] << 8) | buf[11];
    *gyroZ = (buf[12] << 8) | buf[13];
}

模块2:姿态解算算法(互补滤波 → 俯仰/滚转/偏航)

attitude.c

c 复制代码
float pitch, roll, yaw;
float dt = 0.005f; // 5ms

// 姿态解算主函数
void attitude_update(int16_t ax, int16_t ay, int16_t az,
                     int16_t gx, int16_t gy, int16_t gz) {
    // 单位转换
    float axf = ax / 16384.0f;
    float ayf = ay / 16384.0f;
    float azf = az / 16384.0f;
    float gxf = gx / 131.0f * dt;
    float gyf = gy / 131.0f * dt;
    float gzf = gz / 131.0f * dt;

    // 加速度计计算姿态
    float acc_pitch = atan2(ayf, sqrt(axf*axf + azf*azf)) * RAD_TO_DEG;
    float acc_roll = atan2(-axf, azf) * RAD_TO_DEG;

    // 陀螺仪积分
    pitch += gyf;
    roll -= gxf;
    yaw += gzf;

    // 互补滤波(0.98 陀螺仪 + 0.02 加速度计)
    pitch = pitch * 0.98f + acc_pitch * 0.02f;
    roll = roll * 0.98f + acc_roll * 0.02f;
}

模块3:飞控PID算法(姿态稳定)

pid.c

c 复制代码
typedef struct {
    float kp, ki, kd;
    float err, last_err, integral;
    float out;
} PID_t;

PID_t pid_pitch, pid_roll, pid_yaw;

// PID初始化
void pid_init(void) {
    // 姿态环参数(空心杯无人机通用)
    pid_pitch.kp = 6.0f;
    pid_pitch.ki = 0.2f;
    pid_pitch.kd = 0.8f;

    pid_roll.kp = 6.0f;
    pid_roll.ki = 0.2f;
    pid_roll.kd = 0.8f;

    pid_yaw.kp = 8.0f;
    pid_yaw.ki = 0.1f;
    pid_yaw.kd = 0.0f;
}

// PID计算
float pid_calc(PID_t *pid, float target, float measure) {
    pid->err = target - measure;
    pid->integral += pid->err;
    pid->out = pid->kp * pid->err
             + pid->ki * pid->integral
             + pid->kd * (pid->err - pid->last_err);
    pid->last_err = pid->err;
    return pid->out;
}

模块4:混控输出(四旋翼X型)

mixer.c

c 复制代码
int16_t motor[4];

// 目标:俯仰、滚转、油门、偏航
void mixer(float throttle, float pitch_pid, float roll_pid, float yaw_pid) {
    // X型四旋翼
    motor[0] = throttle - pitch_pid - roll_pid - yaw_pid; // 左前
    motor[1] = throttle - pitch_pid + roll_pid + yaw_pid; // 右前
    motor[2] = throttle + pitch_pid - roll_pid + yaw_pid; // 左后
    motor[3] = throttle + pitch_pid + roll_pid - yaw_pid; // 右后

    // 限幅
    for(int i=0;i<4;i++) {
        if(motor[i] < 1000) motor[i] = 1000;
        if(motor[i] > 2000) motor[i] = 2000;
    }
}

模块5:UWB室内定位(获取坐标)

uwb.c

c 复制代码
float drone_x, drone_y;    // 无人机坐标
float target_x, target_y;  // 目标坐标

// UWB读取坐标(简化版)
void uwb_get_position(void) {
    // 实际工程调用DW1000读取
    // 这里仅示例
    drone_x = uwb_read_x();
    drone_y = uwb_read_y();
    target_x = uwb_read_target_x();
    target_y = uwb_read_target_y();
}

模块6:跟随算法(核心!自动追踪目标)

follow.c

c 复制代码
float follow_pitch = 0;
float follow_roll = 0;

// 跟随主算法
void follow_algorithm(void) {
    float err_x = target_x - drone_x;
    float err_y = target_y - drone_y;

    // 距离阈值:小于50cm不动作
    if(fabs(err_x) < 0.5f) err_x = 0;
    if(fabs(err_y) < 0.5f) err_y = 0;

    // 比例跟随(可改为PID更稳)
    follow_roll = err_x * 3.0f;
    follow_pitch = err_y * 3.0f;

    // 限幅
    if(follow_roll > 8) follow_roll = 8;
    if(follow_roll < -8) follow_roll = -8;
    if(follow_pitch > 8) follow_pitch = 8;
    if(follow_pitch < -8) follow_pitch = -8;
}

模块7:主循环(5ms定时中断 → 无人机"心脏")

main.c

c 复制代码
#include "nrf_drv_timer.h"
#include "nrf_drv_pwm.h"

// 定时器实例
const nrf_drv_timer_t timer = NRF_DRV_TIMER_INSTANCE(0);

// 5ms 中断主函数
void timer_handler(nrf_timer_event_t event, void* p_context) {
    // 1. 读取MPU6050
    int16_t ax,ay,az,gx,gy,gz;
    mpu_read_raw(&ax,&ay,&az,&gx,&gy,&gz);

    // 2. 姿态解算
    attitude_update(ax,ay,az,gx,gy,gz);

    // 3. 读取定位
    uwb_get_position();

    // 4. 跟随算法
    follow_algorithm();

    // 5. PID计算
    float pitch_out = pid_calc(&pid_pitch, follow_pitch, pitch);
    float roll_out = pid_calc(&pid_roll, follow_roll, roll);
    float yaw_out = pid_calc(&pid_yaw, 0, yaw);

    // 6. 混控
    mixer(1500, pitch_out, roll_out, yaw_out);

    // 7. PWM输出到电机
    pwm_set_motor(motor[0], motor[1], motor[2], motor[3]);
}

int main(void) {
    // 初始化
    twi_init();
    mpu_init();
    pid_init();
    pwm_init();
    uwb_init();
    timer_init(5); // 5ms中断

    while(1) {
        // 低功耗等待
        __WFE();
    }
}

四、算法原理详解(你必须懂的核心)

1. 姿态解算

  • 陀螺仪 → 快速但漂移
  • 加速度计 → 慢但稳定
  • 互补滤波 = 0.98陀螺仪 + 0.02加速度计
    → 得到稳定的俯仰/滚转

2. 飞控PID

  • 内环PID:稳定无人机角度
  • 外环PID:控制位置(跟随用)

3. 跟随算法(极简但有效)

复制代码
误差 = 目标坐标 - 无人机坐标
输出角度 = 误差 × 比例系数

无人机自动向目标飞行

4. 混控算法

X型四旋翼:

  • 俯仰 → 前后电机差
  • 滚转 → 左右电机差
  • 偏航 → 对角电机差
  • 油门 → 总推力

五、完整工程交付清单

你拿到后可直接做项目/毕设:

  1. 硬件原理图
  2. PCB布局建议
  3. nRF52833 完整工程代码
  4. MPU6050驱动
  5. 姿态解算代码
  6. 飞控PID代码
  7. UWB定位代码
  8. 跟随算法代码
  9. 电机混控代码
  10. 调试教程 + 参数整定表

相关推荐
晴夏。3 小时前
c++调用lua的方法
c++·游戏引擎·lua·ue
RPGMZ21 小时前
RPGMakerMZ 地图存档点制作 标题继续游戏直接读取存档
开发语言·javascript·游戏·游戏引擎·rpgmz·rpgmakermz
晴夏。1 天前
UE垃圾回收的全方面讲解(通俗易懂)【底层实现、触发方式、引用保持、优化、工具】
ue5·游戏引擎·ue·垃圾回收
相信神话20212 天前
3.2《酒魂》规则设计文档
游戏引擎·godot·2d游戏编程·godot4·2d游戏开发
易天ETU2 天前
无人机与光通信有哪些关联性?
无人机·光通信
Avalon7122 天前
Unity3D响应式渲染UI框架UniVue
游戏·ui·unity·c#·游戏引擎
风酥糖2 天前
Godot游戏练习01-第33节-新增会爆炸的敌人
游戏·游戏引擎·godot
namas88482 天前
座舱式个人飞行器 - 部署指南
无人机
a1117762 天前
“像风之翼“无人机巡检平台仪表盘
前端·javascript·开源·html·无人机
郑寿昌3 天前
UE5与UE6在Lumen和Nanite的差异解析
游戏引擎·图形渲染·着色器