mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-04-21 03:38:15 +00:00
448
examples/door_demo_example/door_app/console.cpp
Normal file
448
examples/door_demo_example/door_app/console.cpp
Normal file
@@ -0,0 +1,448 @@
|
||||
#include "include/console.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <conio.h> // Needed for _kbhit
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
const CConsole::SConsolePos g_sTitle{ 1, 1 };
|
||||
const CConsole::SConsolePos g_sSubTitle{ 2, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator11{ 4, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator12{ 6, 1 };
|
||||
const CConsole::SConsolePos g_sFrontLeftDoorIsOpen{ 7, 1 };
|
||||
const CConsole::SConsolePos g_sFrontRightDoorIsOpen{ 8, 1 };
|
||||
const CConsole::SConsolePos g_sRearLeftDoorIsOpen{ 9, 1 };
|
||||
const CConsole::SConsolePos g_sRearRightDoorIsOpen{ 10, 1 };
|
||||
const CConsole::SConsolePos g_sFrontLeftDoorIsLocked{ 7, 42 };
|
||||
const CConsole::SConsolePos g_sFrontRightDoorIsLocked{ 8, 42 };
|
||||
const CConsole::SConsolePos g_sRearLeftDoorIsLocked{ 9, 42 };
|
||||
const CConsole::SConsolePos g_sRearRightDoorIsLocked{ 10, 42 };
|
||||
const CConsole::SConsolePos g_sSeparator21{ 12, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator22{ 14, 1 };
|
||||
const CConsole::SConsolePos g_sVehicleDevice{ 15, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator31{ 17, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator32{ 19, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceL1{ 20, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceR1{ 21, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceL2{ 22, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceR2{ 23, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator41{ 25, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator42{ 26, 1 };
|
||||
const CConsole::SConsolePos g_sComplexService{ 27, 1 };
|
||||
const CConsole::SConsolePos g_sControlDescription{ 29, 1 };
|
||||
const CConsole::SConsolePos g_sCursor{ 30, 1 };
|
||||
|
||||
CConsole::CConsole()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Enable ANSI escape codes
|
||||
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hStdOut != INVALID_HANDLE_VALUE && GetConsoleMode(hStdOut, &m_dwConsoleOutMode))
|
||||
SetConsoleMode(hStdOut, m_dwConsoleOutMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (hStdIn != INVALID_HANDLE_VALUE && GetConsoleMode(hStdIn, &m_dwConsoleInMode))
|
||||
SetConsoleMode(hStdIn, m_dwConsoleInMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
|
||||
#elif defined __unix__
|
||||
// Disable echo
|
||||
tcgetattr(STDIN_FILENO, &m_sTermAttr);
|
||||
struct termios sTermAttrTemp = m_sTermAttr;
|
||||
sTermAttrTemp.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &sTermAttrTemp);
|
||||
m_iFileStatus = fcntl(STDIN_FILENO, F_GETFL, 0);
|
||||
fcntl(STDIN_FILENO, F_SETFL, m_iFileStatus | O_NONBLOCK);
|
||||
#else
|
||||
#error The OS is not supported!
|
||||
#endif
|
||||
}
|
||||
|
||||
CConsole::~CConsole()
|
||||
{
|
||||
SetCursorPos(g_sCursor);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Return to the stored console mode
|
||||
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hStdOut != INVALID_HANDLE_VALUE)
|
||||
SetConsoleMode(hStdOut, m_dwConsoleOutMode);
|
||||
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (hStdIn != INVALID_HANDLE_VALUE)
|
||||
SetConsoleMode(hStdIn, m_dwConsoleInMode);
|
||||
#elif defined __unix__
|
||||
// Return the previous file status flags.
|
||||
fcntl(STDIN_FILENO, F_SETFL, m_iFileStatus);
|
||||
|
||||
// Return to previous terminal state
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &m_sTermAttr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CConsole::PrintHeader(const uint32_t numberOfDoors)
|
||||
{
|
||||
// Clear the screen...
|
||||
std::cout << "\x1b[2J";
|
||||
|
||||
std::string title = "Door demo example: Data link attached (4 doors) ";
|
||||
if (numberOfDoors <= 4)
|
||||
{
|
||||
title = "Door demo example: Vehicle has ";
|
||||
title.append(std::to_string(numberOfDoors));
|
||||
title.append(" doors.");
|
||||
}
|
||||
|
||||
// Print the titles
|
||||
PrintText(g_sTitle, title.c_str());
|
||||
PrintText(g_sSubTitle, " Doors are locked automatically after 2 seconds when all doors are closed.");
|
||||
PrintText(g_sSeparator11, "============================================================================");
|
||||
PrintText(g_sSeparator12, "Data dispatch service:");
|
||||
PrintText(g_sFrontLeftDoorIsOpen, "Front Left Door:.. not available");
|
||||
PrintText(g_sFrontRightDoorIsOpen, "Front Right Door:.. not available");
|
||||
PrintText(g_sRearLeftDoorIsOpen, "Rear Left Door:.. not available");
|
||||
PrintText(g_sRearRightDoorIsOpen, "Rear Right Door:.. not available");
|
||||
PrintText(g_sSeparator21, "----------------------------------------------------------------------------");
|
||||
PrintText(g_sSeparator22, "Vehicle device:");
|
||||
PrintText(g_sVehicleDevice, "Vehicle Device Interface not available.");
|
||||
PrintText(g_sSeparator31, "----------------------------------------------------------------------------");
|
||||
PrintText(g_sSeparator32, "Basic services:");
|
||||
PrintText(g_sBasicServiceL1, "Basic Service Interface not available.");
|
||||
PrintText(g_sSeparator41, "----------------------------------------------------------------------------");
|
||||
PrintText(g_sSeparator42, "Complex service:");
|
||||
PrintText(g_sComplexService, "Complex Service Interface not available.");
|
||||
if (!m_isExternalApp)
|
||||
{
|
||||
PrintText(g_sControlDescription, "Press 'X' to quit; '1', '2', '3', '4' to toggle doors...");
|
||||
}
|
||||
else
|
||||
{
|
||||
title.append(" [Connected to an instance]");
|
||||
PrintText(g_sTitle, title.c_str());
|
||||
PrintText(g_sControlDescription, "Press 'X' to quit; Doors are toggled automatically");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CConsole::PrepareDataConsumers()
|
||||
{
|
||||
if (!m_isExternalApp)
|
||||
{
|
||||
if(!(PrepareDataConsumersForStandAlone()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto basicServiceL1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (!basicServiceL1)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'LeftService::IVSS_IsOpen': [CConsole]");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Interface exists -> Clean the line for Console window */
|
||||
PrintText(g_sBasicServiceL1, " ");
|
||||
}
|
||||
basicServiceL1->RegisterOnSignalChangeOfLeftDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
bool value = false;
|
||||
PrintValue(g_sFrontLeftDoorIsLocked, "Front Left Latch:", value, (value ? "locked" : "unlocked"));
|
||||
|
||||
// all other doors are optional
|
||||
auto basicServiceR1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR1)
|
||||
{
|
||||
basicServiceR1->RegisterOnSignalChangeOfRightDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
PrintValue(g_sFrontRightDoorIsLocked, "Front Right Latch:", value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
|
||||
auto basicServiceL2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (basicServiceL2)
|
||||
{
|
||||
basicServiceL2->RegisterOnSignalChangeOfLeftDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
PrintValue(g_sRearLeftDoorIsLocked, "Rear Left Latch:", value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
|
||||
auto basicServiceR2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR2)
|
||||
{
|
||||
basicServiceR2->RegisterOnSignalChangeOfRightDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
PrintValue(g_sRearRightDoorIsLocked, "Rear Right Latch:", value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
|
||||
m_pDoorService = sdv::core::GetObject("Doors Example Service").GetInterface<IDoorService>();
|
||||
if (!m_pDoorService)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: Could not get complex service interface 'IDoorService'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_isExternalApp)
|
||||
{
|
||||
PrintText(g_sFrontLeftDoorIsLocked, " ");
|
||||
PrintText(g_sFrontRightDoorIsLocked, " ");
|
||||
PrintText(g_sRearLeftDoorIsLocked, " ");
|
||||
PrintText(g_sRearRightDoorIsLocked, " ");
|
||||
PrintText(g_sFrontLeftDoorIsOpen, "External Application, no dispatch service.");
|
||||
PrintText(g_sFrontRightDoorIsOpen, " ");
|
||||
PrintText(g_sRearLeftDoorIsOpen, " ");
|
||||
PrintText(g_sRearRightDoorIsOpen, " ");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CConsole::ResetSignals()
|
||||
{
|
||||
// Set the cursor position at the end
|
||||
SetCursorPos(g_sCursor);
|
||||
|
||||
// Registrate for the vehicle device & basic service of the front left door. Front left door mzust exist, the others are optional
|
||||
auto vehicleDevice = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_IsOpen>();
|
||||
if (vehicleDevice)
|
||||
vehicleDevice->UnregisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceL1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (basicServiceL1)
|
||||
basicServiceL1->UnregisterOnSignalChangeOfLeftDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceR1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR1)
|
||||
basicServiceR1->UnregisterOnSignalChangeOfRightDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceL2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (basicServiceL2)
|
||||
basicServiceL2->UnregisterOnSignalChangeOfLeftDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceR2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR2)
|
||||
basicServiceR2->UnregisterOnSignalChangeOfRightDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister the data link signalss
|
||||
if (m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsOpen.Reset();
|
||||
if (m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsOpen.Reset();
|
||||
if (m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsOpen.Reset();
|
||||
if (m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsOpen.Reset();
|
||||
if (m_SignalFrontLeftDoorIsLocked)
|
||||
m_SignalFrontLeftDoorIsLocked.Reset();
|
||||
if (m_SignalFrontRightDoorIsLocked)
|
||||
m_SignalFrontRightDoorIsLocked.Reset();
|
||||
if (m_SignalRearLeftDoorIsLocked)
|
||||
m_SignalRearLeftDoorIsLocked.Reset();
|
||||
if (m_SignalRearRightDoorIsLocked)
|
||||
m_SignalRearRightDoorIsLocked.Reset();
|
||||
}
|
||||
|
||||
void CConsole::StartUpdateDataThread()
|
||||
{
|
||||
if (m_bThreadStarted)
|
||||
return;
|
||||
|
||||
m_bThreadStarted = true;
|
||||
|
||||
m_bRunning = true;
|
||||
m_threadReadTxSignals = std::thread(&CConsole::UpdateDataThreadFunc, this);
|
||||
}
|
||||
|
||||
void CConsole::StopUpdateDataThread()
|
||||
{
|
||||
// Stop running and wait for any thread to finalize
|
||||
m_bRunning = false;
|
||||
if (m_threadReadTxSignals.joinable())
|
||||
m_threadReadTxSignals.join();
|
||||
}
|
||||
|
||||
void CConsole::SetExternalApp()
|
||||
{
|
||||
m_isExternalApp = true;
|
||||
}
|
||||
|
||||
void CConsole::WriteIsOpen(bool value)
|
||||
{
|
||||
PrintValue(g_sVehicleDevice, "Front Left Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenL1(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceL1, "Front Left Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenR1(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceR1, "Front Right Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenL2(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceL2, "Rear Left Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenR2(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceR2, "Rear Right Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
bool CConsole::PrepareDataConsumersForStandAlone()
|
||||
{
|
||||
// Subscribe for the door and if available get TX signal. Either both exists or none of them
|
||||
sdv::core::CDispatchService dispatch;
|
||||
m_SignalFrontLeftDoorIsOpen = dispatch.Subscribe(doors::dsLeftDoorIsOpen01, [&](sdv::any_t value) { CallbackFrontLeftDoorIsOpen(value); });
|
||||
if(m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch01, 0);
|
||||
|
||||
m_SignalFrontRightDoorIsOpen = dispatch.Subscribe(doors::dsRightDoorIsOpen01, [&](sdv::any_t value) { CallbackFrontRightDoorIsOpen(value); });
|
||||
if(m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch01, 0);
|
||||
|
||||
m_SignalRearLeftDoorIsOpen = dispatch.Subscribe(doors::dsLeftDoorIsOpen02, [&](sdv::any_t value) {CallbackRearLeftDoorIsOpen(value); });
|
||||
if(m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch02, 0);
|
||||
|
||||
m_SignalRearRightDoorIsOpen = dispatch.Subscribe(doors::dsRightDoorIsOpen02, [&](sdv::any_t value) { CallbackRearRightDoorIsOpen(value); });
|
||||
if(m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch02, 0);
|
||||
|
||||
// Validate: Either both exists or none of them
|
||||
if (m_SignalFrontLeftDoorIsOpen != m_SignalFrontLeftDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalFrontLeftDoorIsOpen != m_SignalFrontLeftDoorIsLocked do not match, failed");
|
||||
return false;
|
||||
}
|
||||
if (m_SignalFrontRightDoorIsOpen != m_SignalFrontRightDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalFrontRightDoorIsOpen != m_SignalFrontRightDoorIsLocked do not match, failed");
|
||||
return false;
|
||||
}
|
||||
if (m_SignalRearLeftDoorIsOpen != m_SignalRearLeftDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalRearLeftDoorIsOpen != m_SignalRearLeftDoorIsLockeddo not match, failed");
|
||||
return false;
|
||||
}
|
||||
if (m_SignalRearRightDoorIsOpen != m_SignalRearRightDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalRearRightDoorIsOpen != m_SignalRearRightDoorIsLocked do not match, failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Registrate for the vehicle device & basic service of the front left door. Front left door mzust exist, the others are optional
|
||||
auto vehicleDevice = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_IsOpen>();
|
||||
if (!vehicleDevice)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'LeftDevice::IVSS_IsOpen': [CConsole]");
|
||||
return false;
|
||||
}
|
||||
vehicleDevice->RegisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CConsole::CallbackFrontLeftDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_FrontLeftDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sFrontLeftDoorIsOpen, "Front Left Door:", m_FrontLeftDoorIsOpen, (m_FrontLeftDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
void CConsole::CallbackFrontRightDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_FrontRightDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sFrontRightDoorIsOpen, "Front Right Door:", m_FrontRightDoorIsOpen, (m_FrontRightDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
void CConsole::CallbackRearLeftDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_RearLeftDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sRearLeftDoorIsOpen, "Rear Left Door:", m_RearLeftDoorIsOpen, (m_RearLeftDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
void CConsole::CallbackRearRightDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_RearRightDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sRearRightDoorIsOpen, "Rear Right Door:", m_RearRightDoorIsOpen, (m_RearRightDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::UpdateDataThreadFunc()
|
||||
{
|
||||
bool bDoorsAreLocked = true;
|
||||
bool bFirstStatusCheck = true;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
while (m_bRunning)
|
||||
{
|
||||
if (!m_isExternalApp)
|
||||
{
|
||||
UpdateTXSignal(g_sFrontLeftDoorIsLocked, "Front Left Latch:", m_SignalFrontLeftDoorIsLocked, m_FrontLeftDoorIsLocked);
|
||||
UpdateTXSignal(g_sFrontRightDoorIsLocked, "Front Right Latch:", m_SignalFrontRightDoorIsLocked, m_FrontRightDoorIsLocked);
|
||||
UpdateTXSignal(g_sRearLeftDoorIsLocked, "Rear Left Latch:", m_SignalRearLeftDoorIsLocked, m_RearLeftDoorIsLocked);
|
||||
UpdateTXSignal(g_sRearRightDoorIsLocked, "Rear Right Latch:", m_SignalRearRightDoorIsLocked, m_RearRightDoorIsLocked);
|
||||
}
|
||||
|
||||
if (m_pDoorService)
|
||||
{
|
||||
auto latch = m_pDoorService->GetDoorsStatus();
|
||||
if ((bDoorsAreLocked != latch) || (bFirstStatusCheck))
|
||||
{
|
||||
bDoorsAreLocked = latch;
|
||||
PrintText(g_sComplexService, bDoorsAreLocked ? "All doors are locked" :"All doors are unlocked");
|
||||
bFirstStatusCheck = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void CConsole::UpdateTXSignal(SConsolePos sPos, const std::string& label, sdv::core::CSignal& signal, bool& value)
|
||||
{
|
||||
// signal may be optional (door may not exist)
|
||||
if (signal)
|
||||
{
|
||||
auto frontLeftDoorIsLocked = value;
|
||||
value = signal.Read().get<bool>();
|
||||
if (frontLeftDoorIsLocked != value)
|
||||
{
|
||||
PrintValue(sPos, label , value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CConsole::SConsolePos CConsole::GetCursorPos() const
|
||||
{
|
||||
SConsolePos sPos{};
|
||||
std::cout << "\033[6n";
|
||||
|
||||
char buff[128];
|
||||
int indx = 0;
|
||||
for(;;) {
|
||||
int cc = std::cin.get();
|
||||
buff[indx] = (char)cc;
|
||||
indx++;
|
||||
if(cc == 'R') {
|
||||
buff[indx + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
int iRow = 0, iCol = 0;
|
||||
sscanf(buff, "\x1b[%d;%dR", &iRow, &iCol);
|
||||
sPos.uiRow = static_cast<uint32_t>(iRow);
|
||||
sPos.uiCol = static_cast<uint32_t>(iCol);
|
||||
fseek(stdin, 0, SEEK_END);
|
||||
|
||||
return sPos;
|
||||
}
|
||||
|
||||
void CConsole::SetCursorPos(SConsolePos sPos)
|
||||
{
|
||||
std::cout << "\033[" << sPos.uiRow << ";" << sPos.uiCol << "H";
|
||||
}
|
||||
|
||||
void CConsole::PrintText(SConsolePos sPos, const std::string& rssText)
|
||||
{
|
||||
auto text = rssText;
|
||||
while (text.length() < 47)
|
||||
{
|
||||
text.append(" ");
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mtxPrintToConsole);
|
||||
SetCursorPos(sPos);
|
||||
std::cout << text;
|
||||
}
|
||||
246
examples/door_demo_example/door_app/door_application.cpp
Normal file
246
examples/door_demo_example/door_app/door_application.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
#include "../door_app/include/door_application.h"
|
||||
#include "../door_app/include/signal_names.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <conio.h> // Needed for _kbhit
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
bool CDoorControl::LoadConfigFile(const std::string& inputMsg, const std::string& configFileName)
|
||||
{
|
||||
std::string msg = inputMsg;
|
||||
if (m_appcontrol.LoadConfig(configFileName) == sdv::core::EConfigProcessResult::successful)
|
||||
{
|
||||
msg.append("ok\n");
|
||||
std::cout << msg.c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
msg.append("FAILED.\n");
|
||||
std::cout << msg.c_str();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CDoorControl::KeyHit()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _kbhit();
|
||||
#elif __unix__
|
||||
int ch = getchar();
|
||||
if (ch != EOF) {
|
||||
ungetc(ch, stdin);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
char CDoorControl::GetChar()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return static_cast<char>(_getch());
|
||||
#else
|
||||
return getchar();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CDoorControl::RegisterSignals()
|
||||
{
|
||||
sdv::core::CDispatchService dispatch;
|
||||
|
||||
m_SignalFrontLeftDoorIsOpen = dispatch.RegisterRxSignal(doors::dsLeftDoorIsOpen01);
|
||||
m_SignalFrontLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch01, 0);
|
||||
|
||||
if (m_iNumberOfDoors > 1)
|
||||
{
|
||||
m_SignalFrontRightDoorIsOpen = dispatch.RegisterRxSignal(doors::dsRightDoorIsOpen01);
|
||||
m_SignalFrontRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch01, 0);
|
||||
|
||||
if (m_iNumberOfDoors > 2)
|
||||
{
|
||||
m_SignalRearLeftDoorIsOpen = dispatch.RegisterRxSignal(doors::dsLeftDoorIsOpen02);
|
||||
m_SignalRearLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch02, 0);
|
||||
|
||||
if (m_iNumberOfDoors > 3)
|
||||
{
|
||||
m_SignalRearRightDoorIsOpen = dispatch.RegisterRxSignal(doors::dsRightDoorIsOpen02);
|
||||
m_SignalRearRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch02, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CDoorControl::IsSDVFrameworkEnvironmentSet()
|
||||
{
|
||||
const char* envVariable = std::getenv("SDV_FRAMEWORK_RUNTIME");
|
||||
if (envVariable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDoorControl::Initialize(const uint32_t numberOfDoors)
|
||||
{
|
||||
if (m_bInitialized)
|
||||
return true;
|
||||
|
||||
if ((numberOfDoors >= 1) && (numberOfDoors <= 4))
|
||||
{
|
||||
m_iNumberOfDoors = numberOfDoors;
|
||||
}
|
||||
|
||||
if (!IsSDVFrameworkEnvironmentSet())
|
||||
{
|
||||
// if SDV_FRAMEWORK_RUNTIME environment variable is not set we need to set the Framework Runtime directory
|
||||
m_appcontrol.SetFrameworkRuntimeDirectory("../../bin");
|
||||
}
|
||||
|
||||
if(!m_appcontrol.Startup(""))
|
||||
return false;
|
||||
|
||||
// Switch to config mode.
|
||||
m_appcontrol.SetConfigMode();
|
||||
bool bResult = LoadConfigFile("Load dispatch example: ", "data_dispatch_example.toml");
|
||||
|
||||
bResult &= LoadConfigFile("Load task timer: ", "task_timer_example.toml");
|
||||
bResult &= RegisterSignals();
|
||||
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for front left door: ", "front_left_door_example.toml");
|
||||
if (m_iNumberOfDoors > 1)
|
||||
{
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for front right door: ", "front_right_door_example.toml");
|
||||
if (m_iNumberOfDoors > 2)
|
||||
{
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for rear left door: ", "rear_left_door_example.toml");
|
||||
if (m_iNumberOfDoors > 3)
|
||||
{
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for rear right door: ", "rear_right_door_example.toml");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bResult &= LoadConfigFile("Load door service (complex service): ", "door_comple_service.toml");
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
SDV_LOG_ERROR("One or more configurations could not be loaded. Cannot continue.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t CDoorControl::GetNumberOfDoors() const
|
||||
{
|
||||
return m_iNumberOfDoors;
|
||||
}
|
||||
|
||||
void CDoorControl::Shutdown()
|
||||
{
|
||||
if (!m_bInitialized)
|
||||
m_appcontrol.Shutdown();
|
||||
m_bInitialized = false;
|
||||
}
|
||||
|
||||
void CDoorControl::SetRunningMode()
|
||||
{
|
||||
m_appcontrol.SetRunningMode();
|
||||
}
|
||||
|
||||
|
||||
void CDoorControl::RunUntilBreak()
|
||||
{
|
||||
bool bRunning = true;
|
||||
bool openFrontLeftDoor = true;
|
||||
bool openFrontRightDoor = true;
|
||||
bool openRearLeftDoor = true;
|
||||
bool openRearRightDoor = true;
|
||||
|
||||
// Update console by writing the first value if available
|
||||
if (m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsOpen.Write<bool>(openFrontLeftDoor);
|
||||
if (m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsOpen.Write<bool>(openFrontRightDoor);
|
||||
if (m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsOpen.Write<bool>(openRearLeftDoor);
|
||||
if (m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsOpen.Write<bool>(openRearRightDoor);
|
||||
|
||||
while (bRunning)
|
||||
{
|
||||
// Check for a key
|
||||
if (!KeyHit())
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get a keyboard value (if there is any).
|
||||
char c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
openFrontLeftDoor = !openFrontLeftDoor;
|
||||
if (m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsOpen.Write<bool>(openFrontLeftDoor);
|
||||
break;
|
||||
case '2':
|
||||
openFrontRightDoor = !openFrontRightDoor;
|
||||
if (m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsOpen.Write<bool>(openFrontRightDoor);
|
||||
break;
|
||||
case '3':
|
||||
openRearLeftDoor = !openRearLeftDoor;
|
||||
if (m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsOpen.Write<bool>(openRearLeftDoor);
|
||||
break;
|
||||
case '4':
|
||||
openRearRightDoor = !openRearRightDoor;
|
||||
if (m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsOpen.Write<bool>(openRearRightDoor);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
bRunning = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CDoorControl::UserInputNumberOfDoors()
|
||||
{
|
||||
uint32_t numberOfDoors = 4;
|
||||
// Clear the screen and goto top...
|
||||
std::cout << "\x1b[2J\033[0;0H";
|
||||
std::cout << "How many doors does the vehicle have? Press a number between 1 and 4: ";
|
||||
|
||||
// Get a keyboard value (if there is any).
|
||||
char c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
numberOfDoors = 1;
|
||||
break;
|
||||
case '2':
|
||||
numberOfDoors = 2;
|
||||
break;
|
||||
case '3':
|
||||
numberOfDoors = 3;
|
||||
break;
|
||||
case '4':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return numberOfDoors;
|
||||
}
|
||||
27
examples/door_demo_example/door_app/door_demo_example.cpp
Normal file
27
examples/door_demo_example/door_app/door_demo_example.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include "../door_app/include/door_application.h"
|
||||
#include "../door_app/include/console.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
CDoorControl appobj;
|
||||
if (!appobj.Initialize(appobj.UserInputNumberOfDoors()))
|
||||
{
|
||||
std::cout << "ERROR: Failed to initialize application control." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CConsole visual_obj;
|
||||
visual_obj.PrintHeader(appobj.GetNumberOfDoors());
|
||||
visual_obj.PrepareDataConsumers();
|
||||
visual_obj.StartUpdateDataThread();
|
||||
|
||||
appobj.SetRunningMode();
|
||||
appobj.RunUntilBreak();
|
||||
|
||||
visual_obj.StopUpdateDataThread();
|
||||
visual_obj.ResetSignals();
|
||||
|
||||
appobj.Shutdown();
|
||||
return 0;
|
||||
}
|
||||
102
examples/door_demo_example/door_app/door_extern_application.cpp
Normal file
102
examples/door_demo_example/door_app/door_extern_application.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "../door_app/include/door_extern_application.h"
|
||||
#include "../door_app/include/signal_names.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <conio.h> // Needed for _kbhit
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
bool CDoorExternControl::Initialize()
|
||||
{
|
||||
if (m_bInitialized)
|
||||
return true;
|
||||
|
||||
if (!IsSDVFrameworkEnvironmentSet())
|
||||
{
|
||||
// if SDV_FRAMEWORK_RUNTIME environment variable is not set we need to set the Framework Runtime directory
|
||||
m_appcontrol.SetFrameworkRuntimeDirectory("../../bin");
|
||||
}
|
||||
|
||||
std::stringstream sstreamAppConfig;
|
||||
sstreamAppConfig << "[Application]" << std::endl;
|
||||
sstreamAppConfig << "Mode=\"External\"" << std::endl;
|
||||
sstreamAppConfig << "Instance=\"3002\"" << std::endl;
|
||||
sstreamAppConfig << "Retries=" << 6 << std::endl;
|
||||
sstreamAppConfig << "[Console]" << std::endl;
|
||||
sstreamAppConfig << "Report=\"Silent\"" << std::endl;
|
||||
|
||||
if (!m_appcontrol.Startup(sstreamAppConfig.str()))
|
||||
return false;
|
||||
|
||||
m_bInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDoorExternControl::Shutdown()
|
||||
{
|
||||
if (!m_bInitialized)
|
||||
m_appcontrol.Shutdown();
|
||||
m_bInitialized = false;
|
||||
}
|
||||
|
||||
void CDoorExternControl::RunUntilBreak()
|
||||
{
|
||||
bool bRunning = true;
|
||||
|
||||
while (bRunning)
|
||||
{
|
||||
// Check for a key
|
||||
if (!KeyHit())
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get a keyboard value (if there is any).
|
||||
char c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case 'x':
|
||||
case 'X':
|
||||
bRunning = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CDoorExternControl::IsSDVFrameworkEnvironmentSet()
|
||||
{
|
||||
const char* envVariable = std::getenv("SDV_FRAMEWORK_RUNTIME");
|
||||
if (envVariable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDoorExternControl::KeyHit()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _kbhit();
|
||||
#elif __unix__
|
||||
int ch = getchar();
|
||||
if (ch != EOF) {
|
||||
ungetc(ch, stdin);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
char CDoorExternControl::GetChar()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return static_cast<char>(_getch());
|
||||
#else
|
||||
return getchar();
|
||||
#endif
|
||||
}
|
||||
27
examples/door_demo_example/door_app/door_extern_example.cpp
Normal file
27
examples/door_demo_example/door_app/door_extern_example.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include "../door_app/include/door_extern_application.h"
|
||||
#include "../door_app/include/console.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
CDoorExternControl appobj;
|
||||
if (!appobj.Initialize())
|
||||
{
|
||||
std::cout << "ERROR: Failed to initialize application control." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CConsole visual_obj;
|
||||
visual_obj.SetExternalApp();
|
||||
visual_obj.PrintHeader(4);
|
||||
visual_obj.PrepareDataConsumers();
|
||||
visual_obj.StartUpdateDataThread();
|
||||
|
||||
appobj.RunUntilBreak();
|
||||
|
||||
visual_obj.StopUpdateDataThread();
|
||||
visual_obj.ResetSignals();
|
||||
|
||||
appobj.Shutdown();
|
||||
return 0;
|
||||
}
|
||||
271
examples/door_demo_example/door_app/include/console.h
Normal file
271
examples/door_demo_example/door_app/include/console.h
Normal file
@@ -0,0 +1,271 @@
|
||||
#ifndef CONSOLE_OUTPUT_H
|
||||
#define CONSOLE_OUTPUT_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <support/signal_support.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/timer.h>
|
||||
#include "signal_names.h"
|
||||
#include <fcntl.h>
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle01left_vd_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle01left_bs_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle01right_bs_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle02left_bs_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle02right_bs_rx.h"
|
||||
|
||||
#ifdef __unix__
|
||||
#include <termios.h> // Needed for tcgetattr and fcntl
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../generated/door_service/door_ifc.h"
|
||||
|
||||
/**
|
||||
* @brief Console operation class.
|
||||
* @details This class retrieves RX data from the data dispatch service, vehicle device & basic service of front left door on event change.
|
||||
* Furthermore, it shows TX value by polling the RX signals.
|
||||
*/
|
||||
class CConsole : public vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event
|
||||
, 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:
|
||||
/**
|
||||
* @brief Screen position structure
|
||||
*/
|
||||
struct SConsolePos
|
||||
{
|
||||
uint32_t uiRow; ///< Row position (starts at 1)
|
||||
uint32_t uiCol; ///< Column position (starts at 1)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CConsole();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CConsole();
|
||||
|
||||
/**
|
||||
* @brief Print the header.
|
||||
* @param[in] numberOfDoors number of doors
|
||||
*/
|
||||
void PrintHeader(const uint32_t numberOfDoors);
|
||||
|
||||
/**
|
||||
* @brief Prepare the data consumers..
|
||||
* @details Gets all signals (4 RX signals showing Open/Closed doors and 4 TX signals if the doors are locked)
|
||||
* Open/Closed is done as input (user) while locking the doors is done automatically by complex service when all doors are closed
|
||||
* Need to work independent from the number of doors (1-4)
|
||||
* @return Returns whether the preparation of the data consumers was successful or not.
|
||||
*/
|
||||
bool PrepareDataConsumers();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write leftDoorIsOpen signal
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal (front door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL1(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (front door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR1(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal (rear door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL2(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (rear door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR2(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief For gracefully shutdown all signals need to be reset.
|
||||
*/
|
||||
void ResetSignals();
|
||||
|
||||
/**
|
||||
* @brief Starts thread for polling the TX signals (if the doors are locked by the complex service)
|
||||
*/
|
||||
void StartUpdateDataThread();
|
||||
|
||||
/**
|
||||
* @brief Stops thread
|
||||
*/
|
||||
void StopUpdateDataThread();
|
||||
|
||||
/**
|
||||
* @brief Used to set a flag for when we use external App
|
||||
*/
|
||||
void SetExternalApp();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Prepare the data consumers for Standalone application
|
||||
* @return Returns whether the preparation of the Standalone data consumers was successful or not.
|
||||
*/
|
||||
bool PrepareDataConsumersForStandAlone();
|
||||
|
||||
/**
|
||||
* @brief Callback function when front left door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackFrontLeftDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Callback function when front right door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackFrontRightDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Callback function when rear left door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackRearLeftDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Callback function when rear right door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackRearRightDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Read the data link TX signals and print them into the console.
|
||||
*/
|
||||
void UpdateDataThreadFunc();
|
||||
|
||||
/**
|
||||
* @brief Update the signal on the console output depending on the signal
|
||||
* @details Check if the signal is valid. If invalid, ignore it.
|
||||
*/
|
||||
void UpdateTXSignal(SConsolePos sPos, const std::string& label, sdv::core::CSignal& signal, bool& value);
|
||||
|
||||
/**
|
||||
* @brief Get the cursor position of the console.
|
||||
* @return The cursor position.
|
||||
*/
|
||||
SConsolePos GetCursorPos() const;
|
||||
|
||||
/**
|
||||
* @brief Set the current cursor position for the console.
|
||||
* @param[in] sPos Console position to place the current cursor at.
|
||||
*/
|
||||
void SetCursorPos(SConsolePos sPos);
|
||||
|
||||
/**
|
||||
* @brief Print text at a specific location.
|
||||
* @param[in] sPos The location to print text at.
|
||||
* @param[in] rssText Reference to the text to print.
|
||||
*/
|
||||
void PrintText(SConsolePos sPos, const std::string& rssText);
|
||||
|
||||
/**
|
||||
* @brief Print a value string at a specific location.
|
||||
* @tparam TValue Type of value.
|
||||
* @param[in] sPos The location to print the value at.
|
||||
* @param[in] rssName Reference to the value.
|
||||
* @param[in] tValue The value.
|
||||
* @param[in] rssStatus Status, becuse we have signals of type bool
|
||||
*/
|
||||
template <typename TValue>
|
||||
void PrintValue(SConsolePos sPos, const std::string& rssName, TValue tValue, const std::string& rssStatus);
|
||||
|
||||
/**
|
||||
* @brief Align string between name and value.
|
||||
* @param[in] message Reference to the message to align.
|
||||
* @param[in] desiredLength The desired length or 0 when no length is specified.
|
||||
* @return The aligned string.
|
||||
*/
|
||||
std::string AlignString(const std::string& message, uint32_t desiredLength = 0);
|
||||
|
||||
mutable std::mutex m_mtxPrintToConsole; ///< Mutex to print complete message
|
||||
bool m_bThreadStarted = false; ///< Set when initialized.
|
||||
bool m_bRunning = false; ///< When set, the application is running.
|
||||
bool m_isExternalApp = false; ///< True when we have an external application
|
||||
mutable std::mutex m_mPrintToConsole; ///< Mutex to print complete message
|
||||
|
||||
std::thread m_threadReadTxSignals; ///< Simulation datalink thread.
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsOpen; ///< Front Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsOpen; ///< Front Right Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsOpen; ///< Rear Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsOpen; ///< Rear Right Door signal (RX input) - open / closed
|
||||
|
||||
bool m_FrontLeftDoorIsOpen = false; ///< Front Left Door value (RX input signal) - open / closed
|
||||
bool m_FrontRightDoorIsOpen = false; ///< Front Right Door value (RX input signal) - open / closed
|
||||
bool m_RearLeftDoorIsOpen = false; ///< Rear Left Door value (RX input signal) - open / closed
|
||||
bool m_RearRightDoorIsOpen = false; ///< Rear Right Door value (RX input signal) - open / closed
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsLocked; ///< Front Left Door signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsLocked; ///< Front Right Door signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsLocked; ///< Rear Left Door signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsLocked; ///< Rear Right Door signal (TX output) - locked / unlocked
|
||||
|
||||
bool m_FrontLeftDoorIsLocked = false; ///< Front Left Door value (TX output) - locked / unlocked
|
||||
bool m_FrontRightDoorIsLocked = false; ///< Front Right Door value (TX output) - locked / unlocked
|
||||
bool m_RearLeftDoorIsLocked = false; ///< Rear Left Door value (TX output) - locked / unlocked
|
||||
bool m_RearRightDoorIsLocked = false; ///< Rear Right Door value (TX output) - locked / unlocked
|
||||
|
||||
IDoorService* m_pDoorService = nullptr; ///< Door service interface pointer.
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD m_dwConsoleOutMode = 0u; ///< The console mode before switching on ANSI support.
|
||||
DWORD m_dwConsoleInMode = 0u; ///< The console mode before switching on ANSI support.
|
||||
#elif defined __unix__
|
||||
struct termios m_sTermAttr{}; ///< The terminal attributes before disabling echo.
|
||||
int m_iFileStatus = 0; ///< The file status flags for STDIN.
|
||||
#else
|
||||
#error The OS is not supported!
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template <typename TValue>
|
||||
inline void CConsole::PrintValue(SConsolePos sPos, const std::string& rssName, TValue tValue, const std::string& rssUnits)
|
||||
{
|
||||
std::string endName = " ";
|
||||
const size_t nEndNameLen = 14 - rssUnits.size();
|
||||
const size_t nValueNameLen = 26;
|
||||
std::stringstream sstreamValueText;
|
||||
sstreamValueText << rssName <<
|
||||
std::string(nValueNameLen - std::min(rssName.size(), static_cast<size_t>(nValueNameLen - 1)) - 1, '.') <<
|
||||
" " << std::fixed << std::setprecision(2) << tValue << " " << rssUnits <<
|
||||
std::string(nEndNameLen - std::min(endName.size(), static_cast<size_t>(nEndNameLen - 1)) - 1, ' ');
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mPrintToConsole);
|
||||
SetCursorPos(sPos);
|
||||
std::cout << sstreamValueText.str();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void CConsole::PrintValue<bool>(SConsolePos sPos, const std::string& rssName, bool bValue, const std::string& rssStatus)
|
||||
{;
|
||||
PrintValue(sPos, rssName, bValue ? "" : "", rssStatus);
|
||||
}
|
||||
|
||||
#endif // !define CONSOLE_OUTPUT_H
|
||||
@@ -0,0 +1,99 @@
|
||||
#include <string>
|
||||
#include <support/app_control.h>
|
||||
#include <support/signal_support.h>
|
||||
|
||||
/**
|
||||
* @brief Application Class of the door example
|
||||
*/
|
||||
class CDoorControl
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Start and initialize the application control and load vehicle devices and
|
||||
* basic services depending on the number of doors
|
||||
* @param[in] numberOfDoors number of doors (1-4), default 4
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool Initialize(const uint32_t numberOfDoors = 4);
|
||||
|
||||
/**
|
||||
* @brief After initialization/configuration the system mode needs to be set to running mode
|
||||
*/
|
||||
void SetRunningMode();
|
||||
|
||||
/**
|
||||
* @brief Ask user for input how many doors the vehicle should have (1-4)
|
||||
* @return Return number of doors (default 4)
|
||||
*/
|
||||
uint32_t UserInputNumberOfDoors();
|
||||
|
||||
/**
|
||||
* @brief Run loop as long as user input does not exit
|
||||
* Allow user to open/close each door.
|
||||
*/
|
||||
void RunUntilBreak();
|
||||
|
||||
/**
|
||||
* @brief Shutdown the system.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* @brief Get number of doors
|
||||
* @return Return number of doors (default 4)
|
||||
*/
|
||||
uint32_t GetNumberOfDoors() const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief check if SDV_FRAMEWORK_RUNTIME environment variable exists
|
||||
* @return Return true if environment variable is found otherwise false
|
||||
*/
|
||||
bool IsSDVFrameworkEnvironmentSet();
|
||||
|
||||
/**
|
||||
* @brief Loac config file and register vehicle device and basic service.
|
||||
* @remarks It is expected that each config file has the complete door:
|
||||
* vehicle device & basic service for input and output
|
||||
* @param[in] inputMsg message string to be printed on console in case of success and failure
|
||||
* @param[in] configFileName config toml file name
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool LoadConfigFile(const std::string& inputMsg, const std::string& configFileName);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Key hit check. Windows uses the _kbhit function; POSIX emulates this.
|
||||
* @return Returns whether a key has been pressed.
|
||||
*/
|
||||
bool KeyHit();
|
||||
|
||||
/**
|
||||
* @brief Get the character from the keyboard buffer if pressed.
|
||||
* @return Returns the character from the keyboard buffer.
|
||||
*/
|
||||
char GetChar();
|
||||
|
||||
/**
|
||||
* @brief Register/Create Signals in the dispatch service depending on the number of doors
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool RegisterSignals();
|
||||
|
||||
sdv::app::CAppControl m_appcontrol; ///< App-control of SDV V-API.
|
||||
bool m_bInitialized = false; ///< Set when initialized.
|
||||
uint32_t m_iNumberOfDoors = 4; ///< Number iof doors, maximuum 4
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsOpen; ///< Front Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsOpen; ///< Front Right Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsOpen; ///< Rear Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsOpen; ///< Rear Right Door signal (RX input) - open / closed
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsLocked; ///< Front Left Latch signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsLocked; ///< Front Right Latch signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsLocked; ///< Rear Left Latch signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsLocked; ///< Rear Right Latch signal (TX output) - locked / unlocked
|
||||
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <string>
|
||||
#include <support/app_control.h>
|
||||
#include <support/signal_support.h>
|
||||
|
||||
/**
|
||||
* @brief Application Class of the door example
|
||||
*/
|
||||
class CDoorExternControl
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Start and initialize the application control and load vehicle devices and
|
||||
* basic services depending on the numerb of doors
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool Initialize();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Run loop as long as user input does not exit
|
||||
* Allow user to open/close each door.
|
||||
*/
|
||||
void RunUntilBreak();
|
||||
|
||||
/**
|
||||
* @brief Shutdown the system.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief check if SDV_FRAMEWORK_RUNTIME environment variable exists
|
||||
* @return Return true if environment variable is found otherwise false
|
||||
*/
|
||||
bool IsSDVFrameworkEnvironmentSet();
|
||||
|
||||
/**
|
||||
* @brief Key hit check. Windows uses the _kbhit function; POSIX emulates this.
|
||||
* @return Returns whether a key has been pressed.
|
||||
*/
|
||||
bool KeyHit();
|
||||
|
||||
/**
|
||||
* @brief Get the character from the keyboard buffer if pressed.
|
||||
* @return Returns the character from the keyboard buffer.
|
||||
*/
|
||||
char GetChar();
|
||||
|
||||
sdv::app::CAppControl m_appcontrol; ///< App-control of SDV V-API.
|
||||
bool m_bInitialized = false; ///< Set when initialized.
|
||||
uint32_t m_iNumberOfDoors = 4; ///< Number iof doors, maximuum 4
|
||||
|
||||
};
|
||||
30
examples/door_demo_example/door_app/include/signal_names.h
Normal file
30
examples/door_demo_example/door_app/include/signal_names.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* namespace for the signal names
|
||||
* in case /interfaces/signal_identifier.h
|
||||
* exists, use the file, otherwise define the namespace
|
||||
*/
|
||||
#ifndef SIGNAL_NAMES_H
|
||||
#define SIGNAL_NAMES_H
|
||||
|
||||
#ifdef __has_include
|
||||
#if __has_include("../interfaces/signal_identifier.h")
|
||||
#include "../interfaces/signal_identifier.h"
|
||||
#else
|
||||
|
||||
namespace doors
|
||||
{
|
||||
// Data Dispatch Service signal names to dbc variable names C-type RX/TX vss name space
|
||||
static std::string dsLeftDoorIsOpen01 = "CAN_Input_L1.Door01LeftIsOpen"; ///< bool RX Vehicle.Chassis.Door.Axle01.Left
|
||||
static std::string dsRightDoorIsOpen01 = "CAN_Input_R1.Door01RightIs"; ///< bool RX Vehicle.Chassis.Door.Axle01.Right
|
||||
static std::string dsLeftDoorIsOpen02 = "CAN_Input_L2.Door02LeftIsOpen"; ///< bool RX Vehicle.Chassis.Door.Axle02.Left
|
||||
static std::string dsRightDoorIsOpen02 = "CAN_Input_R2.Door02RightIsOpen"; ///< bool RX Vehicle.Chassis.Door.Axle02.Right
|
||||
static std::string dsLeftLatch01 = "CAN_Output.LockDoor01Left" ; ///< bool TX Vehicle.Chassis.TX.Door.Axle01.Left
|
||||
static std::string dsRightLatch01 = "CAN_Output.LockDoor01Right"; ///< bool TX Vehicle.Chassis.TX.Door.Axle01.Right
|
||||
static std::string dsLeftLatch02 = "CAN_Output.LockDoor02Left" ; ///< bool TX Vehicle.Chassis.TX.Door.Axle02.Left
|
||||
static std::string dsRightLatch02 = "CAN_Output.LockDoor02Right"; ///< bool TX Vehicle.Chassis.TX.Door.Axle02.Right
|
||||
} // doors
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // SIGNAL_NAMES_H
|
||||
Reference in New Issue
Block a user