Line data Source code
1 : // -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- 2 : #pragma once 3 : 4 : #include "AP_Generator_Backend.h" 5 : 6 : #if AP_GENERATOR_LOWEHEISER_ENABLED 7 : 8 : #include <AP_Common/AP_Common.h> 9 : #include <RC_Channel/RC_Channel.h> 10 : #include <GCS_MAVLink/GCS_MAVLink.h> 11 : 12 : #include <stdint.h> 13 : 14 : /* 15 : Example setup: 16 : param set SERIAL2_PROTOCOL 2 # Generator protocol 17 : param set SERIAL2_BAUD 115200 18 : param set GEN_TYPE 4 19 : param set EFI_TYPE 4 20 : param set RC9_OPTION 85 # generator 21 : param set RC10_OPTION 212 # loweheiser manual throttle 22 : long SET_MESSAGE_INTERVAL 225 100000 // emit EFI_STATUS at 10Hz 23 : */ 24 : 25 : class AP_Generator_Loweheiser : public AP_Generator_Backend 26 : { 27 : friend class AP_EFI_Loweheiser; 28 : 29 : public: 30 : // constructor 31 : using AP_Generator_Backend::AP_Generator_Backend; 32 : 33 : // init should be called at vehicle startup to get the generator 34 : // library ready 35 : void init(void) override; 36 : 37 : // update should be called regularly to update the generator state 38 : void update(void) override; 39 : 40 : // methods to control the desired generator state: 41 : bool stop(void) override; 42 : bool idle(void) override; 43 : bool run(void) override; 44 : 45 : // handle loweheiser_gov_efi and related MAVLink messages: 46 : void handle_mavlink_msg(const class GCS_MAVLINK &channel, const mavlink_message_t &msg); 47 : 48 : // method to send a GENERATOR_STATUS mavlink message, called by 49 : // the GCS_MAVLink library when it wants the message emitted: 50 : void send_generator_status(const class GCS_MAVLINK &channel) override; 51 : 52 : // prearm checks to ensure generator is good for arming: 53 : bool pre_arm_check(char *failmsg, uint8_t failmsg_len) const override; 54 : 55 : // healthy returns true if the generator is not present, or it is 56 : // present, providing telemetry and not indicating an errors: 57 : bool healthy() const override; 58 : 59 : // parameters for the Loweheiser generator: 60 : static const struct AP_Param::GroupInfo var_info[]; 61 : 62 10 : const struct AP_Param::GroupInfo *get_var_info() const override { 63 10 : return var_info; 64 : } 65 : 66 : // method to reset the amount of energy consumed by the generator. 67 : // This typically means someone has refueled the vehicle without 68 : // powering it off. 69 10 : bool reset_consumed_energy() override { 70 10 : accumulated_consumed_fuel_litres = 0.0f; 71 10 : return true; 72 : } 73 : 74 : // return the amount of fuel consumed from when capacity was last 75 : // reset 76 3705 : float fuel_consumed() { 77 3705 : if (last_packet_received_ms == 0) { 78 0 : return std::numeric_limits<double>::quiet_NaN(); 79 : } 80 3705 : return accumulated_consumed_fuel_litres; 81 : } 82 : 83 : private: 84 : 85 : // second init is called after parameters are loaded from eeprom; 86 : // init() before. 87 : bool second_init_done; 88 : void check_second_init(); 89 : 90 : // we store the entirety of the most recent packet for the time being: 91 : mavlink_loweheiser_gov_efi_t packet; 92 : uint32_t last_packet_received_ms; 93 : 94 : mavlink_command_ack_t ack_packet; 95 : uint32_t last_ack_packet_ms; 96 : // record the timestamp of the most recently processed ack: 97 : uint32_t last_ack_packet_processed_ms; 98 : // good_ack is true if the last ack we received from the generator 99 : // reported success: 100 : bool good_ack; 101 : 102 : // state recorded from the first Loweheiser message we see so we 103 : // only process from one source: 104 : bool seen_good_message; 105 : const class GCS_MAVLINK *mavlink_channel; 106 : uint8_t sysid; 107 : uint8_t compid; 108 : uint8_t efi_index; 109 : 110 : // methods and state to record pilot desired runstate and actual runstate: 111 : enum class RunState { 112 : STOP = 17, 113 : IDLE = 18, 114 : WARMING_UP = 19, 115 : RUN = 20, 116 : COOLING_DOWN = 21, 117 : }; 118 : enum class PilotDesiredRunState { 119 : STOP = 65, 120 : IDLE = 66, 121 : RUN = 67, 122 : }; 123 : PilotDesiredRunState pilot_desired_runstate = PilotDesiredRunState::STOP; 124 : // last pilot desired runstate we acted on; forced to an invalid 125 : // value so that we action at least once. 126 : RunState commanded_runstate = RunState::STOP; // output is based on this 127 : void set_pilot_desired_runstate(PilotDesiredRunState newstate); 128 : void update_runstate(); 129 : const char *runstate_string(PilotDesiredRunState runstate); 130 : 131 : // returns true if the generator should be allowed to move into 132 : // the "run" (high-RPM) state: 133 : bool generator_ok_to_run() const; 134 : 135 : // returns true if the generator should be allowed to move into 136 : // the "stop" state. This is used to enforce a cool-down period 137 : // for the device 138 : bool generator_ok_to_stop() const; 139 : 140 : // timestamp of last time we told the user we're waiting for the 141 : // generator to change temperature: 142 : uint32_t last_waiting_temperature_change_ms; 143 : 144 : // estop_reported is true if we do not need to tell the user of an 145 : // estop event if it occurs: 146 : bool estop_reported; 147 : 148 : // prepare and send commands to generator: 149 : void command_generator(); 150 : 151 : // log data to onboard storage: 152 : void Log_Write(); 153 : uint32_t last_logged_reading_ms; 154 : 155 : // state related to loweheuser-specific RC input to the generator: 156 : RC_Channel *rc_channel_manual_throttle; 157 : RC_Channel *rc_channel_starter_motor; 158 : uint32_t last_rc_channel_check; 159 : uint32_t last_start_time_ms; 160 : 161 : // user-configurable parameters: 162 : AP_Int32 time_until_maintenance; 163 : AP_Int32 total_runtime; 164 : AP_Float high_idle_throttle; 165 : AP_Float idle_throttle; 166 : AP_Float temp_required_for_run; 167 : AP_Float temp_required_for_idle; 168 : AP_Float temp_for_overtemp_warning; 169 : 170 : // update runtime and maintenance-required time 171 : void update_stats(); 172 : uint32_t run_start_ms; 173 : bool was_running; 174 : uint32_t last_stats_saved_ms; 175 : uint32_t runtime_delta_ms; 176 : 177 : // update_common_backend_variables: These are used by the base class 178 : // (AP_Generator_Backend) to provide data to the battery monitor 179 : // library. 180 : void update_common_backend_variables(); 181 : 182 : float accumulated_consumed_fuel_litres; 183 : 184 : // should_emergency_stop - returns true if the generator must stop 185 : // immediately 186 : bool should_emergency_stop(); 187 : 188 : // periodically checks parameters related to rc input and updates 189 : // some data sources appropriately: 190 : void check_rc_input_channels(); 191 : 192 : }; 193 : 194 : #endif // AP_GENERATOR_LOWEHEISER_ENABLED