Navigation

## ROBOT OPERATING SYSTEM (ROS)

The Robot Operating System, is an open-source, meta-operating system. It provides services similar to that of an operating system, including hardware abstraction, low-level device control, implementation of commonly-used functionality, message-passing between processes, and package management. Through the use of this system, nodes are created within the AUV, which establish a form of communication with each other, via the use of “subscribers” and “publishers”.

## ARDUINO CODES

The arduino mega is used to control 2 components, being the servo motor and the 4 T100 motors. Furthermore, it receives input from a switch, that is used to switch off the processes running in the AUV.

Firstly, in order to communicate and function with the odroid and other components, libraries and pin numbers have to be declared. Libraries that have to be included is <ros,h> for the ROS libraries, <std\_msgs/String.h> for subscribing or publishing with the format of “string”. <std\_msgs/Int16.h> for subscribing or publishing with the format of “integer” and lastly, <Servo.h> for the Arduino to control the servo motors, In this AUV, the following pin numbers are assigned to the following components:

➞2: Kill Switch

➞6: Servo Motor

➞9: Left Vertical Thruster

➞10: Right Vertical Thruster

➞11: Horizontal Left Thruster

➞12: Horizontal Right Thruster

### Declarations in Arduino

Next, a formula has to be applied to the received data from the odroid, before being sent to the T100 thrusters to control the speed. The T100 thrusters speed is controlled from a percentage of 0-100% which scales with the received values of 1500- 2000 Microseconds, In the arduino, the formula for changing the received odroid values to T100 thrusters is

[( received input \* 4 ) + 1500]

This means that any input from the odroid to the arduino is put through this formula, before being sent to the T100 thruster to set its speed. Furthermore, as a safety measure, the thruster values will only be sent, when the data received is bigger than -100 and smaller than 100. This ensures that the motor will not operate outside of its acceptable range. Next, each thruster is assigned to be controlled by a certain subscriber, which receives their respective value from the odroid. In the figure below, the left horizontal thruster can be seen to be binded to the subscriber horz\_l, which comes from the odroid.

### Formula for Thruster Values

To control the servo motor to drop the ball, a segment called “balldrop” is created. This segment of code will only run, when it receives a “1” from the publisher “ball\_drop”. When a “1” is received, it will first go to its initialising position, wait for a set time to allow the user to insert a ball into the holder, before closing to keep the ball in place. This segment of code can be seen in the figure below.

Figure 4.2.3: Ball Holding Servo Code

To summarise, the code will react in lieu with certain inputs from certain publishers or physical interaction. This is shown in the table below.

 Physical Switch “High”
 Physical Switch “Low”
 Arduino switches “ON”
 Ball\_drop publishes “1”
 Any Thruster Publisher sends “0”
 Any Thruster Publisher sends “1-80”
 Any Thruster Publisher sends
“(-1) - (-80)”

### HEADING & DEPTH PI CONTROLLER CODES

To control the depth, through the vertical thrusters, the effort has to be determined. This is done through deducting the current depth “depth” by the desired depth “des\_depth”, thus giving the value of “depth\_E” or effort. This is then put through an equation that will add the effort to the depth thrust, whilst being limited by a positive and negative thrust limit. Both vertical right and vertical left thruster values are equal, so as to maintain stability. Then, these thruster values are published to the arduino, which will control the power of the thrusters accordingly.

To control the heading, the heading effort is first obtained, so as to determine how much power is to be used in the thrusters, in order to reach the desired heading. This is acquired through deducting the current heading “heading”, by the desired heading “des\_heading”. Next, these values are put through the controller, which takes the current desired thrust “des\_thrust” from the statemachine, and adds in the heading effort, which will then be limited by positive and negative “THRUST\_LIMIT” values.

How the Proportional and Integral Controller works in these two cases, is the proportional segment, produces and output which is proportional to the current error. This is achieved by multiplying the “heading\_E” by the adjustable value “heading KP”. For the integral segment, it speeds up the current process towards the required set point, “des\_heading”. Thus, decreasing the amount of time needed to achieve the “des\_heading”. The same processes is present in the depth controller.

## LAUNCH FILE CODES

<launch>

<node pkg="sp\_auv" type="sp\_auv\_depth" name="sp\_auv\_depth" respawn="false">

➞<param name="port" type="str" value="/dev/ttyUSB1" />

➞<param name="baud" type="str" value="9600" />

</node>

<node pkg="SpartonCompass" type="SpartonCompass.py" name="SpartonCompass" respawn="true">

➞<param name="port" value="/dev/ttyUSB0" />

➞<param name="baud" value="19200" />

➞<param name="frequency" value="5" />

</node>

<node pkg="sp\_auv" type="sp\_auv\_controller" name="sp\_auv\_controller" respawn="false" >

➞<param name="HeadingKP" type="double" value="5.2" />

➞<param name="HeadingKI" type="double" value="0.12" />

➞<param name="HeadingKImax" type="double" value="0.3" />

➞<param name="HeadingKImin" type="double" value="-0.3" />

➞<param name="DepthTolerance" type="double" value="0.1" />

➞<param name="DepthKP" type="double" value="30" />

➞<param name="DepthKI" type="double" value="1" />

➞<param name="DepthKImax" type="double" value="0.5" />

➞<param name="DepthKImin" type="double" value="-0.5" />

</node>

<node pkg="sp\_auv" type="sp\_auv\_statemachine" name="sp\_auv\_statemachine" respawn="false" output="screen">

➞<param name="SetupTime" type="double" value="20.0" />

➞<param name="Leg1Time" type="double" value="15.0" />

➞<param name="theta1" type="double" value="0.28"/>

➞<param name="theta2" type="double" value="0"/>

➞<param name="TimeOut" type="double" value="130.0" />

➞<param name="Depth" type="double" value="0.0" />

➞<param name="HeadingTolerance" type="double" value="0.03" />

</node>

<node pkg="beginner\_tutorials" type="Ivan" name="Ivan" respawn="false" output="screen">

</node>

<node pkg="rosserial\_python" type="serial\_node.py" name="serial\_node" output="screen">

 ➞<param name="port" value="/dev/ttyACM0" />

</node>

</launch>

These 6 nodes are “sp\_auv\_depth” which is the node for the depth sounder to function within ROS, “SpartonCompass.py” which operates as the driver for the IMU to act as a publisher within ROS, “sp\_auv\_controller” which allows for certain parameters to be edited within the sp\_auv\_controller.cpp without the need to compile the entire library, “sp\_auv\_statemachine” which also allows for certain parameters to be edited within the sp\_auv\_statemachine.cpp without the need to compile the entire library, thus saving time for both codes. Next, there is the node called “Ivan”, which functions as the launcher for the camera code. Lastly, the node “serial\_node.py” which is to enable the communication between the odroid, and the arduino, through the USB port.