Cannot Control Blue ROV's thrusters with pymavlink or QGroundControl

Hi,
I am new to Blue ROV and I am having a problem with controlling it with joystick. Sorry the problem description is bit long, I’ve been searching and trying different solutions I found, but it still dosen’t work. Thanks in advance!

A brief of my system:
Ardusub Firmware Version: 3.5.4
Companion Computer Raspberry Pi
Companion Firmware Version: 0.1.0 (shown in ip to companion computer:2770/system)
Flight Controller: Pixhawk

Problem I am facing within QGroundControl:
I first tried with the latest version of QGroundControl, but it always says a few parameters are missing, in the vehicle setting, there isn’t the “motor” or “frame” tab. I found somewhere says this could be an incompatible issue between the lastest version of QGroudnControl and Ardusub Firmware version. So I downloaded the older version of QGroundControl (v3.5.6) and there isn’t any missing parameter warning. However, I still cannot control the ROV with joystick input. I can calibrate the joystick and click “enable” under the joystick tab. I tried to run the motor test, first, there isn’t an auto test button; second, when I turn on the manual motor test, it immediately says motor test fails, needs to coll down for 10s. The motors can move when I choose the flight mode to be “stablise”.

Another problem I had when I first tried QGroundControl was that the thrusters went into full speed when I arm the ROV. I did change flight mode to manual. Then I found the RC3_trim was set to 1500 instead of 1100. When I change it back to 1100, it does not go to full speed when armed. But I am not sure why this is the reason.

Problem With Using Pymavlink Directly
I have tried with the send RC example from the pymavlink GitBook. I added wait_heartbeat() and wait_arm() before I send out the RC command and connect can be set up correctly and it can be armed correctly, but none of the thrusters moves. I also tried the set_servo() function, the motors still do not move, but I found I can control the light with set_servo() properly. Then I tried this send RC example post by Eliot I think. in the output, it also shows the connect is correct and it is armed correctly, but all the thruster outputs are 0.

Note: we have some customised software with the current system, so I cannot upgrade the firmware.

Sorry for such a long question and thanks in advance!

Hi @hjz_123, welcome to the forum :slight_smile:

ArduSub 3.5.4 is from almost 4 years ago, and I don’t believe Companion 0.1.0 exists (the last version we released before publicly releasing BlueOS was 0.0.31), so I’m not sure how that could be shown.

My first suggestion would be to try installing our latest recommended software versions to see if the joystick controls at least work with a supported configuration.

Ok, but be aware that we don’t actively support outdated software versions, and can’t meaningfully support software customisations that we know nothing about.

I have no experience with ArduSub 3.5.4 or QGC v3.5.6, so have quite a limited understanding of their differences to the current software versions. It’s possible that ArduSub version does not support the same MAVLink messages as our current software, which means we can’t guarantee our available examples are expected to work with it.

This could be indicative of an issue with your system, or could just be a bug in QGC - I know there has previously been a bug similar to that behaviour.

  1. In the motor test page, or with joystick control?
  2. If your joystick control only works with stabilize mode then have you perhaps modified manual control, and it’s now no longer working?

This is a bit confusing to follow.

  1. Did the motors then work properly once the trim was changed from 1500 to 1100, or did they still go full speed when you armed the vehicle?
  2. Do you have custom ESCs?
    • starting on arming could potentially happen if the ESCs aren’t bidirectional, although I’d expect it to happen on startup instead
  3. Are you sure you’re running ArduSub?
    • if a firmware is expecting unidirectional ESCs it could have the same behaviour as the point above

From your log output, note the

 WARNING: ... - mode change failed!
         MAV_RESULT_UNSUPPORTED: Command is not supported (unknown).

Presumably that means the MAV_CMD_DO_SET_MODE command that Pymavlink is trying to send is not supported by the autopilot, in which case it likely uses the old SET_MODE MAVLink message instead.

It may be possible to do that by replacing the self.master.set_mode(mode_id) line with something like

self.mav.set_mode_send(self.master.target_system, mode_id, 0)

but I haven’t needed to use that before, so don’t know if it will work.

I’m also unsure what your version of QGroundControl is trying to send, and I don’t know whether the mode change failing is relevant to the thrusters not appearing to turn on, since the arming does seem to have worked. It’s also possible that ArduSub version doesn’t support the SERVO_OUTPUT_RAW message, in which case the reported thruster_outputs from the script would be meaningless.

Maybe double check that your SERVO{n}_FUNCTION (n = 1-6, or 1-8 for a heavy config) parameters are set to Motor{n}? If they’re set to disabled or a servo output or something then they won’t react to the motion commands.

It may also be relevant to note that QGroundControl commands motion using MANUAL_CONTROL messages, which ArduSub internally converts as though they were RC_CHANNELS_OVERRIDE messages. My example script uses RC_CHANNELS_OVERRIDE messages directly, which can have slightly different behaviour to MANUAL_CONTROL commands (although I don’t expect that to be important here).

Hi Eliot,
Thanks for your reply.

I found that as well, but it does show as 0.1.0 for companion firmware when I checked. Here is a screenshot of it. I remember my teammate mentioned once the ROV I’m using right now may not even have BlueOS, so I feel that the reason it shows the firmware version as 0.1.0
image

This happened when I was in the flight page (I mean the page where I can arm the ROV and choose which flight mode to use). At that time, the joystick was connected, but I was not touching it. Some of the thrusters were moving slowly.

After I changed RC3_trim to 1100, the motor did not go full speed, which should be the proper behavior after arming. I am not sure about the ESCs, I will check it right now.

I will try these. Thanks very much!

Hi Eliot,
I’ve changed the set mode function to use the older method and here is the output:
The motor output at manual mode is still 0. For stablise mode, it has some non-zero output but the motors were not moving.

If script gets stuck, press CTRL+C to disarm and quit

INFO: 10:01:23.231 - MAVLink connection successful
INFO: 10:01:24.237 - connection to autopilot confirmed
INFO: 10:01:24.237 - __enter__ -> reviving heart (if required)
INFO: 10:01:24.249 - mode='manual', change successful
NOTE: 10:01:24.265 - thruster_outputs=[0, 0, 0, 0, 0, 0]
INFO: 10:01:24.265 - clear_motion
INFO: 10:01:24.266 - send_rc
NOTE: 10:01:24.665 - thruster_outputs=[0, 0, 0, 0, 0, 0]
INFO: 10:01:27.247 - Motors armed!
INFO: 10:01:27.247 - send_rc
NOTE: 10:01:27.308 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:27.408 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:27.524 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:27.789 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:27.905 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:28.026 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:28.145 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:28.345 - thruster_outputs=[0, 0, 0, 0, 0, 0]
INFO: 10:01:28.395 - send_rc
NOTE: 10:01:28.446 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:28.697 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:28.792 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.025 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.145 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.344 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.493 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.605 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.725 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.845 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:29.946 - thruster_outputs=[0, 0, 0, 0, 0, 0]
INFO: 10:01:29.997 - __exit__ -> disarming, and stopping heart
INFO: 10:01:32.228 - Motors disarmed
INFO: 10:01:37.750 - __enter__ -> reviving heart (if required)
INFO: 10:01:37.750 - RE-ENTERING
INFO: 10:01:37.762 - mode='stabilize', change successful
INFO: 10:01:37.762 - clear_motion
INFO: 10:01:37.762 - send_rc
INFO: 10:01:38.246 - Motors armed!
INFO: 10:01:38.246 - send_rc
NOTE: 10:01:38.325 - thruster_outputs=[0, -1, 0, -1, 3, 3]
NOTE: 10:01:38.426 - thruster_outputs=[0, -1, 0, -1, 3, 3]
NOTE: 10:01:38.526 - thruster_outputs=[0, -1, 0, -1, 3, 3]
NOTE: 10:01:38.625 - thruster_outputs=[0, -1, 0, -1, 3, 3]
NOTE: 10:01:38.725 - thruster_outputs=[0, -1, 0, -1, 3, 3]
NOTE: 10:01:38.845 - thruster_outputs=[0, -1, 0, -1, 4, 3]
NOTE: 10:01:38.987 - thruster_outputs=[0, -1, 0, -1, 4, 4]
NOTE: 10:01:39.105 - thruster_outputs=[0, -1, 0, -1, 4, 4]
NOTE: 10:01:39.225 - thruster_outputs=[0, -1, 0, -1, 4, 4]
NOTE: 10:01:39.345 - thruster_outputs=[0, -1, 0, -1, 4, 4]
NOTE: 10:01:39.606 - thruster_outputs=[0, -1, 0, -1, 5, 5]
NOTE: 10:01:39.726 - thruster_outputs=[0, -1, 0, -1, 5, 5]
NOTE: 10:01:39.825 - thruster_outputs=[0, -1, 0, -1, 5, 5]
NOTE: 10:01:39.926 - thruster_outputs=[0, -1, 0, -1, 5, 5]
NOTE: 10:01:40.046 - thruster_outputs=[0, -1, 0, -1, 5, 5]
NOTE: 10:01:40.194 - thruster_outputs=[0, -1, 0, -1, 6, 6]
NOTE: 10:01:40.305 - thruster_outputs=[0, -1, 0, -1, 6, 6]
INFO: 10:01:40.356 - __exit__ -> disarming, and stopping heart
INFO: 10:01:41.228 - Motors disarmed
INFO: 10:01:41.555 - disconnect -> closing MAVLink connection
INFO: 10:01:47.228 - MAVLink connection successful
INFO: 10:01:48.228 - connection to autopilot confirmed
INFO: 10:01:48.228 - __enter__ -> reviving heart (if required)
INFO: 10:01:48.228 - Engaging per-thruster control!
WARNING: 10:01:48.229 - Thruster actions no longer require arming!
WARNING: 10:01:48.229 - Failsafes no longer engaged!
INFO: 10:01:48.229 - Servo mode engaged:
 -> control thrusters with self.set_servo
NOTE: 10:01:48.229 - backing up servo thruster functions
NOTE: 10:01:48.229 - read_param(name='SERVO1_FUNCTION', index=-1, timeout=None)
NOTE: 10:01:48.237 - read_param(name='SERVO2_FUNCTION', index=-1, timeout=None)
NOTE: 10:01:48.245 - read_param(name='SERVO3_FUNCTION', index=-1, timeout=None)
NOTE: 10:01:48.254 - read_param(name='SERVO4_FUNCTION', index=-1, timeout=None)
NOTE: 10:01:48.262 - read_param(name='SERVO5_FUNCTION', index=-1, timeout=None)
NOTE: 10:01:48.277 - read_param(name='SERVO6_FUNCTION', index=-1, timeout=None)
INFO: 10:01:48.284 - set_servo(servo=1, pwm=1500)
INFO: 10:01:48.285 - set_servo(servo=2, pwm=1500)
INFO: 10:01:48.285 - set_servo(servo=3, pwm=1500)
INFO: 10:01:48.285 - set_servo(servo=4, pwm=1500)
INFO: 10:01:48.285 - set_servo(servo=5, pwm=1500)
INFO: 10:01:48.285 - set_servo(servo=6, pwm=1500)
INFO: 10:01:48.286 - set_param(name=b'SERVO1_FUNCTION', value=0, type=0)
INFO: 10:01:48.298 - set_param(name=b'SERVO2_FUNCTION', value=0, type=0)
INFO: 10:01:48.308 - set_param(name=b'SERVO3_FUNCTION', value=0, type=0)
INFO: 10:01:48.318 - set_param(name=b'SERVO4_FUNCTION', value=0, type=0)
INFO: 10:01:48.330 - set_param(name=b'SERVO5_FUNCTION', value=0, type=0)
INFO: 10:01:48.340 - set_param(name=b'SERVO6_FUNCTION', value=0, type=0)
INFO: 10:01:49.355 - set_servo(servo=1, pwm=1500)
INFO: 10:01:49.355 - set_servo(servo=2, pwm=1500)
INFO: 10:01:49.356 - set_servo(servo=3, pwm=1500)
INFO: 10:01:49.356 - set_servo(servo=4, pwm=1500)
INFO: 10:01:49.356 - set_servo(servo=5, pwm=1500)
INFO: 10:01:49.356 - set_servo(servo=6, pwm=1500)
NOTE: 10:01:49.506 - thruster_outputs=[0, 0, 0, 0, 0, 0]
INFO: 10:01:49.506 - set_servo(servo=1, pwm=1300)
NOTE: 10:01:49.806 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:49.905 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:50.005 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:50.106 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:50.305 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:50.405 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:50.605 - thruster_outputs=[0, 0, 0, 0, 0, 0]
INFO: 10:01:50.655 - set_servo(servo=3, pwm=1400)
INFO: 10:01:50.655 - set_servo(servo=4, pwm=1550)
NOTE: 10:01:50.706 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:50.806 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:50.905 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:51.004 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:51.204 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:51.305 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:51.405 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:51.505 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:51.605 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:51.807 - thruster_outputs=[0, 0, 0, 0, 0, 0]
NOTE: 10:01:52.107 - thruster_outputs=[0, 0, 0, 0, 0, 0]
INFO: 10:01:52.158 - set_servo(servo=1, pwm=1500)
INFO: 10:01:52.158 - set_servo(servo=2, pwm=1500)
INFO: 10:01:52.158 - set_servo(servo=3, pwm=1500)
INFO: 10:01:52.158 - set_servo(servo=4, pwm=1500)
INFO: 10:01:52.159 - set_servo(servo=5, pwm=1500)
INFO: 10:01:52.159 - set_servo(servo=6, pwm=1500)
INFO: 10:01:52.159 - set_param(name=b'SERVO1_FUNCTION', value=33.0, type=2)
INFO: 10:01:52.190 - set_param(name=b'SERVO2_FUNCTION', value=34.0, type=2)
INFO: 10:01:52.200 - set_param(name=b'SERVO3_FUNCTION', value=35.0, type=2)
INFO: 10:01:52.213 - set_param(name=b'SERVO4_FUNCTION', value=36.0, type=2)
INFO: 10:01:52.223 - set_param(name=b'SERVO5_FUNCTION', value=37.0, type=2)
INFO: 10:01:52.241 - set_param(name=b'SERVO6_FUNCTION', value=38.0, type=2)
NOTE: 10:01:52.255 - servo functions restored
INFO: 10:01:52.255 - per-thruster control successfully exited
WARNING: 10:01:52.255 - Arming and failsafe requirements re-engaged
INFO: 10:01:52.255 - __exit__ -> disarming, and stopping heart
INFO: 10:01:53.228 - Motors disarmed
INFO: 10:01:53.888 - __exit__ -> disarming, and stopping heart
INFO: 10:01:54.228 - Motors disarmed
INFO: 10:01:54.228 - disconnect -> closing MAVLink connection
INFO: 10:01:54.228 - __exit__ -> disarming, and stopping heart
INFO: 10:01:54.228 - disconnect -> closing MAVLink connection

You’re on our old “Companion Software” (not BlueOS, which is new from this year), but as I mentioned the versions on the Companion Software only ever went up to 0.0.31, so I’m not sure how it’s showing 0.1.0 for you unless you’re running a modified version that has a custom version number.

The firmware version number here is being reported as 3.5.4, but the heading doesn’t actually check that it’s a version of ArduSub - it just assumes it to be so. That said, if you’ve customised the firmware I doubt you’d be trying to run something that wasn’t ArduSub on an ROV.

Did you end up checking this?

It looks like the autopilot is reporting that the mode change was successful, and same with the arming, but the SERVO_OUTPUT_RAW message is still reporting neutral (1500) values except for small deviations while the vehicle is in “stabilize” mode.

It looks like the autopilot also accepted the script configuring the motor outputs as standard servo outputs, and that before that they were the Motor{n} outputs they should have been (which it restored them to), but I don’t understand why they’re not affected by the set_servo commands, unless that message is not available / supported in your firmware, which seems somewhat unlikely. It’s also not clear to me why the response is so muted in stabilise mode, or why it stays neutral while in manual mode.

Are you able to try flashing on an unmodified ArduSub firmware and seeing if that works as expected?


More generally, I’m confused as to how you’ve ended up with a vehicle running very old custom firmware that appears to be missing basic functionality. Is there not someone in your group / organisation who knows how it was supposed to work, and can confirm whether it’s expected that only stabilise flight mode works or something?

It seems odd that you would need to troubleshoot this by yourself, unless the only person/people who knew how to operate the vehicle have left, in which case one would hope there would be some documentation available that they had left behind. If there isn’t, how are you able to use their customisations? Would it perhaps make sense to just start with the latest available firmware and try to re-create the customisations instead of trying to somehow re-enable basic functionality that’s expected to be available automatically?