Hello all,
So, I’ve coded up an extremely simple C++ MAVLink command emitter, that sends heartbeats and command_long messages over UDP (driving a gimbal from a custom Windows-based ground element.) The receiving end is a Raspberry Pi Zero, running Ser2Net to bridge the hardware serial port to the UDP socket. I’ve got an Orange Cube, running Arducopter 4.3.3 (admittedly, a little out-of-date). So far, this all works quite well, the AP responds as expected, and connecting via Mission Planner over USB, I can see the expected traffic on the MAVLink Inspector.
However, I’m trying to add Set_Position_Target_Local_NED commands, and this has gone extremely poorly - the messages wouldn’t show up in MAVLink Inspector, but doing some packet sniffing on the RPi serial port, and manually decoding the resulting hex dumps via the Mission Planner utility, and correlating them back to different inputs, I found that if the coordinate frame parameter is non-zero, the packet will consistently fail to decode (“NULL”), whereas an otherwise-invalid coordinate frame value of 0 will always produce readable hex dumps (and the messages appear in MAVLink Inspector). Interestingly, I’ve also found this is the case for Set_Position_Target_Global_Int.
I feel like I’m missing something absurdly obvious - any suggestions would be greatly appreciated. I’ve attached the Set_Position and UDP sender functions below.
Thanks!
Regards,
-Luke
int sendSetPositionLocalVelocity(float vx, float vy, float vz, float yaw_rate)
{
int bytes_sent;
mavlink_message_t mavlink_message_vel;mavlink_set_position_target_local_ned_t set_vel_local = { 0 };
set_vel_local.time_boot_ms = currentTime();
set_vel_local.target_system = 0;
//Pack the message
set_vel_local.target_component = 0;
set_vel_local.coordinate_frame = 9; //Also tried MAV_FRAME_BODY_OFFSET_NED
set_vel_local.type_mask = 1497; //Velocity + yaw rate (see below)
set_vel_local.x = 0;
set_vel_local.y = 0;
set_vel_local.z = 0;
set_vel_local.vx = vx;
set_vel_local.vy = vy;
set_vel_local.vz = vz;
set_vel_local.afx = 0;
set_vel_local.afy = 0;
set_vel_local.afz = 0;
set_vel_local.yaw = 0;
set_vel_local.yaw_rate = yaw_rate;//Bitmask (0 = do not ignore, 1 = ignore)
//bit12:yaw rate, bit11:yaw, bit10: FZ vs AccZ, bit9:AccZ, bit8:AccY, bit7:AccX, bit6:VelZ, bit5:VelY, bit4:VelX, bit3:PosZ, bit2:PosY, bit1:PosX
//For velocity control with yaw rate: 010111000111 → 1479mavlink_msg_set_position_target_local_ned_encode(SOURCE_SYSID, SOURCE_COMPID, &mavlink_message_vel, &set_vel_local); //Encode message for transmission
bytes_sent = sendUDP(mavlink_message_vel); //Send over UDP socketreturn bytes_sent;
}
int sendUDP(const mavlink_message_t& message)
{
char mavlink_buffer[300]; //Buffer to send
unsigned length; //Length of message in the buffer
int length_sent; //Length of message actually sentlength = mavlink_msg_to_send_buffer((uint8_t*)mavlink_buffer, &message);
//Convert to character buffer for serial transmission
length_sent = sendto(socket_udp, mavlink_buffer, length, 0, (struct sockaddr*)&udp_socket_add, sizeof(udp_socket_add));
//Send the message over the socket, to the specified addressreturn length_sent; //Return the message length sent
}