13.4.1 无人机安全的理论框架
无人机安全机制是飞控系统的最后防线,其理论任务是在系统发生异常或面临危险时,能够及时检测、准确判断并采取有效措施,保障无人机自身安全以及地面人员和财产的安全。与普通消费电子产品不同,无人机作为飞行器,其失效可能导致严重的物理后果,因此安全机制的设计必须贯穿从硬件到软件的整个系统。
无人机安全的三层防御体系:
text
┌─────────────────────────────────────────────────────────────┐
│ 主动预防层 (Proactive Prevention) │
│ • 飞行前自检 • 电子围栏 • 地理围栏 • 禁飞区 │
│ • 气象预警 • 电量预估 • 链路质量监测 │
├─────────────────────────────────────────────────────────────┤
│ 实时监控层 (Real-time Monitoring) │
│ • 传感器故障检测 • 电机异常检测 • 姿态异常监控 • 定位丢 │
│ • 通信链路监控 • 电源监控 • 振动分析 │
├─────────────────────────────────────────────────────────────┤
│ 应急响应层 (Emergency Response) │
│ • 自动返航(RTH) • 紧急降落 • 悬停等待 • 降落伞 │
│ • 迫降保护 • 失控保护 • 低电量保护 │
└─────────────────────────────────────────────────────────────┘
无人机安全的根本挑战源于飞行器的特殊性:
| 挑战维度 | 描述 | 设计考量 |
|---|---|---|
| 后果严重性 | 失控可能造成人员伤亡、财产损失 | 多重冗余、失效安全 |
| 环境复杂性 | 天气、地形、电磁干扰多变 | 环境感知、自适应策略 |
| 资源有限性 | 电池、计算能力、通信带宽有限 | 轻量算法、优先级管理 |
| 动态性 | 飞行状态快速变化 | 实时监控、快速响应 |
| 法规符合性 | 需满足各国航空法规 | 标准遵循、可审计性 |
13.4.2 飞行前自检与预防机制
安全始于起飞前。全面的飞行前自检可以发现潜在问题,避免带病飞行。
自检流程设计
c
typedef enum {
PREFLIGHT_PENDING,
PREFLIGHT_IN_PROGRESS,
PREFLIGHT_PASSED,
PREFLIGHT_FAILED,
PREFLIGHT_WARNING
} PreflightStatus_t;
typedef struct {
// 传感器自检
struct {
int imu_ok; // IMU自检通过
int mag_ok; // 磁力计自检
int baro_ok; // 气压计自检
int gps_ok; // GPS自检
float mag_strength; // 磁场强度(用于检测干扰)
float imu_variance; // IMU方差(静止检测)
} sensors;
// 系统自检
struct {
int battery_voltage_ok; // 电池电压正常
int battery_cells_ok; // 电池电芯平衡
int motor_ok[4]; // 电机自检
int esc_ok[4]; // 电调自检
int sd_card_ok; // 存储正常
} system;
// 环境检查
struct {
int gps_fix; // GPS定位有效
int satellite_count; // 卫星数
float hdop; // 水平精度因子
int within_geofence; // 在电子围栏内
int weather_warning; // 气象警告
} environment;
PreflightStatus_t status;
char fail_reason[128];
} PreflightCheck_t;
void preflight_check(PreflightCheck_t *check) {
check->status = PREFLIGHT_IN_PROGRESS;
int fail_count = 0;
// 1. 传感器自检
check->sensors.imu_ok = imu_self_test();
if (!check->sensors.imu_ok) {
strcpy(check->fail_reason, "IMU self-test failed");
fail_count++;
}
// 静止时采集IMU数据,计算方差(检测振动异常)
check->sensors.imu_variance = imu_stationary_test(1000); // 1秒数据
if (check->sensors.imu_variance > IMU_VARIANCE_THRESHOLD) {
strcpy(check->fail_reason, "IMU vibration too high");
fail_count++;
}
// 磁力计检查
check->sensors.mag_ok = mag_self_test();
check->sensors.mag_strength = mag_get_strength();
if (fabs(check->sensors.mag_strength - 0.5f) > 0.1f) {
strcpy(check->fail_reason, "Magnetic field abnormal, check environment");
fail_count++;
}
// 2. 系统自检
check->system.battery_voltage_ok = battery_voltage_check();
check->system.battery_cells_ok = battery_cells_balanced();
// 电机/电调自检(低速旋转,检测电流和反馈)
for (int i = 0; i < 4; i++) {
check->system.motor_ok[i] = motor_self_test(i);
check->system.esc_ok[i] = esc_self_test(i);
}
// 3. 环境检查
check->environment.gps_fix = gps_get_fix_status();
check->environment.satellite_count = gps_get_satellite_count();
check->environment.hdop = gps_get_hdop();
check->environment.within_geofence = check_geofence();
if (check->environment.satellite_count < MIN_SATELLITES) {
strcpy(check->fail_reason, "Insufficient satellites");
fail_count++;
}
if (check->environment.hdop > MAX_HDOP) {
strcpy(check->fail_reason, "GPS precision too low");
fail_count++;
}
if (!check->environment.within_geofence) {
strcpy(check->fail_reason, "Outside geofence");
fail_count++;
}
// 最终判定
if (fail_count == 0) {
check->status = PREFLIGHT_PASSED;
} else {
check->status = PREFLIGHT_FAILED;
}
}
// 自检结果上报
void preflight_report(PreflightCheck_t *check) {
switch (check->status) {
case PREFLIGHT_PASSED:
printf("✅ All preflight checks passed\n");
break;
case PREFLIGHT_FAILED:
printf("❌ Preflight failed: %s\n", check->fail_reason);
break;
case PREFLIGHT_WARNING:
printf("⚠️ Preflight warning: %s\n", check->fail_reason);
break;
default:
break;
}
}
电子围栏与禁飞区
电子围栏是防止无人机飞入危险区域的关键技术:
c
typedef struct {
enum {
GEOFENCE_CIRCLE,
GEOFENCE_POLYGON,
GEOFENCE_ALTITUDE
} type;
union {
struct {
float center[2]; // 中心经纬度
float radius; // 半径(米)
} circle;
struct {
float vertices[MAX_VERTICES][2]; // 多边形顶点
int vertex_count;
} polygon;
struct {
float max_altitude;
float min_altitude;
} altitude;
} params;
enum {
GEOFENCE_WARNING,
GEOFENCE_RTH,
GEOFENCE_LAND
} action; // 触发时的动作
uint32_t id;
} Geofence_t;
int check_geofence_violation(Geofence_t *fence, float lat, float lon, float alt) {
switch (fence->type) {
case GEOFENCE_CIRCLE:
float dist = distance_haversine(lat, lon,
fence->params.circle.center[0],
fence->params.circle.center[1]);
if (dist > fence->params.circle.radius) {
return 1; // 越界
}
break;
case GEOFENCE_ALTITUDE:
if (alt > fence->params.altitude.max_altitude ||
alt < fence->params.altitude.min_altitude) {
return 1;
}
break;
}
return 0;
}
void geofence_violation_action(Geofence_t *fence) {
switch (fence->action) {
case GEOFENCE_WARNING:
send_telemetry("WARNING: Approaching geofence boundary");
break;
case GEOFENCE_RTH:
trigger_return_to_home();
break;
case GEOFENCE_LAND:
trigger_emergency_land();
break;
}
}
13.4.3 实时故障检测与诊断
飞行过程中的实时故障检测是应急处理的前提,需要多维度、多层次的监控体系。
传感器故障检测
c
typedef struct {
float expected_value; // 期望值(基于模型预测)
float measured_value; // 测量值
float variance; // 方差(用于检测噪声异常)
float timeout_count; // 超时计数
uint8_t health; // 健康状态 0-100%
} SensorMonitor_t;
// IMU故障检测(基于多IMU冗余)
int imu_fault_detection(float *imu_data[3], int imu_count) {
// 三冗余IMU,多数表决
if (imu_count < 3) return 0; // 冗余不足
float distances[3][3]; // 两两之间的差值
for (int i = 0; i < imu_count; i++) {
for (int j = i+1; j < imu_count; j++) {
distances[i][j] = vector_distance(imu_data[i], imu_data[j], 6);
}
}
// 检测故障IMU(与其他两个差异都大的)
for (int i = 0; i < imu_count; i++) {
int fail_count = 0;
for (int j = 0; j < imu_count; j++) {
if (i != j && distances[min(i,j)][max(i,j)] > IMU_FAILURE_THRESHOLD) {
fail_count++;
}
}
if (fail_count >= imu_count - 1) {
return i; // 返回故障IMU索引
}
}
return -1; // 无故障
}
// GPS故障检测(基于位置跳变和速度一致性)
int gps_fault_detection(float *gps_pos, float *gps_vel,
float *estimated_pos, float *estimated_vel) {
// 位置跳变检测
float pos_jump = distance(gps_pos, estimated_pos);
if (pos_jump > GPS_JUMP_THRESHOLD) {
return GPS_FAULT_POSITION_JUMP;
}
// 速度一致性检测
float vel_error = fabs(gps_vel[2] - estimated_vel[2]); // 垂直速度
if (vel_error > GPS_VEL_ERROR_THRESHOLD) {
return GPS_FAULT_VELOCITY;
}
// HDOP异常检测
float hdop = gps_get_hdop();
if (hdop > GPS_HDOP_MAX) {
return GPS_FAULT_LOW_PRECISION;
}
return GPS_FAULT_NONE;
}
执行器异常检测
电机和电调的异常检测基于电流、转速和温度的综合分析:
c
typedef struct {
float current; // 当前电流
float rpm; // 当前转速
float temperature; // 温度
float expected_rpm; // 期望转速(根据控制指令)
// 历史数据
float current_history[50];
float rpm_history[50];
int history_index;
} MotorMonitor_t;
int motor_fault_detection(MotorMonitor_t *motor, int motor_id) {
// 1. 堵转检测(期望转速高但实际转速低,电流大)
if (motor->expected_rpm > RPM_MIN && motor->rpm < RPM_MIN) {
if (motor->current > CURRENT_STALL_THRESHOLD) {
return MOTOR_FAULT_STALL;
}
}
// 2. 过流检测
if (motor->current > CURRENT_MAX) {
return MOTOR_FAULT_OVERCURRENT;
}
// 3. 过热检测
if (motor->temperature > TEMP_MAX) {
return MOTOR_FAULT_OVERTEMP;
}
// 4. 转速异常检测(与期望值偏差过大)
float rpm_error = fabs(motor->rpm - motor->expected_rpm);
if (rpm_error > RPM_ERROR_THRESHOLD) {
return MOTOR_FAULT_RPM_ERROR;
}
// 5. 振动异常检测(基于电流/转速的FFT分析)
float vibration = analyze_vibration(motor->current_history, 50);
if (vibration > VIBRATION_THRESHOLD) {
return MOTOR_FAULT_VIBRATION;
}
return MOTOR_FAULT_NONE;
}
// 电调通信检测
int esc_heartbeat_check(uint32_t last_heartbeat) {
uint32_t now = get_system_time_ms();
if (now - last_heartbeat > ESC_HEARTBEAT_TIMEOUT) {
return ESC_FAULT_COMM_LOST;
}
return ESC_FAULT_NONE;
}
通信链路监控
c
typedef struct {
uint32_t last_packet_time; // 最后接收数据包时间
uint32_t packet_count; // 累计接收包数
uint32_t lost_packet_count; // 丢包数
float link_quality; // 链路质量 0-100%
int rssi; // 信号强度
int snr; // 信噪比
} LinkMonitor_t;
void link_monitor_update(LinkMonitor_t *link, uint32_t now) {
// 计算丢包率
uint32_t expected_packets = (now - link->last_packet_time) / PACKET_INTERVAL;
if (expected_packets > 0) {
link->lost_packet_count += expected_packets - 1;
}
// 更新链路质量
link->link_quality = 100.0f * (1.0f - (float)link->lost_packet_count /
(link->packet_count + link->lost_packet_count));
// 超时检测
if (now - link->last_packet_time > LINK_TIMEOUT) {
link->link_quality = 0;
}
}
int link_fault_detection(LinkMonitor_t *link) {
if (link->link_quality < LINK_QUALITY_WARNING) {
return LINK_FAULT_POOR_QUALITY;
}
if (link->link_quality < LINK_QUALITY_CRITICAL) {
return LINK_FAULT_LOST;
}
return LINK_FAULT_NONE;
}
电池监控与续航预测
c
typedef struct {
float voltage; // 电压
float current; // 电流
float remaining_capacity; // 剩余容量 mAh
float full_capacity; // 满容量 mAh
float temperature; // 温度
uint8_t cell_count; // 电芯数
float cell_voltage[12]; // 各电芯电压
// 预测
float remaining_flight_time; // 剩余飞行时间(秒)
float power_consumption_rate; // 功耗率 mAh/s
} BatteryMonitor_t;
void battery_monitor_update(BatteryMonitor_t *bat) {
// 计算剩余电量百分比
float soc = bat->remaining_capacity / bat->full_capacity * 100.0f;
// 计算功耗率
float power = bat->voltage * bat->current / 1000.0f; // W
bat->power_consumption_rate = bat->current / 3600.0f; // mAh/s
// 预测剩余时间
if (bat->power_consumption_rate > 0) {
bat->remaining_flight_time = bat->remaining_capacity /
bat->power_consumption_rate;
}
// 低电量检测
if (soc < BATTERY_LOW_THRESHOLD) {
trigger_low_battery_action();
}
// 电芯不平衡检测
float max_cell = 0, min_cell = 100;
for (int i = 0; i < bat->cell_count; i++) {
if (bat->cell_voltage[i] > max_cell) max_cell = bat->cell_voltage[i];
if (bat->cell_voltage[i] < min_cell) min_cell = bat->cell_voltage[i];
}
if (max_cell - min_cell > CELL_IMBALANCE_THRESHOLD) {
send_telemetry("WARNING: Battery cells imbalanced");
}
}
int battery_fault_detection(BatteryMonitor_t *bat) {
// 过放检测
if (bat->voltage < BATTERY_UNDERVOLTAGE) {
return BATTERY_FAULT_UNDERVOLTAGE;
}
// 过流检测
if (bat->current > BATTERY_OVERCURRENT) {
return BATTERY_FAULT_OVERCURRENT;
}
// 过热检测
if (bat->temperature > BATTERY_OVERTEMP) {
return BATTERY_FAULT_OVERTEMP;
}
return BATTERY_FAULT_NONE;
}
13.4.4 应急处理策略
当检测到故障时,系统需根据故障类型和严重程度,采取相应的应急措施。
应急状态机
c
typedef enum {
EMERGENCY_NONE,
EMERGENCY_LOW_BATTERY,
EMERGENCY_GPS_LOST,
EMERGENCY_IMU_FAILURE,
EMERGENCY_MOTOR_FAILURE,
EMERGENCY_COMM_LOST,
EMERGENCY_WINDCONDITIONS,
EMERGENCY_TERMINATE
} EmergencyType_t;
typedef struct {
EmergencyType_t type;
uint32_t detection_time;
float confidence;
uint8_t active;
// 应急动作
enum {
ACTION_RTH, // 自动返航
ACTION_LAND, // 原地降落
ACTION_HOVER, // 悬停等待
ACTION_FINISH_MISSION, // 完成任务后返航
ACTION_TERMINATE // 紧急停机
} action;
// 状态
float start_altitude; // 开始应急时的高度
float remaining_battery;
uint32_t action_start_time;
} EmergencyState_t;
void emergency_state_machine(EmergencyState_t *emerg) {
switch (emerg->type) {
case EMERGENCY_LOW_BATTERY:
if (emerg->remaining_battery < 10) {
// 电量极低,立即降落
emerg->action = ACTION_LAND;
} else if (emerg->remaining_battery < 20) {
// 电量较低,自动返航
emerg->action = ACTION_RTH;
}
break;
case EMERGENCY_GPS_LOST:
// 切换到视觉导航模式
switch_to_visual_navigation();
emerg->action = ACTION_HOVER;
break;
case EMERGENCY_IMU_FAILURE:
// IMU故障,立即降落
emerg->action = ACTION_LAND;
break;
case EMERGENCY_MOTOR_FAILURE:
// 单电机故障,执行紧急降落
emerg->action = ACTION_TERMINATE;
break;
case EMERGENCY_COMM_LOST:
// 通信丢失,自动返航
emerg->action = ACTION_RTH;
break;
}
}
自动返航(RTH)实现
自动返航是最常用的应急策略,在低电量、信号丢失等情况下自动返回起飞点:
c
typedef struct {
float home_position[3]; // 返航点经纬度/高度
float current_position[3];
float rth_altitude; // 返航高度
float safe_altitude; // 安全高度(避障用)
enum {
RTH_CLIMB, // 爬升到安全高度
RTH_RETURN, // 水平返航
RTH_DESCEND // 下降降落
} phase;
uint32_t phase_start_time;
} RTHController_t;
void rth_controller_init(RTHController_t *rth, float *home_pos, float rth_alt) {
memcpy(rth->home_position, home_pos, 3 * sizeof(float));
rth->rth_altitude = rth_alt;
rth->phase = RTH_CLIMB;
rth->phase_start_time = get_system_time_ms();
}
int rth_controller_update(RTHController_t *rth, float *cmd) {
switch (rth->phase) {
case RTH_CLIMB:
// 先爬升到安全高度
if (rth->current_position[2] < rth->rth_altitude) {
cmd[0] = 0; // 水平速度为0
cmd[1] = 0;
cmd[2] = RTH_CLIMB_SPEED; // 垂直爬升速度
} else {
rth->phase = RTH_RETURN;
rth->phase_start_time = get_system_time_ms();
}
break;
case RTH_RETURN:
// 水平返航
float to_home[2];
to_home[0] = rth->home_position[0] - rth->current_position[0];
to_home[1] = rth->home_position[1] - rth->current_position[1];
float dist = sqrt(to_home[0]*to_home[0] + to_home[1]*to_home[1]);
if (dist > RTH_ARRIVE_THRESHOLD) {
// 计算返航方向
cmd[0] = RTH_SPEED * to_home[0] / dist;
cmd[1] = RTH_SPEED * to_home[1] / dist;
cmd[2] = 0; // 保持高度
} else {
rth->phase = RTH_DESCEND;
rth->phase_start_time = get_system_time_ms();
}
break;
case RTH_DESCEND:
// 下降降落
if (rth->current_position[2] > 0.5) {
cmd[0] = 0;
cmd[1] = 0;
cmd[2] = -RTH_DESCEND_SPEED;
} else {
// 到达地面,关闭电机
disarm_motors();
return 1; // 完成
}
break;
}
return 0; // 进行中
}
紧急降落与迫降
当无法返航时(如电机故障),需执行紧急降落:
c
typedef struct {
float land_velocity; // 下降速度
float land_position[3]; // 降落点(可选)
int motor_out[4]; // 电机状态
enum {
LAND_FIND_SPOT, // 寻找安全降落点
LAND_DESCEND, // 下降
LAND_TOUCHDOWN // 触地检测
} phase;
} EmergencyLand_t;
void emergency_land_update(EmergencyLand_t *land, float *cmd) {
switch (land->phase) {
case LAND_FIND_SPOT:
// 如果有激光/视觉测距,寻找下方平坦区域
if (find_safe_landing_spot(land->land_position)) {
land->phase = LAND_DESCEND;
} else {
// 无法找到安全点,原地下降
land->phase = LAND_DESCEND;
}
break;
case LAND_DESCEND:
// 垂直下降
cmd[0] = 0;
cmd[1] = 0;
cmd[2] = -land->land_velocity;
// 触地检测(通过加速度计或高度计)
if (detect_touchdown()) {
land->phase = LAND_TOUCHDOWN;
}
break;
case LAND_TOUCHDOWN:
// 触地后关闭电机
disarm_motors();
break;
}
}
// 触地检测
int detect_touchdown(void) {
// 方法1:高度计检测(高度不再变化)
float height = get_sonar_height();
static float prev_height = 0;
if (fabs(height - prev_height) < 0.01f && height < 0.1f) {
return 1;
}
prev_height = height;
// 方法2:加速度计检测(撞击脉冲)
float accel_z = get_accel_z();
if (accel_z > IMPACT_THRESHOLD) {
return 1;
}
return 0;
}
降落伞触发与急停
对于大型无人机或载人无人机,降落伞是最后的救命手段:
c
typedef struct {
float deployment_altitude; // 开伞高度
float descent_rate; // 下降速率
float impact_velocity; // 触地速度
// 触发条件
int motor_failure_count; // 电机失效数量
float angular_rate; // 角速度(检测旋冲)
float attitude_error; // 姿态偏差
} ParachuteSystem_t;
void parachute_monitor(ParachuteSystem_t *para) {
// 触发条件1:两个以上电机失效
if (para->motor_failure_count >= 2) {
deploy_parachute();
return;
}
// 触发条件2:失控旋转(角速度过大)
if (para->angular_rate > MAX_ANGULAR_RATE * 2) {
deploy_parachute();
return;
}
// 触发条件3:姿态严重偏离
if (para->attitude_error > 45.0f * DEG_TO_RAD) {
deploy_parachute();
return;
}
}
void deploy_parachute(void) {
// 1. 停止所有电机
disarm_motors();
// 2. 触发开伞机构(舵机/电磁铁)
trigger_parachute_servo();
// 3. 发送紧急信标
send_emergency_beacon();
// 4. 记录黑匣子数据
save_flight_log_to_eeprom();
}
13.4.5 数据记录与黑匣子
飞行数据的完整记录对于事故分析和系统改进至关重要。
黑匣子设计
c
typedef struct {
uint32_t timestamp; // 时间戳
float attitude[3]; // 姿态角
float position[3]; // 位置
float velocity[3]; // 速度
float gyro[3]; // 角速度
float accel[3]; // 加速度
float mag[3]; // 磁场
float motor_rpm[4]; // 电机转速
float motor_current[4]; // 电机电流
float battery_voltage; // 电池电压
float battery_current; // 电池电流
uint16_t rssi; // 信号强度
uint8_t gps_satellites; // GPS卫星数
uint8_t flight_mode; // 飞行模式
uint8_t emergency_status; // 应急状态
uint8_t error_code; // 错误码
uint16_t checksum; // 校验和
} FlightLogEntry_t;
typedef struct {
FlightLogEntry_t buffer[LOG_BUFFER_SIZE];
uint32_t write_index;
uint32_t read_index;
uint32_t entry_count;
// 闪存存储
uint32_t flash_write_addr;
uint32_t flash_sector;
// 触发保存标志
int emergency_triggered;
} BlackBox_t;
void blackbox_init(BlackBox_t *bb) {
bb->write_index = 0;
bb->entry_count = 0;
bb->emergency_triggered = 0;
// 初始化闪存(预留最后几个扇区)
bb->flash_write_addr = FLASH_BLACKBOX_START;
}
void blackbox_write(BlackBox_t *bb, FlightLogEntry_t *entry) {
// 计算校验和
uint16_t sum = 0;
uint16_t *ptr = (uint16_t*)entry;
for (int i = 0; i < sizeof(FlightLogEntry_t)/2 - 1; i++) {
sum += ptr[i];
}
entry->checksum = sum;
// 写入环形缓冲区
memcpy(&bb->buffer[bb->write_index], entry, sizeof(FlightLogEntry_t));
bb->write_index = (bb->write_index + 1) % LOG_BUFFER_SIZE;
if (bb->entry_count < LOG_BUFFER_SIZE) {
bb->entry_count++;
}
// 定期写入闪存(每10秒)
static uint32_t last_flash_write = 0;
uint32_t now = entry->timestamp;
if (now - last_flash_write > 10000) {
blackbox_flush_to_flash(bb);
last_flash_write = now;
}
}
void blackbox_flush_to_flash(BlackBox_t *bb) {
// 从缓冲区读取并写入闪存
int entries_to_write = bb->entry_count;
int start_idx = (bb->write_index - entries_to_write + LOG_BUFFER_SIZE) % LOG_BUFFER_SIZE;
for (int i = 0; i < entries_to_write; i++) {
int idx = (start_idx + i) % LOG_BUFFER_SIZE;
flash_write(bb->flash_write_addr + i * sizeof(FlightLogEntry_t),
(uint8_t*)&bb->buffer[idx],
sizeof(FlightLogEntry_t));
}
bb->flash_write_addr += entries_to_write * sizeof(FlightLogEntry_t);
}
void blackbox_emergency_save(BlackBox_t *bb) {
// 紧急情况时强制保存所有数据
blackbox_flush_to_flash(bb);
// 保存故障快照
FlightLogEntry_t last_entry;
memcpy(&last_entry, &bb->buffer[(bb->write_index - 1) % LOG_BUFFER_SIZE],
sizeof(FlightLogEntry_t));
flash_write(FLASH_FAULT_SNAPSHOT_ADDR,
(uint8_t*)&last_entry, sizeof(FlightLogEntry_t));
bb->emergency_triggered = 1;
}
13.4.6 软件看门狗与故障恢复
软件看门狗用于检测任务死锁和系统挂起,确保系统在故障时能够自动恢复。
c
typedef struct {
TaskHandle_t task_handles[MAX_TASKS];
uint32_t last_feed_time[MAX_TASKS];
uint32_t expected_interval[MAX_TASKS];
int task_count;
// 系统级看门狗
uint32_t system_last_feed;
uint32_t system_timeout;
// 硬件看门狗
IWDG_HandleTypeDef hiwdg;
} WatchdogManager_t;
void watchdog_manager_init(WatchdogManager_t *wd) {
wd->task_count = 0;
wd->system_last_feed = get_system_time_ms();
// 初始化硬件看门狗(5秒超时)
wd->hiwdg.Instance = IWDG;
wd->hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
wd->hiwdg.Init.Reload = 5000 / (64000 / 64); // 5秒
HAL_IWDG_Init(&wd->hiwdg);
}
void watchdog_register_task(WatchdogManager_t *wd,
TaskHandle_t task,
uint32_t interval) {
if (wd->task_count < MAX_TASKS) {
wd->task_handles[wd->task_count] = task;
wd->last_feed_time[wd->task_count] = get_system_time_ms();
wd->expected_interval[wd->task_count] = interval;
wd->task_count++;
}
}
void watchdog_task_feed(WatchdogManager_t *wd, TaskHandle_t task) {
for (int i = 0; i < wd->task_count; i++) {
if (wd->task_handles[i] == task) {
wd->last_feed_time[i] = get_system_time_ms();
break;
}
}
}
void watchdog_monitor_task(void *param) {
WatchdogManager_t *wd = (WatchdogManager_t*)param;
while (1) {
uint32_t now = get_system_time_ms();
// 检查各任务喂狗情况
for (int i = 0; i < wd->task_count; i++) {
if (now - wd->last_feed_time[i] > wd->expected_interval[i] * 2) {
printf("WARNING: Task %d watchdog timeout\n", i);
// 尝试重启任务
vTaskDelete(wd->task_handles[i]);
create_task(i); // 重新创建
}
}
// 系统级喂狗(硬件看门狗)
HAL_IWDG_Refresh(&wd->hiwdg);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
13.4.7 常见问题与最佳实践
常见问题与解决方案
问题1:误触发应急处理
现象:正常飞行时频繁触发低电量返航或避障停机。
根因分析:阈值设置过敏感,或传感器噪声大。
解决方案:
-
增加滤波和防抖机制(连续多次检测才触发)
-
动态调整阈值(根据飞行状态、电池老化)
-
引入置信度机制,结合多传感器判断
问题2:返航时与障碍物碰撞
现象:自动返航过程中撞上树木、建筑物。
根因分析:返航路径未考虑障碍物,或避障失效。
解决方案:
-
返航前先爬升到安全高度(高于周围障碍物)
-
实时感知并局部重规划路径
-
使用立体视觉/激光雷达辅助避障
问题3:通信丢失后失控
现象:超出遥控距离后无人机失控飞走。
根因分析:失控保护未正确配置或未触发。
解决方案:
-
配置失控保护为自动返航
-
多次确认链路丢失后再触发(避免短暂丢包)
-
返航点实时更新,避免返回已移动的起降点
问题4:电池电量预测不准
现象:电量显示还有30%,但实际已耗尽。
根因分析:电压法估算不准,未考虑电流积分和老化。
解决方案:
-
使用库仑计(电流积分)结合电压补偿
-
记录电池历史数据,建立老化模型
-
预留20%安全余量
问题5:电机故障时坠毁
现象:单电机停转后无法控制,直接坠毁。
根因分析:六轴以下无人机单电机失效无法稳定。
解决方案:
-
使用六轴以上布局,具备冗余
-
开发容错控制算法(自动补偿剩余电机)
-
降落伞系统作为最后手段
最佳实践指南
实践1:安全阈值设置原则
| 参数 | 建议值 | 说明 |
|---|---|---|
| 低电量警告 | 30% | 提前预警,给返航留时间 |
| 紧急返航 | 20% | 强制返航,确保安全 |
| 立即降落 | 10% | 无论在哪,立即降落 |
| GPS丢星 | <8颗 | 警告 |
| GPS无效 | <6颗 | 切换定位模式 |
| 通信丢失 | 3秒 | 确认丢失后触发返航 |
| 姿态异常 | 45° | 超过此角度视为失控 |
实践2:应急策略优先级
-
最高优先级:紧急停机/降落伞(危及生命时)
-
高优先级:立即降落(电机故障)
-
中优先级:自动返航(低电量、信号丢失)
-
低优先级:悬停等待(短时信号丢失)
-
最低优先级:继续任务(轻微异常)
实践3:飞行前检查清单
-
电池电压、电芯平衡正常
-
GPS卫星数≥10,HDOP≤1.0
-
磁力计校准有效,无磁场干扰
-
所有电机启动正常,无异响
-
遥控器信号正常,失控保护测试通过
-
返航点已记录(起飞后)
-
电子围栏配置正确
-
存储卡空间充足,可记录日志
实践4:事故分析流程
-
恢复黑匣子数据:从闪存读取最后飞行日志
-
回放飞行过程:在地面站软件中回放姿态、控制、状态
-
分析异常点:查找参数突变、错误码
-
故障树分析:构建故障树,定位根本原因
-
改进措施:更新软件、调整参数、修改硬件
实践5:冗余设计推荐
-
传感器冗余:至少2个IMU,2个磁力计(可选)
-
电源冗余:主电池+备用电池/电容
-
通信冗余:2.4G遥控 + 4G数传备份
-
执行器冗余:六轴以上布局,单电机失效仍可控
-
存储冗余:SD卡 + 内部Flash双备份
13.4.8 未来发展趋势
无人机安全技术正朝着预测性、自适应、群体协同的方向发展。
预测性安全基于大数据和机器学习,通过分析历史飞行数据和实时状态,提前预测潜在故障。如通过电机振动频谱预测轴承磨损,在失效前预警维护。
自适应安全阈值根据环境条件和飞行状态动态调整。风大时提高安全高度,夜航时增加避障冗余,电池老化后调整返航阈值。
群体协同安全在多机集群中实现相互监控和协同避让。一架无人机检测到危险可广播给机群,实现群体规避。当无人机失效时,邻机可接替其任务。
自动取证内置数字取证模块,在事故发生时自动保存完整证据链,包括飞行数据、感知视频、控制指令,为事故分析提供可靠依据。
13.4.9 本章小结
安全机制与应急处理是无人机系统的生命线,其理论体系涵盖飞行前预防、实时监控、故障检测、应急响应和数据记录等多个层面。本章系统阐述了从基础理论到工程实践的安全设计方法。
飞行前自检通过传感器、系统、环境三级检查,确保无人机以健康状态起飞。电子围栏和禁飞区防止进入危险区域。
实时监控覆盖传感器、执行器、通信链路和电池等关键子系统,通过冗余表决、一致性检查、趋势分析等方法及时检测异常。
应急响应根据故障类型和严重程度采取分级措施,包括自动返航、紧急降落、迫降保护直至降落伞触发。状态机设计确保响应有序、可预测。
黑匣子持续记录飞行数据,在故障时保存最后状态,为事故分析提供依据。
软件看门狗监控任务执行状态,防止死锁和挂起。
从实践角度看,无人机安全系统的开发遵循明确的技术路径:风险识别→预防措施设计→监控机制实现→应急策略制定→测试验证→持续优化。每个环节都需要将理论原理转化为具体的工程决策。
优秀的安全系统应具备多层次防护(预防-监控-响应)、高可靠性(冗余设计)、自适应性(动态阈值)和完备性(记录可追溯)。它不仅是飞控系统的附属功能,更是贯穿整个无人机设计的核心思想,是无人机从"玩具"走向"工具"的根本保障。