mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-07-02 05:35:11 +00:00
176
examples/system_demo_example/example_service/complex_service.cpp
Normal file
176
examples/system_demo_example/example_service/complex_service.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
#include <iostream>
|
||||
#include "complex_service.h"
|
||||
|
||||
const float g_fSpeedThreshold = 30.0f / 3.6f;
|
||||
|
||||
CCounterSteeringExampleService::CCounterSteeringExampleService()
|
||||
{
|
||||
}
|
||||
|
||||
CCounterSteeringExampleService::~CCounterSteeringExampleService()
|
||||
{
|
||||
// Just in case...
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::Initialize(const sdv::u8string& /*ssObjectConfig*/)
|
||||
{
|
||||
m_eStatus = sdv::EObjectStatus::initializing;
|
||||
|
||||
// Request the basic service for monitoring the alive counter.
|
||||
m_pAliveCounterSvc = sdv::core::GetObject("Vehicle.Software.Application.IsActiveCounter_Service").GetInterface<vss::Vehicle::Software::Application::IsActiveCounterService::IVSS_SetCounter>();
|
||||
if (!m_pAliveCounterSvc)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_SetCounter': [CCounterSteeringExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Request the basic service for the rear axle.
|
||||
m_pRearAxleSvc = sdv::core::GetObject("Vehicle.Chassis.RearAxle.Row.Wheel_Service").GetInterface<vss::Vehicle::Chassis::RearAxle::Row::WheelService::IVSS_SetRearAxle>();
|
||||
if (!m_pRearAxleSvc)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_SetAngle': [CCounterSteeringExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Request the basic service for the steering wheel.
|
||||
auto pSteeringWheelSvc = sdv::core::GetObject("Vehicle.Chassis.SteeringWheel.Angle_Service").GetInterface<vss::Vehicle::Chassis::SteeringWheel::AngleService::IVSS_GetSteeringWheel>();
|
||||
if (!pSteeringWheelSvc)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_SetSteeringAngle': [CCounterSteeringExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Request the basic service for the vehicle speed.
|
||||
auto pVehSpeedSvc = sdv::core::GetObject("Vehicle.Speed_Service").GetInterface<vss::Vehicle::SpeedService::IVSS_GetSpeed>();
|
||||
if (!pVehSpeedSvc)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_SetSpeed': [CCounterSteeringExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Register steering wheel change event handler.
|
||||
pSteeringWheelSvc->RegisterOnSignalChangeOfWheelAngle(static_cast<vss::Vehicle::Chassis::SteeringWheel::AngleService::IVSS_SetSteeringWheel_Event*> (this));
|
||||
|
||||
// Register vehicle speed change event handler.
|
||||
pVehSpeedSvc->RegisterOnSignalChangeOfVehicleSpeed(static_cast<vss::Vehicle::SpeedService::IVSS_SetSpeed_Event*> (this));
|
||||
|
||||
// Start the alive timer with 10 ms period.
|
||||
m_Timer = sdv::core::CTaskTimer(10, [&]() {TimerFunction(); });
|
||||
if (!m_Timer)
|
||||
{
|
||||
SDV_LOG_ERROR("CCounterSteeringExampleService: tasktimer with 10 milliseconds could not be created.");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
SDV_LOG_INFO("CCounterSteeringExampleService: tasktimer created with 10 milliseconds");
|
||||
|
||||
m_eStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
sdv::EObjectStatus CCounterSteeringExampleService::GetStatus() const
|
||||
{
|
||||
return m_eStatus;
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::SetOperationMode(sdv::EOperationMode /*eMode*/)
|
||||
{
|
||||
// Not applicable
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::Shutdown()
|
||||
{
|
||||
// Terminate the alive counter
|
||||
m_Timer.Reset();
|
||||
|
||||
// Unregister the steering wheel event handler.
|
||||
auto pSteeringWheelSvc = sdv::core::GetObject("Vehicle.Chassis.SteeringWheel.Angle_Service").GetInterface<vss::Vehicle::Chassis::SteeringWheel::AngleService::IVSS_GetSteeringWheel>();
|
||||
if (pSteeringWheelSvc)
|
||||
pSteeringWheelSvc->UnregisterOnSignalChangeOfWheelAngle(static_cast<vss::Vehicle::Chassis::SteeringWheel::AngleService::IVSS_SetSteeringWheel_Event*> (this));
|
||||
|
||||
// Unregister the vehicle speed event handler.
|
||||
auto pVehSpeedSvc = sdv::core::GetObject("Vehicle.Speed_Service").GetInterface<vss::Vehicle::SpeedService::IVSS_GetSpeed>();
|
||||
if (pVehSpeedSvc)
|
||||
pVehSpeedSvc->UnregisterOnSignalChangeOfVehicleSpeed(static_cast<vss::Vehicle::SpeedService::IVSS_SetSpeed_Event*> (this));
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::SetSteeringWheel(float value)
|
||||
{
|
||||
if (m_fSteeringWheel == value) return;
|
||||
m_fSteeringWheel = value;
|
||||
UpdateRearAxleAngle();
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::SetSpeed(float value)
|
||||
{
|
||||
if (m_fVehSpeed == value) return;
|
||||
m_fVehSpeed = value;
|
||||
UpdateRearAxleAngle();
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::ActivateService(/*in*/ bool bActivate)
|
||||
{
|
||||
if (m_bActivated == bActivate) return;
|
||||
m_bActivated = bActivate;
|
||||
UpdateRearAxleAngle();
|
||||
}
|
||||
|
||||
bool CCounterSteeringExampleService::IsActivated() const
|
||||
{
|
||||
return m_bActivated;
|
||||
}
|
||||
|
||||
bool CCounterSteeringExampleService::CounterSteeringActive() const
|
||||
{
|
||||
return m_bActivated && m_fVehSpeed < g_fSpeedThreshold;
|
||||
}
|
||||
|
||||
double CCounterSteeringExampleService::RearAxleAngle() const
|
||||
{
|
||||
return m_fRearAxleAngle;
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::UpdateRearAxleAngle()
|
||||
{
|
||||
float fRearAxleAngle = 0.0;
|
||||
if (CounterSteeringActive())
|
||||
{
|
||||
// Get steering wheel angle percentage
|
||||
// The steering wheel can have values from -16...16 rad.
|
||||
float fSteeringWheelPercent = m_fSteeringWheel / 16.0f;
|
||||
if (fSteeringWheelPercent > 1.0) fSteeringWheelPercent = 1.0;
|
||||
if (fSteeringWheelPercent < -1.0) fSteeringWheelPercent = -1.0;
|
||||
|
||||
// Calculate the vehicle speed percentage up to 30 km/h
|
||||
// The vehicle speed is calculated in m/s.
|
||||
float fVehSpeedPercent = m_fVehSpeed / g_fSpeedThreshold;
|
||||
if (fVehSpeedPercent > 1.0) fVehSpeedPercent = 1.0;
|
||||
|
||||
// Calculate the counter steering percentage (counter proportional to the vehicle speed - the quicker, the less counter
|
||||
// steering).
|
||||
// The rear axle angle can change between -5.12...5.11 deg.
|
||||
fRearAxleAngle = 5.11f * -fSteeringWheelPercent * (1.0f - fVehSpeedPercent);
|
||||
}
|
||||
if (fRearAxleAngle == m_fRearAxleAngle) return;
|
||||
|
||||
// Inform the rear exle about the new steering position.
|
||||
m_fRearAxleAngle = fRearAxleAngle;
|
||||
if (m_pRearAxleSvc) m_pRearAxleSvc->SetRearAxle(fRearAxleAngle);
|
||||
}
|
||||
|
||||
void CCounterSteeringExampleService::TimerFunction()
|
||||
{
|
||||
// Increase the counter (max 5 bits).
|
||||
m_uiAliveCounter++;
|
||||
if (m_uiAliveCounter > 31)
|
||||
m_uiAliveCounter = 0;
|
||||
|
||||
// Inform the alive counter monitor service
|
||||
if (m_pAliveCounterSvc)
|
||||
m_pAliveCounterSvc->SetCounter(m_uiAliveCounter);
|
||||
}
|
||||
156
examples/system_demo_example/example_service/complex_service.h
Normal file
156
examples/system_demo_example/example_service/complex_service.h
Normal file
@@ -0,0 +1,156 @@
|
||||
#ifndef COMPLEX_SERVICE_EXAMPLE_H
|
||||
#define COMPLEX_SERVICE_EXAMPLE_H
|
||||
|
||||
// C++ library
|
||||
#include <iostream>
|
||||
|
||||
// SDV framework support
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include <support/timer.h>
|
||||
|
||||
// VSS interfaces - located in ../generated/vss_files/include
|
||||
#include "vss_vehiclechassisrearaxlerowwheel_bs_tx.h"
|
||||
#include "vss_vehiclechassissteeringwheelangle_bs_rx.h"
|
||||
#include "vss_vehiclesoftwareapplicationisactivecounter_bs_tx.h"
|
||||
#include "vss_vehiclespeed_bs_rx.h"
|
||||
|
||||
// Complex service counter steering interface - located in ../generated/example_service
|
||||
#include "countersteering.h"
|
||||
|
||||
/**
|
||||
* @brief Counter steering example service
|
||||
* @details This complex service provides a simple counter steering example (rear axle steering to reduce the turning radius of the
|
||||
* vehicle) that will be activated dependable on the speed. For a speed of 30 km/s or less, the steering wheel angle is
|
||||
* counter-steering the rear axle. The amount of counter-steering is proportional to the speed (the lower the speed the more
|
||||
* counter-steering takes place).
|
||||
* Input events from basic service: steering wheel angle (-16...16 rad)
|
||||
* vehicle speed (0...128 m/s)
|
||||
* Output calls for basic service: rear axle angle (-5.12...5.11 deg)
|
||||
* alive counter (increase every 10 ms)
|
||||
* Input calls for applications: counter steering enabled (true/false)
|
||||
* Output info for applications: rear axle angle (-5.12...5.11 deg)
|
||||
* counter steering active (true/false)
|
||||
* counter steering enabled (true/false)
|
||||
*/
|
||||
class CCounterSteeringExampleService :
|
||||
public sdv::CSdvObject,
|
||||
public sdv::IObjectControl,
|
||||
public vss::Vehicle::Chassis::SteeringWheel::AngleService::IVSS_SetSteeringWheel_Event,
|
||||
public vss::Vehicle::SpeedService::IVSS_SetSpeed_Event,
|
||||
public ICounterSteeringService
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CCounterSteeringExampleService();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CCounterSteeringExampleService();
|
||||
|
||||
// Interface map
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::SteeringWheel::AngleService::IVSS_SetSteeringWheel_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::SpeedService::IVSS_SetSpeed_Event)
|
||||
SDV_INTERFACE_ENTRY(ICounterSteeringService)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
// Object declarations
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Counter Steering Example Service")
|
||||
DECLARE_OBJECT_SINGLETON()
|
||||
|
||||
/**
|
||||
* @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
void Initialize(const sdv::u8string& ssObjectConfig) override;
|
||||
|
||||
/**
|
||||
* @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
|
||||
* @return Return the current status of the object.
|
||||
*/
|
||||
sdv::EObjectStatus GetStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode) override;
|
||||
|
||||
/**
|
||||
* @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
|
||||
*/
|
||||
void Shutdown() override;
|
||||
|
||||
/**
|
||||
* @brief Set steering angle event. Overload of
|
||||
* vss::Vehicle::Chassis::SteeringWheel::AngleService::IVSS_SetSteeringWheel_Event::SetSteeringWheel.
|
||||
* @param[in] value Steering wheel angle in radials (-16...16 rad)
|
||||
*/
|
||||
virtual void SetSteeringWheel(float value) override;
|
||||
|
||||
/**
|
||||
* @brief Speed event. Overload of vss::Vehicle::SpeedService::IVSS_SetSpeed_Event::SetSpeed.
|
||||
* @param[in] value Vehicle speed in m/s (0... 128 m/s)
|
||||
*/
|
||||
virtual void SetSpeed(float value) override;
|
||||
|
||||
/**
|
||||
* @brief Activate or deactivate the counter steering service. Overload of ICounterSteeringService::ActivateService.
|
||||
* @param[in] bActivate When set, the service will be activated; otherwise deactivated.
|
||||
*/
|
||||
virtual void ActivateService(/*in*/ bool bActivate) override;
|
||||
|
||||
/**
|
||||
* @brief Is the counter steering service currently activated? Overload of ICounterSteeringService::IsActivated.
|
||||
* @return Returns whether the counter steering service is currently activated.
|
||||
*/
|
||||
virtual bool IsActivated() const override;
|
||||
|
||||
/**
|
||||
* @brief Does counter steering currently take place (speed > 30 km/s)? Overload of
|
||||
* ICounterSteeringService::CounterSteeringActive.
|
||||
* @return Returns whether counter steering currently takes place.
|
||||
*/
|
||||
virtual bool CounterSteeringActive() const override;
|
||||
|
||||
/**
|
||||
* @brief The calculated rear steering axle position. Overload of ICounterSteeringService::RearAxleAngle.
|
||||
* @return Returns the rear steering axle position in degrees (or 0 when not active).
|
||||
*/
|
||||
virtual double RearAxleAngle() const override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Update the rear axle angle baed on the stored input.
|
||||
*/
|
||||
void UpdateRearAxleAngle();
|
||||
|
||||
/**
|
||||
* @brief Timer function, function will be called by the timer, default every 10 ms
|
||||
*/
|
||||
void TimerFunction();
|
||||
|
||||
sdv::EObjectStatus m_eStatus = sdv::EObjectStatus::initialization_pending; ///< Current object status
|
||||
volatile float m_fSteeringWheel = 0.0; ///< Steering wheel angle
|
||||
volatile float m_fVehSpeed = 0.0; ///< Vehicle speed
|
||||
volatile float m_fRearAxleAngle = 0.0; ///< Output rear angle
|
||||
uint8_t m_uiAliveCounter = 0u; ///< Output alive counter
|
||||
bool m_bActivated = false; ///< Is the service activated?
|
||||
sdv::core::CTaskTimer m_Timer; ///< Timer for alive counter (10 ms)
|
||||
|
||||
///< Alive counter interface.
|
||||
vss::Vehicle::Software::Application::IsActiveCounterService::IVSS_SetCounter* m_pAliveCounterSvc = nullptr;
|
||||
|
||||
///< Rear axle interface.
|
||||
vss::Vehicle::Chassis::RearAxle::Row::WheelService::IVSS_SetRearAxle* m_pRearAxleSvc = nullptr;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CCounterSteeringExampleService)
|
||||
|
||||
#endif // !define COMPLEX_SERVICE_EXAMPLE_H
|
||||
@@ -0,0 +1,35 @@
|
||||
/*******************************************************************************
|
||||
* @file countersteering.idl
|
||||
* @details Counter steering example service interface definition.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Counter steering example service interface. The interface provides functions for the
|
||||
* counter steering example complex service.
|
||||
*/
|
||||
interface ICounterSteeringService
|
||||
{
|
||||
/**
|
||||
* @brief Activate or deactivate the counter steering service.
|
||||
* @param[in] bActivate When set, the service will be activated; otherwise deactivated.
|
||||
*/
|
||||
void ActivateService(in boolean bActivate);
|
||||
|
||||
/**
|
||||
* @brief Is the counter steering service currently activated?
|
||||
* @return Returns whether the counter steering service is currently activated.
|
||||
*/
|
||||
boolean IsActivated() const;
|
||||
|
||||
/**
|
||||
* @brief Does counter steering currently take place (speed > 30 km/s)?
|
||||
* @return Returns whether counter steering currently takes place.
|
||||
*/
|
||||
boolean CounterSteeringActive() const;
|
||||
|
||||
/**
|
||||
* @brief The calculated rear steering axle position.
|
||||
* @return Returns the rear steering axle position in degrees (or 0 when not active).
|
||||
*/
|
||||
double RearAxleAngle() const;
|
||||
};
|
||||
Reference in New Issue
Block a user