Pymavlink.mavutil, MAVSDK-python or MAVROS

Hi guys!

So I am working on a project in which I am converting a electric offroad GoKart into an autonomous Rover. Converting this GoKart’s hardware side is already done so I only need to do the programming (and maybe some hardware tweaking). For this project I am using on the Rover:

  • The CubePilot’s Orange Cube: as flight controller
  • QGroundControl: as ground control station
  • PX4 Firmware version 1.14.0
  • Airframe type: Rover
  • Vehicle: Generic Ground Vehicle (Ackermann)
  • Jetson Nano: as companion computer

And have the following on my computer on which I am developing (same specs will be used on the companion computer):

  • Ubuntu 20:04
  • ROS2 Foxy
  • Python 3.8.10
  • PX4_sitl with gazebo-classic_rover as testing platform (gazebo11)

(If needed, I can upgrade my ubuntu, ROS2 or python but I was hoping not to.)

So I am currently using pymavlink.mavutil for communication between the cube and the companion computer, however, as can be seen with my recent posts, I have run into some troubles there. This got me questioning my methods, as I am fairly new to the whole MAVlink so I just used pymavlink.mavutil as it was the first thing I used.

The companion computer uses ROS2 to communicate to it’s sensors (stereo camera, mono camera and LiDAR), it’s own path finding calculations and then one ROS2 node is using pymavlink.mavutil to communicate with my Orange Cube. My goal is to either send local position commands or velocity commands to the Orange Cube.

This brings me to my question: What do you guys think is the best solution for my project? Sticking to pymavutil.mavlink, MAVSDK-python or MAVROS? And what are the pro’s and cons of using the different options?

Thanks in advance!

With kind regards,
Jurjen

P.S.: My apologies if this question is a bit unfit for this forum as it is not really a closed question, however, I could not find a good answer for it online for my specific goal.

Good question. As the author of MAVSDK I would usually recommend MAVSDK but if you’re already using ROS2 I’d probably make use of that directly, and use the DDS bridge:

Thanks for the reply! I have been looking into the ROS2 and PX4 communication and it looks very useful. Once again, it works in the PX4_sitl to connect to my Rover and send it towards a set position. However, when I try this on my ‘real’ OrangeCube, it is not working. I am using the following command:

sudo MicroXRCEAgent serial --dev /dev/ttyAMC0 -b 57600

And it gives me the following output:

[1713165130.135926] info | TermiosAgentLinux.cpp | init | Serial port not found.  device: /ttyAMC0, error 2, waiting for connection...

I am connecting my OrangeCube via USB to my laptop and it has a SER_TEL1_BAUD of 57600 8N1. And if I use tree /dev is see the following output:

├── serial
│   ├── by-id
│   │   └── usb-CubePilot_CubeOrange_0-if00 -> ../../ttyACM0
│   └── by-path
│       └── pci-0000:00:14.0-usb-0:2:1.0 -> ../../ttyACM0

Which confirms that the OrangeCube should be connected with ACM0.

Do you perhaps happen to know why this is happening and how to solve it? (Or should I make a new topic as this question’s subject is quite different than this current topic?)

Thank you in advance!

With kind regards,
Jurjen

By the way, I have also tried using MAVSDK-python in which I used your example of an offboard-position-control (MAVSDK-Python/examples/offboard_position_ned.py at 8320ad7081d4fb8addf7e12c55142092a15e3958 · mavlink/MAVSDK-Python · GitHub).

Where I made one minor change; I changed

print("Waiting for drone to have a global position estimate...")
async for health in drone.telemetry.health():
  if health.is_global_position_ok and health.is_home_position_ok:
    print("-- Global position estimate OK")
    break

Into:

print('Waiting for UGV to have local position estmimate...')
async for health in ugv.telemetry.health():
  if health.is_local_position_ok:
    print(f'-- local position estimate OK')
    break

As I do not have my GPS connected yet.

Similar as with pymavlink and MAVROS, this code works in the PX4_sitl but not on my ‘real’ OrangeCube. I get the following error when trying to arm the drone:

Traceback (most recent call last):
  File "/home/jurjen/MAVSDK.py", line 68, in <module>
    asyncio.run(run())
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/home/jurjen/MAVSDK.py", line 25, in run
    await ugv.action.arm()
  File "/home/jurjen/.local/lib/python3.10/site-packages/mavsdk/action.py", line 336, in arm
    raise ActionError(result, "arm()")
mavsdk.action.ActionError: TIMEOUT: 'Timeout'; origin: arm(); params: ()

I am a little in bit in despair as with and Pymavlink.mavutil (see: Offboard mode not able to arm) , and MAVSDK-python and MAVROS I am currently unable to send commands to my drone and the deadline for my project is coming more and more close :sweat_smile: :sweat_smile:.

Is there something I am doing wrong or that I am forgetting that causes my real OrangeCube not to receive any commands.

Thanks again in advance!

With kind regards,
Jurjen

If they all timeout then something with the communication link is not right.

Thanks for the reply! However, would you happen to know how that is possible? I have tried the following set-ups, all with the same result:

  1. Directly to my laptop with a USB cable and directly into the cube with a MicroUSB.
    a) Connecting via udp and localhost
    b) Connecting via serial
  2. With a Jetson Nano with a USB cable and a MicroUSB cable to the cube.
  3. With a Jetson Nano, now connected via the Telem2 port to the pinout on the Jetson Nano

With kind regards,
Jurjen

And all of them don’t work?