LCOV - code coverage report
Current view: top level - SITL - SIM_Multicopter.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 47 49 95.9 %
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             :   multicopter simulator class
      17             : */
      18             : 
      19             : #include "SIM_Multicopter.h"
      20             : #include <AP_Motors/AP_Motors.h>
      21             : 
      22             : #include <stdio.h>
      23             : 
      24             : using namespace SITL;
      25             : 
      26         909 : MultiCopter::MultiCopter(const char *frame_str) :
      27         909 :     Aircraft(frame_str)
      28             : {
      29         909 :     frame = Frame::create_frame(frame_str);
      30         909 :     if (frame == nullptr) {
      31           0 :         printf("Frame '%s' not found or insufficient memory", frame_str);
      32           0 :         exit(1);
      33             :     }
      34             : 
      35         909 :     frame->init(frame_str);
      36        1818 :     battery.setup(frame->get_model_batt_capacity_ah(),
      37         909 :                   frame->get_model_batt_resistance_ohm(),
      38         909 :                   frame->get_model_batt_max_voltage(),
      39             :                   ambient_outside_temperature_degC());
      40             : 
      41         909 :     mass = frame->get_mass();
      42         909 :     frame_height = 0.1;
      43         909 :     ground_behavior = GROUND_BEHAVIOR_NO_MOVEMENT;
      44         909 :     lock_step_scheduled = true;
      45         909 : }
      46             : 
      47             : // calculate rotational and linear accelerations
      48    81459271 : void MultiCopter::calculate_forces(const struct sitl_input &input, Vector3f &rot_accel, Vector3f &body_accel)
      49             : {
      50    81459271 :     motor_mask |= ((1U<<frame->num_motors)-1U) << frame->motor_offset;
      51    81459271 :     frame->calculate_forces(*this, input, rot_accel, body_accel, rpm);
      52             : 
      53    81459271 :     add_shove_forces(rot_accel, body_accel);
      54    81459271 :     add_twist_forces(rot_accel);
      55             : 
      56             :     // add forces from slung payload or tether payload
      57    81459271 :     add_external_forces(body_accel);
      58    81459271 : }
      59             : 
      60             : /*
      61             :   update the multicopter simulation by one time step
      62             :  */
      63    81459271 : void MultiCopter::update(const struct sitl_input &input)
      64             : {
      65             :     // refresh mass in case SIM_FRM_ parameters have changed
      66    81459271 :     mass = frame->get_mass();
      67             : 
      68             :     // get wind vector setup
      69    81459271 :     update_wind(input);
      70             : 
      71    81459271 :     Vector3f rot_accel;
      72             : 
      73    81459271 :     calculate_forces(input, rot_accel, accel_body);
      74             :     // simulated clamp holding vehicle down
      75    81459271 :     if (clamp.clamped(*this, input)) {
      76       74045 :         rot_accel.zero();
      77       74045 :         accel_body.zero();
      78             :     }
      79             : 
      80    81459271 :     update_battery();
      81    81459271 :     update_dynamics(rot_accel);
      82    81459271 :     update_external_payload(input);
      83             : 
      84             :     // update lat/lon/altitude
      85    81459271 :     update_position();
      86    81459271 :     time_advance();
      87             : 
      88             :     // update magnetic field
      89    81459271 :     update_mag_field_bf();
      90    81459271 : }
      91             : 
      92    81459271 : void MultiCopter::update_battery() {
      93    81459271 :     if (frame->battery_changed()) {
      94             :         // battery model changed via SIM_FRM_ parameters
      95        1818 :         battery.setup(frame->get_model_batt_capacity_ah(),
      96         909 :                       frame->get_model_batt_resistance_ohm(),
      97         909 :                       frame->get_model_batt_max_voltage(),
      98             :                       ambient_outside_temperature_degC());
      99             :     }
     100    81459271 :     battery.maybe_reset(sitl->batt_voltage, sitl->batt_capacity_ah, sitl->batt_resistance);
     101    81459271 :     battery_voltage = battery.get_voltage();
     102    81459271 :     battery_current = frame->get_current_amp();
     103    81459271 :     battery_temperature_degC = battery.get_temperature_degC();
     104             : 
     105    81459271 :     const uint64_t now_us = AP_HAL::micros64();
     106    81459271 :     battery.consume_energy(battery_current, now_us);
     107    81459271 : }

Generated by: LCOV version 1.14