Line data Source code
1 : /* 2 : This program is free software: you can redistribute it and/or modify 3 : it under the terms of the GNU General Public License as published by 4 : the Free Software Foundation, either version 3 of the License, or 5 : (at your option) any later version. 6 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : /* 16 : ROV/AUV/Submarine simulator class 17 : */ 18 : 19 : #pragma once 20 : 21 : #include "SIM_Aircraft.h" 22 : #include "SIM_Motor.h" 23 : #include "SIM_Frame.h" 24 : #include <AP_InternalError/AP_InternalError.h> 25 : 26 : namespace SITL { 27 : 28 : /* 29 : a submarine simulator 30 : */ 31 : 32 : 33 : class Thruster { 34 : public: 35 30030 : Thruster(int8_t _servo, float roll_fac, float pitch_fac, float yaw_fac, float throttle_fac, float forward_fac, float lat_fac) : 36 30030 : servo(_servo) 37 : { 38 30030 : linear = Vector3f(forward_fac, lat_fac, -throttle_fac); 39 30030 : rotational = Vector3f(roll_fac, pitch_fac, yaw_fac); 40 30030 : }; 41 : int8_t servo; 42 : Vector3f linear; 43 : Vector3f rotational; 44 : }; 45 : 46 : class Submarine : public Aircraft { 47 : public: 48 : Submarine(const char *frame_str); 49 : 50 : /* update model by one time step */ 51 : void update(const struct sitl_input &input) override; 52 : 53 : /* static object creator */ 54 83 : static Aircraft *create(const char *frame_str) { 55 83 : return NEW_NOTHROW Submarine(frame_str); 56 : } 57 : 58 : 59 : protected: 60 : const float water_density = 1023.6; // (kg/m^3) At a temperature of 25 °C, salinity of 35 g/kg and 1 atm pressure 61 : 62 : const struct { 63 : float length = 0.457; // x direction (meters) 64 : float width = 0.338; // y direction (meters) 65 : float height = 0.254; // z direction (meters) 66 : float weight = 10.5; // (kg) 67 : float thrust = 51.48; // (N) 68 : float thruster_mount_radius = 0.25; // distance in meters from thrusters to center of mass. Used to calculate torque. 69 : float equivalent_sphere_radius = 0.2; 70 : // volume = 4.pi.r³/3 71 : float volume = 4 * M_PI * powf(equivalent_sphere_radius, 3) / 3; 72 : float density = 500; 73 : float mass = volume * density; // 16.75 kg 74 : // Moment of Inertia (I)(kg.m²) approximated with a sphere with a 25 cm radius (r) and same density as water 75 : // I = 2.m.r²/5 76 : float moment_of_inertia = 2 * (mass * powf(equivalent_sphere_radius, 2) / 5); 77 : 78 : // Frame drag coefficient 79 : const Vector3f linear_drag_coefficient = Vector3f(1.4, 1.8, 2.0); 80 : // Angular drag coefficient CD for a cube is 1.05. This is subject to change based on experimentation. 81 : const Vector3f angular_drag_coefficient = Vector3f(1.05, 1.05, 1.05); 82 : // Calculate equivalent sphere area for drag force 83 : // $ A = pi * r^2 / 4 $ 84 : // $ V = 4 * pi * r^3 / 3 $ 85 : // $ r ^2 = (V * 3 / 4) ^ (2/3) $ 86 : // A = area (m^3), r = sphere radius (m) 87 : float equivalent_sphere_area = M_PI_4 * powf(volume * 3.0f / 4.0f, 2.0f / 3.0f); 88 : 89 : } frame_property; 90 : 91 : bool on_ground() const override; 92 : 93 0 : float rangefinder_beam_width() const override { return 10; } 94 : 95 : float perpendicular_distance_to_rangefinder_surface() const override; 96 : 97 : // calculate sea floor depth based for terrain follow 98 : float calculate_sea_floor_depth(const Vector3d &/*position*/) const; 99 : // calculate rotational and linear accelerations 100 : void calculate_forces(const struct sitl_input &input, Vector3f &rot_accel, Vector3f &body_accel); 101 : // calculate buoyancy 102 : float calculate_buoyancy_acceleration(); 103 : // calculate drag from velocity and drag coefficient 104 : void calculate_drag_force(const Vector3f &velocity, const Vector3f &drag_coefficient, Vector3f &force) const; 105 : // calculate torque water resistance 106 : void calculate_angular_drag_torque(const Vector3f &angular_velocity, const Vector3f &drag_coefficient, Vector3f &torque) const; 107 : // calculate torque induced by buoyancy foams 108 : void calculate_buoyancy_torque(Vector3f &torque); 109 : // compute and set battery usage 110 : void update_battery(const struct sitl_input &input) override; 111 : // Sub needs the sitl_input, should never use the parent's input-free version. 112 : // (Using it would be using the wrong battery model, but it would silently work.) 113 0 : void update_battery() override { INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control); }; 114 40696914 : bool battery_is_empty() { return battery_voltage < 0.5f; }; 115 : 116 : Frame *frame; 117 : Thruster* thrusters; 118 : uint8_t n_thrusters; 119 : }; 120 : }