3.4AP_HAL::RCInput and AP_HAL::RCOutput

来源:互联网 发布:海南大学网络登录入口 编辑:程序博客网 时间:2024/06/03 16:51

前言

 前面梳理了AP_HAL的硬件抽象层,包括串口、调度器、I2C等等,这次涉及到增加电机的输出口,所以有必要RC的输入输出的框架梳理一遍

AP_HAL::RCInput

 这里是对RCinput进行了抽象,具体的实现我们参看AP_HAL_PX4下的RCInput.cpp的实现
#define RC_INPUT_MIN_PULSEWIDTH 900#define RC_INPUT_MAX_PULSEWIDTH 2100class AP_HAL::RCInput {public:  /**  * Call init from the platform hal instance init, so that both the type of  * the RCInput implementation and init argument (e.g. ISRRegistry) are  * known to the programmer. (It's too difficult to describe this dependency  * in the C++ type system.)  */  virtual void init() = 0;// 初始化订阅 orb_subscribe(ORB_ID(input_rc))消息  virtual void teardown() {};  /**  * Return true if there has been new input since the last call to new_input()  * 通过_rcin.timestamp_last_signal来判断是否有新的数值更新上来  */  virtual bool new_input(void) = 0;  /**  * Return the number of valid channels in the last read  * 返回_rcin.channel_count的通道数目  */  virtual uint8_t num_channels() = 0;  /* Read a single channel at a time */优先返回 _override[ch]的值,没有的情况下返回_rcin.values[ch]的值  virtual uint16_t read(uint8_t ch) = 0;  /* Read an array of channels, return the valid count */从_rcin.values[ch]中读取len个channel的值  virtual uint8_t read(uint16_t* periods, uint8_t len) = 0;  /**  * Overrides: these are really grody and don't belong here but we need  * them at the moment to make the port work.  * case v of:  * v == -1 -> no change to this channel  * v == 0 -> do not override this channel  * v > 0 -> set v as override.  * 在实现上_override[ch]这个数组是和_rcin.values[ch]等价的,区别就是在read优先读取_override[ch]的值  */这个override我在使用mavros的时候用到过,主要是实现代替遥控RC信号输入  /* set_overrides: array starts at ch 0, for len channels */设置len个_override数组元素的值  virtual bool set_overrides(int16_t *overrides, uint8_t len) = 0;  /* set_override: set just a specific channel */设置单个通道的数值  virtual bool set_override(uint8_t channel, int16_t override) = 0;  /* clear_overrides: equivalent to setting all overrides to 0 */将整个_override[ch]的数值清零  virtual void clear_overrides() = 0;  /* execute receiver bind */绑定接收信号类型  virtual bool rc_bind(int dsmMode) { return false; }};

所以从AP_HA::RCInput上来看,实现上还是依赖了ORB_ID(input_rc)传来的数值,是延续使用了PX4的驱动的,就自身而言实现了原本的RC信号的获取的同时,新增加了override的功能进来;

AP_HAL::RCOutput

 对于AP_HAL::RCInput来说也是一样,我们开始分析;
#define RC_OUTPUT_MIN_PULSEWIDTH 400#define RC_OUTPUT_MAX_PULSEWIDTH 2100/* Define the CH_n names, indexed from 1, if we don't have them already */#ifndef CH_1#define CH_1 0#define CH_2 1#define CH_3 2#define CH_4 3#define CH_5 4#define CH_6 5#define CH_7 6#define CH_8 7#define CH_9 8#define CH_10 9#define CH_11 10#define CH_12 11#define CH_13 12#define CH_14 13#define CH_15 14#define CH_16 15#define CH_17 16#define CH_18 17#define CH_NONE 255#endifclass AP_HAL::RCOutput {public:  virtual void init() = 0;  /* Output freq (1/period) control */通过ioctrol对"/dev/pwm_outputX"进行模式设置  virtual void set_freq(uint32_t chmask, uint16_t freq_hz) = 0;  virtual uint16_t get_freq(uint8_t ch) = 0;  /* Output active/highZ control, either by single channel at a time  * or a mask of channels */通过设置掩码,实现对通道的使能和失能  virtual void enable_ch(uint8_t ch) = 0;  virtual void disable_ch(uint8_t ch) = 0;  /*  * Output a single channel, possibly grouped with previous writes if  * cork() has been called before.把period_us写入到_period[ch]中,等待更新  */  virtual void write(uint8_t ch, uint16_t period_us) = 0;  /*  * Delay subsequent calls to write() going to the underlying hardware in  * order to group related writes together. When all the needed writes are  * done, call push() to commit the changes.  */  virtual void cork() = 0;  /*  * Push pending changes to the underlying hardware. All changes between a  * call to cork() and push() are pushed together in a single transaction.  */将更新后的_period[ch]通过write"/dev/pwm_outputX"设备中  virtual void push() = 0;  /* Read back current output state, as either single channel or  * array of channels. On boards that have a separate IO controller,  * this returns the latest output value that the IO controller has  * reported */读取px4io发送过来的通道值,如果没有使用上一次接收的值  virtual uint16_t read(uint8_t ch) = 0;  virtual void read(uint16_t* period_us, uint8_t len) = 0;  /* Read the current input state. This returns the last value that was written. */  virtual uint16_t read_last_sent(uint8_t ch) { return read(ch); }  virtual void read_last_sent(uint16_t* period_us, uint8_t len) { read(period_us, len); };  /*  set PWM to send to a set of channels when the safety switch is  in the safe state  */读取上一次的值就是存在_period[ch]里的值  virtual void set_safety_pwm(uint32_t chmask, uint16_t period_us) {}  /*  set PWM to send to a set of channels if the FMU firmware dies  */设置安全PWM值并直接ioctrol给device  virtual void set_failsafe_pwm(uint32_t chmask, uint16_t period_us) {}  /*  force the safety switch on, disabling PWM output from the IO board  return false (indicating failure) by default so that boards with no safety switch  do not need to implement this method  */设置_safety_state_request为AP_HAL::Util::SAFETY_DISARMED  virtual bool force_safety_on(void) { return false; }  /*  force the safety switch off, enabling PWM output from the IO board  */设置_safety_state_request为AP_HAL::Util::SAFETY_ARMED  virtual void force_safety_off(void) {}  /*  If we support async sends (px4), this will force it to be serviced immediately  */检查是否有一个待处理的saftey_state更改。并立即处理  virtual void force_safety_no_wait(void) {}  /*  setup scaling of ESC output for ESCs that can output a  percentage of power (such as UAVCAN ESCs). The values are in  microseconds, and represent minimum and maximum PWM values which  will be used to convert channel writes into a percentage  */貌似没有实现  virtual void set_esc_scaling(uint16_t min_pwm, uint16_t max_pwm) {}  /*  enable SBUS out at the given rate,使能S.BUS输出,并按照rate_gz频率  */  virtual bool enable_sbus_out(uint16_t rate_gz) { return false; }  /*  * Optional method to control the update of the motors. Derived classes  * can implement it if their HAL layer requires.  */周期执行电机输出指令  virtual void timer_tick(void) { }  /*  output modes. Allows for support of oneshot  */电机输出的信号模式,ioctrol时候会用到  enum output_mode {  MODE_PWM_NORMAL,  MODE_PWM_ONESHOT,  MODE_PWM_BRUSHED16KHZ  };  virtual void set_output_mode(enum output_mode mode) {}};

在AP_HAL::RCOutput的实现上,主要是依赖了”/dev/pwm_outputX”这个设备,通过ioctrol、write等口实现了pwm输出模式和频率的设置,同时还有通道使能和sbus输出等功能;

总结

 在AP_HAL::RCOutput和AP_HAL::RCInput的是实现上,APM还是沿用了PX4基于Nuttx的驱动来对抽象层的实现, AP_HAL::RCInput:通过urb来获取新的通道值,这个值是通过px4io发出的; AP_HAL::RCOutput:通过对/dev/pwm_outputX的设备的操作来实现PWM值的下发,我猜想这个设备最后还是会px4io相关;
原创粉丝点击