CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_BoardConfig/IMU_heater.cpp
Views: 1798
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
control IMU heater
17
*/
18
19
#include <AP_HAL/AP_HAL.h>
20
#include <AP_Math/AP_Math.h>
21
#include <AP_IOMCU/AP_IOMCU.h>
22
#include <AP_Logger/AP_Logger.h>
23
#include <GCS_MAVLink/GCS.h>
24
#include "AP_BoardConfig.h"
25
26
#if HAL_HAVE_IMU_HEATER
27
28
extern const AP_HAL::HAL& hal;
29
30
#ifndef HAL_HEATER_GPIO_ON
31
#define HAL_HEATER_GPIO_ON 1
32
#endif
33
34
void AP_BoardConfig::set_imu_temp(float current)
35
{
36
int8_t target = heater.imu_target_temperature.get();
37
// pass to HAL for Linux
38
hal.util->set_imu_target_temp((int8_t *)&heater.imu_target_temperature);
39
hal.util->set_imu_temp(current);
40
41
if (target == -1) {
42
// nothing to do, make sure heater is left off
43
#if defined(HAL_HEATER_GPIO_PIN)
44
hal.gpio->write(HAL_HEATER_GPIO_PIN, !HAL_HEATER_GPIO_ON);
45
#endif
46
#if defined(HAL_HEATER2_GPIO_PIN)
47
hal.gpio->write(HAL_HEATER2_GPIO_PIN, !HAL_HEATER_GPIO_ON);
48
#endif
49
return;
50
}
51
52
53
// limit to 65 degrees to prevent damage
54
target = constrain_int16(target, -1, 65);
55
56
// average over temperatures to remove noise
57
heater.count++;
58
heater.sum += current;
59
60
// update at 10Hz
61
uint32_t now = AP_HAL::millis();
62
if (now - heater.last_update_ms < 100) {
63
#if defined(HAL_HEATER_GPIO_PIN)
64
// output as duty cycle to local pin. Use a random sequence to
65
// prevent a periodic change to magnetic field
66
bool heater_on = (get_random16() < uint32_t(heater.output) * 0xFFFFU / 100U);
67
hal.gpio->write(HAL_HEATER_GPIO_PIN, heater_on?HAL_HEATER_GPIO_ON : !HAL_HEATER_GPIO_ON);
68
#if defined(HAL_HEATER2_GPIO_PIN)
69
hal.gpio->write(HAL_HEATER2_GPIO_PIN, heater_on?HAL_HEATER_GPIO_ON : !HAL_HEATER_GPIO_ON);
70
#endif
71
#endif
72
return;
73
}
74
float dt = (now - heater.last_update_ms) * 0.001;
75
dt = constrain_float(dt, 0, 0.5);
76
77
heater.last_update_ms = now;
78
79
heater.temperature = heater.sum / heater.count;
80
heater.sum = 0;
81
heater.count = 0;
82
83
if (target < 0) {
84
heater.output = 0;
85
} else {
86
heater.output = heater.pi_controller.update(heater.temperature, target, dt);
87
heater.output = constrain_float(heater.output, 0, 100);
88
}
89
90
#if HAL_LOGGING_ENABLED
91
if (now - heater.last_log_ms >= 1000) {
92
// @LoggerMessage: HEAT
93
// @Description: IMU Heater data
94
// @Field: TimeUS: Time since system startup
95
// @Field: Temp: Current IMU temperature
96
// @Field: Targ: Target IMU temperature
97
// @Field: P: Proportional portion of response
98
// @Field: I: Integral portion of response
99
// @Field: Out: Controller output to heating element
100
AP::logger().WriteStreaming("HEAT", "TimeUS,Temp,Targ,P,I,Out", "Qfbfff",
101
AP_HAL::micros64(),
102
heater.temperature, target,
103
heater.pi_controller.get_P(),
104
heater.pi_controller.get_I(),
105
heater.output);
106
heater.last_log_ms = now;
107
}
108
#endif // HAL_LOGGING_ENABLED
109
110
#if 0
111
GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Heater: Out=%.1f Temp=%.1f",
112
double(heater.output),
113
double(avg));
114
#endif
115
116
#if HAL_WITH_IO_MCU
117
if (io_enabled()) {
118
AP_IOMCU *iomcu = AP::iomcu();
119
if (iomcu) {
120
// tell IOMCU to setup heater
121
iomcu->set_heater_duty_cycle(heater.output);
122
}
123
}
124
#endif
125
}
126
127
// getter for current temperature, return false if heater disabled
128
bool AP_BoardConfig::get_board_heater_temperature(float &temperature) const
129
{
130
if (heater.imu_target_temperature == -1) {
131
return false; // heater disabled
132
}
133
temperature = heater.temperature;
134
return true;
135
}
136
137
// getter for min arming temperature, return false if heater disabled or min check disabled
138
bool AP_BoardConfig::get_board_heater_arming_temperature(int8_t &temperature) const
139
{
140
if ((heater.imu_target_temperature == -1) || (heater.imu_arming_temperature_margin_low == 0)) {
141
return false; // heater or temperature check disabled
142
}
143
temperature = heater.imu_target_temperature - heater.imu_arming_temperature_margin_low;
144
return true;
145
}
146
147
#endif // HAL_HAVE_IMU_HEATER
148
149