Precommit (#1)

* first commit

* cleanup
This commit is contained in:
tompzf
2025-11-04 13:28:06 +01:00
committed by GitHub
parent dba45dc636
commit 6ed4b1534e
898 changed files with 256340 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
#include <iostream>
#include <fstream>
#include <support/app_control.h>
#include <support/signal_support.h>
#include "signal_names.h"
#include "autoheadlight_simulate.h"
#include "autoheadlight_console.h"
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain()
#else
extern "C" int main()
#endif
{
CAutoHeadlightAppSimulate AppSimulate;
if(AppSimulate.Initialize()) //Initialize and if failed do not run the test run.
{
CConsole visual_obj;
visual_obj.PrintHeader();
visual_obj.PrepareDataConsumers(); // Get access to required services
visual_obj.StartUpdateDataThread(); // start a thread to get Headlight and tunnel information and print on console
AppSimulate.ExecuteTestRun(); // Execute the test run feeding driveway data
visual_obj.StopUpdateDataThread();
visual_obj.ResetSignals();
AppSimulate.Shutdown(); //Shutdown the app.
}
return 0;
}

View File

@@ -0,0 +1,355 @@
#include "autoheadlight_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_sLatitudeMin{ 3, 1 };
const CConsole::SConsolePos g_sLatitudeMax{ 3, 30 };
const CConsole::SConsolePos g_sLongitudeMin{ 4, 1 };
const CConsole::SConsolePos g_sLongitudeMax{ 4, 30 };
const CConsole::SConsolePos g_sSeparator11{ 6, 1 };
const CConsole::SConsolePos g_sSeparator12{ 8, 1 };
const CConsole::SConsolePos g_sDispatchService1{ 9, 1 };
const CConsole::SConsolePos g_sDispatchService2{ 10, 1 };
const CConsole::SConsolePos g_sDispatchService4{ 12, 1 };
const CConsole::SConsolePos g_sSeparator21{ 14, 1 };
const CConsole::SConsolePos g_sSeparator22{ 16, 1 };
const CConsole::SConsolePos g_sVehicleDevice1{ 17, 1 };
const CConsole::SConsolePos g_sVehicleDevice2{ 18, 1 };
const CConsole::SConsolePos g_sSeparator31{ 20, 1 };
const CConsole::SConsolePos g_sSeparator32{ 22, 1 };
const CConsole::SConsolePos g_sBasicService1{ 23, 1 };
const CConsole::SConsolePos g_sBasicService2{ 24, 1 };
const CConsole::SConsolePos g_sSeparator4{ 26, 1 };
const CConsole::SConsolePos g_sComplexService1{ 28, 1 };
const CConsole::SConsolePos g_sComplexService2{ 29, 1 };
const CConsole::SConsolePos g_sComplexService3{ 30, 1 };
const CConsole::SConsolePos g_sSeparator5{ 32, 1 };
const CConsole::SConsolePos g_sControlDescription{ 34, 1 };
const CConsole::SConsolePos g_sCursor{ 35, 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()
{
// Clear the screen...
std::cout << "\x1b[2J";
// Print the titles
PrintText(g_sTitle, "Headlight");
PrintText(g_sSeparator11, "============================================================================");
PrintText(g_sSeparator12, "Data dispatch service:");
PrintText(g_sSeparator21, "----------------------------------------------------------------------------");
PrintText(g_sSeparator22, "Vehicle device:");
PrintText(g_sSeparator31, "----------------------------------------------------------------------------");
PrintText(g_sSeparator32, "Basic services:");
PrintText(g_sSeparator4, "----------------------------------------------------------------------------");
PrintText(g_sComplexService1, "Complex service:");
PrintText(g_sSeparator5, "----------------------------------------------------------------------------");
PrintText(g_sControlDescription, "Press 'X' to quit.");
}
bool CConsole::PrepareDataConsumers()
{
// Vehicle Device
auto pVDCurrentLatitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLatitude_Device").GetInterface<vss::Vehicle::Position::CurrentLatitudeDevice::IVSS_CurrentLatitude>();
if (!pVDCurrentLatitudeSvc)
{
SDV_LOG_ERROR("Could not get interface 'IVSS_GetVDCurrentLatitude': [CAutoHeadlightService]");
return false;
}
auto pVDCurrentLongitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLongitude_Device").GetInterface<vss::Vehicle::Position::CurrentLongitudeDevice::IVSS_CurrentLongitude>();
if (!pVDCurrentLongitudeSvc)
{
SDV_LOG_ERROR("Could not get interface 'IVSS_GetVDCurrentLongitude': [CAutoHeadlightService]");
return false;
}
if (pVDCurrentLatitudeSvc)
pVDCurrentLatitudeSvc->RegisterCurrentLatitudeEvent(static_cast<vss::Vehicle::Position::CurrentLatitudeDevice::IVSS_WriteCurrentLatitude_Event*> (this));
if (pVDCurrentLongitudeSvc)
pVDCurrentLongitudeSvc->RegisterCurrentLongitudeEvent(static_cast<vss::Vehicle::Position::CurrentLongitudeDevice::IVSS_WriteCurrentLongitude_Event*> (this));
// BASIC SERVICES
auto pBSCurrentLatitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLatitude_Service").GetInterface<vss::Vehicle::Position::CurrentLatitudeService::IVSS_GetCurrentLatitude>();
if (!pBSCurrentLatitudeSvc)
{
SDV_LOG_ERROR("Could not get interface 'IVSS_GetBSCurrentLatitude': [CAutoHeadlightService]");
return false;
}
auto pBSCurrentLongitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLongitude_Service").GetInterface<vss::Vehicle::Position::CurrentLongitudeService::IVSS_GetCurrentLongitude>();
if (!pBSCurrentLongitudeSvc)
{
SDV_LOG_ERROR("Could not get interface 'IVSS_GetBSCurrentLongitude': [CAutoHeadlightService]");
return false;
}
if (pBSCurrentLatitudeSvc)
pBSCurrentLatitudeSvc->RegisterOnSignalChangeOfFCurrentLatitude(static_cast<vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event*> (this));
if (pBSCurrentLongitudeSvc)
pBSCurrentLongitudeSvc->RegisterOnSignalChangeOfFCurrentLongitude(static_cast<vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event*> (this));
RegisterSignals();
UpdateTXSignal(g_sDispatchService4, "Headlight:", m_signalHeadlight, m_bHeadLight);
m_pIAutoheadlightComplexService = sdv::core::GetObject("Auto Headlight Service").GetInterface<IAutoheadlightService>();
if (!m_pIAutoheadlightComplexService)
{
SDV_LOG_ERROR("Console ERROR: Could not get complex service interface 'IAutoheadlightService'");
return false;
}
auto tunnel = m_pIAutoheadlightComplexService->GetGPSBoundBox();
std::string minLatitude = "Tunnel Latitude: ";
std::string maxLatitude = " - ";
std::string minLongitude = " Longitude: ";
std::string maxLongitude = " - ";
minLatitude.append(std::to_string(tunnel.fTunnelMinLat));
maxLatitude.append(std::to_string(tunnel.fTunnelMaxLat));
minLongitude.append(std::to_string(tunnel.fTunnelMinLon));
maxLongitude.append(std::to_string(tunnel.fTunnelMaxLon));
PrintText(g_sLatitudeMin, minLatitude);
PrintText(g_sLatitudeMax, maxLatitude);
PrintText(g_sLongitudeMin, minLongitude);
PrintText(g_sLongitudeMax, maxLongitude);
return true;
}
bool CConsole::RegisterSignals()
{
// Set the cursor position at the end
SetCursorPos(g_sCursor);
sdv::core::CDispatchService dispatch;
m_signalCurrentLatitude = dispatch.Subscribe(headlight::dsFCurrentLatitude, [&](sdv::any_t value) { CallbackCurrentLatitude(value); });
m_signalCurrentLongitude = dispatch.Subscribe(headlight::dsFCurrentLongitude, [&](sdv::any_t value) { CallbackCurrentLongitude(value); });
m_signalHeadlight = dispatch.RegisterTxSignal(headlight::dsBHeadLightLowBeam, false);
return true;
}
void CConsole::CallbackCurrentLatitude(sdv::any_t value)
{
m_fCurrentLatitude = value.get<float>();
PrintValue(g_sDispatchService1, "Latitude: ", m_fCurrentLatitude, " N");
}
void CConsole::CallbackCurrentLongitude(sdv::any_t value)
{
m_fCurrentLongitude = value.get<float>();
PrintValue(g_sDispatchService2, "Longitude: ", m_fCurrentLongitude, " E");
}
void CConsole::ResetSignals()
{
// Set the cursor position at the end
SetCursorPos(g_sCursor);
// Vehicle Device
auto pVDCurrentLatitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLatitude_Device").GetInterface<vss::Vehicle::Position::CurrentLatitudeDevice::IVSS_CurrentLatitude>();
if (pVDCurrentLatitudeSvc)
pVDCurrentLatitudeSvc->UnregisterCurrentLatitudeEvent(static_cast<vss::Vehicle::Position::CurrentLatitudeDevice::IVSS_WriteCurrentLatitude_Event*> (this));
auto pVDCurrentLongitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLongitude_Device").GetInterface<vss::Vehicle::Position::CurrentLongitudeDevice::IVSS_CurrentLongitude>();
if (pVDCurrentLongitudeSvc)
pVDCurrentLongitudeSvc->UnregisterCurrentLongitudeEvent(static_cast<vss::Vehicle::Position::CurrentLongitudeDevice::IVSS_WriteCurrentLongitude_Event*> (this));
// BASIC SERVICES
auto pBSCurrentLatitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLatitude_Service").GetInterface<vss::Vehicle::Position::CurrentLatitudeService::IVSS_GetCurrentLatitude>();
if (pBSCurrentLatitudeSvc)
pBSCurrentLatitudeSvc->RegisterOnSignalChangeOfFCurrentLatitude(static_cast<vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event*> (this));
auto pBSCurrentLongitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLongitude_Service").GetInterface<vss::Vehicle::Position::CurrentLongitudeService::IVSS_GetCurrentLongitude>();
if (pBSCurrentLongitudeSvc)
pBSCurrentLongitudeSvc->RegisterOnSignalChangeOfFCurrentLongitude(static_cast<vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event*> (this));
if (m_signalCurrentLatitude)
{
m_signalCurrentLatitude.Reset();
}
if (m_signalCurrentLongitude)
{
m_signalCurrentLongitude.Reset();
}
if (m_signalHeadlight)
{
m_signalHeadlight.Reset();
}
}
void CConsole::WriteCurrentLatitude(float value)
{
m_fVehicleDeviceCurrentLatitude = value;
PrintValue(g_sVehicleDevice1, "Latitude: ", m_fVehicleDeviceCurrentLatitude, " N");
}
void CConsole::WriteCurrentLongitude(float value)
{
m_fVehicleDeviceCurrentLongitude = value;
PrintValue(g_sVehicleDevice2, "Longitude: ", m_fVehicleDeviceCurrentLongitude, " E");
}
void CConsole::SetCurrentLatitude(float value)
{
m_fBasicServiceCurrentLatitude = value;
PrintValue(g_sBasicService1, "Latitude: ", m_fBasicServiceCurrentLatitude, " N");
}
void CConsole::SetCurrentLongitude(float value)
{
m_fBasicServiceCurrentLongitude = value;
PrintValue(g_sBasicService2, "Longitude: ", m_fBasicServiceCurrentLongitude, " E");
}
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)
{
std::lock_guard<std::mutex> lock(m_mtxPrintToConsole);
SetCursorPos(sPos);
std::cout << rssText;
}
void CConsole::UpdateTXSignal(SConsolePos sPos, const std::string& label, sdv::core::CSignal& signal, bool& value)
{
if (signal)
{
auto headlight = value;
value = signal.Read().get<bool>();
if (headlight != value)
{
PrintValue(sPos, label, value, (value ? "on >>>>>>>>>>>>>>>>>>>>>>" : "off "));
}
}
}
void CConsole::UpdateDataThreadFunc()
{
static auto oldLight = m_pIAutoheadlightComplexService->GetHeadlightStatus();
static auto olsIsInTunnel = m_pIAutoheadlightComplexService->IsinTunnel();
PrintValue(g_sComplexService2, "Light: ", olsIsInTunnel, (olsIsInTunnel ? "on" : "off"));
PrintValue(g_sComplexService3, "Is in tunnel: ", oldLight, (oldLight ? "yes" : "no"));
while (m_bRunning)
{
UpdateTXSignal(g_sDispatchService4, "Headlight:", m_signalHeadlight, m_bHeadLight);
auto light = m_pIAutoheadlightComplexService->GetHeadlightStatus();
if (oldLight != light)
{
PrintValue(g_sComplexService3, "Is in tunnel: ", light, (light ? "yes" : "no"));
oldLight = light;
}
auto isInTunnel = m_pIAutoheadlightComplexService->IsinTunnel();
if (olsIsInTunnel != isInTunnel)
{
PrintValue(g_sComplexService2, "Headlight: ", isInTunnel, (isInTunnel ? "on" : "off"));
olsIsInTunnel = isInTunnel;
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
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();
}

View File

@@ -0,0 +1,248 @@
#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 "vss_vehiclepositioncurrentlatitude_vd_rx.h"
#include "vss_vehiclepositioncurrentlongitude_vd_rx.h"
#include "vss_vehiclepositioncurrentlatitude_bs_rx.h"
#include "vss_vehiclepositioncurrentlongitude_bs_rx.h"
#include "vss_vehiclebodylightfrontlowbeam_bs_tx.h"
// Complex service Headlight interface - located in ../generated/example_service
#include "autoheadlight_cs_ifc.h"
#ifdef __unix__
#include <termios.h> // Needed for tcgetattr and fcntl
#include <unistd.h>
#endif
/**
* @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::Position::CurrentLatitudeDevice::IVSS_WriteCurrentLatitude_Event, // Vehicle Device interface
public vss::Vehicle::Position::CurrentLongitudeDevice::IVSS_WriteCurrentLongitude_Event, // Vehicle Device interface
public vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event, // Basic service interface
public vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event // Basic service interface
{
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.
*/
void PrintHeader();
/**
* @brief Prepare the data consumers..
* @details Gets all signals (2 RX signals [GPS] and 1 TX signals [headlight beam)
* @return Returns whether the preparation of the data consumers was successful or not.
*/
bool PrepareDataConsumers();
/**
* @brief For gracefully shutdown all signals need to be reset.
*/
void ResetSignals();
/**
* @brief Starts thread for polling the TX signals
*/
void StartUpdateDataThread();
/**
* @brief Stops thread
*/
void StopUpdateDataThread();
private:
/**
* @brief sets the current latitude.
* @param[in] value current latitude value
*/
void WriteCurrentLatitude(float value) override;
/**
* @brief sets the current longitude.
* @param[in] value current longitude value
*/
void WriteCurrentLongitude(float value) override;
/**
* @brief sets the current latitude.
* @param[in] value current latitude value
*/
void SetCurrentLatitude(float value) override;
/**
* @brief sets the current longitude.
* @param[in] value current longitude value
*/
void SetCurrentLongitude(float value) override;
/**
* @brief Register Signals
* @return Return true if there was no issue with registering signals otherwise return false
*/
bool RegisterSignals();
/**
* @brief Callback function when new latitude value is available
* @param[in] value The value of the latitude
*/
void CallbackCurrentLatitude(sdv::any_t value);
/**
* @brief Callback function when new longitude value is available
* @param[in] value The value of the longitude
*/
void CallbackCurrentLongitude(sdv::any_t value);
/**
* @brief Callback function when new latitude value is available
* @param[in] value The value of the latitude
*/
void CallbackToSetCurrentLatitude(sdv::any_t value);
/**
* @brief Callback function when new longitude value is available
* @param[in] value The value of the longitude
*/
void CallbackToSetCurrentLongitude(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
std::thread m_threadReadTxSignals; ///< Simulation datalink thread.
bool m_bThreadStarted = false; ///< Set when initialized.
bool m_bRunning = false; ///< When set, the application is running.
mutable std::mutex m_mPrintToConsole; ///< Mutex to print complete message
sdv::core::CSignal m_signalCurrentLatitude; ///< Signal Current latitude
sdv::core::CSignal m_signalCurrentLongitude; ///< Signal Current longitude
sdv::core::CSignal m_signalHeadlight; ///< Signal Headlight status
float m_fCurrentLongitude = 0.0f; //< Current latitude
float m_fCurrentLatitude = 0.0f; //< Current longitude
bool m_bHeadLight = true; ///< Head light
float m_fVehicleDeviceCurrentLatitude = 0.0f; ///< Current latitude (Vehicle Device)
float m_fVehicleDeviceCurrentLongitude = 0.0; ///< Current longitude (Vehicle Device)
float m_fBasicServiceCurrentLatitude = 0.0f; ///< Current latitude (basic Service)
float m_fBasicServiceCurrentLongitude = 0.0; ///< Current longitude (basic Service)
IAutoheadlightService* m_pIAutoheadlightComplexService = nullptr; ///< Autoheadlight 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)
{
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(6) << tValue << " " << rssUnits << " ";
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& rssUnits)
{
PrintValue(sPos, rssName, bValue ? "" : "", rssUnits);
}
#endif // !define CONSOLE_OUTPUT_H

View File

@@ -0,0 +1,246 @@
#include "autoheadlight_simulate.h"
#ifdef _WIN32
#include <conio.h> // Needed for _kbhit
#else
#include <fcntl.h>
#endif
CAutoHeadlightAppSimulate::~CAutoHeadlightAppSimulate()
{
ResetSignalsSimDatalink();
Shutdown();
}
bool CAutoHeadlightAppSimulate::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::cout << "framework runtime directory set\n";
}
auto bResult = m_appcontrol.Startup("");
m_appcontrol.SetConfigMode();
if (!m_appcontrol.AddConfigSearchDir("config"))
{
m_appcontrol.Shutdown();
return false;
}
bResult &= m_appcontrol.LoadConfig("data_dispatch_example.toml") == sdv::core::EConfigProcessResult::successful;
bResult &= m_appcontrol.LoadConfig("task_timer_example.toml") == sdv::core::EConfigProcessResult::successful;
bResult &= RegisterSignalsSimDatalink(); //register signals
bResult &= m_appcontrol.LoadConfig("autoheadlight_vd_bs.toml") == sdv::core::EConfigProcessResult::successful;
bResult &= m_appcontrol.LoadConfig("autoheadlight_cs.toml") == sdv::core::EConfigProcessResult::successful;
if (!bResult)
{
SDV_LOG_ERROR("One or more configurations could not be loaded. Cannot continue.");
m_appcontrol.Shutdown();
return false;
}
if (!GetAccessToServices())
{
return false;
}
return true;
}
void CAutoHeadlightAppSimulate::Shutdown()
{
if (!m_bInitialized)
m_appcontrol.Shutdown();
m_bInitialized = false;
}
bool CAutoHeadlightAppSimulate::GetAccessToServices()
{
m_VisualCurrentLatitude = m_dispatch.Subscribe(headlight::dsFCurrentLatitude, [&](sdv::any_t value) { CAutoHeadlightAppSimulate::CallbackToSetCurrentLatitude(value); });
m_VisualCurrentLongitude = m_dispatch.Subscribe(headlight::dsFCurrentLongitude, [&](sdv::any_t value) { CAutoHeadlightAppSimulate::CallbackToSetCurrentLongitude(value); });
// BASIC SERVICES
auto pCurrentLatitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLatitude_Service").GetInterface<vss::Vehicle::Position::CurrentLatitudeService::IVSS_GetCurrentLatitude>();
if (!pCurrentLatitudeSvc)
{
SDV_LOG_ERROR("Could not get interface 'IVSS_GetCurrentLatitude': [CAutoHeadlightService]");
return false;
}
auto pCurrentLongitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLongitude_Service").GetInterface<vss::Vehicle::Position::CurrentLongitudeService::IVSS_GetCurrentLongitude>();
if (!pCurrentLongitudeSvc)
{
SDV_LOG_ERROR("Could not get interface 'IVSS_GetCurrentLongitude': [CAutoHeadlightService]");
return false;
}
if (pCurrentLatitudeSvc)
pCurrentLatitudeSvc->RegisterOnSignalChangeOfFCurrentLatitude(static_cast<vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event*> (this));
if (pCurrentLongitudeSvc)
pCurrentLongitudeSvc->RegisterOnSignalChangeOfFCurrentLongitude(static_cast<vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event*> (this));
// COMPLEX SERVICE
m_pIAutoheadlightComplexService = sdv::core::GetObject("Auto Headlight Service").GetInterface<IAutoheadlightService>();
if (!m_pIAutoheadlightComplexService)
{
SDV_LOG_ERROR("Console ERROR: Could not get complex service interface 'IAutoheadlightService'");
return false;
}
m_bInitialized = true;
return true;
}
void CAutoHeadlightAppSimulate::ExecuteTestRun()
{
if (!m_bInitialized)
return;
// Switch to running mode.
m_appcontrol.SetRunningMode();
m_bRunning = true;
bool bRunUntilBreak = true;
while (bRunUntilBreak)
{
for (const GPS& position : m_DriveWayData)
{
m_signalCurrentLatitude.Write<float>(position.latitude);
m_signalCurrentLongitude.Write<float>(position.longitude);
// Check for a key
if (!KeyHit())
{
std::this_thread::sleep_for(std::chrono::milliseconds(200));
continue;
}
// Get a keyboard value (if there is any).
char c = GetChar();
if (c == 'x' || c == 'X')
{
bRunUntilBreak = false;
break;
}
}
}
}
bool CAutoHeadlightAppSimulate::RegisterSignalsSimDatalink()
{
std::string msg = "Signals Registered: ";
m_signalCurrentLatitude = m_dispatch.RegisterRxSignal(headlight::dsFCurrentLatitude);
m_signalCurrentLongitude = m_dispatch.RegisterRxSignal(headlight::dsFCurrentLongitude);
m_signalHeadlight = m_dispatch.RegisterTxSignal(headlight::dsBHeadLightLowBeam, false);
if (m_signalCurrentLatitude && m_signalCurrentLongitude && m_signalHeadlight)
{
std::cout << "Registration was successful\n";
}
else
{
std::cout << "ATTENTION! Registration failed\n";
return false;
}
auto allSignals = m_dispatch.GetRegisteredSignals();
msg.append("(");
msg.append(std::to_string(allSignals.size()));
msg.append(")\n");
std::cout << msg.c_str();
return true;
}
void CAutoHeadlightAppSimulate::ResetSignalsSimDatalink()
{
if (m_signalCurrentLatitude)
{
m_signalCurrentLatitude.Reset();
}
if (m_signalCurrentLongitude)
{
m_signalCurrentLongitude.Reset();
}
if (m_signalHeadlight)
{
m_signalHeadlight.Reset();
}
if(m_VisualCurrentLatitude)
{
m_VisualCurrentLatitude.Reset();
}
if(m_VisualCurrentLongitude)
{
m_VisualCurrentLongitude.Reset();
}
}
bool CAutoHeadlightAppSimulate::IsSDVFrameworkEnvironmentSet()
{
const char* envVariable = std::getenv("SDV_FRAMEWORK_RUNTIME");
if (envVariable)
{
std::cout << "framework runtime directory already set\n";
return true;
}
return false;
}
void CAutoHeadlightAppSimulate::SetCurrentLatitude(float value)
{
m_fBasicServiceCurrentLatitude = value;
}
void CAutoHeadlightAppSimulate::SetCurrentLongitude(float value)
{
m_fBasicServiceCurrentLongitude = value;
}
void CAutoHeadlightAppSimulate::CallbackToSetCurrentLatitude(sdv::any_t value)
{
m_fDataLinkCurrentLatitude = value.get<float>();
}
void CAutoHeadlightAppSimulate::CallbackToSetCurrentLongitude(sdv::any_t value)
{
m_fDataLinkCurrentLongitude= value.get<float>();
}
bool CAutoHeadlightAppSimulate::KeyHit()
{
#ifdef _WIN32
return _kbhit();
#elif __unix__
int ch = getchar();
if (ch != EOF) {
ungetc(ch, stdin);
return true;
}
return false;
#endif
}
char CAutoHeadlightAppSimulate::GetChar()
{
#ifdef _WIN32
return static_cast<char>(_getch());
#else
return getchar();
#endif
}

View File

@@ -0,0 +1,169 @@
#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"
// VSS interfaces - located in ../generated/vss_files/include
#include "vss_vehiclepositioncurrentlatitude_bs_rx.h"
#include "vss_vehiclepositioncurrentlongitude_bs_rx.h"
#include "vss_vehiclebodylightfrontlowbeam_bs_tx.h"
// Complex service Headlight interface - located in ../generated/example_service
#include "autoheadlight_cs_ifc.h"
/**
* @brief Driveway Simulation utility
*/
class CAutoHeadlightAppSimulate :
public vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event, // Basic service interface
public vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event // Basic service interface
{
public:
/**
* @brief Destructor.
*/
~CAutoHeadlightAppSimulate();
/**
* @brief Initialize the app.
* @return Return true on success otherwise false
*/
bool Initialize();
/**
* @brief Reset and Stop the app.
*/
void Shutdown();
/**
* @brief Driveway data is provided to complex service and headlight is enabled based on the tunnel data
*/
void ExecuteTestRun();
private:
/**
* @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 Access to required services to get information on desired signals
* @return True if the access to all the services are success
*/
/**
* @brief Access to required services to get information on desired signals
* @return Return true if there was no issue with getting access to services otherwise return false
*/
bool GetAccessToServices();
/**
* @brief Register Signals
* @return Return true if there was no issue with registering signals otherwise return false
*/
bool RegisterSignalsSimDatalink();
/**
* @brief Reset Signals
*/
void ResetSignalsSimDatalink();
/**
* @brief Set the evnironment path to fetch framework binaries
* @return Return true if there was no issue with setting framework path otherwise return false
*/
bool IsSDVFrameworkEnvironmentSet();
/**
* @brief sets the current latitude.
* @param[in] value current latitude value
*/
virtual void SetCurrentLatitude(float value) override;
/**
* @brief sets the current longitude.
* @param[in] value current longitude value
*/
virtual void SetCurrentLongitude(float value) override;
/**
* @brief Callback function when new latitude value is available
* @param[in] value The value of the latitude
*/
void CallbackToSetCurrentLatitude(sdv::any_t value);
/**
* @brief Callback function when new longitude value is available
* @param[in] value The value of the longitude
*/
void CallbackToSetCurrentLongitude(sdv::any_t value);
sdv::core::CDispatchService m_dispatch; ///< Dispatch service
bool m_bInitialized = false; ///< Set when initialized.
bool m_bRunning = false; ///< When set, the application is running.
std::filesystem::path m_pathFramework; ///< Path to the SDV V-API framework.
sdv::app::CAppControl m_appcontrol; ///< App-control of SDV V-API.
sdv::core::CSignal m_signalCurrentLatitude; ///< Signal Current latitude
sdv::core::CSignal m_signalCurrentLongitude; ///< Signal Current longitude
sdv::core::CSignal m_signalHeadlight; ///< Signal Headlight status
sdv::core::CSignal m_VisualCurrentLatitude; ///< Signal value visualization purpose : Current latitude subscription
sdv::core::CSignal m_VisualCurrentLongitude; ///< Signal value visualization purpose : Current longitude subscription
float m_fDataLinkCurrentLatitude = 0.0f; ///< default value (input signal) - datalink monitoring
float m_fDataLinkCurrentLongitude = 0.0f; ///< default value (input signal) - datalink monitoring
bool m_bDataLinkHeadlightStatus = false; ///< default value (output signal) - datalink monitoring
float m_fBasicServiceCurrentLatitude = 0.0f; ///< Current Latitude - basic service event value
float m_fBasicServiceCurrentLongitude = 0.0f; ///< Current Longitude - basic service event value
bool m_bBasicServiceHeadlightStatus = false; ///< Headlight Status - basic service event value
IAutoheadlightService* m_pIAutoheadlightComplexService = nullptr; ///< Autoheadlight Service interface pointer.
/**
* @brief GPS driveway struct for coordinates and text wrt tunnel info
*/
struct GPS {
float latitude = 0.0f; ///< Latitude
float longitude = 0.0f; ///< Longitude
std::string location = "Before Tunnel"; ///< Text : "Before Tunnel", "Inside Tunnel", "After Tunnel"
};
/**
* @brief Driveway data including the tunnel information
*/
std::vector<GPS> m_DriveWayData = {
{47.6495f, 9.4695f, "Before Tunnel"},
{47.6496f, 9.4696f, "Before Tunnel"},
{47.6497f, 9.4697f, "Before Tunnel"},
{47.6498f, 9.4698f, "Before Tunnel"},
{47.6499f, 9.4699f, "Before Tunnel"},
{47.6500f, 9.4700f, "Inside Tunnel"},
{47.6501f, 9.4701f, "Inside Tunnel"},
{47.6502f, 9.4702f, "Inside Tunnel"},
{47.6503f, 9.4703f, "Inside Tunnel"},
{47.6504f, 9.4704f, "Inside Tunnel"},
{47.6505f, 9.4705f, "Inside Tunnel"},
{47.6506f, 9.4706f, "After Tunnel"},
{47.6507f, 9.4707f, "After Tunnel"},
{47.6508f, 9.4708f, "After Tunnel"},
{47.6509f, 9.4709f, "After Tunnel"},
{47.6510f, 9.4710f, "After Tunnel"}
};
};

View File

@@ -0,0 +1,25 @@
/**
* namespace for the signal names
* in case /generated/vss_files/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("../generated/vss_files/signal_identifier.h")
#include "../generated/vss_files/signal_identifier.h"
#else
namespace headlight
{
// Data Dispatch Service signal names to dbc variable names C-type RX/TX vss name space
static std::string dsFCurrentLatitude = "CAN_Input.Current_Latitude" ; ///< float RX Vehicle.Position.CurrentLatitude
static std::string dsFCurrentLongitude = "CAN_Input.Current_Longitude" ; ///< float RX Vehicle.Position.CurrentLongitude
static std::string dsBHeadlightLowBeam = "CAN_Output.HeadLight_LowBeam"; ///< bool TX Vehicle.Body.Light.Front.Lowbeam
} // headlight
#endif
#endif
#endif // ! defined SIGNAL_NAMES_H