3 /*****************************************************************************
4 * Functions to check and perform ESC calibration
5 *****************************************************************************/
7 #define ESC_CALIBRATION_HIGH_THROTTLE 950
9 // check if we should enter esc calibration mode
10 void Copter::esc_calibration_startup_check()
12 if (motors
->is_brushed_pwm_type()) {
13 // ESC cal not valid for brushed motors
17 #if FRAME_CONFIG != HELI_FRAME
18 // delay up to 2 second for first radio input
20 while ((i
++ < 100) && (last_radio_update_ms
== 0)) {
21 hal
.scheduler
->delay(20);
25 // exit immediately if pre-arm rc checks fail
26 if (!arming
.rc_calibration_checks(true)) {
27 // clear esc flag for next time
28 if ((g
.esc_calibrate
!= ESCCalibrationModes::ESCCAL_NONE
) && (g
.esc_calibrate
!= ESCCalibrationModes::ESCCAL_DISABLED
)) {
29 g
.esc_calibrate
.set_and_save(ESCCalibrationModes::ESCCAL_NONE
);
34 // check ESC parameter
35 switch (g
.esc_calibrate
) {
36 case ESCCalibrationModes::ESCCAL_NONE
:
37 // check if throttle is high
38 if (channel_throttle
->get_control_in() >= ESC_CALIBRATION_HIGH_THROTTLE
) {
39 // we will enter esc_calibrate mode on next reboot
40 g
.esc_calibrate
.set_and_save(ESCCalibrationModes::ESCCAL_PASSTHROUGH_IF_THROTTLE_HIGH
);
41 // send message to gcs
42 gcs().send_text(MAV_SEVERITY_CRITICAL
,"ESC calibration: Restart board");
43 // turn on esc calibration notification
44 AP_Notify::flags
.esc_calibration
= true;
45 // block until we restart
46 while(1) { hal
.scheduler
->delay(5); }
49 case ESCCalibrationModes::ESCCAL_PASSTHROUGH_IF_THROTTLE_HIGH
:
50 // check if throttle is high
51 if (channel_throttle
->get_control_in() >= ESC_CALIBRATION_HIGH_THROTTLE
) {
52 // pass through pilot throttle to escs
53 esc_calibration_passthrough();
56 case ESCCalibrationModes::ESCCAL_PASSTHROUGH_ALWAYS
:
57 // pass through pilot throttle to escs
58 esc_calibration_passthrough();
60 case ESCCalibrationModes::ESCCAL_AUTO
:
61 // perform automatic ESC calibration
62 esc_calibration_auto();
64 case ESCCalibrationModes::ESCCAL_DISABLED
:
70 // clear esc flag for next time
71 if (g
.esc_calibrate
!= ESCCalibrationModes::ESCCAL_DISABLED
) {
72 g
.esc_calibrate
.set_and_save(ESCCalibrationModes::ESCCAL_NONE
);
74 #endif // FRAME_CONFIG != HELI_FRAME
77 // esc_calibration_passthrough - pass through pilot throttle to escs
78 void Copter::esc_calibration_passthrough()
80 #if FRAME_CONFIG != HELI_FRAME
81 // send message to GCS
82 gcs().send_text(MAV_SEVERITY_INFO
,"ESC calibration: Passing pilot throttle to ESCs");
84 esc_calibration_setup();
88 esc_calibration_notify();
93 // we run at high rate to make oneshot ESCs happy. Normal ESCs
94 // will only see pulses at the RC_SPEED
95 hal
.scheduler
->delay(3);
97 // pass through to motors
98 auto &srv
= AP::srv();
100 motors
->set_throttle_passthrough_for_esc_calibration(channel_throttle
->get_control_in() * 0.001f
);
103 #endif // FRAME_CONFIG != HELI_FRAME
106 // esc_calibration_auto - calibrate the ESCs automatically using a timer and no pilot input
107 void Copter::esc_calibration_auto()
109 #if FRAME_CONFIG != HELI_FRAME
110 // send message to GCS
111 gcs().send_text(MAV_SEVERITY_INFO
,"ESC calibration: Auto calibration");
113 esc_calibration_setup();
115 // raise throttle to maximum
116 auto &srv
= AP::srv();
118 motors
->set_throttle_passthrough_for_esc_calibration(1.0f
);
121 // delay for 5 seconds while outputting pulses
122 uint32_t tstart
= millis();
123 while (millis() - tstart
< 5000) {
125 motors
->set_throttle_passthrough_for_esc_calibration(1.0f
);
127 esc_calibration_notify();
128 hal
.scheduler
->delay(3);
131 // block until we restart
134 motors
->set_throttle_passthrough_for_esc_calibration(0.0f
);
136 esc_calibration_notify();
137 hal
.scheduler
->delay(3);
139 #endif // FRAME_CONFIG != HELI_FRAME
142 // flash LEDs to notify the user that ESC calibration is happening
143 void Copter::esc_calibration_notify()
145 AP_Notify::flags
.esc_calibration
= true;
146 uint32_t now
= AP_HAL::millis();
147 if (now
- esc_calibration_notify_update_ms
> 20) {
148 esc_calibration_notify_update_ms
= now
;
153 void Copter::esc_calibration_setup()
155 // clear esc flag for next time
156 g
.esc_calibrate
.set_and_save(ESCCAL_NONE
);
158 if (motors
->is_normal_pwm_type()) {
159 // run at full speed for oneshot ESCs (actually done on push)
160 motors
->set_update_rate(g
.rc_speed
);
162 // reduce update rate to motors to 50Hz
163 motors
->set_update_rate(50);
166 // disable safety if requested
167 BoardConfig
.init_safety();
169 // wait for safety switch to be pressed
171 while (hal
.util
->safety_switch_state() == AP_HAL::Util::SAFETY_DISARMED
) {
172 const uint32_t tnow
= AP_HAL::millis();
173 if (tnow
- tstart
>= 5000) {
174 gcs().send_text(MAV_SEVERITY_INFO
,"ESC calibration: Push safety switch");
177 esc_calibration_notify();
178 hal
.scheduler
->delay(3);
181 // arm and enable motors
183 SRV_Channels::enable_by_mask(motors
->get_motor_mask());
184 hal
.util
->set_soft_armed(true);