2013-08-29 02:34:47 -03:00
|
|
|
/*
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2010-12-19 12:40:33 -04:00
|
|
|
/*
|
2017-01-10 19:46:43 -04:00
|
|
|
* ArduCopter (also known as APM, APM:Copter or just Copter)
|
|
|
|
* Wiki: copter.ardupilot.org
|
2013-05-03 04:58:00 -03:00
|
|
|
* Creator: Jason Short
|
|
|
|
* Lead Developer: Randy Mackay
|
2013-11-15 23:10:38 -04:00
|
|
|
* Lead Tester: Marco Robustini
|
|
|
|
* Based on code and ideas from the Arducopter team: Leonard Hall, Andrew Tridgell, Robert Lefebvre, Pat Hickey, Michael Oborne, Jani Hirvinen,
|
|
|
|
Olivier Adler, Kevin Hester, Arthur Benemann, Jonathan Challinger, John Arne Birkeland,
|
|
|
|
Jean-Louis Naudin, Mike Smith, and more
|
|
|
|
* Thanks to: Chris Anderson, Jordi Munoz, Jason Short, Doug Weibel, Jose Julio
|
2012-08-21 23:19:50 -03:00
|
|
|
*
|
2013-11-15 23:10:38 -04:00
|
|
|
* Special Thanks to contributors (in alphabetical order by first name):
|
2012-08-21 23:19:50 -03:00
|
|
|
*
|
2014-04-23 23:26:10 -03:00
|
|
|
* Adam M Rivera :Auto Compass Declination
|
|
|
|
* Amilcar Lucas :Camera mount library
|
|
|
|
* Andrew Tridgell :General development, Mavlink Support
|
|
|
|
* Angel Fernandez :Alpha testing
|
2013-11-15 23:10:38 -04:00
|
|
|
* AndreasAntonopoulous:GeoFence
|
|
|
|
* Arthur Benemann :DroidPlanner GCS
|
|
|
|
* Benjamin Pelletier :Libraries
|
|
|
|
* Bill King :Single Copter
|
2014-04-23 23:26:10 -03:00
|
|
|
* Christof Schmid :Alpha testing
|
2013-11-15 23:10:38 -04:00
|
|
|
* Craig Elder :Release Management, Support
|
2013-01-11 02:28:08 -04:00
|
|
|
* Dani Saez :V Octo Support
|
2014-04-23 23:26:10 -03:00
|
|
|
* Doug Weibel :DCM, Libraries, Control law advice
|
|
|
|
* Emile Castelnuovo :VRBrain port, bug fixes
|
|
|
|
* Gregory Fletcher :Camera mount orientation math
|
|
|
|
* Guntars :Arming safety suggestion
|
|
|
|
* HappyKillmore :Mavlink GCS
|
2013-11-15 23:10:38 -04:00
|
|
|
* Hein Hollander :Octo Support, Heli Testing
|
2012-08-21 23:19:50 -03:00
|
|
|
* Igor van Airde :Control Law optimization
|
2014-04-23 23:26:10 -03:00
|
|
|
* Jack Dunkle :Alpha testing
|
|
|
|
* James Goppert :Mavlink Support
|
|
|
|
* Jani Hiriven :Testing feedback
|
2013-11-15 23:10:38 -04:00
|
|
|
* Jean-Louis Naudin :Auto Landing
|
2012-08-21 23:19:50 -03:00
|
|
|
* John Arne Birkeland :PPM Encoder
|
2014-04-23 23:26:10 -03:00
|
|
|
* Jose Julio :Stabilization Control laws, MPU6k driver
|
2014-07-11 02:08:09 -03:00
|
|
|
* Julien Dubois :PosHold flight mode
|
2013-11-15 23:10:38 -04:00
|
|
|
* Julian Oes :Pixhawk
|
|
|
|
* Jonathan Challinger :Inertial Navigation, CompassMot, Spin-When-Armed
|
|
|
|
* Kevin Hester :Andropilot GCS
|
2014-04-23 23:26:10 -03:00
|
|
|
* Max Levine :Tri Support, Graphics
|
|
|
|
* Leonard Hall :Flight Dynamics, Throttle, Loiter and Navigation Controllers
|
|
|
|
* Marco Robustini :Lead tester
|
|
|
|
* Michael Oborne :Mission Planner GCS
|
|
|
|
* Mike Smith :Pixhawk driver, coding support
|
2013-11-15 23:10:38 -04:00
|
|
|
* Olivier Adler :PPM Encoder, piezo buzzer
|
2014-04-23 23:26:10 -03:00
|
|
|
* Pat Hickey :Hardware Abstraction Layer (HAL)
|
|
|
|
* Robert Lefebvre :Heli Support, Copter LEDs
|
2013-11-15 23:10:38 -04:00
|
|
|
* Roberto Navoni :Library testing, Porting to VRBrain
|
|
|
|
* Sandro Benigno :Camera support, MinimOSD
|
2014-07-11 02:08:09 -03:00
|
|
|
* Sandro Tognana :PosHold flight mode
|
2013-11-15 23:10:38 -04:00
|
|
|
* ..and many more.
|
2012-08-21 23:19:50 -03:00
|
|
|
*
|
2016-03-25 06:46:54 -03:00
|
|
|
* Code commit statistics can be found here: https://github.com/ArduPilot/ardupilot/graphs/contributors
|
2016-04-23 17:59:02 -03:00
|
|
|
* Wiki: http://copter.ardupilot.org/
|
2013-11-15 23:10:38 -04:00
|
|
|
* Requires modified version of Arduino, which can be found here: http://ardupilot.com/downloads/?category=6
|
2012-08-21 23:19:50 -03:00
|
|
|
*
|
|
|
|
*/
|
2010-12-19 12:40:33 -04:00
|
|
|
|
2015-05-29 23:12:49 -03:00
|
|
|
#include "Copter.h"
|
2014-03-31 04:07:46 -03:00
|
|
|
|
2015-12-26 00:00:03 -04:00
|
|
|
#define SCHED_TASK(func, rate_hz, max_time_micros) SCHED_TASK_CLASS(Copter, &copter, func, rate_hz, max_time_micros)
|
2012-12-14 17:19:35 -04:00
|
|
|
|
2013-12-16 23:25:33 -04:00
|
|
|
/*
|
|
|
|
scheduler table for fast CPUs - all regular tasks apart from the fast_loop()
|
2016-04-19 04:36:45 -03:00
|
|
|
should be listed here, along with how often they should be called (in hz)
|
|
|
|
and the maximum time they are expected to take (in microseconds)
|
2013-12-16 23:25:33 -04:00
|
|
|
*/
|
2015-10-25 14:03:46 -03:00
|
|
|
const AP_Scheduler::Task Copter::scheduler_tasks[] = {
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(rc_loop, 100, 130),
|
|
|
|
SCHED_TASK(throttle_loop, 50, 75),
|
|
|
|
SCHED_TASK(update_GPS, 50, 200),
|
2014-07-11 23:33:49 -03:00
|
|
|
#if OPTFLOW == ENABLED
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(update_optical_flow, 200, 160),
|
2015-05-29 23:12:49 -03:00
|
|
|
#endif
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(update_batt_compass, 10, 120),
|
|
|
|
SCHED_TASK(read_aux_switches, 10, 50),
|
|
|
|
SCHED_TASK(arm_motors_check, 10, 50),
|
|
|
|
SCHED_TASK(auto_disarm_check, 10, 50),
|
|
|
|
SCHED_TASK(auto_trim, 10, 75),
|
2016-05-20 22:19:53 -03:00
|
|
|
SCHED_TASK(read_rangefinder, 20, 100),
|
2016-08-15 03:53:45 -03:00
|
|
|
SCHED_TASK(update_proximity, 100, 50),
|
2016-10-26 23:37:49 -03:00
|
|
|
SCHED_TASK(update_beacon, 400, 50),
|
2016-05-20 22:19:53 -03:00
|
|
|
SCHED_TASK(update_altitude, 10, 100),
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(run_nav_updates, 50, 100),
|
2016-06-09 09:42:15 -03:00
|
|
|
SCHED_TASK(update_throttle_hover,100, 90),
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(three_hz_loop, 3, 75),
|
|
|
|
SCHED_TASK(compass_accumulate, 100, 100),
|
|
|
|
SCHED_TASK(barometer_accumulate, 50, 90),
|
2015-02-16 00:39:18 -04:00
|
|
|
#if PRECISION_LANDING == ENABLED
|
2016-07-05 18:48:59 -03:00
|
|
|
SCHED_TASK(update_precland, 400, 50),
|
2015-02-16 00:39:18 -04:00
|
|
|
#endif
|
2013-12-16 23:25:33 -04:00
|
|
|
#if FRAME_CONFIG == HELI_FRAME
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(check_dynamic_flight, 50, 75),
|
2015-05-29 23:12:49 -03:00
|
|
|
#endif
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(update_notify, 50, 90),
|
|
|
|
SCHED_TASK(one_hz_loop, 1, 100),
|
|
|
|
SCHED_TASK(ekf_check, 10, 75),
|
|
|
|
SCHED_TASK(landinggear_update, 10, 75),
|
|
|
|
SCHED_TASK(lost_vehicle_check, 10, 50),
|
|
|
|
SCHED_TASK(gcs_check_input, 400, 180),
|
|
|
|
SCHED_TASK(gcs_send_heartbeat, 1, 110),
|
|
|
|
SCHED_TASK(gcs_send_deferred, 50, 550),
|
|
|
|
SCHED_TASK(gcs_data_stream_send, 50, 550),
|
|
|
|
SCHED_TASK(update_mount, 50, 75),
|
2016-01-19 01:26:14 -04:00
|
|
|
SCHED_TASK(update_trigger, 50, 75),
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(ten_hz_logging_loop, 10, 350),
|
2016-05-03 00:21:23 -03:00
|
|
|
SCHED_TASK(twentyfive_hz_logging, 25, 110),
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(dataflash_periodic, 400, 300),
|
|
|
|
SCHED_TASK(perf_update, 0.1, 75),
|
|
|
|
SCHED_TASK(read_receiver_rssi, 10, 75),
|
|
|
|
SCHED_TASK(rpm_update, 10, 200),
|
|
|
|
SCHED_TASK(compass_cal_update, 100, 100),
|
2015-10-16 19:05:53 -03:00
|
|
|
SCHED_TASK(accel_cal_update, 10, 100),
|
2015-11-27 00:53:08 -04:00
|
|
|
#if ADSB_ENABLED == ENABLED
|
2016-08-17 04:49:50 -03:00
|
|
|
SCHED_TASK(avoidance_adsb_update, 10, 100),
|
2016-08-16 07:23:27 -03:00
|
|
|
#endif
|
|
|
|
#if ADVANCED_FAILSAFE == ENABLED
|
|
|
|
SCHED_TASK(afs_fs_check, 10, 100),
|
2014-07-28 19:25:40 -03:00
|
|
|
#endif
|
2016-03-19 03:25:13 -03:00
|
|
|
SCHED_TASK(terrain_update, 10, 100),
|
2016-10-28 19:08:22 -03:00
|
|
|
#if GRIPPER_ENABLED == ENABLED
|
|
|
|
SCHED_TASK(gripper_update, 10, 75),
|
|
|
|
#endif
|
2013-12-16 23:25:33 -04:00
|
|
|
#ifdef USERHOOK_FASTLOOP
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(userhook_FastLoop, 100, 75),
|
2013-12-16 23:25:33 -04:00
|
|
|
#endif
|
|
|
|
#ifdef USERHOOK_50HZLOOP
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(userhook_50Hz, 50, 75),
|
2013-12-16 23:25:33 -04:00
|
|
|
#endif
|
|
|
|
#ifdef USERHOOK_MEDIUMLOOP
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(userhook_MediumLoop, 10, 75),
|
2013-12-16 23:25:33 -04:00
|
|
|
#endif
|
|
|
|
#ifdef USERHOOK_SLOWLOOP
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(userhook_SlowLoop, 3.3, 75),
|
2013-12-16 23:25:33 -04:00
|
|
|
#endif
|
|
|
|
#ifdef USERHOOK_SUPERSLOWLOOP
|
2015-12-26 00:00:03 -04:00
|
|
|
SCHED_TASK(userhook_SuperSlowLoop, 1, 75),
|
2013-12-16 23:25:33 -04:00
|
|
|
#endif
|
2016-07-21 22:24:13 -03:00
|
|
|
SCHED_TASK(button_update, 5, 100),
|
2016-10-13 06:34:25 -03:00
|
|
|
SCHED_TASK(stats_update, 1, 100),
|
2013-12-16 23:25:33 -04:00
|
|
|
};
|
2013-01-11 21:01:10 -04:00
|
|
|
|
2015-05-29 23:12:49 -03:00
|
|
|
|
|
|
|
void Copter::setup()
|
2013-12-28 01:02:32 -04:00
|
|
|
{
|
2012-12-13 22:16:32 -04:00
|
|
|
cliSerial = hal.console;
|
|
|
|
|
|
|
|
// Load the default values of variables listed in var_info[]s
|
2012-12-14 17:19:35 -04:00
|
|
|
AP_Param::setup_sketch_defaults();
|
2012-12-12 19:53:48 -04:00
|
|
|
|
2014-08-13 01:44:31 -03:00
|
|
|
// setup storage layout for copter
|
|
|
|
StorageManager::set_layout_copter();
|
|
|
|
|
2012-08-21 23:19:50 -03:00
|
|
|
init_ardupilot();
|
2013-01-11 21:01:10 -04:00
|
|
|
|
|
|
|
// initialise the main loop scheduler
|
2015-07-06 12:30:40 -03:00
|
|
|
scheduler.init(&scheduler_tasks[0], ARRAY_SIZE(scheduler_tasks));
|
2015-02-15 19:02:53 -04:00
|
|
|
|
|
|
|
// setup initial performance counters
|
|
|
|
perf_info_reset();
|
2015-11-19 23:04:45 -04:00
|
|
|
fast_loopTimer = AP_HAL::micros();
|
2010-12-19 12:40:33 -04:00
|
|
|
}
|
|
|
|
|
2013-01-06 20:02:50 -04:00
|
|
|
/*
|
2013-01-08 01:45:12 -04:00
|
|
|
if the compass is enabled then try to accumulate a reading
|
2013-01-06 20:02:50 -04:00
|
|
|
*/
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::compass_accumulate(void)
|
2013-01-08 01:45:12 -04:00
|
|
|
{
|
|
|
|
if (g.compass_enabled) {
|
|
|
|
compass.accumulate();
|
2013-10-29 01:28:27 -03:00
|
|
|
}
|
2013-01-08 01:45:12 -04:00
|
|
|
}
|
|
|
|
|
2013-01-09 08:08:19 -04:00
|
|
|
/*
|
|
|
|
try to accumulate a baro reading
|
|
|
|
*/
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::barometer_accumulate(void)
|
2013-01-09 08:08:19 -04:00
|
|
|
{
|
|
|
|
barometer.accumulate();
|
|
|
|
}
|
|
|
|
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::perf_update(void)
|
2013-01-06 20:02:50 -04:00
|
|
|
{
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_PM))
|
2013-01-08 01:45:12 -04:00
|
|
|
Log_Write_Performance();
|
2013-01-11 21:06:40 -04:00
|
|
|
if (scheduler.debug()) {
|
2015-11-04 13:32:01 -04:00
|
|
|
gcs_send_text_fmt(MAV_SEVERITY_WARNING, "PERF: %u/%u %lu %lu\n",
|
2015-02-15 19:02:53 -04:00
|
|
|
(unsigned)perf_info_get_num_long_running(),
|
|
|
|
(unsigned)perf_info_get_num_loops(),
|
|
|
|
(unsigned long)perf_info_get_max_time(),
|
|
|
|
(unsigned long)perf_info_get_min_time());
|
2013-01-11 21:06:40 -04:00
|
|
|
}
|
2013-01-08 01:45:12 -04:00
|
|
|
perf_info_reset();
|
2013-04-29 09:30:22 -03:00
|
|
|
pmTest1 = 0;
|
2013-01-06 20:02:50 -04:00
|
|
|
}
|
|
|
|
|
2016-10-13 06:34:25 -03:00
|
|
|
/*
|
|
|
|
update AP_Stats
|
|
|
|
*/
|
|
|
|
void Copter::stats_update(void)
|
|
|
|
{
|
|
|
|
g2.stats.update();
|
|
|
|
}
|
|
|
|
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::loop()
|
2010-12-19 12:40:33 -04:00
|
|
|
{
|
2013-10-08 03:30:43 -03:00
|
|
|
// wait for an INS sample
|
2014-10-15 20:33:24 -03:00
|
|
|
ins.wait_for_sample();
|
|
|
|
|
2012-11-10 01:39:41 -04:00
|
|
|
uint32_t timer = micros();
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2013-10-08 03:30:43 -03:00
|
|
|
// check loop time
|
|
|
|
perf_info_check_loop_time(timer - fast_loopTimer);
|
2012-11-18 12:16:07 -04:00
|
|
|
|
2013-10-08 03:30:43 -03:00
|
|
|
// used by PI Loops
|
2015-04-24 02:19:45 -03:00
|
|
|
G_Dt = (float)(timer - fast_loopTimer) / 1000000.0f;
|
2013-10-08 03:30:43 -03:00
|
|
|
fast_loopTimer = timer;
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2013-10-08 03:30:43 -03:00
|
|
|
// for mainloop failure monitoring
|
|
|
|
mainLoop_count++;
|
2012-10-09 00:30:17 -03:00
|
|
|
|
2013-10-08 03:30:43 -03:00
|
|
|
// Execute the fast loop
|
|
|
|
// ---------------------
|
|
|
|
fast_loop();
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2013-10-08 03:30:43 -03:00
|
|
|
// tell the scheduler one tick has passed
|
|
|
|
scheduler.tick();
|
2013-07-23 04:05:16 -03:00
|
|
|
|
2013-10-08 03:30:43 -03:00
|
|
|
// run all the tasks that are due to run. Note that we only
|
|
|
|
// have to call this once per loop, as the tasks are scheduled
|
|
|
|
// in multiples of the main loop tick. So if they don't run on
|
|
|
|
// the first call to the scheduler they won't run on a later
|
|
|
|
// call until scheduler.tick() is called again
|
2013-12-16 23:25:33 -04:00
|
|
|
uint32_t time_available = (timer + MAIN_LOOP_MICROS) - micros();
|
2016-08-05 11:16:13 -03:00
|
|
|
scheduler.run(time_available > MAIN_LOOP_MICROS ? 0u : time_available);
|
2010-12-19 12:40:33 -04:00
|
|
|
}
|
2011-07-10 21:47:08 -03:00
|
|
|
|
2013-01-08 01:45:12 -04:00
|
|
|
|
2015-05-28 15:59:49 -03:00
|
|
|
// Main loop - 400hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::fast_loop()
|
2010-12-19 12:40:33 -04:00
|
|
|
{
|
2017-04-02 22:05:14 -03:00
|
|
|
// update INS immediately to get current gyro data populated
|
|
|
|
ins.update();
|
|
|
|
|
2017-03-02 07:50:29 -04:00
|
|
|
// run low level rate controllers that only require IMU data
|
|
|
|
attitude_control->rate_controller_run();
|
2013-12-17 00:58:11 -04:00
|
|
|
|
2017-04-02 22:05:14 -03:00
|
|
|
// send outputs to the motors library immediately
|
|
|
|
motors_output();
|
|
|
|
|
|
|
|
// run EKF state estimator (expensive)
|
2012-08-21 23:19:50 -03:00
|
|
|
// --------------------
|
|
|
|
read_AHRS();
|
2011-09-19 18:02:42 -03:00
|
|
|
|
2014-05-09 18:07:52 -03:00
|
|
|
#if FRAME_CONFIG == HELI_FRAME
|
|
|
|
update_heli_control_dynamics();
|
|
|
|
#endif //HELI_FRAME
|
2013-01-11 01:32:40 -04:00
|
|
|
|
2012-08-21 23:19:50 -03:00
|
|
|
// Inertial Nav
|
|
|
|
// --------------------
|
2012-11-07 06:03:30 -04:00
|
|
|
read_inertia();
|
2012-06-14 02:27:03 -03:00
|
|
|
|
2016-10-10 03:35:08 -03:00
|
|
|
// check if ekf has reset target heading or position
|
|
|
|
check_ekf_reset();
|
2015-06-23 04:49:42 -03:00
|
|
|
|
2014-01-11 04:03:05 -04:00
|
|
|
// run the attitude controllers
|
|
|
|
update_flight_mode();
|
2015-02-26 01:34:21 -04:00
|
|
|
|
|
|
|
// update home from EKF if necessary
|
|
|
|
update_home_from_EKF();
|
2015-04-16 15:35:17 -03:00
|
|
|
|
2015-06-17 08:37:15 -03:00
|
|
|
// check if we've landed or crashed
|
|
|
|
update_land_and_crash_detectors();
|
2015-07-12 10:06:21 -03:00
|
|
|
|
2016-01-13 23:16:42 -04:00
|
|
|
#if MOUNT == ENABLED
|
2016-01-05 01:20:48 -04:00
|
|
|
// camera mount's fast update
|
|
|
|
camera_mount.update_fast();
|
2016-01-13 23:16:42 -04:00
|
|
|
#endif
|
2016-01-05 01:20:48 -04:00
|
|
|
|
2015-07-12 10:06:21 -03:00
|
|
|
// log sensor health
|
|
|
|
if (should_log(MASK_LOG_ANY)) {
|
|
|
|
Log_Sensor_Health();
|
|
|
|
}
|
2013-12-16 23:25:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// rc_loops - reads user input from transmitter/receiver
|
|
|
|
// called at 100hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::rc_loop()
|
2013-12-16 23:25:33 -04:00
|
|
|
{
|
2012-11-12 23:50:51 -04:00
|
|
|
// Read radio and 3-position switch on radio
|
|
|
|
// -----------------------------------------
|
|
|
|
read_radio();
|
|
|
|
read_control_switch();
|
2010-12-19 12:40:33 -04:00
|
|
|
}
|
|
|
|
|
2013-10-11 05:03:26 -03:00
|
|
|
// throttle_loop - should be run at 50 hz
|
2013-05-19 23:05:14 -03:00
|
|
|
// ---------------------------
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::throttle_loop()
|
2013-05-19 23:05:14 -03:00
|
|
|
{
|
2015-03-09 09:16:08 -03:00
|
|
|
// update throttle_low_comp value (controls priority of throttle vs attitude control)
|
2015-05-03 11:21:44 -03:00
|
|
|
update_throttle_thr_mix();
|
2015-03-09 09:16:08 -03:00
|
|
|
|
2013-05-19 23:05:14 -03:00
|
|
|
// check auto_armed status
|
|
|
|
update_auto_armed();
|
2013-11-06 08:39:39 -04:00
|
|
|
|
|
|
|
#if FRAME_CONFIG == HELI_FRAME
|
2013-11-08 04:29:54 -04:00
|
|
|
// update rotor speed
|
|
|
|
heli_update_rotor_speed_targets();
|
|
|
|
|
2013-11-06 08:39:39 -04:00
|
|
|
// update trad heli swash plate movement
|
|
|
|
heli_update_landing_swash();
|
|
|
|
#endif
|
2015-12-22 15:27:24 -04:00
|
|
|
|
2016-08-08 05:16:36 -03:00
|
|
|
// compensate for ground effect (if enabled)
|
2015-12-22 15:27:24 -04:00
|
|
|
update_ground_effect_detector();
|
2013-10-11 05:03:26 -03:00
|
|
|
}
|
2013-05-19 23:05:14 -03:00
|
|
|
|
2013-10-11 08:40:20 -03:00
|
|
|
// update_mount - update camera mount position
|
2013-10-11 05:03:26 -03:00
|
|
|
// should be run at 50hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::update_mount()
|
2013-10-11 05:03:26 -03:00
|
|
|
{
|
2013-05-19 23:05:14 -03:00
|
|
|
#if MOUNT == ENABLED
|
|
|
|
// update camera mount's position
|
2015-01-11 02:37:26 -04:00
|
|
|
camera_mount.update();
|
2013-05-19 23:05:14 -03:00
|
|
|
#endif
|
2015-06-07 14:20:25 -03:00
|
|
|
}
|
2013-05-19 23:05:14 -03:00
|
|
|
|
2015-06-07 14:20:25 -03:00
|
|
|
// update camera trigger
|
|
|
|
void Copter::update_trigger(void)
|
|
|
|
{
|
2013-05-19 23:05:14 -03:00
|
|
|
#if CAMERA == ENABLED
|
|
|
|
camera.trigger_pic_cleanup();
|
2016-01-19 01:26:14 -04:00
|
|
|
if (camera.check_trigger_pin()) {
|
|
|
|
gcs_send_message(MSG_CAMERA_FEEDBACK);
|
|
|
|
if (should_log(MASK_LOG_CAMERA)) {
|
|
|
|
DataFlash.Log_Write_Camera(ahrs, gps, current_loc);
|
|
|
|
}
|
2015-06-07 14:20:25 -03:00
|
|
|
}
|
2013-05-19 23:05:14 -03:00
|
|
|
#endif
|
2013-10-11 05:03:26 -03:00
|
|
|
}
|
|
|
|
|
2013-10-11 08:40:20 -03:00
|
|
|
// update_batt_compass - read battery and compass
|
|
|
|
// should be called at 10hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::update_batt_compass(void)
|
2013-10-11 08:40:20 -03:00
|
|
|
{
|
|
|
|
// read battery before compass because it may be used for motor interference compensation
|
|
|
|
read_battery();
|
|
|
|
|
|
|
|
if(g.compass_enabled) {
|
2014-02-03 01:06:08 -04:00
|
|
|
// update compass with throttle value - used for compassmot
|
2017-01-09 03:31:26 -04:00
|
|
|
compass.set_throttle(motors->get_throttle());
|
2014-08-15 22:45:11 -03:00
|
|
|
compass.read();
|
2013-10-11 08:40:20 -03:00
|
|
|
// log compass information
|
2016-05-04 01:01:58 -03:00
|
|
|
if (should_log(MASK_LOG_COMPASS) && !ahrs.have_ekf_logging()) {
|
2015-01-16 18:27:37 -04:00
|
|
|
DataFlash.Log_Write_Compass(compass);
|
2013-10-11 08:40:20 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ten_hz_logging_loop
|
|
|
|
// should be run at 10hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::ten_hz_logging_loop()
|
2013-10-11 08:40:20 -03:00
|
|
|
{
|
2015-04-19 23:23:57 -03:00
|
|
|
// log attitude data if we're not already logging at the higher rate
|
|
|
|
if (should_log(MASK_LOG_ATTITUDE_MED) && !should_log(MASK_LOG_ATTITUDE_FAST)) {
|
2014-01-07 09:41:56 -04:00
|
|
|
Log_Write_Attitude();
|
2017-01-09 03:31:26 -04:00
|
|
|
DataFlash.Log_Write_Rate(ahrs, *motors, *attitude_control, *pos_control);
|
2015-05-27 01:32:05 -03:00
|
|
|
if (should_log(MASK_LOG_PID)) {
|
2017-01-09 03:31:26 -04:00
|
|
|
DataFlash.Log_Write_PID(LOG_PIDR_MSG, attitude_control->get_rate_roll_pid().get_pid_info());
|
|
|
|
DataFlash.Log_Write_PID(LOG_PIDP_MSG, attitude_control->get_rate_pitch_pid().get_pid_info());
|
|
|
|
DataFlash.Log_Write_PID(LOG_PIDY_MSG, attitude_control->get_rate_yaw_pid().get_pid_info());
|
2015-05-27 01:32:05 -03:00
|
|
|
DataFlash.Log_Write_PID(LOG_PIDA_MSG, g.pid_accel_z.get_pid_info() );
|
|
|
|
}
|
2015-03-04 02:21:01 -04:00
|
|
|
}
|
2015-03-18 09:08:30 -03:00
|
|
|
if (should_log(MASK_LOG_MOTBATT)) {
|
|
|
|
Log_Write_MotBatt();
|
2015-03-04 02:21:01 -04:00
|
|
|
}
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_RCIN)) {
|
2014-01-07 09:41:56 -04:00
|
|
|
DataFlash.Log_Write_RCIN();
|
2015-09-04 12:50:48 -03:00
|
|
|
if (rssi.enabled()) {
|
|
|
|
DataFlash.Log_Write_RSSI(rssi);
|
|
|
|
}
|
2014-01-07 09:41:56 -04:00
|
|
|
}
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_RCOUT)) {
|
2014-01-07 09:41:56 -04:00
|
|
|
DataFlash.Log_Write_RCOUT();
|
2013-10-11 08:40:20 -03:00
|
|
|
}
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_NTUN) && (mode_requires_GPS(control_mode) || landing_with_GPS())) {
|
2014-01-21 23:56:07 -04:00
|
|
|
Log_Write_Nav_Tuning();
|
|
|
|
}
|
2015-06-11 22:28:13 -03:00
|
|
|
if (should_log(MASK_LOG_IMU) || should_log(MASK_LOG_IMU_FAST) || should_log(MASK_LOG_IMU_RAW)) {
|
|
|
|
DataFlash.Log_Write_Vibration(ins);
|
|
|
|
}
|
2016-06-29 01:43:44 -03:00
|
|
|
if (should_log(MASK_LOG_CTUN)) {
|
2017-01-09 03:31:26 -04:00
|
|
|
attitude_control->control_monitor_log();
|
2016-08-16 09:09:17 -03:00
|
|
|
Log_Write_Proximity();
|
2016-10-27 01:40:55 -03:00
|
|
|
Log_Write_Beacon();
|
2016-06-29 01:43:44 -03:00
|
|
|
}
|
2015-06-18 18:09:39 -03:00
|
|
|
#if FRAME_CONFIG == HELI_FRAME
|
|
|
|
Log_Write_Heli();
|
|
|
|
#endif
|
2013-10-11 08:40:20 -03:00
|
|
|
}
|
|
|
|
|
2016-10-22 01:31:10 -03:00
|
|
|
// twentyfive_hz_logging - should be run at 25hz
|
2016-05-03 00:21:23 -03:00
|
|
|
void Copter::twentyfive_hz_logging()
|
2013-10-11 05:03:26 -03:00
|
|
|
{
|
|
|
|
#if HIL_MODE != HIL_MODE_DISABLED
|
|
|
|
// HIL for a copter needs very fast update of the servo values
|
2017-01-10 11:19:55 -04:00
|
|
|
gcs_send_message(MSG_SERVO_OUTPUT_RAW);
|
2013-10-11 05:03:26 -03:00
|
|
|
#endif
|
2013-05-19 23:05:14 -03:00
|
|
|
|
2014-01-07 09:41:56 -04:00
|
|
|
#if HIL_MODE == HIL_MODE_DISABLED
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_ATTITUDE_FAST)) {
|
2013-05-19 23:05:14 -03:00
|
|
|
Log_Write_Attitude();
|
2017-01-09 03:31:26 -04:00
|
|
|
DataFlash.Log_Write_Rate(ahrs, *motors, *attitude_control, *pos_control);
|
2015-05-27 01:32:05 -03:00
|
|
|
if (should_log(MASK_LOG_PID)) {
|
2017-01-09 03:31:26 -04:00
|
|
|
DataFlash.Log_Write_PID(LOG_PIDR_MSG, attitude_control->get_rate_roll_pid().get_pid_info());
|
|
|
|
DataFlash.Log_Write_PID(LOG_PIDP_MSG, attitude_control->get_rate_pitch_pid().get_pid_info());
|
|
|
|
DataFlash.Log_Write_PID(LOG_PIDY_MSG, attitude_control->get_rate_yaw_pid().get_pid_info());
|
2015-05-27 01:32:05 -03:00
|
|
|
DataFlash.Log_Write_PID(LOG_PIDA_MSG, g.pid_accel_z.get_pid_info() );
|
|
|
|
}
|
2013-05-19 23:05:14 -03:00
|
|
|
}
|
|
|
|
|
2015-04-19 23:23:57 -03:00
|
|
|
// log IMU data if we're not already logging at the higher rate
|
2016-05-03 00:21:23 -03:00
|
|
|
if (should_log(MASK_LOG_IMU) && !should_log(MASK_LOG_IMU_RAW)) {
|
2013-11-03 23:37:46 -04:00
|
|
|
DataFlash.Log_Write_IMU(ins);
|
2014-01-07 09:41:56 -04:00
|
|
|
}
|
2013-05-19 23:05:14 -03:00
|
|
|
#endif
|
2016-07-05 18:48:59 -03:00
|
|
|
|
|
|
|
#if PRECISION_LANDING == ENABLED
|
|
|
|
// log output
|
|
|
|
Log_Write_Precland();
|
|
|
|
#endif
|
2013-05-19 23:05:14 -03:00
|
|
|
}
|
|
|
|
|
2015-08-06 09:18:39 -03:00
|
|
|
void Copter::dataflash_periodic(void)
|
|
|
|
{
|
|
|
|
DataFlash.periodic_tasks();
|
|
|
|
}
|
|
|
|
|
2013-10-11 08:40:20 -03:00
|
|
|
// three_hz_loop - 3.3hz loop
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::three_hz_loop()
|
2010-12-19 12:40:33 -04:00
|
|
|
{
|
2013-10-11 08:40:20 -03:00
|
|
|
// check if we've lost contact with the ground station
|
|
|
|
failsafe_gcs_check();
|
2012-04-04 10:50:43 -03:00
|
|
|
|
2016-04-22 08:37:48 -03:00
|
|
|
// check if we've lost terrain data
|
|
|
|
failsafe_terrain_check();
|
|
|
|
|
2013-04-26 06:51:07 -03:00
|
|
|
#if AC_FENCE == ENABLED
|
2013-10-11 08:40:20 -03:00
|
|
|
// check if we have breached a fence
|
|
|
|
fence_check();
|
2013-04-26 06:51:07 -03:00
|
|
|
#endif // AC_FENCE_ENABLED
|
|
|
|
|
2013-08-04 11:20:21 -03:00
|
|
|
#if SPRAYER == ENABLED
|
2013-10-11 08:40:20 -03:00
|
|
|
sprayer.update();
|
2012-08-21 23:19:50 -03:00
|
|
|
#endif
|
2011-06-01 02:50:17 -03:00
|
|
|
|
2013-10-11 08:40:20 -03:00
|
|
|
update_events();
|
2011-02-17 05:36:33 -04:00
|
|
|
|
2015-01-16 02:12:58 -04:00
|
|
|
// update ch6 in flight tuning
|
|
|
|
tuning();
|
2010-12-19 12:40:33 -04:00
|
|
|
}
|
|
|
|
|
2013-10-11 08:40:20 -03:00
|
|
|
// one_hz_loop - runs at 1Hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::one_hz_loop()
|
2011-02-25 01:33:39 -04:00
|
|
|
{
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_ANY)) {
|
2013-01-12 11:17:44 -04:00
|
|
|
Log_Write_Data(DATA_AP_STATE, ap.value);
|
|
|
|
}
|
2012-11-11 21:59:53 -04:00
|
|
|
|
2017-01-09 03:45:48 -04:00
|
|
|
arming.update();
|
2013-04-22 12:01:20 -03:00
|
|
|
|
2017-01-09 03:31:26 -04:00
|
|
|
if (!motors->armed()) {
|
2013-10-11 08:40:20 -03:00
|
|
|
// make it possible to change ahrs orientation at runtime during initial config
|
2013-06-03 03:52:52 -03:00
|
|
|
ahrs.set_orientation();
|
2013-10-11 08:40:20 -03:00
|
|
|
|
2015-11-15 21:58:15 -04:00
|
|
|
update_using_interlock();
|
|
|
|
|
2016-12-12 06:22:56 -04:00
|
|
|
// check the user hasn't updated the frame class or type
|
2017-01-09 03:31:26 -04:00
|
|
|
motors->set_frame_class_and_type((AP_Motors::motor_frame_class)g2.frame_class.get(), (AP_Motors::motor_frame_type)g.frame_type.get());
|
2015-05-14 22:04:41 -03:00
|
|
|
|
2016-12-12 06:22:56 -04:00
|
|
|
#if FRAME_CONFIG != HELI_FRAME
|
2015-05-14 22:04:41 -03:00
|
|
|
// set all throttle channel settings
|
2017-01-09 03:31:26 -04:00
|
|
|
motors->set_throttle_range(channel_throttle->get_radio_min(), channel_throttle->get_radio_max());
|
2015-07-15 02:35:20 -03:00
|
|
|
#endif
|
2013-06-03 03:52:52 -03:00
|
|
|
}
|
|
|
|
|
2015-10-13 16:19:05 -03:00
|
|
|
// update assigned functions and enable auxiliary servos
|
2017-01-06 21:06:40 -04:00
|
|
|
SRV_Channels::enable_aux_servos();
|
2013-10-11 08:40:20 -03:00
|
|
|
|
|
|
|
check_usb_mux();
|
2014-07-22 05:22:36 -03:00
|
|
|
|
2015-05-06 23:09:00 -03:00
|
|
|
// enable/disable raw gyro/accel logging
|
|
|
|
ins.set_raw_logging(should_log(MASK_LOG_IMU_RAW));
|
2016-03-19 03:25:13 -03:00
|
|
|
|
|
|
|
// log terrain data
|
|
|
|
terrain_logging();
|
2016-07-21 02:43:46 -03:00
|
|
|
|
|
|
|
adsb.set_is_flying(!ap.land_complete);
|
2016-09-20 16:42:24 -03:00
|
|
|
|
|
|
|
// update error mask of sensors and subsystems. The mask uses the
|
|
|
|
// MAV_SYS_STATUS_* values from mavlink. If a bit is set then it
|
|
|
|
// indicates that the sensor or subsystem is present but not
|
|
|
|
// functioning correctly
|
|
|
|
update_sensor_status_flags();
|
2011-02-25 01:33:39 -04:00
|
|
|
}
|
|
|
|
|
2012-05-21 13:58:14 -03:00
|
|
|
// called at 50hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::update_GPS(void)
|
2010-12-19 12:40:33 -04:00
|
|
|
{
|
2014-04-09 21:30:10 -03:00
|
|
|
static uint32_t last_gps_reading[GPS_MAX_INSTANCES]; // time of last gps message
|
|
|
|
bool gps_updated = false;
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2014-03-31 04:07:46 -03:00
|
|
|
gps.update();
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2015-03-12 23:05:30 -03:00
|
|
|
// log after every gps message
|
2014-04-09 21:30:10 -03:00
|
|
|
for (uint8_t i=0; i<gps.num_sensors(); i++) {
|
|
|
|
if (gps.last_message_time_ms(i) != last_gps_reading[i]) {
|
|
|
|
last_gps_reading[i] = gps.last_message_time_ms(i);
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2014-04-09 21:30:10 -03:00
|
|
|
// log GPS message
|
2016-05-04 01:01:58 -03:00
|
|
|
if (should_log(MASK_LOG_GPS) && !ahrs.have_ekf_logging()) {
|
|
|
|
DataFlash.Log_Write_GPS(gps, i);
|
2014-04-09 21:30:10 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
gps_updated = true;
|
2013-03-25 04:25:13 -03:00
|
|
|
}
|
2014-04-09 21:30:10 -03:00
|
|
|
}
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2014-04-09 21:30:10 -03:00
|
|
|
if (gps_updated) {
|
2015-02-09 07:23:49 -04:00
|
|
|
// set system time if necessary
|
|
|
|
set_system_time_from_GPS();
|
2014-03-31 04:07:46 -03:00
|
|
|
|
2015-02-09 07:23:49 -04:00
|
|
|
// checks to initialise home and take location based pictures
|
|
|
|
if (gps.status() >= AP_GPS::GPS_OK_FIX_3D) {
|
2014-06-06 19:17:38 -03:00
|
|
|
|
2013-06-24 23:52:44 -03:00
|
|
|
#if CAMERA == ENABLED
|
2015-12-18 03:16:11 -04:00
|
|
|
if (camera.update_location(current_loc, copter.ahrs) == true) {
|
2014-03-31 04:07:46 -03:00
|
|
|
do_take_picture();
|
|
|
|
}
|
2013-10-29 01:28:27 -03:00
|
|
|
#endif
|
2014-03-31 04:07:46 -03:00
|
|
|
}
|
2012-08-21 23:19:50 -03:00
|
|
|
}
|
2010-12-19 12:40:33 -04:00
|
|
|
}
|
2011-02-17 05:36:33 -04:00
|
|
|
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::init_simple_bearing()
|
2012-01-04 02:54:29 -04:00
|
|
|
{
|
2013-10-05 06:25:03 -03:00
|
|
|
// capture current cos_yaw and sin_yaw values
|
2014-02-08 03:40:45 -04:00
|
|
|
simple_cos_yaw = ahrs.cos_yaw();
|
|
|
|
simple_sin_yaw = ahrs.sin_yaw();
|
2012-01-04 02:54:29 -04:00
|
|
|
|
2013-10-05 06:25:03 -03:00
|
|
|
// initialise super simple heading (i.e. heading towards home) to be 180 deg from simple mode heading
|
|
|
|
super_simple_last_bearing = wrap_360_cd(ahrs.yaw_sensor+18000);
|
|
|
|
super_simple_cos_yaw = simple_cos_yaw;
|
|
|
|
super_simple_sin_yaw = simple_sin_yaw;
|
2012-01-04 02:54:29 -04:00
|
|
|
|
2013-10-05 06:25:03 -03:00
|
|
|
// log the simple bearing to dataflash
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_ANY)) {
|
2013-10-05 06:25:03 -03:00
|
|
|
Log_Write_Data(DATA_INIT_SIMPLE_BEARING, ahrs.yaw_sensor);
|
|
|
|
}
|
|
|
|
}
|
2012-01-04 02:54:29 -04:00
|
|
|
|
2013-10-05 06:25:03 -03:00
|
|
|
// update_simple_mode - rotates pilot input if we are in simple mode
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::update_simple_mode(void)
|
2013-10-05 06:25:03 -03:00
|
|
|
{
|
|
|
|
float rollx, pitchx;
|
2012-01-04 02:54:29 -04:00
|
|
|
|
2013-10-05 06:25:03 -03:00
|
|
|
// exit immediately if no new radio frame or not in simple mode
|
2013-10-08 03:25:14 -03:00
|
|
|
if (ap.simple_mode == 0 || !ap.new_radio_frame) {
|
2013-10-05 06:25:03 -03:00
|
|
|
return;
|
2012-08-21 23:19:50 -03:00
|
|
|
}
|
2012-01-04 02:54:29 -04:00
|
|
|
|
2014-03-28 05:03:31 -03:00
|
|
|
// mark radio frame as consumed
|
|
|
|
ap.new_radio_frame = false;
|
|
|
|
|
2013-10-05 06:25:03 -03:00
|
|
|
if (ap.simple_mode == 1) {
|
|
|
|
// rotate roll, pitch input by -initial simple heading (i.e. north facing)
|
ArduCopter: Fix up after refactoring RC_Channel class
Further to refactor of RC_Channel class which included
adding get_xx set_xx methods, change reads and writes to the public members
to calls to get and set functionsss
old public member(int16_t) get function -> int16_t set function (int16_t)
(expression where c is an object of type RC_Channel)
c.radio_in c.get_radio_in() c.set_radio_in(v)
c.control_in c.get_control_in() c.set_control_in(v)
c.servo_out c.get_servo_out() c.set_servo_out(v)
c.pwm_out c.get_pwm_out() // use existing
c.radio_out c.get_radio_out() c.set_radio_out(v)
c.radio_max c.get_radio_max() c.set_radio_max(v)
c.radio_min c.get_radio_min() c.set_radio_min(v)
c.radio_trim c.get_radio_trim() c.set_radio_trim(v);
c.min_max_configured() // return true if min and max are configured
Because data members of RC_Channels are now private and so cannot be written directly
some overloads are provided in the Plane classes to provide the old functionality
new overload Plane::stick_mix_channel(RC_Channel *channel)
which forwards to the previously existing
void stick_mix_channel(RC_Channel *channel, int16_t &servo_out);
new overload Plane::channel_output_mixer(Rc_Channel* , RC_Channel*)const
which forwards to
(uint8_t mixing_type, int16_t & chan1, int16_t & chan2)const;
Rename functions
RC_Channel_aux::set_radio_trim(Aux_servo_function_t function)
to RC_Channel_aux::set_trim_to_radio_in_for(Aux_servo_function_t function)
RC_Channel_aux::set_servo_out(Aux_servo_function_t function, int16_t value)
to RC_Channel_aux::set_servo_out_for(Aux_servo_function_t function, int16_t value)
Rationale:
RC_Channel is a complicated class, which combines
several functionalities dealing with stick inputs
in pwm and logical units, logical and actual actuator
outputs, unit conversion etc, etc
The intent of this PR is to clarify existing use of
the class. At the basic level it should now be possible
to grep all places where private variable is set by
searching for the set_xx function.
(The wider purpose is to provide a more generic and
logically simpler method of output mixing. This is a small step)
2016-05-08 05:46:59 -03:00
|
|
|
rollx = channel_roll->get_control_in()*simple_cos_yaw - channel_pitch->get_control_in()*simple_sin_yaw;
|
|
|
|
pitchx = channel_roll->get_control_in()*simple_sin_yaw + channel_pitch->get_control_in()*simple_cos_yaw;
|
2013-10-05 06:25:03 -03:00
|
|
|
}else{
|
|
|
|
// rotate roll, pitch input by -super simple heading (reverse of heading to home)
|
ArduCopter: Fix up after refactoring RC_Channel class
Further to refactor of RC_Channel class which included
adding get_xx set_xx methods, change reads and writes to the public members
to calls to get and set functionsss
old public member(int16_t) get function -> int16_t set function (int16_t)
(expression where c is an object of type RC_Channel)
c.radio_in c.get_radio_in() c.set_radio_in(v)
c.control_in c.get_control_in() c.set_control_in(v)
c.servo_out c.get_servo_out() c.set_servo_out(v)
c.pwm_out c.get_pwm_out() // use existing
c.radio_out c.get_radio_out() c.set_radio_out(v)
c.radio_max c.get_radio_max() c.set_radio_max(v)
c.radio_min c.get_radio_min() c.set_radio_min(v)
c.radio_trim c.get_radio_trim() c.set_radio_trim(v);
c.min_max_configured() // return true if min and max are configured
Because data members of RC_Channels are now private and so cannot be written directly
some overloads are provided in the Plane classes to provide the old functionality
new overload Plane::stick_mix_channel(RC_Channel *channel)
which forwards to the previously existing
void stick_mix_channel(RC_Channel *channel, int16_t &servo_out);
new overload Plane::channel_output_mixer(Rc_Channel* , RC_Channel*)const
which forwards to
(uint8_t mixing_type, int16_t & chan1, int16_t & chan2)const;
Rename functions
RC_Channel_aux::set_radio_trim(Aux_servo_function_t function)
to RC_Channel_aux::set_trim_to_radio_in_for(Aux_servo_function_t function)
RC_Channel_aux::set_servo_out(Aux_servo_function_t function, int16_t value)
to RC_Channel_aux::set_servo_out_for(Aux_servo_function_t function, int16_t value)
Rationale:
RC_Channel is a complicated class, which combines
several functionalities dealing with stick inputs
in pwm and logical units, logical and actual actuator
outputs, unit conversion etc, etc
The intent of this PR is to clarify existing use of
the class. At the basic level it should now be possible
to grep all places where private variable is set by
searching for the set_xx function.
(The wider purpose is to provide a more generic and
logically simpler method of output mixing. This is a small step)
2016-05-08 05:46:59 -03:00
|
|
|
rollx = channel_roll->get_control_in()*super_simple_cos_yaw - channel_pitch->get_control_in()*super_simple_sin_yaw;
|
|
|
|
pitchx = channel_roll->get_control_in()*super_simple_sin_yaw + channel_pitch->get_control_in()*super_simple_cos_yaw;
|
2013-10-05 06:25:03 -03:00
|
|
|
}
|
2012-01-04 02:54:29 -04:00
|
|
|
|
2013-10-05 06:25:03 -03:00
|
|
|
// rotate roll, pitch input from north facing to vehicle's perspective
|
ArduCopter: Fix up after refactoring RC_Channel class
Further to refactor of RC_Channel class which included
adding get_xx set_xx methods, change reads and writes to the public members
to calls to get and set functionsss
old public member(int16_t) get function -> int16_t set function (int16_t)
(expression where c is an object of type RC_Channel)
c.radio_in c.get_radio_in() c.set_radio_in(v)
c.control_in c.get_control_in() c.set_control_in(v)
c.servo_out c.get_servo_out() c.set_servo_out(v)
c.pwm_out c.get_pwm_out() // use existing
c.radio_out c.get_radio_out() c.set_radio_out(v)
c.radio_max c.get_radio_max() c.set_radio_max(v)
c.radio_min c.get_radio_min() c.set_radio_min(v)
c.radio_trim c.get_radio_trim() c.set_radio_trim(v);
c.min_max_configured() // return true if min and max are configured
Because data members of RC_Channels are now private and so cannot be written directly
some overloads are provided in the Plane classes to provide the old functionality
new overload Plane::stick_mix_channel(RC_Channel *channel)
which forwards to the previously existing
void stick_mix_channel(RC_Channel *channel, int16_t &servo_out);
new overload Plane::channel_output_mixer(Rc_Channel* , RC_Channel*)const
which forwards to
(uint8_t mixing_type, int16_t & chan1, int16_t & chan2)const;
Rename functions
RC_Channel_aux::set_radio_trim(Aux_servo_function_t function)
to RC_Channel_aux::set_trim_to_radio_in_for(Aux_servo_function_t function)
RC_Channel_aux::set_servo_out(Aux_servo_function_t function, int16_t value)
to RC_Channel_aux::set_servo_out_for(Aux_servo_function_t function, int16_t value)
Rationale:
RC_Channel is a complicated class, which combines
several functionalities dealing with stick inputs
in pwm and logical units, logical and actual actuator
outputs, unit conversion etc, etc
The intent of this PR is to clarify existing use of
the class. At the basic level it should now be possible
to grep all places where private variable is set by
searching for the set_xx function.
(The wider purpose is to provide a more generic and
logically simpler method of output mixing. This is a small step)
2016-05-08 05:46:59 -03:00
|
|
|
channel_roll->set_control_in(rollx*ahrs.cos_yaw() + pitchx*ahrs.sin_yaw());
|
|
|
|
channel_pitch->set_control_in(-rollx*ahrs.sin_yaw() + pitchx*ahrs.cos_yaw());
|
2011-09-04 21:15:36 -03:00
|
|
|
}
|
2011-07-10 21:47:08 -03:00
|
|
|
|
2013-01-27 10:48:07 -04:00
|
|
|
// update_super_simple_bearing - adjusts simple bearing based on location
|
2013-01-24 00:36:55 -04:00
|
|
|
// should be called after home_bearing has been updated
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::update_super_simple_bearing(bool force_update)
|
2013-01-24 00:36:55 -04:00
|
|
|
{
|
2013-10-05 06:25:03 -03:00
|
|
|
// check if we are in super simple mode and at least 10m from home
|
|
|
|
if(force_update || (ap.simple_mode == 2 && home_distance > SUPER_SIMPLE_RADIUS)) {
|
|
|
|
// check the bearing to home has changed by at least 5 degrees
|
|
|
|
if (labs(super_simple_last_bearing - home_bearing) > 500) {
|
|
|
|
super_simple_last_bearing = home_bearing;
|
|
|
|
float angle_rad = radians((super_simple_last_bearing+18000)/100);
|
|
|
|
super_simple_cos_yaw = cosf(angle_rad);
|
|
|
|
super_simple_sin_yaw = sinf(angle_rad);
|
2013-01-24 00:36:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::read_AHRS(void)
|
2010-12-19 12:40:33 -04:00
|
|
|
{
|
2012-08-21 23:19:50 -03:00
|
|
|
// Perform IMU calculations and get attitude info
|
|
|
|
//-----------------------------------------------
|
|
|
|
#if HIL_MODE != HIL_MODE_DISABLED
|
|
|
|
// update hil before ahrs update
|
2013-01-08 01:45:12 -04:00
|
|
|
gcs_check_input();
|
2012-08-21 23:19:50 -03:00
|
|
|
#endif
|
|
|
|
|
2017-04-02 22:05:14 -03:00
|
|
|
// we tell AHRS to skip INS update as we have already done it in fast_loop()
|
|
|
|
ahrs.update(true);
|
2011-01-23 12:40:03 -04:00
|
|
|
}
|
2011-02-13 18:32:34 -04:00
|
|
|
|
2016-04-27 08:37:04 -03:00
|
|
|
// read baro and rangefinder altitude at 10hz
|
2015-05-29 23:12:49 -03:00
|
|
|
void Copter::update_altitude()
|
2011-02-21 00:30:56 -04:00
|
|
|
{
|
2013-02-01 23:00:09 -04:00
|
|
|
// read in baro altitude
|
2014-10-22 04:07:10 -03:00
|
|
|
read_barometer();
|
2012-08-21 23:19:50 -03:00
|
|
|
|
2013-02-01 23:00:09 -04:00
|
|
|
// write altitude info to dataflash logs
|
2014-10-16 21:37:49 -03:00
|
|
|
if (should_log(MASK_LOG_CTUN)) {
|
2013-02-01 23:00:09 -04:00
|
|
|
Log_Write_Control_Tuning();
|
2012-08-21 23:19:50 -03:00
|
|
|
}
|
2011-03-26 03:35:52 -03:00
|
|
|
}
|
|
|
|
|
2016-01-19 01:26:14 -04:00
|
|
|
AP_HAL_MAIN_CALLBACKS(&copter);
|