//***************************************************************************** // (C) Automotive Lighting Reutlingen GmbH // Tuebinger Strasse 123, 72762 Reutlingen, Germany // // Automotive Lighting Reutlingen GmbH owns all the rights to this work. // This work shall not be copied, reproduced, used, modified, transferred // or its information shall not be disclosed without the prior written // authorization of Automotive Lighting Reutlingen GmbH. //***************************************************************************** //----------------------------------------------------------------------------- /// \file AvacData.c /// /// \brief /// /// \descr /// /// Additional information can be found in the design description (Link: /// MDDD) /// /// \author Alf Traulsen (taf2rt) /// mailTo:alf.traulsen@al-lighting.com //----------------------------------------------------------------------------- #define RTE_MICROSAR_PIM_EXPORT #include #include "Std_Types.h" #include #include #include #include #include "Rte_Type.h" #undef RTE_APPLICATION_HEADER_FILE #include "Rte_ctaaAvac.h" #undef RTE_APPLICATION_HEADER_FILE #define AvacData_WheelBase 2950 #define SensorCaliData 0 #define ctaaAvac_START_SEC_VAR_INIT_UNSPECIFIED # include "ctaaAvac_MemMap.h" // ---------------------------------------------------------------------------- // Variables // ---------------------------------------------------------------------------- boolean AvacData_boCodingValid = TRUE; boolean AvacData_boPitchConfigValid = TRUE; uint8 AvacData_ucGradientLimiterUp = AVAC_StaticAngleGradFast; uint8 AvacData_ucGradientLimiterDown = AVAC_StaticAngleGradFast; const tRomPara_AvacAlgoDynCfg* CodBlockDavacPara = NULL; // active avac config data const tRomPara_AvacAlgoGenCfg* CodBlockAvacGenGfg = NULL; STATIC_AL tisAvacPosition AvacPositionOutput = { 0 }; STATIC_AL uint8 AvacNVM_vehicleConfg[4] = {0,0,0,0}; STATIC_AL sint16 NvmSensorCaliData = 0; STATIC_AL uint16 VehicleWheelBase = 0; #define ctaaAvac_STOP_SEC_VAR_INIT_UNSPECIFIED # include "ctaaAvac_MemMap.h" //============================================================================= // Functions //============================================================================= void Avac_GetInput(void); static uint8 UaApplCalcPitchAngle(sint32 front_rear_delta, tPitchCan* pitch); static sint16 CalcAcceleration(const uint16 unSpeed); /////////////////////////////////////////////////////////////////////////////// // Avac debug code, generate fake input ////////////////////////////////////////////////////////////////////////////// #define DEBUG_AVAC_DATA STD_ON #if (DEBUG_AVAC_DATA == STD_OFF) sint16 dummySpeed; sint16 dummyAngle; #define DEBUG_AVAC_MAX_STEP 1000 uint16 steps = 0; #endif #define ctaaAvac_START_SEC_CODE # include "ctaaAvac_MemMap.h" void AvacData_Init(void) { tisCodingStatus CodingStatus; uint8 i; uint8 *data; data = Rte_Pim_PimCalibrationZeroLevel(); for (i = 0; i < 4; i++) { AvacNVM_vehicleConfg[i] = *(data+i); } /*check pitch sensor calibration data valid, provided by CalibrationZeroLevel*/ if ((AvacNVM_vehicleConfg[0] == NVM_AXIS_CALI_INVALID) || (AvacNVM_vehicleConfg[1] == NVM_AXIS_CALI_INVALID) || (AvacNVM_vehicleConfg[2] == NVM_AXIS_CALI_INVALID) || (AvacNVM_vehicleConfg[3] == NVM_AXIS_CALI_INVALID)) { AvacData_boPitchConfigValid = FALSE; } else { NvmSensorCaliData = (sint16)(((AvacNVM_vehicleConfg[0] + LEVELING_SENSER_OFFSET + AvacNVM_vehicleConfg[1] + LEVELING_SENSER_OFFSET) - (AvacNVM_vehicleConfg[2] + LEVELING_SENSER_OFFSET + AvacNVM_vehicleConfg[3] + LEVELING_SENSER_OFFSET)) >> 1); AvacData_boPitchConfigValid = TRUE; } //check coding valid (void)Rte_Read_PpareCodMCodingStatus_sCodingStatus(&CodingStatus); if (CodingStatus.eCodingStatus == E_OK) { VehicleWheelBase = applicationCodingData.System.VehicleData.WheelBase; CodBlockDavacPara = &applicationCodingData.System.AvacAlgoDynCfg; CodBlockAvacGenGfg = &applicationCodingData.System.AvacAlgoGenCfg; AvacData_boCodingValid = TRUE; } else { AvacData_boCodingValid = FALSE; } } //----------------------------------------------------------------------------- /// \brief AvacData_GetLowBeamOn /// /// \descr get low beam state /// /// \param - /// /// \return void //----------------------------------------------------------------------------- boolean AvacData_GetLowBeamOn(void) { // if light is switched on physically, AVAC must be active. boolean ret_result = FALSE; tisLightCmd AvacData_LightCmd; Rte_Call_PpaclVehHubLightCmd_ReadData(&AvacData_LightCmd); if ((AvacData_LightCmd.sLowerBeam.boValue) && (SIG_VALID == AvacData_LightCmd.sLowerBeam.eQty)) { ret_result = TRUE; } else { ret_result = FALSE; } if (AvacData_boCodingValid == FALSE) { AvacData_Init(); // check if calibration data written } return ret_result; } //----------------------------------------------------------------------------- /// \brief AvacData_GetAvacS_Ok() /// /// \descr static AVAC OK /// /// \param - /// /// \return OK //----------------------------------------------------------------------------- boolean AvacData_GetAvacS_Ok() { return TRUE; } //----------------------------------------------------------------------------- /// \brief AvacData_GetAvacS_En() /// /// \descr static AVAC enable /// /// \param - /// /// \return enable //----------------------------------------------------------------------------- boolean AvacData_GetAvacS_En() { return AvacData_boCodingValid; } //----------------------------------------------------------------------------- /// \brief AvacData_GetAvacD_Ok() /// /// \descr dynamic AVAC /// /// \param - /// /// \return OK //----------------------------------------------------------------------------- boolean AvacData_GetAvacD_Ok() { return TRUE; // TBD AfsMaster implementation } //----------------------------------------------------------------------------- /// \brief AvacData_GetAvacD_En() /// /// \descr dynamic AVAC enable /// /// \param - /// /// \return enable //----------------------------------------------------------------------------- boolean AvacData_GetAvacD_En() { return AvacData_boCodingValid; } //----------------------------------------------------------------------------- /// \brief AvacData_ReadPitch() /// /// \descr /// /// \param - /// /// \return void //----------------------------------------------------------------------------- void AvacData_ReadPitch(tAvac_Pitch* pPitch) { tPitchCan PitchMsg = { 0, 0, SIG_INVALID }; tisVehicleDynamic Avac_VehicleDynamic; Rte_Call_PpaclVehHubVehicleDynamic_ReadData(&Avac_VehicleDynamic); if (SIG_VALID == Avac_VehicleDynamic.sSuspensionHeight.eQty) { //The suspension height is converted to radians (void)UaApplCalcPitchAngle((sint32)(((((uint16)(Avac_VehicleDynamic.sSuspensionHeight.usValueFL) + LEVELING_SENSER_OFFSET) + //Offset:change from -100 to -127, ((uint16)(Avac_VehicleDynamic.sSuspensionHeight.usValueFR) + LEVELING_SENSER_OFFSET)) - (((uint16)(Avac_VehicleDynamic.sSuspensionHeight.usValueRL) + LEVELING_SENSER_OFFSET) + ((uint16)(Avac_VehicleDynamic.sSuspensionHeight.usValueRR) + LEVELING_SENSER_OFFSET)) ) >> 1), &PitchMsg); } // convert to app pPitch->nAngle = PitchMsg.Angle; // [0.1mrad] pPitch->nHeightErr = PitchMsg.HeightErr; // [0.1mrad] pPitch->eSigQty = (tieSigQty)PitchMsg.eSigQty; // same definition of RTE and App } //----------------------------------------------------------------------------- /// \brief AvacData_ReadSpeed() /// /// \descr /// /// \param - /// /// \return void //----------------------------------------------------------------------------- void AvacData_ReadSpeed(tAvac_Speed* pSpeed) { #if (DEBUG_AVAC_DATA == STD_OFF) pSpeed->nSpeed = dummySpeed++; pSpeed->nAcceleration = 10; pSpeed->unMotion = BB_MotionLow; pSpeed->eSigQty = SIG_VALID; if (steps++ > DEBUG_AVAC_MAX_STEP) { dummySpeed = 0; dummyAngle = 0; steps = 0; } #else tSpeedMsg SpeedMsg; tisVehicleDynamic Avac_VehicleSpeed; Rte_Call_PpaclVehHubVehicleDynamic_ReadData(&Avac_VehicleSpeed); if (SIG_VALID == Avac_VehicleSpeed.sSpeed.eQty) { SpeedMsg.Speed = Avac_VehicleSpeed.sSpeed.usValue; } if (SIG_VALID == Avac_VehicleSpeed.sAccelerationRate.eQtyX) { SpeedMsg.Acceleration = Avac_VehicleSpeed.sAccelerationRate.usAccValueX; } else if (SIG_VALID == Avac_VehicleSpeed.sSpeed.eQty) { SpeedMsg.Acceleration = CalcAcceleration(SpeedMsg.Speed);//Acceleration is calculated from Speed } else { //do nothing } // convert to app pSpeed->nSpeed = SpeedMsg.Speed; // [0.1 km/h] pSpeed->nAcceleration = SpeedMsg.Acceleration; // [0.1 m/s^2] pSpeed->eSigQty = Avac_VehicleSpeed.sSpeed.eQty; // same definition of RTE and app #endif } //----------------------------------------------------------------------------- /// \brief AvacData_ReadAccelPreDetect() /// /// \descr /// /// \param - /// /// \return void //----------------------------------------------------------------------------- void AvacData_ReadAccelPreDetect(tAvac_AccelPreDetect* pAccelPreDetect) { #if (DEBUG_AVAC_DATA == STD_ON) pAccelPreDetect->eSigQty = SIG_INVALID; #else tAccelPreDetectMsg AccelPreDetectMsg; (void) Rte_Read_SigPrepRx_AccelPreDetectMsg_Port(&AccelPreDetectMsg); // convert to app pAccelPreDetect->nValue = AccelPreDetectMsg.Value; // [0..100] % pAccelPreDetect->nDelta = AccelPreDetectMsg.Delta; // [0..100] % pAccelPreDetect->eSigQty = (tieSigQty)AccelPreDetectMsg.eSigQty; #endif } //----------------------------------------------------------------------------- /// \brief AvacData_ReadBrakePreDetect() /// /// \descr /// /// \param - /// /// \return void //----------------------------------------------------------------------------- void AvacData_ReadBrakePreDetect(tAvac_BrakePreDetect* pBrakePreDetect) { #if (DEBUG_AVAC_DATA == STD_ON) pBrakePreDetect->eSigQty = SIG_INVALID; #else tBrakePreDetectMsg BrakePreDetectMsg; (void) Rte_Read_SigPrepRx_BrakePreDetectMsg_Port(&BrakePreDetectMsg); // convert to app pBrakePreDetect->nValue = BrakePreDetectMsg.Value; // [0..100] % pBrakePreDetect->nDelta = BrakePreDetectMsg.Delta; // [0..100] % pBrakePreDetect->eSigQty = (tieSigQty)BrakePreDetectMsg.eSigQty; #endif } // --------------------------------------------------------------------------- /// /// \func Avac_GetInput /// /// \brief cyclic function called every 20ms /// /// \param none /// /// \return none /// // --------------------------------------------------------------------------- void Avac_GetInput(void) { } //----------------------------------------------------------------------------- /// \brief AvacData_WriteAvacOut() /// /// \descr /// /// \param - /// /// \return void //----------------------------------------------------------------------------- void AvacData_WriteAvacOut(const tAvac_Out* pAvacOut) { /*tisAvacPosition AvacPositionOutput;*/ sint16 nAngle; // convert internal Avac-Data [0.1mrad] to RTE-Data [0.01 deg] nAngle = pAvacOut->nAngle; nAngle = (nAngle >= 0) ? (sint16)((((sint32)nAngle * 180) + 157) / 314) : (sint16)((((sint32)nAngle * 180) - 157) / 314); AvacPositionOutput.ssVerAngle0 = nAngle; //left AvacPositionOutput.ssVerAngle1 = nAngle; //Right AvacPositionOutput.eAvacSigQty = pAvacOut->eSigQty; Rte_Write_PpaseAVACAvacPosition_sValue(&AvacPositionOutput); } // input : active front - rear delta // output: pitch and signal validation static uint8 UaApplCalcPitchAngle(sint32 front_rear_delta, tPitchCan* pitch) { sint32 delta; pitch->eSigQty = SIG_INVALID; // offset to calibration data, which is optical nullage delta = front_rear_delta - NvmSensorCaliData; // angle[0.1 mrad] = arctan(delta/wheelbase) * 10,000 pitch->Angle = (sint16)(delta * 10000 / VehicleWheelBase); // calc arctan and convert to 0.1mrad // [1/10 mrad] front side up --> positive value pitch->HeightErr = 0; pitch->eSigQty = SIG_VALID; return 1; } //----------------------------------------------------------------------------- /// \brief Calculate acceleration from speed /// /// \param unSpeed Speed [0.1 km/h] /// /// \return sint16 acceleration [0.1 m/s^2] //----------------------------------------------------------------------------- static sint16 CalcAcceleration(const uint16 unSpeed) { static uint16 aunAvrgSpeed[5] = { 0, 0, 0, 0, 0 }; sint32 lAcc; sint32 lDeltaSpeed = (sint32)unSpeed - (sint32)aunAvrgSpeed[4]; // speed difference on T = 100ms (5*20ms) // calculate acceleration [0.1 m/s^2] // Acc = DeltaSpeed(0.1km/h) / DeltaT(ms) = DeltaSpeed / 100ms // Acc = (DeltaSpeed * 1000m / 3600) / 0.1 // 0.1Acc = DeltaSpeed * 25 / 9 lAcc = (lDeltaSpeed * 25) / 9; // store values aunAvrgSpeed[4] = aunAvrgSpeed[3]; aunAvrgSpeed[3] = aunAvrgSpeed[2]; aunAvrgSpeed[2] = aunAvrgSpeed[1]; aunAvrgSpeed[1] = aunAvrgSpeed[0]; aunAvrgSpeed[0] = unSpeed; return (sint16)lAcc; } #define ctaaAvac_STOP_SEC_CODE # include "ctaaAvac_MemMap.h"