Ardupilot(PX4)飞控驱动蜂鸣器和RGB细节
Ardupilot(PX4)飞控驱动蜂鸣器细节
飞控代码细节
任务调用频率50HZ(20ms),buzzer.update()
内部将频率减少到10HZ(100ms)
单响(SINGLE_BUZZ) 响1次,100ms
解锁事件错误,电池故障提醒,其中加锁只响一次,其他两种会一直间断响
双响(DOUBLE_BUZZ) 100ms间断响两次
vehicle_lost间断响,找飞机时使用
解锁(ARMING_BUZZ) 响声 3S
解锁常响3S一次
BARO_GLITCH,100ms间断响5次(飞控代码暂时没用到这部分)
EKF_BAD,四个音调越来越短 :ekf_bad错误
300ms on >> 100ms off >> 200ms on >> 100ms off >>100ms on >>100ms off >>100ms on >>100ms off
注意: ARM代表解锁,DISARM加锁
代码如下
void Buzzer::update()
{
// return immediately if disabled
if (!AP_Notify::flags.external_leds) {
return;
}
// check for arming failed event
if (AP_Notify::events.arming_failed) {
// arming failed buzz
play_pattern(SINGLE_BUZZ);
}
// reduce 50hz call down to 10hz
_counter++;
if (_counter < 5) {
return;
}
_counter = 0;
// complete currently played pattern
if (_pattern != NONE) {
_pattern_counter++;
switch (_pattern) {
case SINGLE_BUZZ:
// buzz for 10th of a second
if (_pattern_counter == 1) {
on(true);
}else{
on(false);
_pattern = NONE;
}
return;
case DOUBLE_BUZZ:
// buzz for 10th of a second
switch (_pattern_counter) {
case 1:
on(true);
break;
case 2:
on(false);
break;
case 3:
on(true);
break;
case 4:
default:
on(false);
_pattern = NONE;
break;
}
return;
case ARMING_BUZZ:
// record start time
if (_pattern_counter == 1) {
_arming_buzz_start_ms = AP_HAL::millis();
on(true);
} else {
// turn off buzzer after 3 seconds
if (AP_HAL::millis() - _arming_buzz_start_ms >= BUZZER_ARMING_BUZZ_MS) {
_arming_buzz_start_ms = 0;
on(false);
_pattern = NONE;
}
}
return;
case BARO_GLITCH:
// four fast tones
switch (_pattern_counter) {
case 1:
case 3:
case 5:
case 7:
case 9:
on(true);
break;
case 2:
case 4:
case 6:
case 8:
on(false);
break;
case 10:
on(false);
_pattern = NONE;
break;
default:
// do nothing
break;
}
return;
case EKF_BAD:
// four tones getting shorter)
switch (_pattern_counter) {
case 1:
case 5:
case 8:
case 10:
on(true);
break;
case 4:
case 7:
case 9:
on(false);
break;
case 11:
on(false);
_pattern = NONE;
break;
default:
// do nothing
break;
}
return;
default:
// do nothing
break;
}
}
// check if armed status has changed
if (_flags.armed != AP_Notify::flags.armed) {
_flags.armed = AP_Notify::flags.armed;
if (_flags.armed) {
// double buzz when armed
play_pattern(ARMING_BUZZ);
}else{
// single buzz when disarmed
play_pattern(SINGLE_BUZZ);
}
return;
}
// check ekf bad
if (_flags.ekf_bad != AP_Notify::flags.ekf_bad) {
_flags.ekf_bad = AP_Notify::flags.ekf_bad;
if (_flags.ekf_bad) {
// ekf bad warning buzz
play_pattern(EKF_BAD);
}
return;
}
// if vehicle lost was enabled, starting beep
if (AP_Notify::flags.vehicle_lost) {
play_pattern(DOUBLE_BUZZ);
}
// if battery failsafe constantly single buzz
if (AP_Notify::flags.failsafe_battery) {
play_pattern(SINGLE_BUZZ);
}
}
从mavlink协议里面获取这些标志位
加锁解锁状态的获取:
心跳包,条件base_mode&MAV_MODE_FLAG_SAFETY_ARMED==MAV_MODE_FLAG_SAFETY_ARMED,如果为真,则在加锁状态,如果为假,则在解锁状态。
EKF_BAD
飞控代码条件
if (!ekf_position_ok() && !optflow_position_ok()) return true;
return compass_variance >= g.fs_ekf_thresh && vel_variance >= g.fs_ekf_thresh;
上述条件返回真,说明EKF_BAD
g.fs_ekf_thresh为用于设置参数, compass_variance 和vel_variance 可通过mavlink 协议中的MAVLINK_MSG_ID_EKF_STATUS_REPORT消息获得。以下代码程序中的判断条件可以从该消息中获取。
bool Copter::ekf_position_ok()
{
if (!ahrs.have_inertial_nav()) {
// do not allow navigation with dcm position
return false;
}
// with EKF use filter status and ekf check
nav_filter_status filt_status = inertial_nav.get_filter_status();
// if disarmed we accept a predicted horizontal position
if (!motors->armed()) {
return ((filt_status.flags.horiz_pos_abs || filt_status.flags.pred_horiz_pos_abs));
} else {
// once armed we require a good absolute position and EKF must not be in const_pos_mode
return (filt_status.flags.horiz_pos_abs && !filt_status.flags.const_pos_mode);
}
}
// optflow_position_ok - returns true if optical flow based position estimate is ok
bool Copter::optflow_position_ok()
{
#if OPTFLOW != ENABLED && VISUAL_ODOMETRY_ENABLED != ENABLED
return false;
#else
// return immediately if EKF not used
if (!ahrs.have_inertial_nav()) {
return false;
}
// return immediately if neither optflow nor visual odometry is enabled
bool enabled = false;
#if OPTFLOW == ENABLED
if (optflow.enabled()) {
enabled = true;
}
#endif
#if VISUAL_ODOMETRY_ENABLED == ENABLED
if (g2.visual_odom.enabled()) {
enabled = true;
}
#endif
if (!enabled) {
return false;
}
// get filter status from EKF
nav_filter_status filt_status = inertial_nav.get_filter_status();
// if disarmed we accept a predicted horizontal relative position
if (!motors->armed()) {
return (filt_status.flags.pred_horiz_pos_rel);
} else {
return (filt_status.flags.horiz_pos_rel && !filt_status.flags.const_pos_mode);
}
#endif
}
vehicle_lost,飞行器丢失,找飞机使用
// check for pilot stick input to trigger lost vehicle alarm
void Copter::lost_vehicle_check()
{
static uint8_t soundalarm_counter;
// disable if aux switch is setup to vehicle alarm as the two could interfere
if (check_if_auxsw_mode_used(AUXSW_LOST_COPTER_SOUND)) {
return;
}
// ensure throttle is down, motors not armed, pitch and roll rc at max. Note: rc1=roll rc2=pitch
if (ap.throttle_zero && !motors->armed() && (channel_roll->get_control_in() > 4000) && (channel_pitch->get_control_in() > 4000)) {
if (soundalarm_counter >= LOST_VEHICLE_DELAY) {
if (AP_Notify::flags.vehicle_lost == false) {
AP_Notify::flags.vehicle_lost = true;
gcs_send_text(MAV_SEVERITY_NOTICE,"Locate Copter alarm");
}
} else {
soundalarm_counter++;
}
} else {
soundalarm_counter = 0;
if (AP_Notify::flags.vehicle_lost == true) {
AP_Notify::flags.vehicle_lost = false;
}
}
}
Ardupilot(PX4)飞控驱动RGB全彩灯细节
IO控制LED逻辑
闪烁时间: 快闪分配255,中等时间204,慢闪时间102
50HZ的频率调用rgbled.update_colours()函数,内部降频为10HZ
判断usb连接采用中等时间闪烁,为usb供电解压
LED闪烁分10小步骤
闪烁逻辑
系统初始化,奇数次亮红灯,偶数次亮蓝灯,返回
成功保存电调校准和遥控器校准,0-3-6亮红灯,1-4-7亮蓝灯,2-5-8亮绿灯,9-灭灯,返回
电台故障,电源报警,ekf_bad,GPS_glitch(GPS误差大),leak_detected,返回
0-1-2-3-4亮黄灯
5-6-7-8-9
leak_detected,全亮紫色
ekf_bad,红灯
gps_glitch,蓝灯
电台和电源故障,灭灯
加锁状态
GPS固定类型大于GPS_OK_FIX_3D,亮绿灯,否则亮蓝灯
解锁状态
解锁校验失败,0-1-4-5,黄灯(红灯和绿灯亮),2-3-6-7-8-9,全灭
解锁校验成功
快闪绿灯条件
AP_Notify::flags.gps_status >= AP_GPS::GPS_OK_FIX_3D_DGPS && AP_Notify::flags.pre_arm_gps_check;
0-上述条件成立,开绿灯
1-上述条件成立,关绿灯
2-上述条件成立,开绿灯
3-上述条件成立,关绿灯
4-关红灯,上述条件成立,关蓝灯,亮绿灯,不成立亮蓝灯,关绿灯
5-上述条件成立,关绿灯
6-上述条件成立,亮绿灯
7-上述条件成立,关绿灯
8-条件成立,关绿灯
9-全关
代码如下
// _scheduled_update - updates _red, _green, _blue according to notify flags
void RGBLed::update_colours(void)
{
uint8_t brightness = _led_bright;
switch (pNotify->_rgb_led_brightness) {
case RGB_LED_OFF:
brightness = _led_off;
break;
case RGB_LED_LOW:
brightness = _led_dim;
break;
case RGB_LED_MEDIUM:
brightness = _led_medium;
break;
case RGB_LED_HIGH:
brightness = _led_bright;
break;
}
// slow rate from 50Hz to 10hz
counter++;
if (counter < 5) {
return;
}
// reset counter
counter = 0;
// move forward one step
step++;
if (step >= 10) {
step = 0;
}
// use dim light when connected through USB
if (hal.gpio->usb_connected() && brightness > _led_dim) {
brightness = _led_dim;
}
// initialising pattern
if (AP_Notify::flags.initialising) {
if (step & 1) {
// odd steps display red light
_red_des = brightness;
_blue_des = _led_off;
_green_des = _led_off;
} else {
// even display blue light
_red_des = _led_off;
_blue_des = brightness;
_green_des = _led_off;
}
// exit so no other status modify this pattern
return;
}
// save trim and esc calibration pattern
if (AP_Notify::flags.save_trim || AP_Notify::flags.esc_calibration) {
switch(step) {
case 0:
case 3:
case 6:
// red on
_red_des = brightness;
_blue_des = _led_off;
_green_des = _led_off;
break;
case 1:
case 4:
case 7:
// blue on
_red_des = _led_off;
_blue_des = brightness;
_green_des = _led_off;
break;
case 2:
case 5:
case 8:
// green on
_red_des = _led_off;
_blue_des = _led_off;
_green_des = brightness;
break;
case 9:
// all off
_red_des = _led_off;
_blue_des = _led_off;
_green_des = _led_off;
break;
}
// exit so no other status modify this pattern
return;
}
// radio and battery failsafe patter: flash yellow
// gps failsafe pattern : flashing yellow and blue
// ekf_bad pattern : flashing yellow and red
if (AP_Notify::flags.failsafe_radio || AP_Notify::flags.failsafe_battery ||
AP_Notify::flags.ekf_bad || AP_Notify::flags.gps_glitching || AP_Notify::flags.leak_detected) {
switch(step) {
case 0:
case 1:
case 2:
case 3:
case 4:
// yellow on
_red_des = brightness;
_blue_des = _led_off;
_green_des = brightness;
break;
case 5:
case 6:
case 7:
case 8:
case 9:
if (AP_Notify::flags.leak_detected) {
// purple if leak detected
_red_des = brightness;
_blue_des = brightness;
_green_des = brightness;
} else if (AP_Notify::flags.ekf_bad) {
// red on if ekf bad
_red_des = brightness;
_blue_des = _led_off;
_green_des = _led_off;
} else if (AP_Notify::flags.gps_glitching) {
// blue on gps glitch
_red_des = _led_off;
_blue_des = brightness;
_green_des = _led_off;
}else{
// all off for radio or battery failsafe
_red_des = _led_off;
_blue_des = _led_off;
_green_des = _led_off;
}
break;
}
// exit so no other status modify this pattern
return;
}
// solid green or blue if armed
if (AP_Notify::flags.armed) {
// solid green if armed with GPS 3d lock
if (AP_Notify::flags.gps_status >= AP_GPS::GPS_OK_FIX_3D) {
_red_des = _led_off;
_blue_des = _led_off;
_green_des = brightness;
}else{
// solid blue if armed with no GPS lock
_red_des = _led_off;
_blue_des = brightness;
_green_des = _led_off;
}
return;
}else{
// double flash yellow if failing pre-arm checks
if (!AP_Notify::flags.pre_arm_check) {
switch(step) {
case 0:
case 1:
case 4:
case 5:
// yellow on
_red_des = brightness;
_blue_des = _led_off;
_green_des = brightness;
break;
case 2:
case 3:
case 6:
case 7:
case 8:
case 9:
// all off
_red_des = _led_off;
_blue_des = _led_off;
_green_des = _led_off;
break;
}
}else{
// fast flashing green if disarmed with GPS 3D lock and DGPS
// slow flashing green if disarmed with GPS 3d lock (and no DGPS)
// flashing blue if disarmed with no gps lock or gps pre_arm checks have failed
bool fast_green = AP_Notify::flags.gps_status >= AP_GPS::GPS_OK_FIX_3D_DGPS && AP_Notify::flags.pre_arm_gps_check;
switch(step) {
case 0:
if (fast_green) {
_green_des = brightness;
}
break;
case 1:
if (fast_green) {
_green_des = _led_off;
}
break;
case 2:
if (fast_green) {
_green_des = brightness;
}
break;
case 3:
if (fast_green) {
_green_des = _led_off;
}
break;
case 4:
_red_des = _led_off;
if (AP_Notify::flags.gps_status >= AP_GPS::GPS_OK_FIX_3D && AP_Notify::flags.pre_arm_gps_check) {
// flashing green if disarmed with GPS 3d lock
_blue_des = _led_off;
_green_des = brightness;
}else{
// flashing blue if disarmed with no gps lock
_blue_des = brightness;
_green_des = _led_off;
}
break;
case 5:
if (fast_green) {
_green_des = _led_off;
}
break;
case 6:
if (fast_green) {
_green_des = brightness;
}
break;
case 7:
if (fast_green) {
_green_des = _led_off;
}
break;
case 8:
if (fast_green) {
_green_des = brightness;
}
break;
case 9:
// all off
_red_des = _led_off;
_blue_des = _led_off;
_green_des = _led_off;
break;
}
}
}
}
Ardupilot(PX4)飞控驱动蜂鸣器和RGB细节的更多相关文章
- PX4/PixHawk无人机飞控应用开发
最近做的一个国防背景的field UAV项目,细节不能多谈,简单写点技术体会. 1.PX4/Pixhawk飞控软件架构简介 PX4是目前最流行的开源飞控板之一.PX4的软件系统实际上就是一个firmw ...
- 【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-3 底层驱动之LED_蜂鸣器
视频简介: 该视频介绍iCore3应用开发平台出厂源代码中GPIO的配置方法 及如何点亮LED和驱动蜂鸣器发声. 源视频包下载地址: http://pan.baidu.com/s/1nvpYMff ...
- Android深度探索--HAL与驱动开发----第八章读书笔记
通过蜂鸣器的实现原理,实现一个完整的蜂呜器驱动,可以打开和关闭蜂鸣器. PWM驱动的实现方式不同于LED驱动, PWM 驱动将由多个文件组成.这也是大多数 Linux 驱动的标准实现方式. 刚开始是L ...
- 2440裸机驱动之PWM开发
原文http://blog.chinaunix.net/uid-14114479-id-3125685.html ARM驱动蜂鸣器的方式有两种:一种是PWM输出口直接驱动,另一种是利用IO定时翻转电平 ...
- STM32开发指南-蜂鸣器实验
另一种I/O作为输出的应用,利用一个I/O来控制板载的有源蜂鸣器,实现蜂鸣器控制. PS:有源蜂鸣器自带了震荡电路,一通电就会发声:无源蜂鸣器则没有自带震荡电路,必须外部提供2~5Khz左右的方波驱动 ...
- 基于ARM-contexA9-蜂鸣器pwm驱动开发
上次,我们写过一个蜂鸣器叫的程序,但是那个程序仅仅只是驱动蜂鸣器,用电平1和0来驱动而已,跟驱动LED其实没什么两样.我们先来回顾一下蜂鸣器的硬件还有相关的寄存器吧: 还是和以前一样的步骤: 1.看电 ...
- Linux ALSA声卡驱动之一:ALSA架构简介
声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢! 一. 概述 ALSA是Advanced Linux Sound Architecture ...
- linux学习--字符设备驱动
目录 1.字符设备驱动抽象结构 2.设备号及设备节点 2.1 设备号分配与管理 2.2 设备节点的生成 3.打开设备文件 linux驱动有基本的接口进行注册和卸载,这里不再做详细说明,本文主要关注li ...
- Linux ALSA声卡驱动之一:ALS…
声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢! 一. 概述 ALSA是Advanced Linux Sound Architecture ...
随机推荐
- 小程序自定义switch组件
如上图,小程序api中的switch组件只能自定义颜色,不能自定义宽高,所以就开始了自己写switch组件. 自定义组件样式 switch组件样式大致如图,样式思路:未选中时为一个长方形有圆角按钮,和 ...
- 在浏览器中使用ES6的模块功能 import 及 export
感谢英文原作者 Jake Archibald 的技术分享 各个浏览器对于ES6模块 import . export的支持情况 Safari 10.1. Chrome 61. Firefox 54 – ...
- Nginx + uWSGI部署中的一些小坑
1.invalid host in upstream报错 重新启动nginx : sudo /etc/init.d/nginx restart 原因是在配置负载均衡nginx.conf配置文件时,发现 ...
- Java 抽象类 抽象方法 使用说明
知识点 什么是抽象类 抽象类与普通类主要两点不同: 1.在类的修饰符后面多了一个abstract关键字 2.抽象类是不允许通过new来实例化的 由于抽象类不能通过new来实例化,所以基本上是在继承中当 ...
- vue的插件使用
插件通常是为Vue添加全局功能,vue的官网介绍了5中添加插件的方法. vue的插件有个公开方法install.第一个参数是Vue构造器,第二个参数是一个可选的选项对象. 在plugin.js中可以这 ...
- Flutter的盒子约束
由Expanded widget引发的思考 设计稿如下 布局widget分解 很常见的一种布局方式:Column的子widget中包含ListView @override Widget build(B ...
- codeigniter框架的使用感受和注意事项
codeigniter是一个轻量级的php的web框架,今年2月22日,正式发布了4.0版本.简称CI框架 先使用了CI的3.15版,基本上是不用安装,把框架文件放到web目录下,让后通过简单的配置, ...
- Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用
一.前言 上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权 ...
- SpringMVC框架——视图解析
SpringMVC视图解析,就是将业务数据绑定给JSP域对象,并在客户端进行显示. 域对象: pageContext.request.session.application 业务数据绑定是有ViewR ...
- Fast and accurate bacterial species identification in urine specimens using LC-MS/MS mass spectrometry and machine learning (解读人:闫克强)
文献名:Fast and accurate bacterial species identification in urine specimens using LC-MS/MS mass spectr ...