MAVLink distance_sensor Message Not Reaching PX4 from iOS (UDP), Works on macOS

9 views
Skip to first unread message

Emirhan Çelik

unread,
Feb 9, 2025, 2:18:10 PMFeb 9
to MAVLink

Question:
I'm trying to send a MAVLink distance_sensor message to PX4 from both macOS (via a wired connection) and iOS (via a Wi-Fi connection). On macOS, the message works perfectly, but on iOS, the distance_sensor message does not reach PX4 at all. Interestingly, heartbeat messages work fine on both platforms.

Here's the full breakdown:

  1. macOS (Wired Connection): Both heartbeat and distance_sensor messages are received by PX4 without any issues.
  2. iOS (Wi-Fi Connection): heartbeat messages are received by PX4, but the distance_sensor message never arrives.
macOS Code (Works Perfectly)

private func sendDistanceMessage() {
    guard let port = serialPort, port.isOpen else { return }

    var message = mavlink_message_t()
    var distance_sensor = mavlink_distance_sensor_t()

    distance_sensor.min_distance = 0       // Min range in cm
    distance_sensor.max_distance = 1000    // Max range in cm
    distance_sensor.current_distance = 13  // Fixed value for testing
    distance_sensor.type = UInt8(MAV_DISTANCE_SENSOR_LASER.rawValue)
    distance_sensor.id = 132
    distance_sensor.orientation = UInt8(MAV_SENSOR_ROTATION_NONE.rawValue)
    distance_sensor.covariance = 0
    distance_sensor.time_boot_ms = 0       // Set timestamp to 0 for testing

    mavlink_msg_distance_sensor_encode(1, 132, &message, &distance_sensor)

    var buffer = [UInt8](repeating: 0, count: Int(MAVLINK_MAX_PACKET_LEN))
    let length = mavlink_msg_to_send_buffer(&buffer, &message)

    let data = Data(bytes: buffer, count: Int(length))
    port.send(data)
}


iOS Code (Fails to Reach PX4)

func sendDistanceMessage(distance: Float) {
    var message = mavlink_message_t()
    var distance = mavlink_distance_sensor_t()
    distance.current_distance = UInt16(13 * 100) // distance in cm
    distance.min_distance = 0
    distance.max_distance = 1000
    distance.type = UInt8(MAV_DISTANCE_SENSOR_ULTRASOUND.rawValue)
    distance.id = 132
    distance.time_boot_ms = 0  // Timestamp set to 0 for testing

    mavlink_msg_distance_sensor_encode(1, 1, &message, &distance)

    var buffer = [UInt8](repeating: 0, count: Int(MAVLINK_MAX_PACKET_LEN))
    let len = mavlink_msg_to_send_buffer(&buffer, &message)

    var srcAddr = sockaddr_in()
    srcAddr.sin_family = sa_family_t(AF_INET)
    srcAddr.sin_port = in_port_t(14550).bigEndian // PX4 listening port
    srcAddr.sin_addr.s_addr = inet_addr("0.0.0.0")

    var sendAddr = srcAddr
    let ret = withUnsafePointer(to: &sendAddr) { pointer in
        pointer.withMemoryRebound(to: sockaddr.self, capacity: 1) { sockaddrPointer in
            sendto(socketFD, buffer, Int(len), 0, sockaddrPointer, socklen_t(MemoryLayout.size(ofValue: srcAddr)))
        }
    }

    if ret != len {
        delegate?.didReceiveStatusUpdate("Distance send error: \(String(cString: strerror(errno)))")
    } else {
        print("Distance message sent: \(distance) meters")
        delegate?.didReceiveStatusUpdate("Distance message sent successfully")
    }
}


Heartbeat Message (Works Fine on Both iOS and macOS)


private func sendHeartbeat() {
    var message = mavlink_message_t()
    var heartbeat = mavlink_heartbeat_t()

    heartbeat.type = UInt8(MAV_TYPE_GCS.rawValue)
    heartbeat.autopilot = UInt8(MAV_AUTOPILOT_INVALID.rawValue)
    heartbeat.base_mode = 0
    heartbeat.custom_mode = 0
    heartbeat.system_status = UInt8(MAV_STATE_ACTIVE.rawValue)

    mavlink_msg_heartbeat_encode(1, 1, &message, &heartbeat)

    var buffer = [UInt8](repeating: 0, count: Int(MAVLINK_MAX_PACKET_LEN))
    let len = mavlink_msg_to_send_buffer(&buffer, &message)

    var srcAddr = sockaddr_in()
    srcAddr.sin_family = sa_family_t(AF_INET)
    srcAddr.sin_port = in_port_t(14550).bigEndian
    srcAddr.sin_addr.s_addr = inet_addr("0.0.0.0")

    var sendAddr = srcAddr
    let ret = withUnsafePointer(to: &sendAddr) { pointer in
        pointer.withMemoryRebound(to: sockaddr.self, capacity: 1) { sockaddrPointer in
            sendto(socketFD, buffer, Int(len), 0, sockaddrPointer, socklen_t(MemoryLayout.size(ofValue: srcAddr)))
        }
    }

    if ret != len {
        delegate?.didReceiveStatusUpdate("Send error: \(String(cString: strerror(errno)))")
    }
}



Additional Notes:
  • Both heartbeat and distance_sensor messages use the same socket (socketFD) and address (inet_addr("0.0.0.0")).
  • The distance_sensor message has time_boot_ms set to 0 for testing purposes.
  • PX4 is listening on UDP port 14550.
  • Everything works perfectly on macOS with the same logic.
My Question:

Why does the distance_sensor message fail to reach PX4 on iOS, even though it works on macOS and the heartbeatmessage works on both? What could be causing this, and how can I resolve it?

Hamish Willee

unread,
Feb 11, 2025, 6:36:13 PMFeb 11
to MAVLink
I can see what you tried to do here - copy the structure of the distance sender into the heartbeat message, and you're wondering why it doesn't work.
The short answer is that I don't know - but it isn't a MAVLink question, its a networking question. What error do you get back?

Do you run the heartbeat and (problem) distance code in the same program? If so, could you be hogging the socket with the first call? Try doing the distance sensor first and seeing if that is now sent.

Otherwise I am at a loss. Suggest you add to the to the discuss server showing the two simplest cases as similar as you can (i.e. just the heartbeat and the distance sensor code).
Reply all
Reply to author
Forward
0 new messages