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细节的更多相关文章

  1. PX4/PixHawk无人机飞控应用开发

    最近做的一个国防背景的field UAV项目,细节不能多谈,简单写点技术体会. 1.PX4/Pixhawk飞控软件架构简介 PX4是目前最流行的开源飞控板之一.PX4的软件系统实际上就是一个firmw ...

  2. 【30集iCore3_ADP出厂源代码(ARM部分)讲解视频】30-3 底层驱动之LED_蜂鸣器

    视频简介: 该视频介绍iCore3应用开发平台出厂源代码中GPIO的配置方法 及如何点亮LED和驱动蜂鸣器发声. 源视频包下载地址: http://pan.baidu.com/s/1nvpYMff   ...

  3. Android深度探索--HAL与驱动开发----第八章读书笔记

    通过蜂鸣器的实现原理,实现一个完整的蜂呜器驱动,可以打开和关闭蜂鸣器. PWM驱动的实现方式不同于LED驱动, PWM 驱动将由多个文件组成.这也是大多数 Linux 驱动的标准实现方式. 刚开始是L ...

  4. 2440裸机驱动之PWM开发

    原文http://blog.chinaunix.net/uid-14114479-id-3125685.html ARM驱动蜂鸣器的方式有两种:一种是PWM输出口直接驱动,另一种是利用IO定时翻转电平 ...

  5. STM32开发指南-蜂鸣器实验

    另一种I/O作为输出的应用,利用一个I/O来控制板载的有源蜂鸣器,实现蜂鸣器控制. PS:有源蜂鸣器自带了震荡电路,一通电就会发声:无源蜂鸣器则没有自带震荡电路,必须外部提供2~5Khz左右的方波驱动 ...

  6. 基于ARM-contexA9-蜂鸣器pwm驱动开发

    上次,我们写过一个蜂鸣器叫的程序,但是那个程序仅仅只是驱动蜂鸣器,用电平1和0来驱动而已,跟驱动LED其实没什么两样.我们先来回顾一下蜂鸣器的硬件还有相关的寄存器吧: 还是和以前一样的步骤: 1.看电 ...

  7. Linux ALSA声卡驱动之一:ALSA架构简介

    声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢! 一.  概述 ALSA是Advanced Linux Sound Architecture ...

  8. linux学习--字符设备驱动

    目录 1.字符设备驱动抽象结构 2.设备号及设备节点 2.1 设备号分配与管理 2.2 设备节点的生成 3.打开设备文件 linux驱动有基本的接口进行注册和卸载,这里不再做详细说明,本文主要关注li ...

  9. Linux&nbsp;ALSA声卡驱动之一:ALS…

    声明:本博内容均由http://blog.csdn.net/droidphone原创,转载请注明出处,谢谢! 一.  概述 ALSA是Advanced Linux Sound Architecture ...

随机推荐

  1. 小程序自定义switch组件

    如上图,小程序api中的switch组件只能自定义颜色,不能自定义宽高,所以就开始了自己写switch组件. 自定义组件样式 switch组件样式大致如图,样式思路:未选中时为一个长方形有圆角按钮,和 ...

  2. 在浏览器中使用ES6的模块功能 import 及 export

    感谢英文原作者 Jake Archibald 的技术分享 各个浏览器对于ES6模块 import . export的支持情况 Safari 10.1. Chrome 61. Firefox 54 – ...

  3. Nginx + uWSGI部署中的一些小坑

    1.invalid host in upstream报错 重新启动nginx : sudo /etc/init.d/nginx restart 原因是在配置负载均衡nginx.conf配置文件时,发现 ...

  4. Java 抽象类 抽象方法 使用说明

    知识点 什么是抽象类 抽象类与普通类主要两点不同: 1.在类的修饰符后面多了一个abstract关键字 2.抽象类是不允许通过new来实例化的 由于抽象类不能通过new来实例化,所以基本上是在继承中当 ...

  5. vue的插件使用

    插件通常是为Vue添加全局功能,vue的官网介绍了5中添加插件的方法. vue的插件有个公开方法install.第一个参数是Vue构造器,第二个参数是一个可选的选项对象. 在plugin.js中可以这 ...

  6. Flutter的盒子约束

    由Expanded widget引发的思考 设计稿如下 布局widget分解 很常见的一种布局方式:Column的子widget中包含ListView @override Widget build(B ...

  7. codeigniter框架的使用感受和注意事项

    codeigniter是一个轻量级的php的web框架,今年2月22日,正式发布了4.0版本.简称CI框架 先使用了CI的3.15版,基本上是不用安装,把框架文件放到web目录下,让后通过简单的配置, ...

  8. Asp.Net Core 中IdentityServer4 授权原理及刷新Token的应用

    一.前言 上面分享了IdentityServer4 两篇系列文章,核心主题主要是密码授权模式及自定义授权模式,但是仅仅是分享了这两种模式的使用,这篇文章进一步来分享IdentityServer4的授权 ...

  9. SpringMVC框架——视图解析

    SpringMVC视图解析,就是将业务数据绑定给JSP域对象,并在客户端进行显示. 域对象: pageContext.request.session.application 业务数据绑定是有ViewR ...

  10. 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 ...