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 : #pragma GCC optimize("Os") 17 : 18 : #include "AP_Generator.h" 19 : 20 : #if HAL_GENERATOR_ENABLED 21 : 22 : #include "AP_Generator_Cortex.h" 23 : #include "AP_Generator_IE_650_800.h" 24 : #include "AP_Generator_IE_2400.h" 25 : #include "AP_Generator_RichenPower.h" 26 : #include "AP_Generator_Loweheiser.h" 27 : 28 : #include <GCS_MAVLink/GCS.h> 29 : 30 : const AP_Param::GroupInfo *AP_Generator::backend_var_info; 31 : 32 : const AP_Param::GroupInfo AP_Generator::var_info[] = { 33 : 34 : // @Param: TYPE 35 : // @DisplayName: Generator type 36 : // @Description: Generator type 37 : // @Values: 0:Disabled, 1:IE 650w 800w Fuel Cell, 2:IE 2.4kW Fuel Cell, 3: Richenpower, 4: Loweheiser, 5:CORTEX 38 : // @User: Standard 39 : // @RebootRequired: True 40 : AP_GROUPINFO_FLAGS("TYPE", 1, AP_Generator, _type, 0, AP_PARAM_FLAG_ENABLE), 41 : 42 : // @Param: OPTIONS 43 : // @DisplayName: Generator Options 44 : // @Description: Bitmask of options for generators 45 : // @Bitmask: 0:Suppress Maintenance-Required Warnings 46 : // @User: Standard 47 : AP_GROUPINFO("OPTIONS", 2, AP_Generator, _options, 0), 48 : 49 : // @Group:L_ 50 : // @Path: AP_Generator_Loweheiser.cpp 51 : AP_SUBGROUPVARPTR(_driver_ptr, "L_", 3, AP_Generator, backend_var_info), 52 : 53 : AP_GROUPEND 54 : }; 55 : 56 : // Constructor 57 2098 : AP_Generator::AP_Generator() 58 : { 59 2098 : AP_Param::setup_object_defaults(this, var_info); 60 : 61 2098 : if (_singleton) { 62 : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL 63 0 : AP_HAL::panic("Too many generators"); 64 : #endif 65 : return; 66 : } 67 2098 : _singleton = this; 68 : } 69 : 70 2094 : __INITFUNC__ void AP_Generator::init() 71 : { 72 : // Select backend 73 2094 : switch (type()) { 74 : case Type::GEN_DISABLED: 75 : // Not using a generator 76 : return; 77 : 78 : #if AP_GENERATOR_IE_650_800_ENABLED 79 7 : case Type::IE_650_800: 80 7 : _driver_ptr = NEW_NOTHROW AP_Generator_IE_650_800(*this); 81 7 : break; 82 : #endif 83 : 84 : #if AP_GENERATOR_IE_2400_ENABLED 85 4 : case Type::IE_2400: 86 4 : _driver_ptr = NEW_NOTHROW AP_Generator_IE_2400(*this); 87 4 : break; 88 : #endif 89 : 90 : #if AP_GENERATOR_RICHENPOWER_ENABLED 91 2 : case Type::RICHENPOWER: 92 2 : _driver_ptr = NEW_NOTHROW AP_Generator_RichenPower(*this); 93 2 : break; 94 : #endif 95 : 96 : #if AP_GENERATOR_LOWEHEISER_ENABLED 97 10 : case Type::LOWEHEISER: 98 10 : _driver_ptr = NEW_NOTHROW AP_Generator_Loweheiser(*this); 99 10 : break; 100 : #endif // AP_GENERATOR_LOWEHEISER_ENABLED 101 : 102 : #if AP_GENERATOR_CORTEX_ENABLED 103 0 : case Type::CORTEX: 104 0 : _driver_ptr = NEW_NOTHROW AP_Generator_Cortex(*this); 105 0 : break; 106 : #endif // AP_GENERATOR_CORTEX_ENABLED 107 : } 108 : 109 23 : if (_driver_ptr != nullptr) { 110 23 : _driver_ptr->init(); 111 : } 112 : 113 : // if the backend has some local parameters then make those 114 : // available in the tree 115 23 : if (_driver_ptr) { 116 23 : backend_var_info = _driver_ptr->get_var_info(); 117 23 : if (backend_var_info) { 118 10 : AP_Param::load_object_from_eeprom(_driver_ptr, backend_var_info); 119 : 120 : // param count could have changed 121 10 : AP_Param::invalidate_count(); 122 : } 123 : } 124 : } 125 : 126 1504089 : void AP_Generator::update() 127 : { 128 : // Return immediately if not enabled. Don't support run-time disabling of generator 129 1504089 : if (_driver_ptr == nullptr) { 130 : return; 131 : } 132 : 133 : // Calling backend update will cause backend to update the front end variables 134 11908 : _driver_ptr->update(); 135 : } 136 : 137 : // Helper to get param and cast to Type 138 232950 : enum AP_Generator::Type AP_Generator::type() const 139 : { 140 232950 : return (Type)_type.get(); 141 : } 142 : 143 : #if AP_GENERATOR_LOWEHEISER_ENABLED 144 90361 : AP_Generator_Loweheiser *AP_Generator::get_loweheiser() 145 : { 146 90361 : if (type() != Type::LOWEHEISER) { 147 : return nullptr; 148 : } 149 90085 : return (AP_Generator_Loweheiser*)_driver_ptr; 150 : } 151 : #endif 152 : 153 10 : bool AP_Generator::reset_consumed_energy() { 154 10 : if (_driver_ptr == nullptr) { 155 : return false; 156 : } 157 10 : return _driver_ptr->reset_consumed_energy(); 158 : } 159 : 160 : // Pass through to backend 161 1122504 : void AP_Generator::send_generator_status(const GCS_MAVLINK &channel) 162 : { 163 1122504 : if (_driver_ptr == nullptr) { 164 : return; 165 : } 166 7428 : _driver_ptr->send_generator_status(channel); 167 : } 168 : 169 : // Tell backend to perform arming checks 170 140495 : bool AP_Generator::pre_arm_check(char* failmsg, uint8_t failmsg_len) const 171 : { 172 140495 : if (type() == Type::GEN_DISABLED) { 173 : // Don't prevent arming if generator is not enabled and has never been init 174 139799 : if (_driver_ptr == nullptr) { 175 : return true; 176 : } 177 : // Don't allow arming if we have disabled the generator since boot 178 5 : strncpy(failmsg, "Generator disabled, reboot required", failmsg_len); 179 5 : return false; 180 : } 181 696 : if (_driver_ptr == nullptr) { 182 10 : strncpy(failmsg, "No backend driver", failmsg_len); 183 10 : return false; 184 : } 185 686 : return _driver_ptr->pre_arm_check(failmsg, failmsg_len); 186 : } 187 : 188 : // Tell backend check failsafes 189 5092 : AP_BattMonitor::Failsafe AP_Generator::update_failsafes() 190 : { 191 : // Don't invoke a failsafe if driver not assigned 192 5092 : if (_driver_ptr == nullptr) { 193 : return AP_BattMonitor::Failsafe::None; 194 : } 195 5092 : return _driver_ptr->update_failsafes(); 196 : } 197 : 198 : // Pass through to backend 199 17 : bool AP_Generator::stop() 200 : { 201 : // Still allow 202 17 : if (_driver_ptr == nullptr) { 203 : return false; 204 : } 205 15 : return _driver_ptr->stop(); 206 : } 207 : 208 : // Pass through to backend 209 13 : bool AP_Generator::idle() 210 : { 211 13 : if (_driver_ptr == nullptr) { 212 : return false; 213 : } 214 11 : return _driver_ptr->idle(); 215 : } 216 : 217 : // Pass through to backend 218 16 : bool AP_Generator::run() 219 : { 220 : // Don't allow operators to request generator be set to run if it has been disabled 221 16 : if (_driver_ptr == nullptr) { 222 : return false; 223 : } 224 16 : return _driver_ptr->run(); 225 : } 226 : 227 : // Get the AP_Generator singleton 228 1484955 : AP_Generator *AP_Generator::get_singleton() 229 : { 230 1484955 : return _singleton; 231 : } 232 : 233 : AP_Generator *AP_Generator::_singleton = nullptr; 234 : 235 : namespace AP { 236 1484955 : AP_Generator *generator() 237 : { 238 1484955 : return AP_Generator::get_singleton(); 239 : } 240 : }; 241 : #endif