Odometer forwarding - Blueye SDK

Skip to content

# Odometer to Imagenex 831L Publisher

This example shows how one can use the blueye.sdk to forward the odometer distance from the position messages from the drone to the PipeSonarL software from Imagenex. The PipeSonarL software is used to operate the Imagenex 831L Pipe Profiling sonar.

The PipeSonarL software accepts input from external cable counting systems, which is used to generate a 3D point cloud from a pipe inspection.

On a Blueye X3, we can use the odometer distance from the position messages to generate the cable count for the PipeSonarL software. The odometer distance is the distance the drone has traveled since the last reset.

The script performs the following steps:

1. UDP Configuration: Sets up the UDP IP and port for sending NMEA messages. If your receiver expects to receive data on a different port, you need to change it here.
2. Increase publishing frequency: Increases the publishing frequency of the position estimate message to 5 Hz.
3. Drone Connection: Establishes a connection to the Blueye drone.
4. Callback Registration: Registers a callback function to handle position estimate telemetry messages.
5. Main Loop: Keeps the script running to continuously receive and send messages.

    """publish_odometer_to_831l.py

    This example program demonstrates how to publish the drone's odometer as a cable counter
    to the PipeSonarL software used to operate the Imagenex 831L Pipe Profiling Sonar.
    """

    import socket
    import time

    import blueye.protocol as bp

    from blueye.sdk import Drone

    def callback_position_estimate(
        msg_type: str, msg: bp.PositionEstimateTel, udp_socket: socket.socket
    ):
        """Callback for the PositionEstimateTel message."""
        odometer = msg.position_estimate.odometer * 1000  # Convert to mm
        formatted_message = f"{{,#CABLE,{odometer},mm,}}\r\n"

        udp_socket.sendto(formatted_message.encode("ascii"), (UDP_IP, UDP_PORT))
        print(f"Sent: {formatted_message.strip()}")

    if __name__ == "__main__":
        # UDP configuration
        # This IP will broadcast to all devices in the 192.168.1 subnet
        UDP_IP = "192.168.1.255"

        # 1261 is the default UDP port used by the PipeSonarL software.
        UDP_PORT = 1261

        udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)  # Enable broadcasting

        # Instantiate a drone object and connect to the drone
        try:
            print("Connecting to the drone...")
            my_drone = Drone(connect_as_observer=True)
        except ConnectionError:
            print("Could not connect to the drone.")
            exit(1)
        finally:
            print("Connected to the drone.")

        # Increase publishing frequenzy for the PositionEstimateTel message
        my_drone.telemetry.set_msg_publish_frequency(bp.PositionEstimateTel, 5)

        # Add a callback for the PositionEstimateTel message
        my_drone.telemetry.add_msg_callback(
            [bp.PositionEstimateTel], callback_position_estimate, udp_socket=udp_socket
        )

        # Keep the script running to receive and send messages
        try:
            print("Press Ctrl+C to exit.")
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            print("Exiting...")
        finally:
            # Cleanup
            my_drone.disconnect()
            udp_socket.close()