OpenROV Autopilot in Javascript



I wanted to create an auto-pilot algorithm that would allow you set a desired heading between 0-360 degrees and then at some interval supply the ROV's current heading to the autopilot in order to get back the port and starboard thruster power levels. How the port and thruster power levels are calculated I guess I consider to be "the algorithm".

After thinking about it some I've implemented my first attempt in the auto-pilot in javascript and simulated (mocked) how the ROV's current heading is generated.

My long term goal is to attach a compass module to the ROV so that the ROV's currently facing direction can be sent back to the cockpit webpage as a value between 0 and 360. The javascript autopilot algorithm takes this value and returns recommended thruster values to get back on course.

Here is a web page that shows the auto-pilot logic in action:

Here's how the overall auto-pilot process works:

Set a Desired Heading between 0 and 360 degrees. 0 being North, 90 being east, 180 south, and 270 West

Set a buffer angle, i.e 10 degrees. This buffer angle is used to help guide the ROV into the heading. If your desired heading is 90, then headings from 80 to 100 degress are considered in the algorithm. Recommended buffer angle ranges are between 3 to 10.

Once a desired heading has been set call autopilot.updateHeading() with the latest ROV heading between 0 and 360.

The updateHeading method returns an object with portPower and starboardPower properties that have a value between -1.0 and 1.0 with a step of .001. A value of 1 is 100% full forward power and -1 represents 100% reverse power.

The autopilot calculates the port and starboard power using the following process:

  1. Calculate the two angles between latest supplied heading and the desired heading
  2. Choose the smaller of the two angles as the direction to turn the ROV. The smallest angle will always be less than or equal to 180. The two angles always add up to 360.
    1. The smallest angle difference is stored as angle_diff
    2. Apply power to motors in opposite directions to rotate ROV to face the desired heading
      1. Calculate power applied to motors based on how far off of heading

i. More power to motors the further off the heading (to turn quickly)

ii. Less power the closer to the desired heading (so as to not overshoot)

  1. Spin motors in opposite direction until within certain number of degrees (buffer angle) of desired heading

i. Example, assuming buffer angle is 10 degrees. If the desired heading is 100, and latest heading is 20 motors will be spun in opposite directions until current heading is greater than 90

  1. Once the angle_diff is less than the buffer angle range apply forward power to both motors
    1. Two conditions of forward power

i. If angle_diff is greater than half of buffer angle but less than buffer angle (5<angle_diff<10) then one motor at full power and other at half powe. This is done to move forward but with a power bias that steers the ROV closer towards final desired heading

ii. Both motors at full forward power if angle_diff is half of buffer angle (0<angle_diff<=5). The buffer angle can be increased or decreased; it is variably controlled through the software.


Great work I like this feature and I am sure it could easily be adapted to vertical depth positioning which would also be a nice feature.


Nice work! You might want to look into the PID algorithm ( It works pretty well for this kind of stuff!



Great work.

As David mentioned, having a AUTO DEPTH function is very desirable and very useful, if your going to go through the effort of Auto heading then Auto depth/altitude is certainly something I would put in your development. Especially considering it is just a Z axis to your X,Y project.

The Autodepth should be able to be set in two modes.

1. SET DEPTH = i.e set to say '45m'? and it will ascend or descend to 45m

2. HOLD= holds and maintains current depth (this is the more important of the two)

In fact I would go as far as to say that holding depth at the press of a button is more important than Autoheading, because when a ROV pilot is going to the job he can see the heading instantly on screen and fly on that heading, but compensating depth is trickier especially nearer to seabed or objects or if there is drag from tether or seaswell.

Bearing also in mind if your anywhere near a steel wreck your autoheading compass might be affected (I think) same also when you get near the seabed, though I admit I am unsure if the electronic gyros compasses are affected the same as a magnetic compass would be.


This is an awesome thread! As you guys may have scene, Colin Ho has been working on a depth & heading (and attitude) board that would allow the ROV to detect all those things with an external module. Our plan is to design several inner control loops (using PID control) to hold the ROV at the desired depth and heading during flight.

In this configuration, movement of the joystick would no longer directly control thruster movement, but would instead control the "set point" for heading in depth. For instance to turn, moving the joystick on a game pad controller a certain amount would now control turn rate (e.g. degrees per second) which would be realized by the inner control loop of the ROV.

We've been figuring out some of the dynamic characteristics of the ROV empirically with testing, but most likely the gains for these control loops would have to be tuned by hand for each ROV.



Hi Erik and everybody.

Quite a nice topic.

What about making the PID coefficients to be computed from "ROV" experience ?

I see it a lot more interesting, and surely accurate, than taking them from tests.

I mean ....

When we perform Ship's Seatrials, some standarized manouvers are performed, and some useful coefficients derived from them.

Why not we try that the autopilot could compute by itself the PID coefficients from a few standarized manouvers done before starting the first "mission" ?

That way, the ROV would have a kind of intelligence (a smart robotic step ahead) and by the way, would be able to addapt to changes in weights, shape, etc ... (payload).

What do we need as starting data?

Time and path lenght to stop from three speeds ahead and astern(up and down for Z)

Time and path lenght to achive a chosen speed from cero

Time and pathlenght for motion inversion from three speeds to three speeds.

Radius and time to perform a whole turn around at three speeds(starboard and port turns).

Time, radius and path lenght for heading inversion by a Williamson turn (Str and Port).Three speeds again.

May be we could design an addaptable autopilot, able to react at any ROV loading/design condition.

One more step could be fitting a continuous feedback to the system, making it able to modify and addapt itself in real time.


Gyroscopic working principle has nothing to do with magnetic fields, hence its not affected by them.

The problem with a gyroscopic compass, is related to violent accelerations and changes in geographic latitude, but onboard a submarine vehicle almost all motions are smooth. Regarding latitude changes ........ ROV's range is too short for even thinking on that effect.




Hi all again ¡¡

I find this link quite usefull. Its open source and I think can be easily addapted to Openrov.

Kind regards