csi_leon 2024-03-20 18:11 采纳率: 25%
浏览 49

mavlink 如何修改battery_status?

设定:用cube Orange设定电源,并使用rp2040-zero读取电池的状态
已成功: 可以顺利使用mavlink读取电池的值
待测试:无法修改battery_status内的battery_remaining

#include <Arduino.h>
#include <MAVLink_cubepilot.h>

// Define serial port for communication with Cube Orange
#define CUBE_SERIAL Serial1

void setup() {
  Serial.begin(57600); // Initialize serial for debugging
  Serial1.setRX(13);
  Serial1.setTX(12);
  CUBE_SERIAL.begin(57600); // Initialize serial for communication with Cube Orange
  
}

void loop() {
  // Check if data is available on Cube Orange serial port
  
  if (CUBE_SERIAL.available()) {
    
    mavlink_message_t msg;
    mavlink_status_t status;
    request_datastream();
    // Parse incoming MAVLink messages
    while (CUBE_SERIAL.available() > 0) {
      uint8_t c = CUBE_SERIAL.read();
      
      // Try to parse the message
      if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)) {
        // Message successfully parsed, handle the message here
        handle_mavlink_message(&msg);
      }
    }
  }
}

void request_datastream() {
//Request Data from Pixhawk
  uint8_t _system_id = 255; // id of computer which is sending the command (ground control software has id of 255)
  uint8_t _component_id = 2; // seems like it can be any # except the number of what Pixhawk sys_id is
  uint8_t _target_system = 1; // Id # of Pixhawk (should be 1)
  uint8_t _target_component = 0; // Target component, 0 = all (seems to work with 0 or 1
  uint8_t _req_stream_id = MAV_DATA_STREAM_ALL;
  uint16_t _req_message_rate = 0x0F; //number of times per second to request the data in hex
  uint8_t _start_stop = 1; //1 = start, 0 = stop
 
// STREAMS that can be requested
  /*
   * Definitions are in common.h: enum MAV_DATA_STREAM and more importantly at:
     https://mavlink.io/en/messages/common.html#MAV_DATA_STREAM
   *   
   * MAV_DATA_STREAM_ALL=0, // Enable all data streams
   * MAV_DATA_STREAM_RAW_SENSORS=1, /* Enable IMU_RAW, GPS_RAW, GPS_STATUS packets.
   * MAV_DATA_STREAM_EXTENDED_STATUS=2, /* Enable GPS_STATUS, CONTROL_STATUS, AUX_STATUS
   * MAV_DATA_STREAM_RC_CHANNELS=3, /* Enable RC_CHANNELS_SCALED, RC_CHANNELS_RAW, SERVO_OUTPUT_RAW
   * MAV_DATA_STREAM_RAW_CONTROLLER=4, /* Enable ATTITUDE_CONTROLLER_OUTPUT, POSITION_CONTROLLER_OUTPUT, NAV_CONTROLLER_OUTPUT.
   * MAV_DATA_STREAM_POSITION=6, /* Enable LOCAL_POSITION, GLOBAL_POSITION/GLOBAL_POSITION_INT messages.
   * MAV_DATA_STREAM_EXTRA1=10, /* Dependent on the autopilot
   * MAV_DATA_STREAM_EXTRA2=11, /* Dependent on the autopilot
   * MAV_DATA_STREAM_EXTRA3=12, /* Dependent on the autopilot
   * MAV_DATA_STREAM_ENUM_END=13,
   * 
   * Data in PixHawk available in:
   *  - Battery, amperage and voltage (SYS_STATUS) in MAV_DATA_STREAM_EXTENDED_STATUS
   *  - Gyro info (IMU_SCALED) in MAV_DATA_STREAM_EXTRA1
   */
 
  // Initialize the required buffers
  mavlink_message_t msg;
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];
 
  // Pack the message
  mavlink_msg_request_data_stream_pack(_system_id, _component_id, &msg, _target_system, _target_component, _req_stream_id, _req_message_rate, _start_stop);
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);  // Send the message (.write sends as bytes)
 
  Serial1.write(buf, len); //Write data to serial port
}


// Function to handle received MAVLink messages
void handle_mavlink_message(mavlink_message_t *msg) {
  switch (msg->msgid) {
     
    case MAVLINK_MSG_ID_BATTERY_STATUS:{
      mavlink_battery_status_t battery_status;
            mavlink_msg_battery_status_decode(msg, &battery_status);

            // Read battery voltage of cell 1 (index 0 in voltages array)
            float battery_voltage_cell1 = battery_status.voltages[0] / 1000.0f; // Convert millivolts to volts
            Serial.print("battery remaining:");
            Serial.println(battery_status.battery_remaining);
            
            Serial.print("Battery Voltage (Cell 1): ");
            Serial.print(battery_voltage_cell1);
            Serial.println(" V");


            
            battery_status.battery_remaining = 50;
            mavlink_send_battery_status(battery_status);

            break;
    }
    case MAVLINK_MSG_ID_HEARTBEAT: {
      mavlink_heartbeat_t hb;
      mavlink_msg_heartbeat_decode(msg, &hb);
      
      // Handle HEARTBEAT message
      Serial.println("Received HEARTBEAT type:");
      
      break;
    }
    // Add cases for other message types you want to handle
    // case MAVLINK_MSG_ID_OTHER_MESSAGE:
    //   // Handle other message
    //   break;
    default:
      // Handle unknown message types or ignore them
      break;
  }
}
void mavlink_send_battery_status(mavlink_battery_status_t battery_status)
{
  uint8_t system_id = 255; // id of computer which is sending the command (ground control software has id of 255)
  uint8_t component_id = 0;
  mavlink_message_t msg;
  uint8_t id=battery_status.id;
  uint8_t battery_function=battery_status.battery_function;
  uint8_t type=battery_status.type;
  int16_t temperature=battery_status.temperature;
  uint16_t* voltages=battery_status.voltages;
  int16_t current_battery=battery_status.current_battery;
  int32_t current_consumed=battery_status.current_consumed;
  int32_t energy_consumed=battery_status.energy_consumed;
  int8_t battery_remaining=50;
  int32_t time_remaining=battery_status.time_remaining;
  uint8_t charge_state=battery_status.charge_state;
  uint16_t* voltages_ext=battery_status.voltages_ext;
  uint8_t mode=battery_status.mode;
  uint32_t fault_bitmask=battery_status.fault_bitmask;


  //Pack battery message
  uint8_t buf[MAVLINK_MAX_PACKET_LEN];
  mavlink_msg_battery_status_pack(system_id,component_id,&msg,id,battery_function,type,temperature,voltages,current_battery,current_consumed,energy_consumed,battery_remaining,time_remaining,charge_state,voltages_ext,mode,fault_bitmask);
  uint16_t len = mavlink_msg_to_send_buffer(buf, &msg);  // Send the message (.write sends as bytes)
 
  Serial1.write(buf, len); //Write data to serial port
  
}



  • 写回答

2条回答 默认 最新

  • 码农阿豪@新空间 新星创作者: 前端开发技术领域 2024-03-20 18:12
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    问题:在使用Cube Orange设定电源并使用rp2040-zero读取电池状态时,无法修改battery_status内的battery_remaining值,请问该如何解决? 解答:首先要明确的是,无法修改battery_status内的battery_remaining值是什么意思。battery_status是一个结构体,里面包含电池的多个状态值,其中battery_remaining表示电池的剩余电量。如果此处说的无法修改是指无法获取电池剩余电量的值,那么可以考虑检查是否有正确访问数据流的代码,或者是否正确处理mavlink消息的代码。如果此处说的无法修改是指修改值后没有生效,那么需要检查是否有正确的发送修改后的消息的代码。 以下是可能的解决方案示例:
    1. 确认是否正确读取数据流 在请求电池数据流时,需要确保请求的数据列有效,并且请求的目标系统和组件正确。下面是一个例子: uint8_t target_system = 0; // Set to 0 if requesting the data from the connected vehicle uint8_t target_component = 0; // Set to 0 for all components uint8_t req_stream_id = MAV_DATA_STREAM_EXTENDED_STATUS; // Request battery information uint16_t req_message_rate = 1; // Request data every second uint8_t start_stop = 1; // Start streaming the data // Pack the message mavlink_message_t msg; mavlink_msg_request_data_stream_pack(255, MAV_COMP_ID_ALL, &msg, target_system, target_component, req_stream_id, req_message_rate, start_stop); // Send the message uint16_t len = mavlink_msg_to_send_buffer(buf, &msg); Serial1.write(buf, len); 在收到电池数据流后,需要正确解析mavlink消息以提取battery_status结构体中的值。下面是一个例子: // Handle received MAVLink messages void handle_mavlink_message(const mavlink_message_t& msg) { switch (msg.msgid) { case MAVLINK_MSG_ID_SYS_STATUS: { mavlink_sys_status_t status; mavlink_msg_sys_status_decode(&msg, &status); Serial.print("Battery remaining: "); Serial.print(status.battery_remaining); Serial.println("%"); break; } default: break; } } 在这个例子中,我们在打印电池状态时使用了status.battery_remaining值,这个值的来源就是mavlink消息中的battery_status结构体。
    2. 确认是否正确发送修改后的消息 如果要修改电池剩余电量的值,则需要在处理mavlink消息后发送一个新的消息来更新值。下面是一个例子: // Change the battery remaining value to 80% mavlink_message_t msg; mavlink_msg_battery_status_pack(255, MAV_COMP_ID_ALL, &msg, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80); // Set battery_remaining to 80 // Send the message uint16_t len = mavlink_msg_to_send_buffer(buf, &msg); Serial1.write(buf, len); 在这个例子中,我们使用了mavlink_msg_battery_status_pack函数来创建一个新的mavlink消息,并将其中的battery_remaining设置为80。最后,我们使用Serial1.write来将消息发送给Cube Orange。注意,在发送任何消息之前,请确保有一些空闲的时间以避免数据丢失。例如,可以使用delay()来添加一个短暂的延迟。 以上是两种可能的解决方案示例。无法修改battery_status内的battery_remaining值可能有多种原因,需要根据具体情况进行排查和调试。
    评论

报告相同问题?

问题事件

  • 创建了问题 3月20日