14  Tutorial - Simulation of Maneuvering Motions in Python

In this tutorial we will learn to simulate the motions of a ship in python using the linearized maneuvering equations of motion.

After completing this tutorial, the student will be able to:

14.1 Getting Started

We will be using the same repository as the previous tutorial. Once the previous tutorial deadline is over, your instructor will update the upstream repository with the necessary files for this tutorial and raise a pull request on your team repository. You will need to pull in the changes from the upstream repository to your team repository to start this tutorial. The instructions to pull in the changes are given in Appendix B.

After you complete the steps shown in Appendix B to synchronize your repository with the upstream repository, navigate to the root directory of your repository. Pull the latest changes made to your team repository onto your local machine.

cd <your-repository-name>
git pull origin main

The relevant folder structure of the repository for this tutorial is shown below.

<your-repository-name>
├── ros2_ws/
│   ├── src/
│   │   ├── student/
│   │   │   ├── tut_03/
│   │   │   │   ├── hyd.yml
│   │   │   │   ├── input.yml
│   │   │   │   ├── simulate.py
│   │   │   │   ├── read_input.py
│   │   │   │   ├── class_vessel.py
│   │   │   │   ├── module_control.py
│   │   │   │   ├── module_kinematics.py
│   │   │   │   └── plot_results.py
│   │   │   └── ...
├── README.md
├── ros2_run_devdocker.sh
├── ros2_run_devdocker.bat
└── LICENSE

Start your own branch from the main branch.

git checkout -b <your-name>

All your group members can work independently on their own branches. However, you will have to merge your branches back to the main branch before the end of the tutorial. We learnt how to do this in Chapter 13 using pull requests.

14.2 Description of Files

The tutorial contains several Python files that work together to simulate vessel motion:

14.2.1 Configuration Files

  • input.yml: Contains vessel parameters including:
    • Physical properties (mass, dimensions, density)
    • Initial conditions for position and velocity
    • Simulation parameters (time step, duration)
    • Control settings
    • Path to hydrodynamic coefficients file
  • hyd.yml: Contains hydrodynamic derivatives including:
    • Surge coefficients (\(X_u\), \(X_{\dot{u}}\))
    • Sway coefficients (\(Y_v\), \(Y_{\dot{v}}\), \(Y_r\), \(Y_{\dot{r}}\))
    • Yaw coefficients (\(N_v\), \(N_{\dot{v}}\), \(N_r\), \(N_{\dot{r}}\))
    • Rudder coefficients (\(Y_{\delta}\), \(N_{\delta}\))

14.2.2 Python Files

  • simulate.py: Main simulation script that:
    • Reads input parameters
    • Creates vessel instance
    • Runs simulation
    • Generates plots
  • read_input.py: Handles reading and parsing of configuration files:
    • Reads YAML files
    • Converts parameters to appropriate data types
    • Returns structured dictionaries of vessel and hydrodynamic parameters
  • class_vessel.py: Contains the Vessel class implementation:
    • Manages vessel state
    • Implements vessel dynamics (vessel_ode)
    • Handles simulation stepping and history tracking
    • Calculates hydrodynamic and control forces
  • module_control.py: Implements control strategies:
    • Fixed rudder control
    • Switching rudder control
  • module_kinematics.py: Handles vessel kinematics:
    • Rotation matrices
    • Euler rate matrix calculation
    • Expressing cross product in matrix form
  • plot_results.py: Generates visualization of simulation results:
    • Trajectory plot
    • Velocity time history
    • Turn rate history
    • Rudder angle history
    • Heading angle history

The simulation uses numerical integration (RK45 method) to solve the vessel’s equations of motion, taking into account hydrodynamic forces, control inputs, and vessel kinematics. The results are stored in the vessel’s history attribute and plotted using matplotlib.

14.3 Steps to Execute the Code

14.3.1 Start the Course Docker Container

First start docker desktop and then follow the instructions below to run the course docker container. Make sure to navigate in the terminal to the root folder of your repository.

For Windows:

./ros2_run_devdocker.bat

For Ubuntu (or MacOS):

./ros2_run_devdocker.sh

You would have noticed that when entering the docker container your path is /workspaces/mavlab. The root directory of the repository is mounted to the folder /workspaces/mavlab inside the docker container. The files you edit on your system inside the repository folder are immediately accessible inside the docker container.

14.3.2 Run the Python Script to Simulate the Motion

You can now execute the following command to run the Python code that is present in your repository.

python3 ros2_ws/src/student/tut_03/simulate.py

Now we really see the power of running things inside a docker container. If we were working in our own operating systems, the path of the files will be different for different students. For running the python file, each person would have to edit the above command to make sure python is pointed towards the correct path of the file simulate.py. However, as we are running things inside a docker container, the path of the file simulate.py will not change.

Similarly, observe that you did not have to install any python packages like numpy, scipy or matplotlib. These were pre-installed for you in the docker container. Now everyone in the class is using the exact same version of Python and the same version of packages (numpy, scipy and matplotlib).

Running the above command will result in a plot named simulation_results.png being generated in the root directory of your repository. This plot contains the following subplots:

  1. The trajectory of the ship in the x-y plane
  2. The time history of the velocity of the ship
  3. The time history of the turn rate of the ship
  4. The time history of the rudder angle
  5. The time history of the yaw angle

14.4 Implementation Tasks

There are a total of 9 tasks in this tutorial and are described below.

Task 1: Cross Product in Matrix Form

Location: module_kinematics.py, Smat() function

Description: Implement the Smat() function to calculate the cross product of a vector in matrix form.

Input:

  • vec: A 3x1 numpy array representing the vector to be cross-multiplied.

Output:

  • A 3x3 numpy matrix representing the cross product matrix such that when this matrix is multiplied with another vector, it gives the cross product of the input vector with the other vector.

Task 2: Rotation Matrix

Location: module_kinematics.py, eul_to_rotm() function

Description: Implement the eul_to_rotm() function to calculate the rotation matrix from Euler angles.

Input:

  • eul: A 3x1 numpy array representing the Euler angles (roll, pitch, yaw).

Output:

  • A 3x3 numpy matrix representing the rotation matrix such that when this matrix is multiplied with a vector in the body coordinate system, it gives the corresponding vector in the global coordinate system.

Task 3: Euler Rate Matrix

Location: module_kinematics.py, eul_rate_matrix() function

Description: Implement the eul_rate_matrix() function to calculate the Euler rate matrix \([J_2]\).

Input:

  • eul: A 3x1 numpy array representing the Euler angles (roll, pitch, yaw).

Output:

  • A 3x3 numpy matrix representing the Euler rate matrix such that when this matrix is multiplied with the angular velocity vector in the body coordinate system, it gives the rate of change of the Euler angles.

Task 4: Fixed Rudder Control

Location: module_control.py, fixed_rudder() function

Description: Implement the fixed_rudder() function to calculate the rudder angle for fixed rudder control.

Input:

  • t: A float representing the time.
  • state: A 13x1 numpy array representing the state of the vessel. The state vector is defined as:

\[\begin{align} \{x\} = \begin{bmatrix} u & v & w & p & q & r & x & y & z & \phi & \theta & \psi & \delta \end{bmatrix}^T \end{align}\]

Output:

  • A float representing the commanded rudder angle \(\delta_c\) in radians.

Task 5: Switching Rudder Control

Location: module_control.py, switching_rudder() function

Description: Implement the switching_rudder() function to calculate the rudder angle for switching rudder control.

Input:

  • t: A float representing the time.
  • state: A 13x1 numpy array representing the state of the vessel.

Output:

  • A float representing the commanded rudder angle \(\delta_c\) in radians.

Task 6: Mass Matrix

Location: class_vessel.py, _generate_mass_matrix() function

Description: Implement the _generate_mass_matrix() function to calculate the mass matrix.

Input:

  • self: The vessel object.

Output:

  • None

Task 7: Dimentionalize Hydrodynamic Derivatives

Location: class_vessel.py, _dimensionalize_coefficients() function

Description: Implement the _dimensionalize_coefficients() function to dimensionalize the hydrodynamic derivatives.

Input:

  • self: The vessel object.
  • rho: A float representing the density of the fluid.
  • L: A float representing the length of the vessel.
  • U: A float representing the velocity of the vessel.

Output:

  • None

Task 8: Vessel ODE

Location: class_vessel.py, vessel_ode() function

Description: Implement the vessel_ode() function to calculate the vessel’s equations of motion.

Input:

  • self: The vessel object.
  • t: A float representing the time.
  • state: A 13x1 numpy array representing the state of the vessel.

Output:

  • A 13x1 numpy array representing the rate of change of the state.

Task 9: Simulation

Location: simulate.py, simulate() function

Description: Implement the simulate() function to simulate the vessel’s motion.

Input:

  • self: The vessel object.

Output:

  • None

14.5 Testing the Code

To test the code, commit your changes and push them to the remote repository. This will trigger the GitHub Actions workflow to run the tests. You can view the results of the tests by navigating to the “Actions” tab in the GitHub repository. If the tests pass, the workflow will be marked as successful. If the tests fail, you can view the detailed logs to see which tests failed and why. The GitHub workflow will also show the difference between the expected output and the output generated by your code.

14.6 Evaluation

The evaluation of the tutorial will be performed in the classroom. Notice that this is a group activity. You will be working in a group of 4 students. The evaluation will be performed on the group level. In order to pass the tutorial, the group must pass all the tests in the GitHub Actions workflow and also be able to answer all the questions during the evaluation in the classroom. Those who are not present in the classroom on the day of evaluation will not be able to participate in the evaluation and will automatically fail the tutorial.

While one of the objectives of these tutorials is to give you hands on experience with coding and practical implementation, the more important goal is to help you relate what you are doing in your tutorials to the underlying concepts discussed in the class. Therefore, while you are working on the implementation tasks, make sure you are also thinking about the underlying concepts and how they are being applied in the code.

Some questions to think about while you are working on the implementation tasks:

  • Is your code able to pass all the tests in the GitHub Actions workflow?
  • Are you able to show running of the simulation live during the evaluation?
  • What is the difference between fixed and switching rudder control?
  • How have you implemented the switching rudder control?
  • Are we integrating the dynamic equations and kinematics equations separately or together? Where in the code is this happening?
  • How do you think the simulation results would change if we used a different integration method?
  • What is the difference between actual rudder angle and commanded rudder angle?
  • Did you run the simulation and check the results?
  • Do you think the simulation results are in agreement with the expected results? Why or why not?
  • Where is the commanded rudder angle being used in your simulation?
  • Is the vessel straight line stable? Why or why not?
  • Can we simulate and check the vessel’s straight line stability? How?

14.7 Instructor Feedback through Pull Requests

Commit your changes to the remote repository often. This will help you to track your progress and also help you to revert to a working version if you make a mistake. In addition, the instructor and TA will be able to provide you with feedback on your code through the Feeback pull request available in your repository. Please do not close this pull request.