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 : singlecopter simulator class 17 : */ 18 : 19 : #include "SIM_SingleCopter.h" 20 : 21 : #include <stdio.h> 22 : 23 : using namespace SITL; 24 : 25 2 : SingleCopter::SingleCopter(const char *frame_str) : 26 2 : Aircraft(frame_str) 27 : { 28 2 : mass = 2.0f; 29 : 30 2 : if (strstr(frame_str, "coax")) { 31 1 : frame_type = FRAME_COAX; 32 : } else { 33 1 : frame_type = FRAME_SINGLE; 34 : } 35 : 36 : /* 37 : scaling from motor power to Newtons. Allows the copter 38 : to hover against gravity when the motor is at hover_throttle 39 : */ 40 2 : thrust_scale = (mass * GRAVITY_MSS) / hover_throttle; 41 2 : frame_height = 0.1; 42 2 : lock_step_scheduled = true; 43 2 : } 44 : 45 : /* 46 : update the copter simulation by one time step 47 : */ 48 308161 : void SingleCopter::update(const struct sitl_input &input) 49 : { 50 : // get wind vector setup 51 308161 : update_wind(input); 52 : 53 : float actuator[4]; 54 1540805 : for (uint8_t i=0; i<4; i++) { 55 1232644 : actuator[i] = constrain_float((input.servos[i]-1500) / 500.0f, -1, 1); 56 : } 57 : float thrust; 58 : float yaw_thrust; 59 : float roll_thrust; 60 : float pitch_thrust; 61 : 62 308161 : switch (frame_type) { 63 154058 : case FRAME_SINGLE: 64 154058 : thrust = constrain_float((input.servos[4]-1000) / 1000.0f, 0, 1); 65 154058 : yaw_thrust = -(actuator[0] + actuator[1] + actuator[2] + actuator[3]) * 0.25f * thrust + thrust * rotor_rot_accel; 66 154058 : roll_thrust = (actuator[0] - actuator[2]) * 0.5f * thrust; 67 154058 : pitch_thrust = (actuator[1] - actuator[3]) * 0.5f * thrust; 68 154058 : break; 69 : 70 154103 : case FRAME_COAX: 71 : default: { 72 154103 : float motor1 = constrain_float((input.servos[4]-1000) / 1000.0f, 0, 1); 73 154103 : float motor2 = constrain_float((input.servos[5]-1000) / 1000.0f, 0, 1); 74 154103 : thrust = 0.5f*(motor1 + motor2); 75 154103 : yaw_thrust = -(actuator[0] + actuator[1] + actuator[2] + actuator[3]) * 0.25f * thrust + (motor2 - motor1) * rotor_rot_accel; 76 154103 : roll_thrust = (actuator[0] - actuator[2]) * 0.5f * thrust; 77 154103 : pitch_thrust = (actuator[1] - actuator[3]) * 0.5f * thrust; 78 154103 : break; 79 : } 80 : } 81 : 82 : // rotational acceleration, in rad/s/s, in body frame 83 308161 : Vector3f rot_accel(roll_thrust * roll_rate_max, 84 308161 : pitch_thrust * pitch_rate_max, 85 308161 : yaw_thrust * yaw_rate_max); 86 : 87 : // rotational air resistance 88 308161 : rot_accel.x -= gyro.x * radians(5000.0) / terminal_rotation_rate; 89 308161 : rot_accel.y -= gyro.y * radians(5000.0) / terminal_rotation_rate; 90 308161 : rot_accel.z -= gyro.z * radians(400.0) / terminal_rotation_rate; 91 : 92 : // air resistance 93 308161 : Vector3f air_resistance = -velocity_air_ef * (GRAVITY_MSS/terminal_velocity) / eas2tas; 94 : 95 : // scale thrust to newtons 96 308161 : thrust *= thrust_scale; 97 : 98 308161 : accel_body = Vector3f(0, 0, -thrust / mass); 99 308161 : accel_body += dcm.transposed() * air_resistance; 100 : 101 308161 : update_dynamics(rot_accel); 102 : 103 : // update lat/lon/altitude 104 308161 : update_position(); 105 308161 : time_advance(); 106 : 107 : // update magnetic field 108 308161 : update_mag_field_bf(); 109 : 110 308161 : update_battery(); 111 308161 : }