Linking a custom simulator in Python to a PX4 SITL?


We would like to link some own simulator (an alternative to jsbsim written in Python) with a PX4 SITL.

According to the PX4’s doc, the way to start a standalone PX4 SITL is like this:

$ make px4_sitl none_iris

(with “iris” to be adapted according to the situation)

After being launched the terminal indicates the simulator must connect to a TCP port:

  PWM_MIN: curr: 1000 -> new: 1075
  GPS_UBX_DYNMODEL: curr: 7 -> new: 6
* SYS_AUTOCONFIG: curr: 1 -> new: 0
INFO  [dataman] Unknown restart, data manager file './dataman' size is 11798680 bytes
INFO  [simulator] Waiting for simulator to accept connection on TCP port 4560

In Python then, I connect to the port with pymavlink:

from pymavlink import mavutil
vehicle = mavutil.mavlink_connection('tcpin:localhost:4560')
print("Heartbeat from system (system %u component %u)" % (vehicle.target_system, vehicle.target_component))

The connection works and the terminal indicates:

INFO  [simulator] Simulator connected on TCP port 4560.

But then it gets stuck there.

Logically the PX4 should also open a UDP port so that it can be monitored. For example, when using an existing simulator like flightgear with make px4_sitl_nolockstep flightgear_rascal I can connect to the UDP port without issue and monitor the drone attitude.

In the doc (Simulation | PX4 User Guide) it’s said the simulator must send MAVLink messages as HIL_SENSOR or HIL_GPS and receive HIL_ACTUATOR_CONTROLS from the PX4. Always with pymavlink I send all the defined messages, eg:

# Send HIL_GPS

    time_usec           = 1636636640    , # Timestamp (UNIX Epoch time or time since system boot). The receiving end can infer timestamp format (since 1.1.1970 or since system boot) by checking for the magnitude of the number. [us] (type:uint64_t)
    fix_type            = 0             , # 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix. (type:uint8_t)
    lat                 = 40            , # Latitude (WGS84) [degE7] (type:int32_t)
    lon                 = 17            , # Longitude (WGS84) [degE7] (type:int32_t)
    alt                 = 0             , # Altitude (MSL). Positive for up. [mm] (type:int32_t)
    eph                 = 0             , # GPS HDOP horizontal dilution of position (unitless). If unknown, set to: UINT16_MAX (type:uint16_t)
    epv                 = 0             , # GPS VDOP vertical dilution of position (unitless). If unknown, set to: UINT16_MAX (type:uint16_t)
    vel                 = 0             , # GPS ground speed. If unknown, set to: 65535 [cm/s] (type:uint16_t)
    vn                  = 0             , # GPS velocity in north direction in earth-fixed NED frame [cm/s] (type:int16_t)
    ve                  = 0             , # GPS velocity in east direction in earth-fixed NED frame [cm/s] (type:int16_t)
    vd                  = 0             , # GPS velocity in down direction in earth-fixed NED frame [cm/s] (type:int16_t)
    cog                 = 65535         , # Course over ground (NOT heading, but direction of movement), 0.0..359.99 degrees. If unknown, set to: 65535 [cdeg] (type:uint16_t)
    satellites_visible  = 0             , # Number of satellites visible. If unknown, set to 255 (type:uint8_t)
    id                  = 0             , # GPS ID (zero indexed). Used for multiple GPS inputs (type:uint8_t)
    yaw                 = 36000         , # Yaw of vehicle relative to Earth's North, zero means not available, use 36000 for north [cdeg] (type:uint16_t)

but the TCP connection doesn’t receive any HIL_ACTUATOR_CONTROLS message.


  • After the simulator connects to the TCP port, nothing happens, even if needed MAVLink messages are sent from the simulator through this connection.
  • The UDP port is not opened.

Please, how to make it work?..

Thanks for the support :slight_smile: