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 : simulate Hirth EFI system 17 : 18 : ./Tools/autotest/sim_vehicle.py --gdb --debug -v ArduPlane -A --serial5=sim:hirth --speedup=1 19 : param set SERIAL5_PROTOCOL 24 20 : param set SIM_EFI_TYPE 6 21 : param set EFI_TYPE 6 22 : reboot 23 : status EFI_STATUS 24 : 25 : ./Tools/autotest/autotest.py --gdb --debug build.Plane test.Plane.Hirth 26 : 27 : */ 28 : 29 : #pragma once 30 : 31 : #include <SITL/SITL.h> 32 : #include <AP_HAL/utility/Socket_native.h> 33 : #include "SIM_SerialDevice.h" 34 : 35 : namespace SITL { 36 : 37 : class EFI_Hirth : public SerialDevice { 38 : public: 39 : 40 : using SerialDevice::SerialDevice; 41 : 42 : void update(const class Aircraft &aircraft); 43 : 44 : private: 45 : 46 : void update_receive(); 47 : void update_send(const class Aircraft &aircraft); 48 : 49 : void assert_receive_size(uint8_t receive_size); 50 : 51 : void handle_set_values(); 52 : 53 : // maps from an on-wire number to a record number: 54 : enum class PacketCode : uint8_t { 55 : DataRecord1 = 4, 56 : DataRecord2 = 11, 57 : DataRecord3 = 13, 58 : SetValues = 201, 59 : }; 60 : 61 : template <typename T> 62 : class PACKED PackedRecord { 63 : public: 64 3 : PackedRecord(PacketCode _code, T _record) : 65 3 : code(uint8_t(_code)), 66 3 : record(_record) 67 3 : { } 68 : const uint8_t length { sizeof(T) + 3 }; // 1 each of length, code and checksum 69 : const uint8_t code; 70 : T record; 71 : uint8_t checksum; 72 : 73 : void update() { 74 : record.update(); 75 : update_checksum(); 76 : } 77 : 78 563 : void update_checksum() { 79 563 : checksum = 256U - crc_sum_of_bytes((uint8_t*)this, length-1); 80 563 : } 81 : }; 82 : 83 : void send_record1(const class Aircraft &aircraft); 84 : void send_record2(); 85 : void send_record3(); 86 : 87 : class PACKED Record1 { 88 : public: 89 : uint8_t reserved1[2]; 90 : uint16_t save_in_flash; // "1 = data are saved in flash automatically" 91 : uint8_t reserved2[4]; 92 : uint16_t engine_status; 93 : uint16_t rpm; 94 : uint8_t reserved3[12]; 95 : uint16_t number_of_interfering_pulses; 96 : uint16_t reserved4[2]; 97 : uint16_t number_of_speed_errors; 98 : uint16_t injection_time; 99 : uint16_t ignition_angle; 100 : uint16_t reserved5; 101 : uint16_t voltage_throttle; 102 : uint16_t reserved6; 103 : uint8_t reserved7[2]; 104 : uint16_t voltage_engine_temperature; 105 : uint16_t voltage_air_temperature; 106 : uint8_t reserved8[2]; 107 : uint16_t voltage_int_air_pressure; 108 : uint8_t reserved9[20]; 109 : int16_t throttle; 110 : int16_t engine_temperature; 111 : int16_t battery_voltage; 112 : int16_t air_temperature; 113 : int16_t reserved10; 114 : uint16_t sensor_ok; 115 : 116 : void update(); 117 : }; 118 : 119 : class PACKED Record2 { 120 : public: 121 : uint8_t reserved1[12]; 122 : int16_t injection_rate_from_basic_graphic_map; 123 : int16_t reserved2; 124 : int16_t basic_injection_rate; 125 : int16_t injection_rate_from_air_correction; 126 : int16_t reserved3; 127 : int16_t injection_rate_from_warming_up_characteristic_curve; 128 : int16_t injection_rate_from_acceleration_enrichment; 129 : int16_t turn_on_time_of_intake_valves; 130 : int16_t injection_rate_from_race_switch; 131 : int16_t reserved4; 132 : int16_t injection_angle_from_ignition_angle_map; 133 : int16_t injection_angle_from_air_temperature_characteristic_curve; 134 : int16_t injection_angle_from_air_pressure_characteristic_curve; 135 : int16_t ignition_angle_from_engine_temperature_characteristic_curve; 136 : int16_t ignition_angle_from_acceleration; 137 : int16_t ignition_angle_from_race_switch; 138 : uint32_t total_time_in_26ms; 139 : uint32_t total_number_of_rotations; 140 : uint16_t fuel_consumption; 141 : uint16_t number_of_errors_in_error_memory; 142 : int16_t voltage_input1_throttle_target; 143 : int16_t reserved5; 144 : int16_t position_throttle_target; 145 : uint16_t throttle_percent_times_10; // percent * 10 146 : int16_t reserved6[3]; 147 : uint16_t time_of_injector_opening_percent_times_10; 148 : uint8_t reserved7[10]; 149 : uint32_t no_of_logged_data; 150 : uint8_t reserved8[12]; 151 : }; 152 : 153 : class PACKED Record3 { 154 : public: 155 : uint16_t voltage_excess_temperature_1; 156 : uint16_t voltage_excess_temperature_2; 157 : uint16_t voltage_excess_temperature_3; 158 : uint16_t voltage_excess_temperature_4; 159 : uint16_t voltage_excess_temperature_5; 160 : uint8_t reserved1[6]; 161 : uint16_t excess_temperature_1; // cht1 162 : uint16_t excess_temperature_2; // cht2 163 : uint16_t excess_temperature_3; // egt1 164 : uint16_t excess_temperature_4; // egt2 165 : uint16_t excess_temperature_5; 166 : uint8_t reserved2[6]; 167 : uint16_t enrichment_excess_temperature_cylinder_1; 168 : uint16_t enrichment_excess_temperature_cylinder_2; 169 : uint16_t enrichment_excess_temperature_cylinder_3; 170 : uint16_t enrichment_excess_temperature_cylinder_4; 171 : uint8_t reserved3[6]; 172 : uint16_t enrichment_excess_temperature_bitfield; 173 : uint16_t mixing_ratio_oil_pump1; 174 : uint16_t mixing_ratio_oil_pump2; 175 : uint16_t ouput_value_water_pump; 176 : uint16_t ouput_value_fuel_pump; 177 : uint16_t ouput_value_exhaust_valve; 178 : uint16_t ouput_value_air_vane; 179 : uint16_t ouput_value_e_throttle; 180 : uint16_t number_of_injections_oil_pump_1; 181 : uint32_t system_time_in_ms; 182 : uint16_t number_of_injections_oil_pump_2; 183 : uint16_t target_rpm; 184 : uint16_t FPC; 185 : // these appear to be duplicates of the above; one is probably 186 : // voltage? 187 : uint16_t xenrichment_excess_temperature_cylinder_1; 188 : uint16_t xenrichment_excess_temperature_cylinder_2; 189 : uint16_t xenrichment_excess_temperature_cylinder_3; 190 : uint16_t xenrichment_excess_temperature_cylinder_4; 191 : uint16_t voltage_input_temperature_crankshaft_housing; 192 : uint16_t temperature_crankshaft_housing; 193 : uint8_t reserved4[14]; 194 : }; 195 : 196 : class PACKED SetValues { 197 : public: 198 : int16_t throttle; // percent * 10 199 : int16_t rpm;; 200 : int8_t reserved1[16]; 201 : }; 202 : 203 : // these records are just used for initial values of the fields; 204 : // they aren't used past that. 205 : Record1 record1; 206 : Record2 record2; 207 : Record3 record3; 208 : 209 : 210 : SetValues settings; 211 : 212 : PackedRecord<Record1> packed_record1{PacketCode::DataRecord1, record1}; 213 : PackedRecord<Record2> packed_record2{PacketCode::DataRecord2, record2}; 214 : PackedRecord<Record3> packed_record3{PacketCode::DataRecord3, record3}; 215 : 216 : struct { 217 : PacketCode code; // code which was requested by driver 218 : uint32_t time_ms; // time that code was requested by driver 219 : } requested_data_record; 220 : 221 : uint8_t receive_buf[32]; 222 : uint8_t receive_buf_ofs; 223 : 224 : float throttle; 225 : 226 : uint16_t engine_status_field_value() const; 227 : 228 : void init(const class Aircraft &aircraft); 229 : bool init_done = false; 230 : 231 : // engine model: 232 : void update_engine_model(const class Aircraft &aircraft); 233 : struct { 234 : float cht1_temperature; // engine reports in deg-C 235 : float cht2_temperature; 236 : uint32_t last_update_ms; 237 : } engine; 238 : }; 239 : 240 : }