mirror of https://github.com/ArduPilot/ardupilot
241 lines
7.4 KiB
C++
241 lines
7.4 KiB
C++
/*
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
/*
|
|
simulate Hirth EFI system
|
|
|
|
./Tools/autotest/sim_vehicle.py --gdb --debug -v ArduPlane -A --uartF=sim:hirth --speedup=1
|
|
param set SERIAL5_PROTOCOL 24
|
|
param set SIM_EFI_TYPE 6
|
|
param set EFI_TYPE 6
|
|
reboot
|
|
status EFI_STATUS
|
|
|
|
./Tools/autotest/autotest.py --gdb --debug build.Plane test.Plane.Hirth
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <SITL/SITL.h>
|
|
#include <AP_HAL/utility/Socket.h>
|
|
#include "SIM_SerialDevice.h"
|
|
|
|
namespace SITL {
|
|
|
|
class EFI_Hirth : public SerialDevice {
|
|
public:
|
|
|
|
using SerialDevice::SerialDevice;
|
|
|
|
void update();
|
|
|
|
private:
|
|
|
|
void update_receive();
|
|
void update_send();
|
|
|
|
void assert_receive_size(uint8_t receive_size);
|
|
|
|
void handle_set_values();
|
|
|
|
// maps from an on-wire number to a record number:
|
|
enum class PacketCode : uint8_t {
|
|
DataRecord1 = 4,
|
|
DataRecord2 = 11,
|
|
DataRecord3 = 13,
|
|
SetValues = 201,
|
|
};
|
|
|
|
template <typename T>
|
|
class PACKED PackedRecord {
|
|
public:
|
|
PackedRecord(PacketCode _code, T _record) :
|
|
code(uint8_t(_code)),
|
|
record(_record)
|
|
{ }
|
|
const uint8_t length { sizeof(T) + 3 }; // 1 each of length, code and checksum
|
|
const uint8_t code;
|
|
T record;
|
|
uint8_t checksum;
|
|
|
|
void update() {
|
|
record.update();
|
|
update_checksum();
|
|
}
|
|
|
|
void update_checksum() {
|
|
checksum = 256U - crc_sum_of_bytes((uint8_t*)this, length-1);
|
|
}
|
|
};
|
|
|
|
void send_record1();
|
|
void send_record2();
|
|
void send_record3();
|
|
|
|
class PACKED Record1 {
|
|
public:
|
|
uint8_t reserved1[2];
|
|
uint16_t save_in_flash; // "1 = data are saved in flash automatically"
|
|
uint8_t reserved2[4];
|
|
uint16_t engine_status;
|
|
uint16_t rpm;
|
|
uint8_t reserved3[12];
|
|
uint16_t number_of_interfering_pulses;
|
|
uint16_t reserved4[2];
|
|
uint16_t number_of_speed_errors;
|
|
uint16_t injection_time;
|
|
uint16_t ignition_angle;
|
|
uint16_t reserved5;
|
|
uint16_t voltage_throttle;
|
|
uint16_t reserved6;
|
|
uint8_t reserved7[2];
|
|
uint16_t voltage_engine_temperature;
|
|
uint16_t voltage_air_temperature;
|
|
uint8_t reserved8[2];
|
|
uint16_t voltage_int_air_pressure;
|
|
uint8_t reserved9[20];
|
|
int16_t throttle;
|
|
int16_t engine_temperature;
|
|
int16_t battery_voltage;
|
|
int16_t air_temperature;
|
|
int16_t reserved10;
|
|
uint16_t sensor_ok;
|
|
|
|
void update();
|
|
};
|
|
|
|
class PACKED Record2 {
|
|
public:
|
|
uint8_t reserved1[12];
|
|
int16_t injection_rate_from_basic_graphic_map;
|
|
int16_t reserved2;
|
|
int16_t basic_injection_rate;
|
|
int16_t injection_rate_from_air_correction;
|
|
int16_t reserved3;
|
|
int16_t injection_rate_from_warming_up_characteristic_curve;
|
|
int16_t injection_rate_from_acceleration_enrichment;
|
|
int16_t turn_on_time_of_intake_valves;
|
|
int16_t injection_rate_from_race_switch;
|
|
int16_t reserved4;
|
|
int16_t injection_angle_from_ignition_angle_map;
|
|
int16_t injection_angle_from_air_temperature_characteristic_curve;
|
|
int16_t injection_angle_from_air_pressure_characteristic_curve;
|
|
int16_t ignition_angle_from_engine_temperature_characteristic_curve;
|
|
int16_t ignition_angle_from_acceleration;
|
|
int16_t ignition_angle_from_race_switch;
|
|
uint32_t total_time_in_26ms;
|
|
uint32_t total_number_of_rotations;
|
|
uint16_t fuel_consumption;
|
|
uint16_t number_of_errors_in_error_memory;
|
|
int16_t voltage_input1_throttle_target;
|
|
int16_t reserved5;
|
|
int16_t position_throttle_target;
|
|
uint16_t throttle_percent_times_10; // percent * 10
|
|
int16_t reserved6[3];
|
|
uint16_t time_of_injector_opening_percent_times_10;
|
|
uint8_t reserved7[10];
|
|
uint32_t no_of_logged_data;
|
|
uint8_t reserved8[12];
|
|
};
|
|
|
|
class PACKED Record3 {
|
|
public:
|
|
uint16_t voltage_excess_temperature_1;
|
|
uint16_t voltage_excess_temperature_2;
|
|
uint16_t voltage_excess_temperature_3;
|
|
uint16_t voltage_excess_temperature_4;
|
|
uint16_t voltage_excess_temperature_5;
|
|
uint8_t reserved1[6];
|
|
uint16_t excess_temperature_1; // cht1
|
|
uint16_t excess_temperature_2; // cht2
|
|
uint16_t excess_temperature_3; // egt1
|
|
uint16_t excess_temperature_4; // egt2
|
|
uint16_t excess_temperature_5;
|
|
uint8_t reserved2[6];
|
|
uint16_t enrichment_excess_temperature_cylinder_1;
|
|
uint16_t enrichment_excess_temperature_cylinder_2;
|
|
uint16_t enrichment_excess_temperature_cylinder_3;
|
|
uint16_t enrichment_excess_temperature_cylinder_4;
|
|
uint8_t reserved3[6];
|
|
uint16_t enrichment_excess_temperature_bitfield;
|
|
uint16_t mixing_ratio_oil_pump1;
|
|
uint16_t mixing_ratio_oil_pump2;
|
|
uint16_t ouput_value_water_pump;
|
|
uint16_t ouput_value_fuel_pump;
|
|
uint16_t ouput_value_exhaust_valve;
|
|
uint16_t ouput_value_air_vane;
|
|
uint16_t ouput_value_e_throttle;
|
|
uint16_t number_of_injections_oil_pump_1;
|
|
uint32_t system_time_in_ms;
|
|
uint16_t number_of_injections_oil_pump_2;
|
|
uint16_t target_rpm;
|
|
uint16_t FPC;
|
|
// these appear to be duplicates of the above; one is probably
|
|
// voltage?
|
|
uint16_t xenrichment_excess_temperature_cylinder_1;
|
|
uint16_t xenrichment_excess_temperature_cylinder_2;
|
|
uint16_t xenrichment_excess_temperature_cylinder_3;
|
|
uint16_t xenrichment_excess_temperature_cylinder_4;
|
|
uint16_t voltage_input_temperature_crankshaft_housing;
|
|
uint16_t temperature_crankshaft_housing;
|
|
uint8_t reserved4[14];
|
|
};
|
|
|
|
class PACKED SetValues {
|
|
public:
|
|
int16_t throttle; // percent * 10
|
|
int16_t rpm;;
|
|
int8_t reserved1[16];
|
|
};
|
|
|
|
// these records are just used for initial values of the fields;
|
|
// they aren't used past that.
|
|
Record1 record1;
|
|
Record2 record2;
|
|
Record3 record3;
|
|
|
|
|
|
SetValues settings;
|
|
|
|
PackedRecord<Record1> packed_record1{PacketCode::DataRecord1, record1};
|
|
PackedRecord<Record2> packed_record2{PacketCode::DataRecord2, record2};
|
|
PackedRecord<Record3> packed_record3{PacketCode::DataRecord3, record3};
|
|
|
|
struct {
|
|
PacketCode code; // code which was requested by driver
|
|
uint32_t time_ms; // time that code was requested by driver
|
|
} requested_data_record;
|
|
|
|
uint8_t receive_buf[32];
|
|
uint8_t receive_buf_ofs;
|
|
|
|
float throttle;
|
|
|
|
uint16_t engine_status_field_value() const;
|
|
|
|
void init();
|
|
bool init_done = false;
|
|
|
|
// engine model:
|
|
void update_engine_model();
|
|
struct {
|
|
float cht1_temperature; // engine reports in deg-C
|
|
float cht2_temperature;
|
|
uint32_t last_update_ms;
|
|
} engine;
|
|
};
|
|
|
|
}
|