LCOV - code coverage report
Current view: top level - SITL - SIM_Motor.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 47 47 100.0 %
Date: 2026-09-09 11:02:08 Functions: 4 4 100.0 %

          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             :   simple electric motor simulation class
      17             : */
      18             : 
      19             : #pragma once
      20             : 
      21             : #include <AP_Math/AP_Math.h>
      22             : #include <SITL/SITL_Input.h>
      23             : 
      24             : namespace SITL {
      25             : 
      26             : /*
      27             :   class to describe a motor position
      28             :  */
      29             : class Motor {
      30             : public:
      31             :     float angle;
      32             :     float yaw_factor;
      33             :     uint8_t servo;
      34             :     uint8_t display_order;
      35             : 
      36             :     // support for tilting motors
      37             :     int8_t roll_servo = -1;
      38             :     float roll_min, roll_max;
      39             :     int8_t pitch_servo = -1;
      40             :     float pitch_min, pitch_max;
      41             : 
      42             :     // support for variable-pitch (collective) rotors; the motor's
      43             :     // own servo channel commands blade pitch and rotor speed comes
      44             :     // from a shared rotor-speed-control servo
      45             :     int8_t rsc_servo = -1;
      46             : 
      47             :     // support for servo slew rate
      48             :     enum {SERVO_NORMAL, SERVO_RETRACT} servo_type;
      49             :     float servo_rate = 0.24; // seconds per 60 degrees
      50             :     uint64_t last_change_usec;
      51             :     float last_roll_value, last_pitch_value;
      52             : 
      53      456885 :     Motor(uint8_t _servo, float _angle, float _yaw_factor, uint8_t _display_order) :
      54      456885 :         angle(_angle), // angle in degrees from front
      55      456885 :         yaw_factor(_yaw_factor), // positive is clockwise
      56      456885 :         servo(_servo), // what servo output drives this motor
      57      456885 :         display_order(_display_order) // order for clockwise display
      58             :     {
      59      456885 :         position.x = cosf(radians(angle));
      60      456885 :         position.y =  sinf(radians(angle));
      61      456885 :         position.z = 0;
      62             : 
      63      456885 :         thrust_vector.x = 0;
      64      456885 :         thrust_vector.y = 0;
      65      456885 :         thrust_vector.z = -1;
      66      456885 :     }
      67             : 
      68             :     /*
      69             :       alternative constructor for variable-pitch rotors
      70             :      */
      71        8580 :     Motor(uint8_t _servo, float _angle, float _yaw_factor, uint8_t _display_order,
      72        8580 :           int8_t _rsc_servo) :
      73        8580 :         angle(_angle), // angle in degrees from front
      74        8580 :         yaw_factor(_yaw_factor), // positive is clockwise
      75        8580 :         servo(_servo), // what servo output drives this motor's blade pitch
      76        8580 :         display_order(_display_order), // order for clockwise display
      77        8580 :         rsc_servo(_rsc_servo) // what servo output drives the rotor speed
      78             :     {
      79        8580 :         position.x = cosf(radians(angle));
      80        8580 :         position.y =  sinf(radians(angle));
      81        8580 :         position.z = 0;
      82             : 
      83        8580 :         thrust_vector.x = 0;
      84        8580 :         thrust_vector.y = 0;
      85        8580 :         thrust_vector.z = -1;
      86        8580 :     }
      87             : 
      88             :     /*
      89             :       alternative constructor for tiltable motors
      90             :      */
      91       34320 :     Motor(uint8_t _servo, float _angle, float _yaw_factor, uint8_t _display_order,
      92             :           int8_t _roll_servo, float _roll_min, float _roll_max,
      93       34320 :           int8_t _pitch_servo, float _pitch_min, float _pitch_max) :
      94       34320 :         angle(_angle), // angle in degrees from front
      95       34320 :         yaw_factor(_yaw_factor), // positive is clockwise
      96       34320 :         servo(_servo), // what servo output drives this motor
      97       34320 :         display_order(_display_order), // order for clockwise display
      98       34320 :         roll_servo(_roll_servo),
      99       34320 :         roll_min(_roll_min),
     100       34320 :         roll_max(_roll_max),
     101       34320 :         pitch_servo(_pitch_servo),
     102       34320 :         pitch_min(_pitch_min),
     103       34320 :         pitch_max(_pitch_max)
     104             :     {
     105       34320 :         position.x = cosf(radians(angle));
     106       34320 :         position.y =  sinf(radians(angle));
     107       34320 :         position.z = 0;
     108             : 
     109       34320 :         thrust_vector.x = 0;
     110       34320 :         thrust_vector.y = 0;
     111       34320 :         thrust_vector.z = -1;
     112       34320 :     }
     113             : 
     114             :     void calculate_forces(const struct sitl_input &input,
     115             :                           uint8_t motor_offset,
     116             :                           Vector3f &torque, // Newton meters
     117             :                           Vector3f &thrust, // Z is down, Newtons
     118             :                           const Vector3f &velocity_air_bf,
     119             :                           const Vector3f &gyro, // rad/sec
     120             :                           float air_density,
     121             :                           float voltage,
     122             :                           bool use_drag);
     123             : 
     124             :     uint16_t update_servo(uint16_t demand, uint64_t time_usec, float &last_value) const;
     125             : 
     126             :     // get current
     127             :     float get_current(void) const;
     128             : 
     129             :     // convert a PWM value to a thrust demand from 0 to 1
     130             :     float pwm_to_command(float pwm) const;
     131             : 
     132             :     // setup motor key parameters
     133             :     void setup_params(uint16_t _pwm_min, uint16_t _pwm_max, float _spin_min, float _spin_max, float _expo, float _slew_max,
     134             :                       float _diagonal_size, float _power_factor, float _voltage_max, float _effective_prop_area,
     135             :                       float _velocity_max, Vector3f _position, Vector3f _thrust_vector, float _yaw_factor,
     136             :                       float _true_prop_area, float _momentum_drag_coefficient);
     137             : 
     138             :     // override slew limit
     139             :     void set_slew_max(float _slew_max) {
     140             :         slew_max = _slew_max;
     141             :     }
     142             : 
     143    17508600 :     float get_command(void) const {
     144    17508600 :         return last_command;
     145             :     }
     146             : 
     147             :     // calculate thrust of motor
     148             :     float calc_thrust(float command, float air_density, float velocity_in, float voltage_scale) const;
     149             : 
     150             : private:
     151             :     float mot_pwm_min;
     152             :     float mot_pwm_max;
     153             :     float mot_spin_min;
     154             :     float mot_spin_max;
     155             :     float mot_expo;
     156             :     float slew_max;
     157             :     float current;
     158             :     float power_factor;
     159             :     float voltage_max;
     160             :     float effective_prop_area;
     161             :     float max_outflow_velocity;
     162             :     float true_prop_area;
     163             :     float momentum_drag_coefficient;
     164             :     float diagonal_size;
     165             : 
     166             :     float last_command;
     167             :     uint64_t last_calc_us;
     168             : 
     169             :     Vector3f position;
     170             :     Vector3f thrust_vector;
     171             : };
     172             : 
     173             : }

Generated by: LCOV version 1.14