-
Notifications
You must be signed in to change notification settings - Fork 3
404 Complete Boat State Class #432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 38 commits
5c82f48
f2ae1b7
89895c4
301687f
99e722e
60bf855
b045eac
4e2756e
4e44354
59db804
d8e0d19
0d1ca0e
2a57520
02a6f13
6461bbe
ade6f19
35ac17a
50874ae
5cad061
00f5803
f8470e0
d220f62
19869b5
57d53f1
28e67af
534994d
36de344
b37fd9c
90d9b58
dc85627
b6697d5
39dd77f
51ba15f
af195a3
cc40293
94f684f
98b481b
94f3df9
b95ed26
a94ee9b
6a4d9ec
d68d1d1
fb8ef3f
6104ab7
189a5b5
18bf180
4b1364c
e6b6416
95280e1
e4a8be2
26a8c93
7dcb336
8c0d5cf
89dc79c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| { | ||
| "python.autoComplete.extraPaths": [ | ||
| "/workspaces/sailbot_workspace/build/local_pathfinding", | ||
| "/workspaces/sailbot_workspace/build/integration_tests", | ||
| "/workspaces/sailbot_workspace/build/controller", | ||
| "/workspaces/sailbot_workspace/build/boat_simulator", | ||
| "/workspaces/sailbot_workspace/install/local/lib/python3.10/dist-packages", | ||
| "/workspaces/sailbot_workspace/install/lib/python3.10/site-packages", | ||
| "/opt/ros/humble/local/lib/python3.10/dist-packages", | ||
| "/opt/ros/humble/lib/python3.10/site-packages" | ||
| ], | ||
| "python.analysis.extraPaths": [ | ||
| "/workspaces/sailbot_workspace/build/local_pathfinding", | ||
| "/workspaces/sailbot_workspace/build/integration_tests", | ||
| "/workspaces/sailbot_workspace/build/controller", | ||
| "/workspaces/sailbot_workspace/build/boat_simulator", | ||
| "/workspaces/sailbot_workspace/install/local/lib/python3.10/dist-packages", | ||
| "/workspaces/sailbot_workspace/install/lib/python3.10/site-packages", | ||
| "/opt/ros/humble/local/lib/python3.10/dist-packages", | ||
| "/opt/ros/humble/lib/python3.10/site-packages" | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
|
|
||
| from boat_simulator.common.constants import BOAT_PROPERTIES | ||
| from boat_simulator.common.types import Scalar | ||
| from boat_simulator.nodes.physics_engine.fluid_forces import MediumForceComputation | ||
| from boat_simulator.nodes.physics_engine.kinematics_computation import BoatKinematics | ||
| from boat_simulator.nodes.physics_engine.kinematics_data import KinematicsData | ||
|
|
||
|
|
@@ -31,6 +32,19 @@ def __init__(self, timestep: Scalar): | |
| timestep, BOAT_PROPERTIES.mass, BOAT_PROPERTIES.inertia | ||
| ) | ||
|
|
||
| self.__sail_force_computation = MediumForceComputation( | ||
| BOAT_PROPERTIES.sail_lift_coeffs, | ||
| BOAT_PROPERTIES.sail_drag_coeffs, | ||
| BOAT_PROPERTIES.sail_areas, | ||
| BOAT_PROPERTIES.air_density, | ||
| ) | ||
| self.__rudder_force_computation = MediumForceComputation( | ||
| BOAT_PROPERTIES.rudder_lift_coeffs, | ||
| BOAT_PROPERTIES.rudder_drag_coeffs, | ||
| BOAT_PROPERTIES.rudder_areas, | ||
| BOAT_PROPERTIES.water_density, | ||
| ) | ||
|
|
||
| def step( | ||
| self, | ||
| glo_wind_vel: NDArray, | ||
|
|
@@ -88,8 +102,71 @@ def __compute_net_force_and_torque( | |
| the relative reference frame, expressed in newtons (N), and the second element | ||
| represents the net torque, expressed in newton-meters (N•m). | ||
| """ | ||
| # TODO Implement this function | ||
| return (np.array([0, 0, 0]), np.array([0, 0, 0])) | ||
| # Compute apparent wind and water velocities as ND arrays (2-D) | ||
|
|
||
| assert np.any(rel_wind_vel), "rel_wind_vel cannot be 0" | ||
| assert np.any(rel_water_vel), "rel_water_vel cannot be 0" | ||
|
|
||
| apparent_wind_vel = np.subtract(rel_wind_vel, self.relative_velocity[0:2]) | ||
| apparent_water_vel = np.subtract(rel_water_vel, self.relative_velocity[0:2]) | ||
|
Comment on lines
+114
to
+115
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please check if slicing (
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stevenxu27, any update on this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should have been fixed. Will check tomorrow to confirm. |
||
|
|
||
| # angle references all in radians | ||
| wind_angle = np.arctan2(rel_wind_vel[1], rel_wind_vel[0]) | ||
| trim_tab_angle_rad = np.radians(trim_tab_angle) | ||
| main_sail_angle = wind_angle - trim_tab_angle_rad | ||
| rudder_angle_rad = np.radians(rudder_angle_deg) | ||
|
|
||
| # Calculate Forces on sail and rudder | ||
| sail_force = self.__sail_force_computation.compute(apparent_wind_vel[0:2], trim_tab_angle) | ||
| rudder_force = self.__rudder_force_computation.compute( | ||
| apparent_water_vel[0:2], rudder_angle_deg | ||
| ) | ||
|
|
||
| # Calculate Hull Drag Force | ||
| hull_drag_force = self.relative_velocity[0:2] * BOAT_PROPERTIES.hull_drag_factor | ||
|
|
||
| # Total Force Calculation | ||
| total_drag_force = sail_force[1] + rudder_force[1] + hull_drag_force | ||
| total_force = sail_force[0] + rudder_force[0] + total_drag_force | ||
|
|
||
| # Calculating magnitudes of sail | ||
| sail_drag = np.linalg.norm(sail_force[1], ord=2) | ||
| sail_lift = np.linalg.norm(sail_force[0], ord=2) | ||
|
|
||
| # Calculating Total Torque | ||
| sail_lift_constant = ( | ||
| BOAT_PROPERTIES.mast_position[1] # position of sail mount | ||
| - ( | ||
| BOAT_PROPERTIES.sail_dist * np.cos(main_sail_angle) | ||
| ) # distance of sail with changes to trim tab angle | ||
| - BOAT_PROPERTIES.centre_of_gravity[1] # point to take torque around | ||
| ) | ||
| sail_drag_constant = BOAT_PROPERTIES.sail_dist * np.sin(main_sail_angle) | ||
|
|
||
| sail_torque = np.add(sail_drag * sail_drag_constant, sail_lift * sail_lift_constant) | ||
|
|
||
| # Calculating magnitudes of rudder | ||
| rudder_drag = np.linalg.norm(rudder_force[1], ord=2) | ||
| rudder_lift = np.linalg.norm(rudder_force[0], ord=2) | ||
|
|
||
| rudder_drag_constant = BOAT_PROPERTIES.rudder_dist * np.sin(rudder_angle_rad) | ||
|
|
||
| rudder_lift_constant = ( | ||
| BOAT_PROPERTIES.rudder_dist * np.cos(rudder_angle_rad) | ||
| + BOAT_PROPERTIES.centre_of_gravity[1] | ||
| ) | ||
|
|
||
| # adding total rudder torque | ||
| rudder_torque = np.add( | ||
| rudder_lift * rudder_lift_constant, | ||
| rudder_drag * rudder_drag_constant, | ||
| ) | ||
|
|
||
| total_torque = np.add(sail_torque, rudder_torque) # Sum torques about z-axis | ||
|
|
||
| final_torque = np.array([0, 0, total_torque]) # generate 3-D array(only z component) | ||
|
|
||
| return (total_force, final_torque) | ||
|
|
||
| @property | ||
| def global_position(self) -> NDArray: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,87 @@ | ||
| """Tests classes and functions in boat_simulator/nodes/physics_engine/model.py""" | ||
|
|
||
| import numpy as np | ||
| import pytest | ||
|
|
||
| class TestBoatState: | ||
| pass | ||
| from boat_simulator.common.constants import BOAT_PROPERTIES | ||
| from boat_simulator.nodes.physics_engine.model import BoatState | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "rel_wind_vel, rel_water_vel, rudder_angle_deg, trim_tab_angle, timestep", | ||
| [ | ||
| (np.array([1, 2]), np.array([1, 2]), 45, 45, 1), | ||
| (np.array([1, 2]), np.array([1, 2]), 45, 45, 1), | ||
| (np.array([4, 5]), np.array([7, 8]), 30, 60, 2), | ||
| (np.array([10, 20]), np.array([15, 25]), 90, 120, 1), | ||
| (np.array([0, 1]), np.array([1, 1]), 0, 90, 3), | ||
| (np.array([-1, -2]), np.array([-1, -2]), 180, 270, 2), | ||
| (np.array([3.5, 4.5]), np.array([1.5, 2.5]), 15, 75, 4), | ||
| (np.array([100, 200]), np.array([300, 200]), 0, 45, 2), | ||
| # cannot use 0 vector, or will error | ||
| ], | ||
| ) | ||
| def test_compute_net_force_torque( | ||
| rel_wind_vel, | ||
| rel_water_vel, | ||
| rudder_angle_deg, | ||
| trim_tab_angle, | ||
| timestep, | ||
| ): | ||
|
|
||
| current_state = BoatState(timestep) | ||
| net_force = current_state._BoatState__compute_net_force_and_torque( | ||
| rel_wind_vel, rel_water_vel, rudder_angle_deg, trim_tab_angle | ||
| ) | ||
|
|
||
| app_wind_vel = np.subtract(rel_wind_vel, current_state.relative_velocity[0:2]) | ||
| app_water_vel = np.subtract(rel_water_vel, current_state.relative_velocity[0:2]) | ||
|
|
||
| wind_angle = np.arctan2(app_wind_vel[1], app_wind_vel[0]) | ||
| trim_tab_angle_rad = np.radians(trim_tab_angle) | ||
| main_sail_angle = wind_angle - trim_tab_angle_rad | ||
| rudder_angle_rad = np.radians(rudder_angle_deg) | ||
|
|
||
| test_sail_force = current_state._BoatState__sail_force_computation.compute( | ||
| app_wind_vel, trim_tab_angle | ||
| ) | ||
| test_rudder_force = current_state._BoatState__rudder_force_computation.compute( | ||
| app_water_vel, rudder_angle_deg | ||
| ) | ||
|
|
||
| hull_drag_force = current_state.relative_velocity[0:2] * BOAT_PROPERTIES.hull_drag_factor | ||
|
|
||
| total_drag_force = test_sail_force[1] + test_rudder_force[1] + hull_drag_force | ||
| total_force = test_sail_force[0] + test_rudder_force[0] + total_drag_force | ||
|
|
||
| sail_drag = np.linalg.norm(test_sail_force[1], ord=2) | ||
| sail_lift = np.linalg.norm(test_sail_force[0], ord=2) | ||
|
|
||
| sail_lift_constant = ( | ||
| BOAT_PROPERTIES.mast_position[1] | ||
| - (BOAT_PROPERTIES.sail_dist * np.cos(main_sail_angle)) | ||
| - BOAT_PROPERTIES.centre_of_gravity[1] | ||
| ) | ||
|
|
||
| sail_drag_constant = BOAT_PROPERTIES.sail_dist * np.sin(main_sail_angle) | ||
|
|
||
| sail_torque = np.add(sail_drag * sail_drag_constant, sail_lift * sail_lift_constant) | ||
|
|
||
| rudder_drag = np.linalg.norm(test_rudder_force[1], ord=2) | ||
| rudder_lift = np.linalg.norm(test_rudder_force[0], ord=2) | ||
|
|
||
| rudder_drag_constant = BOAT_PROPERTIES.rudder_dist * np.sin(rudder_angle_rad) | ||
|
|
||
| rudder_lift_constant = ( | ||
| BOAT_PROPERTIES.rudder_dist * np.cos(rudder_angle_rad) | ||
| + BOAT_PROPERTIES.centre_of_gravity[1] | ||
| ) | ||
|
|
||
| rudder_torque = np.add(rudder_lift * rudder_lift_constant, rudder_drag * rudder_drag_constant) | ||
|
|
||
| total_torque = np.add(sail_torque, rudder_torque) | ||
|
|
||
| final_torque = np.array([0, 0, total_torque]) | ||
|
|
||
| assert np.allclose(total_force, net_force[0], 0.5) # checking force | ||
| assert np.allclose(final_torque, net_force[1], 0.5) # checking torque |
Uh oh!
There was an error while loading. Please reload this page.