mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-04-18 10:38:16 +00:00
154
examples/door_demo_example/door_service/complex_service.cpp
Normal file
154
examples/door_demo_example/door_service/complex_service.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <iostream>
|
||||
#include "complex_service.h"
|
||||
|
||||
void CDoorsExampleService::Initialize(const sdv::u8string& /*ssObjectConfig*/)
|
||||
{
|
||||
m_eStatus = sdv::EObjectStatus::initializing;
|
||||
|
||||
// Request the basic service for front left door.
|
||||
auto pFrontLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (pFrontLeftDoorSvc)
|
||||
{
|
||||
// Register front left door change event handler.
|
||||
pFrontLeftDoorSvc->RegisterOnSignalChangeOfLeftDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for front right door.
|
||||
auto pFrontRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (pFrontRightDoorSvc)
|
||||
{
|
||||
// Register front right door change event handler.
|
||||
pFrontRightDoorSvc->RegisterOnSignalChangeOfRightDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for rear left door.
|
||||
auto pRearLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (pRearLeftDoorSvc)
|
||||
{
|
||||
// Register rear left door change event handler.
|
||||
pRearLeftDoorSvc->RegisterOnSignalChangeOfLeftDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for front right door.
|
||||
auto pRearRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (pRearRightDoorSvc)
|
||||
{
|
||||
// Register rear right door change event handler.
|
||||
pRearRightDoorSvc->RegisterOnSignalChangeOfRightDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for locking the front left door.
|
||||
m_pFrontLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetLock>();
|
||||
|
||||
// Request the basic service for locking the front right door.
|
||||
m_pFrontRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetLock>();
|
||||
|
||||
// Request the basic service for locking the rear left door.
|
||||
m_pRearLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetLock>();
|
||||
|
||||
// Request the basic service for locking the rear right door.
|
||||
m_pRearRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetLock>();
|
||||
|
||||
// Validate if we have the Open/Closed signal and the Lock/Unlock door signal, both must exist together or both must not exist
|
||||
// Front left door is an exception, it isalways required
|
||||
if ((!pFrontLeftDoorSvc) || (!m_pFrontLeftDoorSvc))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interfaces for 'Front left door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pFrontRightDoorSvc == nullptr) != (m_pFrontRightDoorSvc == nullptr))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get both interfaces for 'Front right door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pRearLeftDoorSvc == nullptr) != (m_pRearLeftDoorSvc == nullptr))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get both interfaces for 'Rear left door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pRearRightDoorSvc == nullptr) != (m_pRearRightDoorSvc == nullptr))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get both interfaces for 'Rear right door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
m_doorsThread.start(m_Interval);
|
||||
m_eStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
sdv::EObjectStatus CDoorsExampleService::GetStatus() const
|
||||
{
|
||||
return m_eStatus;
|
||||
}
|
||||
|
||||
void CDoorsExampleService::SetOperationMode(sdv::EOperationMode /*eMode*/)
|
||||
{
|
||||
// Not applicable
|
||||
}
|
||||
|
||||
void CDoorsExampleService::Shutdown()
|
||||
{
|
||||
// Unregister front left door change event handler.
|
||||
auto pFrontLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (pFrontLeftDoorSvc)
|
||||
pFrontLeftDoorSvc->UnregisterOnSignalChangeOfLeftDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister front right door change event handler.
|
||||
auto pFrontRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (pFrontRightDoorSvc)
|
||||
pFrontRightDoorSvc->UnregisterOnSignalChangeOfRightDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister rear left door change event handler.
|
||||
auto pRearLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (pRearLeftDoorSvc)
|
||||
pRearLeftDoorSvc->UnregisterOnSignalChangeOfLeftDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister rear right door change event handler.
|
||||
auto pRearRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (pRearRightDoorSvc)
|
||||
pRearRightDoorSvc->UnregisterOnSignalChangeOfRightDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
m_doorsThread.stop();
|
||||
}
|
||||
|
||||
void CDoorsExampleService::AreAllDoorsClosed()
|
||||
{
|
||||
if (m_bFrontLeftDoorIsOpen || m_bFrontRightDoorIsOpen || m_bRearLeftDoorIsOpen || m_bRearRightDoorIsOpen)
|
||||
{
|
||||
m_doorsThread.stop();
|
||||
LockDoors(false);
|
||||
m_bAllDoorsAreLocked = false;
|
||||
return;
|
||||
}
|
||||
m_doorsThread.restart(m_Interval);
|
||||
}
|
||||
|
||||
void CDoorsExampleService::LockDoorsIfAllDoorsAreClosed()
|
||||
{
|
||||
if (m_bFrontLeftDoorIsOpen || m_bFrontRightDoorIsOpen || m_bRearLeftDoorIsOpen || m_bRearRightDoorIsOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bAllDoorsAreLocked = true;
|
||||
LockDoors(true);
|
||||
}
|
||||
|
||||
void CDoorsExampleService::LockDoors(const bool lock) const
|
||||
{
|
||||
if (m_pFrontLeftDoorSvc)
|
||||
m_pFrontLeftDoorSvc->SetLock(lock);
|
||||
if (m_pFrontRightDoorSvc)
|
||||
m_pFrontRightDoorSvc->SetLock(lock);
|
||||
if (m_pRearLeftDoorSvc)
|
||||
m_pRearLeftDoorSvc->SetLock(lock);
|
||||
if (m_pRearRightDoorSvc)
|
||||
m_pRearRightDoorSvc->SetLock(lock);
|
||||
}
|
||||
190
examples/door_demo_example/door_service/complex_service.h
Normal file
190
examples/door_demo_example/door_service/complex_service.h
Normal file
@@ -0,0 +1,190 @@
|
||||
#ifndef DOORS_COMPLEX_SERVICE_EXAMPLE_H
|
||||
#define DOORS_COMPLEX_SERVICE_EXAMPLE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// SDV framework support
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include <support/timer.h>
|
||||
|
||||
// VSS interfaces - located in ../interfaces
|
||||
#include "vss_vehiclechassisdooraxle01left_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle01left_bs_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle01right_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle01right_bs_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle02left_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle02left_bs_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle02right_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle02right_bs_tx.h"
|
||||
|
||||
#include "lock_doors_thread.h"
|
||||
|
||||
#include "../generated/door_service/door_ifc.h"
|
||||
|
||||
/**
|
||||
* @brief Doors example service: locks/unlocks doors after closing/opening doors
|
||||
*/
|
||||
class CDoorsExampleService : public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event
|
||||
, public IDoorService
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CDoorsExampleService() : m_doorsThread([&] { this->LockDoorsIfAllDoorsAreClosed(); }) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CDoorsExampleService()
|
||||
{
|
||||
// Just in case...
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
// Interface map
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(IDoorService)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
// Object declarations
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Doors 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 leftDoorIsOpen signal (front door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL1(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bFrontLeftDoorIsOpen != value);
|
||||
m_bFrontLeftDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (front door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR1(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bFrontRightDoorIsOpen != value);
|
||||
m_bFrontRightDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal (rear door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL2(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bRearLeftDoorIsOpen != value);
|
||||
m_bRearLeftDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (rear door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR2(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bRearRightDoorIsOpen != value);
|
||||
m_bRearRightDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get doors state. If the doors are locked/unlocked
|
||||
*/
|
||||
virtual bool GetDoorsStatus() override
|
||||
{
|
||||
return m_bAllDoorsAreLocked;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Check if all doors are close
|
||||
* @details If all doors are not closed, unlock doors
|
||||
*/
|
||||
void AreAllDoorsClosed();
|
||||
|
||||
/**
|
||||
* @brief Check if all doors are close
|
||||
* @details If all doors are closed, lock doors, otherwise do nothing. This is a callback function for timer.
|
||||
*/
|
||||
void LockDoorsIfAllDoorsAreClosed();
|
||||
|
||||
/**
|
||||
* @brief Lock or unlock doors
|
||||
* @param[in] lock if true lock doors, otherwise unlock doors
|
||||
*/
|
||||
void LockDoors(const bool lock) const;
|
||||
|
||||
sdv::EObjectStatus m_eStatus = sdv::EObjectStatus::initialization_pending; ///< Current object status
|
||||
|
||||
bool m_bFrontLeftDoorIsOpen = false; ///< Front Left Door Status
|
||||
bool m_bFrontRightDoorIsOpen = false; ///< Front Right Door Status
|
||||
bool m_bRearLeftDoorIsOpen = false; ///< Rear Left Door Status
|
||||
bool m_bRearRightDoorIsOpen = false; ///< Rear Right Door Status
|
||||
|
||||
bool m_bAllDoorsAreLocked = false; ///< state for locked/unlocked of all doors
|
||||
|
||||
///< Door lock interfaces.
|
||||
vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetLock* m_pFrontLeftDoorSvc = nullptr; ///< Front Left Door
|
||||
vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetLock* m_pFrontRightDoorSvc = nullptr; ///< Front Right Door
|
||||
vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetLock* m_pRearLeftDoorSvc = nullptr; ///< Rear Left Door
|
||||
vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetLock* m_pRearRightDoorSvc = nullptr; ///< Rear Right Door
|
||||
|
||||
LockDoorsThread m_doorsThread; ///< timer thread
|
||||
uint32_t m_Interval = 18; ///< interval value * 100 = x milliseconds
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CDoorsExampleService)
|
||||
|
||||
#endif // !define DOORS_COMPLEX_SERVICE_EXAMPLE_H
|
||||
17
examples/door_demo_example/door_service/door_ifc.idl
Normal file
17
examples/door_demo_example/door_service/door_ifc.idl
Normal file
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* @file door_ifc.idl
|
||||
* @details Door service interface definition.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief DoorService example service interface. The interface provides functions for the
|
||||
* Doors example complex service.
|
||||
*/
|
||||
interface IDoorService
|
||||
{
|
||||
/**
|
||||
* @brief Status of all doors together whether they are locked or unlocked.
|
||||
* @return true if all doors are locked, otherwise unlocked.
|
||||
*/
|
||||
boolean GetDoorsStatus();
|
||||
};
|
||||
95
examples/door_demo_example/door_service/lock_doors_thread.h
Normal file
95
examples/door_demo_example/door_service/lock_doors_thread.h
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
#ifndef LOCK_DOORS_THREAD_H
|
||||
#define LOCK_DOORS_THREAD_H
|
||||
|
||||
/**
|
||||
* @brief Thread to lock the doors (or execute any other callback the thread gets) after a certain time. can be restarted
|
||||
*/
|
||||
class LockDoorsThread
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor, set the callback function
|
||||
* @param[in] callback function to be called
|
||||
* @param[in] m_running when set to false end thread
|
||||
* @param[in] m_timeIn100MilliSeconds timespan * 100 in milliseconds before callback should be executed
|
||||
*/
|
||||
LockDoorsThread(std::function<void()> callback)
|
||||
: m_callback(callback), m_running(false), m_timeIn100MilliSeconds(0) {}
|
||||
|
||||
/**
|
||||
* @brief Stsrt thread
|
||||
* @param[in] timeSpan the time span before the callback will be executed
|
||||
*/
|
||||
void start(uint32_t timeSpan)
|
||||
{
|
||||
if (m_running)
|
||||
return;
|
||||
|
||||
m_timeIn100MilliSeconds = timeSpan;
|
||||
m_counter = 0;
|
||||
m_running = true;
|
||||
m_thread = std::thread(&LockDoorsThread::run, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop thread
|
||||
*/
|
||||
void stop()
|
||||
{
|
||||
m_running = false;
|
||||
if (m_thread.joinable())
|
||||
{
|
||||
m_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop and restart thread with new time setting
|
||||
* @param[in] timeSpan the time span before the callback will be executed
|
||||
*/
|
||||
void restart(uint32_t timeSpan)
|
||||
{
|
||||
stop();
|
||||
m_counter = 0;
|
||||
start(timeSpan);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief destructor
|
||||
*/
|
||||
~LockDoorsThread()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief thread loop. If time span is reach, execute callback and reset. Only one execution required
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
while (m_running && m_counter <= m_timeIn100MilliSeconds)
|
||||
{
|
||||
m_counter++;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
if (m_counter > m_timeIn100MilliSeconds && m_callback)
|
||||
{
|
||||
m_callback();
|
||||
m_counter = 0;
|
||||
}
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
std::function<void()> m_callback; ///< callback function
|
||||
std::atomic<bool> m_running; ///< status if loop is running
|
||||
std::thread m_thread; ///< timer thread
|
||||
uint32_t m_counter; ///< loop counter
|
||||
uint32_t m_timeIn100MilliSeconds; ///< time before the callback will be executed
|
||||
};
|
||||
|
||||
#endif // !define LOCK_DOORS_THREAD_H
|
||||
Reference in New Issue
Block a user