2018-03-28 20:37:58 -03:00
/*
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/>.
*/
# include "AP_EFI.h"
2021-06-08 01:16:33 -03:00
# if HAL_EFI_ENABLED
2018-03-28 20:37:58 -03:00
# include "AP_EFI_Serial_MS.h"
2021-12-18 21:32:33 -04:00
# include "AP_EFI_Serial_Lutan.h"
2020-06-17 19:16:29 -03:00
# include "AP_EFI_NWPMU.h"
2022-06-03 19:09:58 -03:00
# include "AP_EFI_DroneCAN.h"
2022-03-14 22:12:55 -03:00
# include "AP_EFI_Currawong_ECU.h"
2023-11-12 20:33:43 -04:00
# include "AP_EFI_Serial_Hirth.h"
2022-09-04 04:15:49 -03:00
# include "AP_EFI_Scripting.h"
2023-06-27 05:02:59 -03:00
# include "AP_EFI_MAV.h"
2022-09-04 04:15:49 -03:00
2018-03-28 20:37:58 -03:00
# include <AP_Logger/AP_Logger.h>
2022-09-21 18:23:34 -03:00
# include <GCS_MAVLink/GCS.h>
2024-01-10 01:46:04 -04:00
# include <AP_Math/AP_Math.h>
2018-03-28 20:37:58 -03:00
2020-06-17 19:16:29 -03:00
# if HAL_MAX_CAN_PROTOCOL_DRIVERS
# include <AP_CANManager/AP_CANManager.h>
# endif
2018-03-28 20:37:58 -03:00
extern const AP_HAL : : HAL & hal ;
// table of user settable parameters
const AP_Param : : GroupInfo AP_EFI : : var_info [ ] = {
// @Param: _TYPE
// @DisplayName: EFI communication type
// @Description: What method of communication is used for EFI #1
2024-05-19 21:09:34 -03:00
// @Values: 0:None,1:Serial-MS,2:NWPMU,3:Serial-Lutan,5:DroneCAN,6:Currawong-ECU,7:Scripting,8:Hirth,9:MAVLink
2018-03-28 20:37:58 -03:00
// @User: Advanced
// @RebootRequired: True
AP_GROUPINFO_FLAGS ( " _TYPE " , 1 , AP_EFI , type , 0 , AP_PARAM_FLAG_ENABLE ) ,
// @Param: _COEF1
// @DisplayName: EFI Calibration Coefficient 1
2022-05-14 07:12:23 -03:00
// @Description: Used to calibrate fuel flow for MS protocol (Slope). This should be calculated from a log at constant fuel usage rate. Plot (ECYL[0].InjT*EFI.Rpm)/600.0 to get the duty_cycle. Measure actual fuel usage in cm^3/min, and set EFI_COEF1 = fuel_usage_cm3permin / duty_cycle
2018-03-28 20:37:58 -03:00
// @Range: 0 1
// @User: Advanced
AP_GROUPINFO ( " _COEF1 " , 2 , AP_EFI , coef1 , 0 ) ,
// @Param: _COEF2
// @DisplayName: EFI Calibration Coefficient 2
2022-05-14 07:12:23 -03:00
// @Description: Used to calibrate fuel flow for MS protocol (Offset). This can be used to correct for a non-zero offset in the fuel consumption calculation of EFI_COEF1
2018-03-28 20:37:58 -03:00
// @Range: 0 10
// @User: Advanced
AP_GROUPINFO ( " _COEF2 " , 3 , AP_EFI , coef2 , 0 ) ,
2022-03-14 22:14:28 -03:00
// @Param: _FUEL_DENS
2022-03-14 22:12:55 -03:00
// @DisplayName: ECU Fuel Density
// @Description: Used to calculate fuel consumption
// @Units: kg/m/m/m
// @Range: 0 10000
// @User: Advanced
2022-03-14 22:14:28 -03:00
AP_GROUPINFO ( " _FUEL_DENS " , 4 , AP_EFI , ecu_fuel_density , 0 ) ,
2022-03-14 22:12:55 -03:00
2023-11-12 20:33:43 -04:00
# if AP_EFI_THROTTLE_LINEARISATION_ENABLED
// @Group: _THRLIN
// @Path: AP_EFI_ThrottleLinearisation.cpp
AP_SUBGROUPINFO ( throttle_linearisation , " _THRLIN " , 5 , AP_EFI , AP_EFI_ThrLin ) ,
# endif
2018-03-28 20:37:58 -03:00
AP_GROUPEND
} ;
AP_EFI * AP_EFI : : singleton ;
// Initialize parameters
AP_EFI : : AP_EFI ( )
{
singleton = this ;
AP_Param : : setup_object_defaults ( this , var_info ) ;
}
// Initialize backends based on existing params
void AP_EFI : : init ( void )
{
if ( backend ! = nullptr ) {
// Init called twice, perhaps
return ;
}
2020-08-07 01:04:06 -03:00
switch ( ( Type ) type . get ( ) ) {
case Type : : NONE :
break ;
2023-03-15 20:09:13 -03:00
# if AP_EFI_SERIAL_MS_ENABLED
2020-08-07 01:04:06 -03:00
case Type : : MegaSquirt :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_Serial_MS ( * this ) ;
2020-08-07 01:04:06 -03:00
break ;
2023-03-15 20:09:13 -03:00
# endif
# if AP_EFI_SERIAL_LUTAN_ENABLED
2021-12-18 21:32:33 -04:00
case Type : : Lutan :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_Serial_Lutan ( * this ) ;
2021-12-18 21:32:33 -04:00
break ;
2023-03-15 20:09:13 -03:00
# endif
2023-03-15 20:05:59 -03:00
# if AP_EFI_NWPWU_ENABLED
2023-06-21 08:09:25 -03:00
case Type : : NWPMU :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_NWPMU ( * this ) ;
2022-06-03 19:09:58 -03:00
break ;
2023-06-21 08:09:25 -03:00
# endif
2023-03-15 20:05:59 -03:00
# if AP_EFI_DRONECAN_ENABLED
2023-06-21 08:09:25 -03:00
case Type : : DroneCAN :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_DroneCAN ( * this ) ;
2022-03-08 22:25:49 -04:00
break ;
2023-06-21 08:09:25 -03:00
# endif
2023-03-15 20:05:59 -03:00
# if AP_EFI_CURRAWONG_ECU_ENABLED
2023-06-21 08:09:25 -03:00
case Type : : CurrawongECU :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_Currawong_ECU ( * this ) ;
2022-09-04 04:15:49 -03:00
break ;
2023-06-21 08:09:25 -03:00
# endif
2022-09-04 04:15:49 -03:00
# if AP_EFI_SCRIPTING_ENABLED
2023-06-21 08:09:25 -03:00
case Type : : SCRIPTING :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_Scripting ( * this ) ;
2020-08-07 01:04:06 -03:00
break ;
2023-11-12 20:33:43 -04:00
# endif
# if AP_EFI_SERIAL_HIRTH_ENABLED
case Type : : Hirth :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_Serial_Hirth ( * this ) ;
2023-11-12 20:33:43 -04:00
break ;
2023-06-27 05:02:59 -03:00
# endif
# if AP_EFI_MAV_ENABLED
case Type : : MAV :
2024-05-26 22:24:10 -03:00
backend = NEW_NOTHROW AP_EFI_MAV ( * this ) ;
2023-06-27 05:02:59 -03:00
break ;
2023-06-21 08:09:25 -03:00
# endif
2020-08-07 01:04:06 -03:00
default :
2022-06-03 07:59:46 -03:00
GCS_SEND_TEXT ( MAV_SEVERITY_INFO , " Unknown EFI type " ) ;
2020-08-07 01:04:06 -03:00
break ;
2018-03-28 20:37:58 -03:00
}
}
// Ask all backends to update the frontend
void AP_EFI : : update ( )
{
if ( backend ) {
backend - > update ( ) ;
2022-06-03 07:59:46 -03:00
# if HAL_LOGGING_ENABLED
2018-03-28 20:37:58 -03:00
log_status ( ) ;
2022-06-03 07:59:46 -03:00
# endif
2018-03-28 20:37:58 -03:00
}
}
bool AP_EFI : : is_healthy ( void ) const
{
return ( backend & & ( AP_HAL : : millis ( ) - state . last_updated_ms ) < HEALTHY_LAST_RECEIVED_MS ) ;
}
2022-06-03 07:59:46 -03:00
# if HAL_LOGGING_ENABLED
2018-03-28 20:37:58 -03:00
/*
write status to log
*/
void AP_EFI : : log_status ( void )
{
2020-04-06 23:54:54 -03:00
// @LoggerMessage: EFI
// @Description: Electronic Fuel Injection system data
// @Field: TimeUS: Time since system startup
// @Field: LP: Reported engine load
// @Field: Rpm: Reported engine RPM
// @Field: SDT: Spark Dwell Time
// @Field: ATM: Atmospheric pressure
// @Field: IMP: Intake manifold pressure
// @Field: IMT: Intake manifold temperature
// @Field: ECT: Engine Coolant Temperature
// @Field: OilP: Oil Pressure
// @Field: OilT: Oil temperature
// @Field: FP: Fuel Pressure
// @Field: FCR: Fuel Consumption Rate
// @Field: CFV: Consumed fueld volume
// @Field: TPS: Throttle Position
// @Field: IDX: Index of the publishing ECU
2021-08-17 06:57:41 -03:00
AP : : logger ( ) . WriteStreaming ( " EFI " ,
2018-03-28 20:37:58 -03:00
" TimeUS,LP,Rpm,SDT,ATM,IMP,IMT,ECT,OilP,OilT,FP,FCR,CFV,TPS,IDX " ,
" s%qsPPOOPOP--%- " ,
" F00C--00-0-0000 " ,
" QBIffffffffffBB " ,
AP_HAL : : micros64 ( ) ,
uint8_t ( state . engine_load_percent ) ,
uint32_t ( state . engine_speed_rpm ) ,
float ( state . spark_dwell_time_ms ) ,
float ( state . atmospheric_pressure_kpa ) ,
float ( state . intake_manifold_pressure_kpa ) ,
float ( state . intake_manifold_temperature ) ,
float ( state . coolant_temperature ) ,
float ( state . oil_pressure ) ,
float ( state . oil_temperature ) ,
float ( state . fuel_pressure ) ,
float ( state . fuel_consumption_rate_cm3pm ) ,
float ( state . estimated_consumed_fuel_volume_cm3 ) ,
uint8_t ( state . throttle_position_percent ) ,
uint8_t ( state . ecu_index ) ) ;
2020-04-06 23:54:54 -03:00
// @LoggerMessage: EFI2
// @Description: Electronic Fuel Injection system data - redux
// @Field: TimeUS: Time since system startup
// @Field: Healthy: True if EFI is healthy
// @Field: ES: Engine state
// @Field: GE: General error
// @Field: CSE: Crankshaft sensor status
// @Field: TS: Temperature status
// @Field: FPS: Fuel pressure status
// @Field: OPS: Oil pressure status
// @Field: DS: Detonation status
// @Field: MS: Misfire status
// @Field: DebS: Debris status
// @Field: SPU: Spark plug usage
// @Field: IDX: Index of the publishing ECU
2021-08-17 06:57:41 -03:00
AP : : logger ( ) . WriteStreaming ( " EFI2 " ,
2020-04-06 23:52:08 -03:00
" TimeUS,Healthy,ES,GE,CSE,TS,FPS,OPS,DS,MS,DebS,SPU,IDX " ,
2018-03-28 20:37:58 -03:00
" s------------ " ,
" F------------ " ,
" QBBBBBBBBBBBB " ,
AP_HAL : : micros64 ( ) ,
uint8_t ( is_healthy ( ) ) ,
uint8_t ( state . engine_state ) ,
uint8_t ( state . general_error ) ,
uint8_t ( state . crankshaft_sensor_status ) ,
uint8_t ( state . temperature_status ) ,
uint8_t ( state . fuel_pressure_status ) ,
uint8_t ( state . oil_pressure_status ) ,
uint8_t ( state . detonation_status ) ,
uint8_t ( state . misfire_status ) ,
uint8_t ( state . debris_status ) ,
uint8_t ( state . spark_plug_usage ) ,
uint8_t ( state . ecu_index ) ) ;
2020-04-06 23:54:54 -03:00
// @LoggerMessage: ECYL
// @Description: EFI per-cylinder information
// @Field: TimeUS: Time since system startup
// @Field: Inst: Cylinder this data belongs to
// @Field: IgnT: Ignition timing
// @Field: InjT: Injection time
// @Field: CHT: Cylinder head temperature
// @Field: EGT: Exhaust gas temperature
// @Field: Lambda: Estimated lambda coefficient (dimensionless ratio)
2023-11-12 20:33:43 -04:00
// @Field: CHT2: Cylinder2 head temperature
// @Field: EGT2: Cylinder2 Exhaust gas temperature
2020-04-06 23:54:54 -03:00
// @Field: IDX: Index of the publishing ECU
2022-09-29 01:54:05 -03:00
AP : : logger ( ) . WriteStreaming ( " ECYL " ,
2023-11-12 20:33:43 -04:00
" TimeUS,Inst,IgnT,InjT,CHT,EGT,Lambda,CHT2,EGT2,IDX " ,
" s#dsOO-OO- " ,
" F-0C000000 " ,
2024-09-10 22:55:33 -03:00
" QBffffffff " ,
2022-09-29 01:54:05 -03:00
AP_HAL : : micros64 ( ) ,
0 ,
state . cylinder_status . ignition_timing_deg ,
state . cylinder_status . injection_time_ms ,
2024-09-10 22:55:33 -03:00
KELVIN_TO_C ( state . cylinder_status . cylinder_head_temperature ) ,
KELVIN_TO_C ( state . cylinder_status . exhaust_gas_temperature ) ,
2022-09-29 01:54:05 -03:00
state . cylinder_status . lambda_coefficient ,
2024-09-10 22:55:33 -03:00
KELVIN_TO_C ( state . cylinder_status . cylinder_head_temperature2 ) ,
KELVIN_TO_C ( state . cylinder_status . exhaust_gas_temperature2 ) ,
2022-09-29 01:54:05 -03:00
state . ecu_index ) ;
2018-03-28 20:37:58 -03:00
}
2022-06-03 07:59:46 -03:00
# endif // LOGGING_ENABLED
2018-03-28 20:37:58 -03:00
/*
send EFI_STATUS
*/
void AP_EFI : : send_mavlink_status ( mavlink_channel_t chan )
{
if ( ! backend ) {
return ;
}
2023-02-02 21:34:37 -04:00
float ignition_voltage ;
if ( isnan ( state . ignition_voltage ) | |
is_equal ( state . ignition_voltage , - 1.0f ) ) {
// zero means "unknown" in mavlink, 0.0001 means 0 volts
ignition_voltage = 0 ;
} else if ( is_zero ( state . ignition_voltage ) ) {
// zero means "unknown" in mavlink, 0.0001 means 0 volts
ignition_voltage = 0.0001f ;
} else {
ignition_voltage = state . ignition_voltage ;
} ;
2023-03-06 17:53:51 -04:00
// If fuel pressure is supported, but is exactly zero, shift it to 0.0001
// to indicate that it is supported.
float fuel_pressure = state . fuel_pressure ;
2023-02-15 13:06:54 -04:00
if ( is_zero ( fuel_pressure ) & & state . fuel_pressure_status ! = Fuel_Pressure_Status : : NOT_SUPPORTED ) {
2023-03-06 17:53:51 -04:00
fuel_pressure = 0.0001 ;
}
2023-02-15 13:06:54 -04:00
2018-03-28 20:37:58 -03:00
mavlink_msg_efi_status_send (
chan ,
AP_EFI : : is_healthy ( ) ,
state . ecu_index ,
state . engine_speed_rpm ,
state . estimated_consumed_fuel_volume_cm3 ,
state . fuel_consumption_rate_cm3pm ,
state . engine_load_percent ,
state . throttle_position_percent ,
state . spark_dwell_time_ms ,
state . atmospheric_pressure_kpa ,
state . intake_manifold_pressure_kpa ,
2022-01-12 08:03:24 -04:00
KELVIN_TO_C ( state . intake_manifold_temperature ) ,
2022-09-29 01:54:05 -03:00
KELVIN_TO_C ( state . cylinder_status . cylinder_head_temperature ) ,
state . cylinder_status . ignition_timing_deg ,
state . cylinder_status . injection_time_ms ,
2022-10-24 19:26:27 -03:00
KELVIN_TO_C ( state . cylinder_status . exhaust_gas_temperature ) ,
2022-09-29 21:44:13 -03:00
state . throttle_out ,
state . pt_compensation ,
2023-03-06 17:53:51 -04:00
ignition_voltage ,
fuel_pressure
2022-06-07 00:30:33 -03:00
) ;
2018-03-28 20:37:58 -03:00
}
2022-06-03 07:59:46 -03:00
// get a copy of state structure
void AP_EFI : : get_state ( EFI_State & _state )
{
WITH_SEMAPHORE ( sem ) ;
_state = state ;
}
2023-06-27 05:02:59 -03:00
void AP_EFI : : handle_EFI_message ( const mavlink_message_t & msg ) {
if ( backend ! = nullptr ) {
backend - > handle_EFI_message ( msg ) ;
}
}
2018-03-28 20:37:58 -03:00
namespace AP {
AP_EFI * EFI ( )
{
return AP_EFI : : get_singleton ( ) ;
}
}
2021-06-08 01:16:33 -03:00
# endif // HAL_EFI_ENABLED
2018-03-28 20:37:58 -03:00