Mapping custom PWM signals from BlueOS to Cockpit

Hi everyone!

I’ve got a servo set up on my BlueROV, and I’d like to simply press a button on the topside Xbox controller to send a specific PWM signal. Essentially, I need to send four distinct PWM signals (980pwm, 1060pwm, 1140pwm, 900pwm). How do I map the Ardusub control functions (found in BlueOS) to the Cockpit joystick configuration?

I’ve been informed that three servo functions can be used on the ROV at a time. I also have discovered that in BlueOS each servo function only has three commands for PWM (Min, Trim, Max). This means, for example, if I were to use Servo_3, which is linked to pin 11, I would only be able to send three PWM signals, instead of the four signals I need to send. After experimenting with the controls, I found out I cannot use Servo_2 on the same pin as Servo_3 to allow me the functionality of sending a fourth PWM signal. Is there a way to send four specific PWM signals via the servo functions (without or in addition to the Min, Max, Trim command presets)?

I also noticed in Cockpit the option for multiple custom command functions. Would using these allow me to write a custom python script that sends the necessary PWM signals I need? Or would I be able to write a python script for each command function and each PWM signal? Writing this kind of program for an Arduino is very simple - would I be able to achieve the same simplicity with the Navigator board and RPI on the BlueROV?

Also, as a newbie to the BlueOS system, I’ve found the naming conventions of the servo functions a little bit confusing. For example, Servo_1 is a servo function in Cockpit that maps to one of three servos I can use in addition to the thrusters, however in BlueOS Ardusub, SERVO1_FUNCTION is mapped to one of the thrusters and is considered a motor. How should I interpret the names of these functions?

Thank you!

1 Like

Hi @Cnidaria_97,

Thanks for the well-structured post, and specifying what you’ve tried so far, as well as where and how that’s failed and been confusing! :smiley:

Our documentation and examples are still somewhat limited for expansion use-cases like this, but this is actually very straightforward with Cockpit’s Custom Actions functionality, and doesn’t require custom scripting at all.

For each PWM value you want to set, you can

  1. Create a new Custom MAVLink Action
  2. Specify the message type as COMMAND_LONG, with the command ID set to MAV_CMD_DO_SET_SERVO
  3. Set the parameter 1 field to the the desired servo output pin[1] number (of the Navigator’s servo connector), and parameter 2 to the relevant µs pulse-duration (PWM value).
  4. Choose that Action in your joystick button function configuration, for the button you want to trigger it with

This is related to mapping dedicated joystick button functionalities in ArduSub to the servo output bus on the flight controller board it’s running on, and is a longstanding point of confusion that we’re actively working on improving (both in the firmware, and the documentation).

If you’re not using ArduSub’s built in button functions (e.g. if you’re using separate MAVLink messages, like described above) then all you need to think about is the pin numbers on your flight controller board.

For the curious:

If you want to use the servo_n_min/max/... button functions built into ArduSub then they currently correspond to n-8 for the Navigator pin numbers. This hearkens back to the Pixhawk flight controller board they were originally developed for which had its servo bus split into two groups, with 8 MAIN outputs that needed to be dis-counted when trying to control one of its 6 AUX outputs.

We’re working on refactoring the servo control functionality from using hardcoded values to reconfigurable Actuator outputs (in a similar way to the existing RELAYn_PIN functionality), but for now ArduSub includes default joystick button functions for just three servo outputs which are hardcoded to pins 9, 10, and 11.


  1. Note that you’ll need the corresponding SERVOn_FUNCTION parameter in ArduSub configured as Disabled (0) so that you can set custom PWM values for it, instead of using one of ArduSub’s predefined functionalities. This is likely already the case, but worth noting in case it’s not working as expected / is already in use by a different subsystem of the autopilot. The SERVOn_MIN and MAX parameters will also need to be set outside the range of values you want to use (ideally as the limits of safe values for that device), otherwise the outputs will be undesirably clipped. ↩︎

2 Likes

Thank you so much, Eliot! This is just the answer I was looking for! :smiley: I really appreciate all your help! I will work on implementing this functionality within the next couple days. I’ll let you know how it goes!

Thanks again,
Sydney

2 Likes