PX4 REJECT_POSITION_CTRL 源碼部分分析

  • 飛機基本狀態的定義在vehicle_status.msg

    uint8 MAIN_STATE_MANUAL = 0
    uint8 MAIN_STATE_ALTCTL = 1
    uint8 MAIN_STATE_POSCTL = 2
    uint8 MAIN_STATE_AUTO_MISSION = 3
    uint8 MAIN_STATE_AUTO_LOITER = 4
    uint8 MAIN_STATE_AUTO_RTL = 5
    uint8 MAIN_STATE_ACRO = 6
    uint8 MAIN_STATE_OFFBOARD = 7
    uint8 MAIN_STATE_STAB = 8
    uint8 MAIN_STATE_RATTITUDE = 9
    uint8 MAIN_STATE_AUTO_TAKEOFF = 10
    uint8 MAIN_STATE_AUTO_LAND = 11
    uint8 MAIN_STATE_MAX = 12
    
  • state_machine_helper.cpp 描述允許狀態轉換的條件

    ....
    case vehicle_status_s::MAIN_STATE_POSCTL:
          /* need at minimum local position estimate */
          // 也就是只要 Local 或 Global 其中一個定位有效,即可切換 POSCTL
          if (status->condition_local_position_valid ||
              status->condition_global_position_valid) {
              ret = TRANSITION_CHANGED;
          }
          break;
    ....
    
    • status->condition_global_position_valid 的判斷在commander.cpp

      主要是看GPS的時間更新是否有效

      ...
      //update condition_global_position_valid
              //Global positions are only published by the estimators if they are valid
      if (hrt_absolute_time() - global_position.timestamp > POSITION_TIMEOUT) {
        //We have had no good fix for POSITION_TIMEOUT amount of time
        if (status.condition_global_position_valid) {
          set_tune_override(TONE_GPS_WARNING_TUNE);
          status_changed = true;
          status.condition_global_position_valid = false;
        }
      } else if (global_position.timestamp != 0) {
        // Got good global position estimate
        if (!status.condition_global_position_valid) {
          status_changed = true;
          status.condition_global_position_valid = true;
        }
      }
      ...
      
    • status->condition_local_position_validcommander.cpp

      /* update condition_local_position_valid and condition_local_altitude_valid */
      /* hysteresis for EPH */
      bool local_eph_good;
      
      // 無論當前 condition_local_position_valid 是否有效,都有判斷 local_position.eph 的大小
      if (status.condition_local_position_valid) {
        if (local_position.eph > eph_threshold * 2.5f) {
          local_eph_good = false;
        } else {
          local_eph_good = true;
        }
      
      } else {
        if (local_position.eph < eph_threshold) {
          local_eph_good = true;
      
        } else {
          local_eph_good = false;
        }
      }
      
      // 根據上述判斷結果,對 condition_local_position_valid 進行更新
      check_valid(local_position.timestamp, POSITION_TIMEOUT, local_position.xy_valid && local_eph_good, &(status.condition_local_position_valid), &status_changed);
      

      ?

      void check_valid(hrt_abstime timestamp, hrt_abstime timeout, bool valid_in, bool *valid_out, bool *changed)
      // timestamp = local_position.timestamp
      // timeout = POSITION_TIMEOUT
      // valid_in = local_position.xy_valid && local_eph_good  判斷位置精度是否滿足
      // valid_out = &(status.condition_local_position_valid)
      // changed = &status_changed
      {
          hrt_abstime t = hrt_absolute_time();
          bool valid_new = (t < timestamp + timeout && t > timeout && valid_in);  // 判斷是否超時 和 xy_valid 與 local_eph_good 是否同時有效
          if (*valid_out != valid_new) {
              *valid_out = valid_new;   // 對 condition_local_position_valid 進行賦值 = true
              *changed = true;   // 對 status_changed 進行賦值
          }
      }
      

      ?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容