mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-02-05 15:18:45 +00:00
145
examples/auto_headlamp_example/CMakeLists.txt
Normal file
145
examples/auto_headlamp_example/CMakeLists.txt
Normal file
@@ -0,0 +1,145 @@
|
||||
project(AutoHeadlight)
|
||||
|
||||
# Use new policy for project version settings and default warning level
|
||||
cmake_policy(SET CMP0048 NEW) # requires CMake 3.14
|
||||
cmake_policy(SET CMP0092 NEW) # requires CMake 3.15
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Library symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Include directory to the core framework
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
|
||||
######################################################################################################################################################################
|
||||
# preparation
|
||||
######################################################################################################################################################################
|
||||
|
||||
# REMARK: The code generation for the proxy/stub, interface definitions and serialization, the vehicle devices and the basic
|
||||
# services are generated during the configuration phase of CMake. This is necessary, since CMakeFiles.txt files are generated and
|
||||
# they have to be available during the configuration phase of CMake to be taken into the build process. Requisite for the code
|
||||
# generation during the configuration time of CMake is the availability of the tools to do the generation. Hence the tools cannot be
|
||||
# created during the build process, which is executed after the configuration process.
|
||||
|
||||
# Execute sdv_vss_util to create IDL files for devices and basic services.
|
||||
message("Create interface code for devices and basic services of auto headlight example.")
|
||||
execute_process(COMMAND "${SDV_VSS_UTIL}" "${PROJECT_SOURCE_DIR}/vss_autoheadlight_example.csv" "-O${PROJECT_SOURCE_DIR}/generated/" --prefixheadlight --version1.0.0.1 --enable_components)
|
||||
|
||||
# Execute the IDL compiler for the VSS interfaces to digest interface code.
|
||||
message("Compiling vss_vehiclepositioncurrentlatitude_vd_rx.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/generated/vss_files/vss_vehiclepositioncurrentlatitude_vd_rx.idl" "-O${PROJECT_SOURCE_DIR}/generated/vss_files/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
message("Compiling vss_vehiclepositioncurrentlatitude_bs_rx.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/generated/vss_files/vss_vehiclepositioncurrentlatitude_bs_rx.idl" "-O${PROJECT_SOURCE_DIR}/generated/vss_files/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_nameautoheadlight_proxystub)
|
||||
message("Compiling vss_vehiclepositioncurrentlongitude_vd_rx.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/generated/vss_files/vss_vehiclepositioncurrentlongitude_vd_rx.idl" "-O${PROJECT_SOURCE_DIR}/generated/vss_files/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
message("Compiling vss_vehiclepositioncurrentlongitude_bs_rx.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/generated/vss_files/vss_vehiclepositioncurrentlongitude_bs_rx.idl" "-O${PROJECT_SOURCE_DIR}/generated/vss_files/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_nameautoheadlight_proxystub)
|
||||
message("Compiling vss_vehiclebodyheadlight_vd_tx.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/generated/vss_files/vss_vehiclebodylightfrontlowbeam_vd_tx.idl" "-O${PROJECT_SOURCE_DIR}/generated/vss_files/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
message("Compiling vss_vehiclebodyheadlight_bs_tx.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/generated/vss_files/vss_vehiclebodylightfrontlowbeam_bs_tx.idl" "-O${PROJECT_SOURCE_DIR}/generated/vss_files/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_nameautoheadlight_proxystub)
|
||||
|
||||
# Execute sdv_dbc_util to create FMU code.
|
||||
message("Create functional mockup unit (FMU) of auto headlight example.")
|
||||
execute_process(COMMAND ${SDV_DBC_UTIL} "${PROJECT_SOURCE_DIR}/datalink_autoheadlight_example.dbc" "-O${PROJECT_SOURCE_DIR}/generated/" --nodesheadlight --version1.0.0.1 --moduleAutoHeadlightFMU --dl_lib_nameautoheadlight_can_dl_example)
|
||||
|
||||
# Execute the IDL compiler for the complex service to digest interface code.
|
||||
message("Compiling autoheadlight_cs.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/autoheadlight_service/autoheadlight_cs_ifc.idl" "-O${PROJECT_SOURCE_DIR}/generated/autoheadlight_service/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Iexample_service/ --ps_lib_nameautoheadlight_service_proxystub)
|
||||
|
||||
#######################################################################################################################################################################
|
||||
## vehicle devices and basic services
|
||||
#######################################################################################################################################################################
|
||||
|
||||
# REMARK: Proxy/stub and vehicle device and basic service code was generated during the configuration phase of CMake. Following
|
||||
# below are the build steps to build the components that were generated.
|
||||
|
||||
message("Include: auto headlight proxy/stub for vehicle devices and basic services")
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/generated/vss_files)
|
||||
add_subdirectory(generated/vss_files/ps)
|
||||
|
||||
|
||||
add_subdirectory(generated/vss_files/vd_currentlatitude)
|
||||
add_subdirectory(generated/vss_files/vd_currentlongitude)
|
||||
add_subdirectory(generated/vss_files/vd_headlightlowbeam)
|
||||
|
||||
add_subdirectory(generated/vss_files/bs_currentlatitude)
|
||||
add_subdirectory(generated/vss_files/bs_currentlongitude)
|
||||
add_subdirectory(generated/vss_files/bs_headlightlowbeam)
|
||||
|
||||
|
||||
######################################################################################################################################################################
|
||||
# complex service
|
||||
######################################################################################################################################################################
|
||||
|
||||
message("Include: proxy/stub for complex autoheadlight service")
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/generated/autoheadlight_service)
|
||||
add_subdirectory(generated/autoheadlight_service/ps)
|
||||
|
||||
message("Include: Auto Headlight complex service")
|
||||
add_library(autoheadlight_complex_service SHARED
|
||||
"autoheadlight_service/autoheadlight_cs.h"
|
||||
"autoheadlight_service/autoheadlight_cs.cpp"
|
||||
)
|
||||
set_target_properties(autoheadlight_complex_service PROPERTIES OUTPUT_NAME "autoheadlight_service")
|
||||
set_target_properties(autoheadlight_complex_service PROPERTIES PREFIX "")
|
||||
set_target_properties(autoheadlight_complex_service PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
######################################################################################################################################################################
|
||||
# autoheadlight application
|
||||
######################################################################################################################################################################
|
||||
|
||||
# Define the executable
|
||||
add_executable(auto_headlight_app
|
||||
autoheadlight_app/autoheadlight_app.cpp
|
||||
autoheadlight_app/autoheadlight_simulate.h
|
||||
autoheadlight_app/autoheadlight_simulate.cpp
|
||||
autoheadlight_app/autoheadlight_console.h
|
||||
autoheadlight_app/autoheadlight_console.cpp
|
||||
autoheadlight_app/signal_names.h
|
||||
)
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if (WIN32)
|
||||
target_link_libraries(auto_headlight_app Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(auto_headlight_app ${CMAKE_DL_LIBS} rt ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(auto_headlight_app Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
# # Copy the config files
|
||||
# file (COPY ${PROJECT_SOURCE_DIR}/config/CanSocketExample.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/data_link_example.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/data_dispatch_example.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/task_timer_example.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/autoheadlight_vd_bs.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/autoheadlight_cs.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
|
||||
|
||||
|
||||
######################################################################################################################################################################
|
||||
# auto headlight fmu for OpenXilEnv
|
||||
######################################################################################################################################################################
|
||||
|
||||
# REMARK: The CMAKE created by sdv_dbc_util creates all files including the buildDescription.xml
|
||||
#
|
||||
# What cannot be created automatically is the method OpenAPILoad(const std::string& resources) in file model.cpp
|
||||
# The method must load all required components
|
||||
# Therfore here the file is copied and overwritten the auto generated file
|
||||
#
|
||||
# The required toml files need to be copied to the folder:
|
||||
# generated/fmu_DemoExampleFMU/DemoExampleFMU/resources
|
||||
|
||||
message("Include: FMU AutoHeadlightFMU")
|
||||
# Copy the config files
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/fmu_files/resources/fmu_autoheadlight_vd_bs.toml DESTINATION ${PROJECT_SOURCE_DIR}/generated/fmu_AutoHeadlightFMU/AutoHeadlightFMU/resources)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/fmu_files/resources/fmu_autoheadlight_cs.toml DESTINATION ${PROJECT_SOURCE_DIR}/generated/fmu_AutoHeadlightFMU/AutoHeadlightFMU/resources)
|
||||
|
||||
# Overwrite model.cpp with an identical file but loads all components in OpenAPILoad(const std::string& resources)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/fmu_files/model.cpp DESTINATION ${PROJECT_SOURCE_DIR}/generated/fmu_AutoHeadlightFMU/AutoHeadlightFMU)
|
||||
|
||||
# Now the project can be build
|
||||
add_subdirectory(generated/fmu_AutoHeadlightFMU)
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
#include <iostream>
|
||||
#include "autoheadlight_cs.h"
|
||||
|
||||
|
||||
CAutoHeadlightService::CAutoHeadlightService()
|
||||
{
|
||||
}
|
||||
|
||||
CAutoHeadlightService::~CAutoHeadlightService()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void CAutoHeadlightService::Initialize(const sdv::u8string& ssObjectConfig)
|
||||
{
|
||||
m_eStatus = sdv::EObjectStatus::initializing;
|
||||
|
||||
// Request the basic service for the headlight.
|
||||
m_pHeadlightSvc = sdv::core::GetObject("Vehicle.Body.Light.Front.LowBeam_Service").GetInterface<vss::Vehicle::Body::Light::Front::LowBeamService::IVSS_SetHeadLightLowBeam>();
|
||||
if (!m_pHeadlightSvc)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_SetHeadlightLowBeam': [CAutoHeadlightService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Request the basic service for the steering wheel.
|
||||
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]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Request the basic service for the vehicle speed.
|
||||
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]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Register Current Latitude change event handler.
|
||||
pCurrentLatitudeSvc->RegisterOnSignalChangeOfFCurrentLatitude(static_cast<vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event*> (this));
|
||||
|
||||
// Register Current Longitude change event handler.
|
||||
pCurrentLongitudeSvc->RegisterOnSignalChangeOfFCurrentLongitude(static_cast<vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event*> (this));
|
||||
|
||||
|
||||
if(LoadGPSBounds(ssObjectConfig))
|
||||
{
|
||||
SDV_LOG_INFO("AutoHeadlightService: GPS bounds loaded Successfully");
|
||||
m_eStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
else
|
||||
{
|
||||
SDV_LOG_ERROR("AutoHeadlightService: GPS bounds could not be loaded");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
SDV_LOG_INFO("AutoHeadlightService: Initialized Successfully");
|
||||
}
|
||||
|
||||
sdv::EObjectStatus CAutoHeadlightService::GetStatus() const
|
||||
{
|
||||
return m_eStatus;
|
||||
}
|
||||
|
||||
void CAutoHeadlightService::SetOperationMode(sdv::EOperationMode /*eMode*/)
|
||||
{
|
||||
// Not applicable
|
||||
}
|
||||
|
||||
void CAutoHeadlightService::Shutdown()
|
||||
{
|
||||
// Unregister the Current latitude event handler.
|
||||
auto pCurrentLatitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLatitude_Service").GetInterface<vss::Vehicle::Position::CurrentLatitudeService::IVSS_GetCurrentLatitude>();
|
||||
if (pCurrentLatitudeSvc)
|
||||
pCurrentLatitudeSvc->UnregisterOnSignalChangeOfFCurrentLatitude(static_cast<vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event*> (this));
|
||||
|
||||
// Unregister the vehicle speed event handler.
|
||||
auto pCurrentLongitudeSvc = sdv::core::GetObject("Vehicle.Position.CurrentLongitude_Service").GetInterface<vss::Vehicle::Position::CurrentLongitudeService::IVSS_GetCurrentLongitude>();
|
||||
if (pCurrentLongitudeSvc)
|
||||
pCurrentLongitudeSvc->UnregisterOnSignalChangeOfFCurrentLongitude(static_cast<vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event*> (this));
|
||||
}
|
||||
|
||||
void CAutoHeadlightService::SetCurrentLatitude(float value)
|
||||
{
|
||||
if (m_fCurrentLatitude == value)
|
||||
return;
|
||||
|
||||
m_fCurrentLatitude = value;
|
||||
ProcessHeadlightBasedOnEgoPosition();
|
||||
}
|
||||
|
||||
void CAutoHeadlightService::SetCurrentLongitude(float value)
|
||||
{
|
||||
if (m_fCurrentLongitude == value)
|
||||
return;
|
||||
|
||||
m_fCurrentLongitude = value;
|
||||
ProcessHeadlightBasedOnEgoPosition();
|
||||
}
|
||||
|
||||
bool CAutoHeadlightService::IsinTunnel() const
|
||||
{
|
||||
// Check if vehicle is within the tunnel bounds
|
||||
if (m_fCurrentLatitude >= m_SGPSBoundingBox.fTunnelMinLat && m_fCurrentLatitude <= m_SGPSBoundingBox.fTunnelMaxLat &&
|
||||
m_fCurrentLongitude >= m_SGPSBoundingBox.fTunnelMinLon && m_fCurrentLongitude <= m_SGPSBoundingBox.fTunnelMaxLon)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CAutoHeadlightService::GetHeadlightStatus() const
|
||||
{
|
||||
return m_bHeadlight;
|
||||
}
|
||||
|
||||
void CAutoHeadlightService::ProcessHeadlightBasedOnEgoPosition()
|
||||
{
|
||||
auto isInTunnel = IsinTunnel();
|
||||
if (isInTunnel && !m_bHeadlight)
|
||||
{
|
||||
// switch on headlight
|
||||
m_bHeadlight = true;
|
||||
m_pHeadlightSvc->SetHeadLightLowBeam(m_bHeadlight);
|
||||
}
|
||||
if (!IsinTunnel() && m_bHeadlight)
|
||||
{
|
||||
// switch off headlight
|
||||
m_bHeadlight = false;
|
||||
m_pHeadlightSvc->SetHeadLightLowBeam(m_bHeadlight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CAutoHeadlightService::LoadGPSBounds(const sdv::u8string& rssObjectConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
sdv::toml::CTOMLParser config(rssObjectConfig.c_str());
|
||||
|
||||
sdv::toml::CNode fStartLatNode = config.GetDirect("tunnel_start_lat");
|
||||
float fTunnelStartLat = 0.0; ///< Tunnel Start Latitude
|
||||
if (fStartLatNode.GetType() == sdv::toml::ENodeType::node_floating_point)
|
||||
{
|
||||
fTunnelStartLat = static_cast<float>(fStartLatNode.GetValue());
|
||||
}
|
||||
|
||||
sdv::toml::CNode fStartLonNode = config.GetDirect("tunnel_start_lon");
|
||||
float fTunnelStartLon = 0.0; ///< Tunnel Start Longitude
|
||||
if (fStartLonNode.GetType() == sdv::toml::ENodeType::node_floating_point)
|
||||
{
|
||||
fTunnelStartLon = static_cast<float>(fStartLonNode.GetValue());
|
||||
}
|
||||
|
||||
sdv::toml::CNode fEndLatNode = config.GetDirect("tunnel_end_lat");
|
||||
float fTunnelEndLat = 0.0; ///< Tunnel End Latitude
|
||||
if (fEndLatNode.GetType() == sdv::toml::ENodeType::node_floating_point)
|
||||
{
|
||||
fTunnelEndLat = static_cast<float>(fEndLatNode.GetValue());
|
||||
}
|
||||
|
||||
sdv::toml::CNode fEndLonNode = config.GetDirect("tunnel_end_lon");
|
||||
float fTunnelEndLon = 0.0; ///< Tunnel End Longitude
|
||||
if (fEndLonNode.GetType() == sdv::toml::ENodeType::node_floating_point)
|
||||
{
|
||||
fTunnelEndLon = static_cast<float>(fEndLonNode.GetValue());
|
||||
}
|
||||
|
||||
// Calculate bounding box
|
||||
m_SGPSBoundingBox.fTunnelMinLat = std::min(fTunnelStartLat, fTunnelEndLat);
|
||||
m_SGPSBoundingBox.fTunnelMaxLat = std::max(fTunnelStartLat, fTunnelEndLat);
|
||||
m_SGPSBoundingBox.fTunnelMinLon = std::min(fTunnelStartLon, fTunnelEndLon);
|
||||
m_SGPSBoundingBox.fTunnelMaxLon = std::max(fTunnelStartLon, fTunnelEndLon);
|
||||
}
|
||||
catch (const sdv::toml::XTOMLParseException& e)
|
||||
{
|
||||
SDV_LOG_ERROR("Parsing error: ", e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IAutoheadlightService::SGPSBoundBox CAutoHeadlightService::GetGPSBoundBox() const
|
||||
{
|
||||
SGPSBoundBox tunnel;
|
||||
tunnel.fTunnelMinLat = m_SGPSBoundingBox.fTunnelMinLat;
|
||||
tunnel.fTunnelMaxLat = m_SGPSBoundingBox.fTunnelMaxLat;
|
||||
tunnel.fTunnelMinLon = m_SGPSBoundingBox.fTunnelMinLon;
|
||||
tunnel.fTunnelMaxLon = m_SGPSBoundingBox.fTunnelMaxLon;
|
||||
|
||||
return tunnel;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
#ifndef COMPLEX_SERVICE_EXAMPLE_H
|
||||
#define COMPLEX_SERVICE_EXAMPLE_H
|
||||
|
||||
// C++ library
|
||||
#include <iostream>
|
||||
|
||||
|
||||
// SDV framework support
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include <support/timer.h>
|
||||
#include <support/toml.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 Auto Headlight service
|
||||
* @details This complex service enables the headlight if the vehicle position is detected inside the tunnel and disables the headlight
|
||||
* if vehicle is detected outside the tunnel. This also checks if the time based on summer and winter season and enables it accordingly.(time aspect will be developed later)
|
||||
*
|
||||
* Input events from basic service: CurrentLatitude
|
||||
* CurrentLongitude
|
||||
* Output calls for basic service: headlight (true or false)
|
||||
*
|
||||
* Input calls for applications: autoheadlight enabled (true/false)
|
||||
* Output info for applications: headlight status (true/false)
|
||||
* Inside the tunnel (true/false)
|
||||
*/
|
||||
class CAutoHeadlightService :
|
||||
public sdv::CSdvObject,
|
||||
public sdv::IObjectControl,
|
||||
public IAutoheadlightService,
|
||||
public vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event,
|
||||
public vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CAutoHeadlightService();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CAutoHeadlightService();
|
||||
|
||||
// Interface map
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetCurrentLatitude_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetCurrentLongitude_Event)
|
||||
SDV_INTERFACE_ENTRY(IAutoheadlightService)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
// Object declarations
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Auto Headlight 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;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Set Current latitude event. Overload of vss::Vehicle::Position::CurrentLatitudeService::IVSS_SetBSCurrentLatitude_Event
|
||||
* @param[in] value Current latitude value in float
|
||||
*/
|
||||
void SetCurrentLatitude(float value) override;
|
||||
|
||||
/**
|
||||
* @brief Set Current Longitude event. Overload of vss::Vehicle::Position::CurrentLongitudeService::IVSS_SetBSCurrentLongitude_Event
|
||||
* @param[in] value Current latitude value in float
|
||||
*/
|
||||
void SetCurrentLongitude(float value) override;
|
||||
|
||||
/**
|
||||
* @brief Gets status of vehicle position if it is inside tunnel or not. Overload of IAutoheadlightService::IsinTunnel.
|
||||
* @return Returns true if position of vehicle is inside tunnel and false if outside.
|
||||
*/
|
||||
bool IsinTunnel() const override;
|
||||
|
||||
/**
|
||||
* @brief Get status of headlights. Overload of IAutoheadlightService::GetHeadlightStatus.
|
||||
* @return Returns the status of headlights (true if switched on , false if not switched on)
|
||||
*/
|
||||
bool GetHeadlightStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Get the GPS bounding box
|
||||
* @return Returns the bounding box structure
|
||||
*/
|
||||
SGPSBoundBox GetGPSBoundBox() const override;
|
||||
|
||||
/**
|
||||
* @brief Update the headlight status based on the vehicle position with respect to tunnel.
|
||||
*/
|
||||
void ProcessHeadlightBasedOnEgoPosition();
|
||||
|
||||
/**
|
||||
* @brief Load GPS bounding box from the configuration file
|
||||
*/
|
||||
bool LoadGPSBounds(const sdv::u8string& rssObjectConfig);
|
||||
|
||||
sdv::EObjectStatus m_eStatus = sdv::EObjectStatus::initialization_pending; ///< Current object status
|
||||
volatile float m_fCurrentLatitude = 0.0; ///< Current Latitude
|
||||
volatile float m_fCurrentLongitude = 0.0; ///< Current Longitude
|
||||
volatile bool m_bHeadlight = false; ///< Headlight status
|
||||
SGPSBoundBox m_SGPSBoundingBox; ///< Tunnel bounding box coordinates
|
||||
|
||||
|
||||
///< Headlight interface.
|
||||
vss::Vehicle::Body::Light::Front::LowBeamService::IVSS_SetHeadLightLowBeam* m_pHeadlightSvc = nullptr;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CAutoHeadlightService)
|
||||
|
||||
#endif // !define COMPLEX_SERVICE_EXAMPLE_H
|
||||
@@ -0,0 +1,42 @@
|
||||
/*******************************************************************************
|
||||
* @file AutoHeadlight.idl
|
||||
* @details Auto Headlight example service interface definition.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief AutoHeadlight example service interface. The interface provides functions for the
|
||||
* Auto Headlight example complex service.
|
||||
*/
|
||||
interface IAutoheadlightService
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Tunnel Bounding box Coordinates struct.
|
||||
*/
|
||||
struct SGPSBoundBox
|
||||
{
|
||||
float fTunnelMinLat = 0.0; ///< Minimum latitude value of bounding box
|
||||
float fTunnelMinLon = 0.0; ///< Minimum longitude value of bounding box
|
||||
float fTunnelMaxLat = 0.0; ///< Maximum latitude value of bounding box
|
||||
float fTunnelMaxLon = 0.0; ///< Maximum longitude value of bounding box
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Gets status of vehicle position if it is inside tunnel or not
|
||||
* @return Returns true if position of vehicle is inside tunnel and false if outside.
|
||||
*/
|
||||
boolean IsinTunnel() const;
|
||||
|
||||
/**
|
||||
* @brief Get status of headlights
|
||||
* @return Returns the status of headlights (true if switched on , false if not switched on)
|
||||
*/
|
||||
boolean GetHeadlightStatus() const;
|
||||
|
||||
/**
|
||||
* @brief Get the GPS bounding box
|
||||
* @return Returns the bounding box structure
|
||||
*/
|
||||
SGPSBoundBox GetGPSBoundBox() const;
|
||||
};
|
||||
10
examples/auto_headlamp_example/config/autoheadlight_cs.toml
Normal file
10
examples/auto_headlamp_example/config/autoheadlight_cs.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "autoheadlight_service.sdv"
|
||||
Class = "Auto Headlight Service"
|
||||
tunnel_start_lat = 47.6500
|
||||
tunnel_start_lon = 9.4700
|
||||
tunnel_end_lat = 47.6506
|
||||
tunnel_end_lon = 9.4706
|
||||
@@ -0,0 +1,29 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_vd_currentlatitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLatitude_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_vd_currentlongitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLongitude_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_vd_headlightlowbeam_tx.sdv"
|
||||
Class = "Vehicle.Body.Light.Front.LowBeam_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_bs_currentlatitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLatitude_Service"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_bs_currentlongitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLongitude_Service"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_bs_headlightlowbeam_tx.sdv"
|
||||
Class = "Vehicle.Body.Light.Front.LowBeam_Service"
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "can_dl_example.sdv"
|
||||
Class = "CAN_data_link"
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
@@ -0,0 +1,123 @@
|
||||
VERSION "PrivateCAN"
|
||||
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
CM_
|
||||
BA_DEF_
|
||||
BA_
|
||||
VAL_
|
||||
CAT_DEF_
|
||||
CAT_
|
||||
FILTER
|
||||
BA_DEF_DEF_
|
||||
EV_DATA_
|
||||
ENVVAR_DATA_
|
||||
SGTYPE_
|
||||
SGTYPE_VAL_
|
||||
BA_DEF_SGTYPE_
|
||||
BA_SGTYPE_
|
||||
SIG_TYPE_REF_
|
||||
VAL_TABLE_
|
||||
SIG_GROUP_
|
||||
SIG_VALTYPE_
|
||||
SIGTYPE_VALTYPE_
|
||||
BO_TX_BU_
|
||||
BA_DEF_REL_
|
||||
BA_REL_
|
||||
BA_DEF_DEF_REL_
|
||||
BU_SG_REL_
|
||||
BU_EV_REL_
|
||||
BU_BO_REL_
|
||||
SG_MUL_VAL_
|
||||
|
||||
BS_:
|
||||
|
||||
BU_: headlight
|
||||
VAL_TABLE_ Fault_Codes 27 "UKWN" 26 "VEHSPDMAX_EXDD" 25 "STS_ALIVE" 24 "STEER_NOT_E2E_MODE" 23 "OTA_SPD" 22 "OTA_TIMER_DOWNLOAD_FAILED" 21 "OTA_MAX_TIME" 20 "CUBIXAD_STEERSTREQ_NOTACTV" 19 "CUBIXAD_DRVSTREQ_NOTACTV" 18 "SFTYDRV_INTV" 17 "LSDC_ALIVE" 16 "CUBIXAD_ALIVE" 15 "IBC_MAB_NO_PRIO" 14 "IBC_NOT_RDY" 13 "IBC_ALIVE" 12 "LSDC_GEAR" 11 "LSDC_SPD" 10 "LSDC_ACCL" 9 "IBC_NOT_MAB_MOD" 8 "GOLDBOX_ALIVE" 7 "CUBIXAD_GEAR" 6 "CUBIXAD_SPD_TESTTRACK" 5 "DRVREQCHG" 4 "RDY_TIMER" 3 "SFTY_CDN_FAILED" 2 "ACTVNCHK_SPD" 1 "ACTVNCHK_TIMR" 0 "NONE" ;
|
||||
VAL_TABLE_ TestMapID 6 "E_TESTMAPID_UNDEFINED" 5 "E_TESTMAPID_TEST_DRIVE" 4 "E_TESTMAPID_AD_AREA" 3 "E_TESTMAPID_STUTT_ARENA" 2 "E_TESTMAPID_ZF_LASTMILE" 1 "E_TESTMAPID_ZF_TESTTRACK_2" 0 "E_TESTMAPID_NONE" ;
|
||||
VAL_TABLE_ CtrlReqStates 7 "CtrlSts3b_RESERVED_4" 6 "CtrlSts3b_RESERVED_3" 5 "CtrlSts3b_RESERVED_2" 4 "CtrlSts3b_RESERVED_1" 3 "CtrlSts3b_ERROR" 2 "CtrlSts3b_CONTROL_REQUESTED" 1 "CtrlSts3b_CONTROL_NOT_REQUESTED" 0 "CtrlSts3b_INIT" ;
|
||||
VAL_TABLE_ SteerActrReSts 7 "Diag" 6 "Inactive" 5 "Ramping" 4 "Yellow" 3 "Red" 2 "Normal" 1 "Pending" 0 "Initialisation" ;
|
||||
VAL_TABLE_ SwtPark1 1 "SwtParkActv" 0 "SwtParkNotActv" ;
|
||||
VAL_TABLE_ PE_State 2 "ERROR" 1 "INIT" 0 "NO_ERROR" ;
|
||||
VAL_TABLE_ SSM_Req 7 "HMS_TAKEOVER" 6 "RESERVED" 5 "RELESE_VIA_RAMP" 4 "DRIVEOFF" 3 "HOLD_STANDBY" 2 "PARK" 1 "HOLD" 0 "NO_REQUEST" ;
|
||||
VAL_TABLE_ IBC_StandStillMode 12 "SSM_ERROR" 11 "SSM_INIT" 10 "SSM_DRIVEOFF_STANDBY_ACTIVE" 9 "SSM_HOLD_STANDBY_ACTIVE" 8 "SSM_HILL_SLIPPOFF_DETECTED" 7 "SSM_RELEASE_REQ_FROM_DRIVER" 6 "SSM_RELEASE_REQ_ACTIVE" 5 "SSM_DRIVEOFF_ACTIVE" 4 "SSM_PARK_RETAINED_ACTIVE" 3 "SSM_PARK_ACTIVE" 2 "SSM_PARK_REQUESTED" 1 "SSM_HOLD_ACTIVE" 0 "SSM_NO_ACTIVE_FUNCTION" ;
|
||||
VAL_TABLE_ AppTgtStDrv 3 "ACTIVE" 2 "READY" 1 "RESERVED" 0 "NOT_ACTIVE" ;
|
||||
VAL_TABLE_ IBC_Status 4 "IBC_MAB_ERR_COMM" 3 "IBC_MAB_NO_PRIO" 2 "IBC_IN_MAB_MODE" 1 "IBC_READY" 0 "IBC_NOT_READY_FAILED" ;
|
||||
VAL_TABLE_ GearLvrIndcn 7 "GearLvrIndcn2_Undefd" 6 "GearLvrIndcn2_Resd2" 5 "GearLvrIndcn2_Resd1" 4 "GearLvrIndcn2_ManModeIndcn" 3 "GearLvrIndcn2_DrvIndcn" 2 "GearLvrIndcn2_NeutIndcn" 1 "GearLvrIndcn2_RvsIndcn" 0 "GearLvrIndcn2_ParkIndcn" ;
|
||||
VAL_TABLE_ LvlgAdjReq 7 "LvlgAdjReq_Resd2" 6 "LvlgAdjReq_Resd1" 5 "LvlgAdjReq_Ll2" 4 "LvlgAdjReq_Ll1" 3 "LvlgAdjReq_Nrh" 2 "LvlgAdjReq_Hl1" 1 "LvlgAdjReq_Hl2" 0 "LvlgAdjReq_Ukwn" ;
|
||||
VAL_TABLE_ DrvModReq 15 "Err" 14 "Rock" 13 "Mud" 12 "Sand" 11 "Snow" 10 "Power" 9 "Hybrid" 8 "Pure_EV" 7 "Race" 6 "Adaptive" 5 "Offroad_CrossTerrain" 4 "Individual" 3 "Dynamic_Sport" 2 "Comfort_Normal" 1 "ECO" 0 "Undefd" ;
|
||||
VAL_TABLE_ MAB_Info_Message 4 "DRV_GEARLVR_TO_P" 3 "DRV_P_TO_D" 2 "LSDC_DI_NOT_PSBL" 1 "LSDC_ENA_NOT_POSSIBLE" 0 "NONE" ;
|
||||
VAL_TABLE_ MAB_OvrdTool_Sts 11 "HACKATHON" 10 "OTA" 9 "INIT" 8 "FINSHD" 7 "FLT" 6 "CUBIX_AD" 5 "SAVE_THE_SPOILER" 4 "LSDC" 3 "RDY" 2 "ACTVN_CHK" 1 "NO_MANIPULATION" 0 "NONE" ;
|
||||
VAL_TABLE_ HMI_Drvr_Req 9 "FCT_DEACTVN_REQ" 8 "FCT_ACTVN_OTA_CFMD" 7 "FCT_ACTVN_OTA_REQ" 6 "FCT_ACTVN_SAVETHESPOILER_CFMD" 5 "FCT_ACTVN_SAVETHESPOILER_REQ" 4 "FCT_ACTVN_LSDC_CFMD" 3 "FCT_ACTVN_LSDC_REQ" 2 "FCT_ACTVN_CUBIXAD_CFMD" 1 "FCT_ACTVN_CUBIXAD_REQ" 0 "FCT_ACTVN_NONE" ;
|
||||
VAL_TABLE_ Info_Message 4 "DRV_GEARLVR_TO_P" 3 "DRV_P_TO_D" 2 "LSDC_DI_NOT_PSBL" 1 "LSDC_ENA_NOT_POSSIBLE" 0 "NONE" ;
|
||||
VAL_TABLE_ HMI_Fct_Req 8 "FCT_DEACTVN_REQ" 7 "FCT_ACTVN_OTA_REQ" 6 "FCT_ACTVN_SAVETHESPOILER_CFMD" 5 "FCT_ACTVN_SAVETHESPOILER_REQ" 4 "FCT_ACTVN_LSDC_CFMD" 3 "FCT_ACTVN_LSDC_REQ" 2 "FCT_ACTVN_AI4MTN_CFMD" 1 "FCT_ACTVN_AI4MTN_REQ" 0 "FCT_ACTVN_NONE" ;
|
||||
VAL_TABLE_ SOVD_states 2 "SOVD_SHOWCASE_ACTIVE" 1 "SOVD_SHOWCASE_DEACTIVE" 0 "SOVD_NONE" ;
|
||||
VAL_TABLE_ OTA_states 7 "OTA_DOWNLOAD_FAILED" 6 "OTA_INSTALL_FAILED" 5 "OTA_INSTALL_FINISHED" 4 "OTA_INSTALL_START" 3 "OTA_DOWNLOAD_START" 2 "OTA_SCHEDULED" 1 "OTA_STANDBY" 0 "OTA_NONE" ;
|
||||
|
||||
|
||||
BO_ 0 CAN_Input: 8 Vector__XXX
|
||||
SG_ Current_Longitude : 39|32@0- (1E-007,0) [-180|180] "deg" headlight
|
||||
SG_ Current_Latitude : 7|32@0- (1E-007,0) [-90|90] "deg" headlight
|
||||
|
||||
BO_ 3 CAN_Output: 1 headlight
|
||||
SG_ HeadLight_LowBeam : 7|8@0- (1,0) [0|1] "" Vector__XXX
|
||||
|
||||
|
||||
|
||||
BA_DEF_ "Baudrate" INT 1000 1000000;
|
||||
BA_DEF_ "BusType" STRING ;
|
||||
BA_DEF_ "DBName" STRING ;
|
||||
BA_DEF_ "ProtocolType" STRING ;
|
||||
BA_DEF_ BU_ "NmAsrNode" ENUM "No","Yes";
|
||||
BA_DEF_ BU_ "NmAsrNodeIdentifier" INT 0 255;
|
||||
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 65536;
|
||||
BA_DEF_ BO_ "GenMsgCycleTimeFast" FLOAT 0 300000;
|
||||
BA_DEF_ BO_ "GenMsgDelayTime" INT 0 65536;
|
||||
BA_DEF_ BO_ "GenMsgNrOfRepetition" INT 0 100000;
|
||||
BA_DEF_ BO_ "GenMsgSendType" ENUM "cyclic","spontaneous","not-used","not-used","not-used","cyclicAndSpontaneous","not-used","cyclicIfActive","NoMsgSendType";
|
||||
BA_DEF_ BO_ "GenMsgStartDelayTime" INT 0 65536;
|
||||
BA_DEF_ SG_ "GenSigSendType" ENUM "Cyclic","OnWrite","OnWriteWithRepetition","OnChange","OnChangeWithRepetition","IfActive","IfActiveWithRepetition","NoSigSendType";
|
||||
BA_DEF_ SG_ "GenSigStartValue" HEX 0 80000000;
|
||||
BA_DEF_ BO_ "GenMsgILSupport" ENUM "No","Yes";
|
||||
BA_DEF_ BO_ "NmAsrMessage" ENUM "No","Yes";
|
||||
BA_DEF_ "NmAsrBaseAddress" HEX 0 536870911;
|
||||
BA_DEF_ "NmAsrMessageCount" INT 0 255;
|
||||
BA_DEF_ BU_ "NodeLayerModules" STRING ;
|
||||
BA_DEF_ BU_ "ILused" ENUM "No","Yes";
|
||||
BA_DEF_ SG_ "GenSigFuncType" ENUM "NoFunction","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","CHK","CNTR","n/a","n/a","n/a","CNTR_AR_01","CRC_AR_01_BOTH","CRC_AR_01_ALT","CRC_AR_01_LOW","CRC_AR_01_NIBBLE","CNTR_AR_04","CRC_AR_04A","CNTR_AR_05","CRC_AR_05";
|
||||
BA_DEF_ SG_ "GenSigDataID" STRING ;
|
||||
BA_DEF_ SG_ "SigGroup" STRING ;
|
||||
BA_DEF_DEF_ "Baudrate" 1000;
|
||||
BA_DEF_DEF_ "BusType" "";
|
||||
BA_DEF_DEF_ "DBName" "";
|
||||
BA_DEF_DEF_ "ProtocolType" "";
|
||||
BA_DEF_DEF_ "NmAsrNode" "No";
|
||||
BA_DEF_DEF_ "NmAsrNodeIdentifier" 0;
|
||||
BA_DEF_DEF_ "GenMsgCycleTime" 0;
|
||||
BA_DEF_DEF_ "GenMsgCycleTimeFast" 0;
|
||||
BA_DEF_DEF_ "GenMsgDelayTime" 0;
|
||||
BA_DEF_DEF_ "GenMsgNrOfRepetition" 0;
|
||||
BA_DEF_DEF_ "GenMsgSendType" "NoMsgSendType";
|
||||
BA_DEF_DEF_ "GenMsgStartDelayTime" 0;
|
||||
BA_DEF_DEF_ "GenSigSendType" "NoSigSendType";
|
||||
BA_DEF_DEF_ "GenSigStartValue" 0;
|
||||
BA_DEF_DEF_ "GenMsgILSupport" "Yes";
|
||||
BA_DEF_DEF_ "NmAsrMessage" "No";
|
||||
BA_DEF_DEF_ "NmAsrBaseAddress" 1280;
|
||||
BA_DEF_DEF_ "NmAsrMessageCount" 64;
|
||||
BA_DEF_DEF_ "NodeLayerModules" "CANoeILNLSPA.dll";
|
||||
BA_DEF_DEF_ "ILused" "Yes";
|
||||
BA_DEF_DEF_ "GenSigFuncType" "NoFunction";
|
||||
BA_DEF_DEF_ "GenSigDataID" "";
|
||||
BA_DEF_DEF_ "SigGroup" "";
|
||||
BA_ "ProtocolType" "CAN";
|
||||
BA_ "BusType" "CAN";
|
||||
BA_ "Baudrate" 500000;
|
||||
BA_ "DBName" "PrivateCAN";
|
||||
BA_ "GenMsgSendType" BO_ 0 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 0 10;
|
||||
BA_ "GenMsgSendType" BO_ 3 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 3 10;
|
||||
BA_ "GenSigStartValue" SG_ 0 Current_Latitude 0;
|
||||
|
||||
291
examples/auto_headlamp_example/fmu_files/model.cpp
Normal file
291
examples/auto_headlamp_example/fmu_files/model.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/**
|
||||
* @file model.cpp
|
||||
* @date 2025-09-12 15:01:57
|
||||
* This file defines the data link object between CAN and the V-API devices.
|
||||
* This file was generated by the DBC utility from:
|
||||
* datalink_autoheadlight_example.dbc
|
||||
* DBC file version: 1.0.0.1
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <support/timer.h>
|
||||
#include "signal_identifier.h"
|
||||
#include <support/signal_support.h>
|
||||
#include <support/app_control.h>
|
||||
|
||||
sdv::core::CSignal g_signalCurrent_Longitude;
|
||||
sdv::core::CSignal g_signalCurrent_Latitude;
|
||||
sdv::core::CSignal g_signalHeadLight_LowBeam;
|
||||
|
||||
// in case the simulation timer should be used
|
||||
sdv::core::ITimerSimulationStep* g_pTimerSimulationStep;
|
||||
|
||||
std::unique_ptr<sdv::app::CAppControl> g_appcontrol;
|
||||
|
||||
bool InitializeAppControl(const std::string& resource, const std::string& configFileName)
|
||||
{
|
||||
auto bResult = g_appcontrol->AddModuleSearchDir( resource );
|
||||
bResult &= g_appcontrol->Startup("");
|
||||
g_appcontrol->SetConfigMode();
|
||||
bResult &= g_appcontrol->AddConfigSearchDir( resource );
|
||||
|
||||
if (!configFileName.empty())
|
||||
{
|
||||
bResult &= g_appcontrol->LoadConfig(configFileName.c_str()) == sdv::core::EConfigProcessResult::successful;
|
||||
}
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
sdv::core::EConfigProcessResult RegisterAllSignals()
|
||||
{
|
||||
std::string msg = "register all signals: ";
|
||||
sdv::core::CDispatchService dispatch;
|
||||
|
||||
g_signalCurrent_Longitude = dispatch.RegisterRxSignal("CAN_Input.Current_Longitude");
|
||||
g_signalCurrent_Latitude = dispatch.RegisterRxSignal("CAN_Input.Current_Latitude");
|
||||
g_signalHeadLight_LowBeam = dispatch.RegisterTxSignal("CAN_Output.HeadLight_LowBeam",0);
|
||||
|
||||
if (g_signalCurrent_Longitude && g_signalCurrent_Latitude && g_signalHeadLight_LowBeam)
|
||||
{
|
||||
return sdv::core::EConfigProcessResult::successful;
|
||||
}
|
||||
|
||||
return sdv::core::EConfigProcessResult::failed;
|
||||
}
|
||||
|
||||
bool ResetAllSignals()
|
||||
{
|
||||
sdv::core::CDispatchService dispatch;
|
||||
|
||||
if (g_signalCurrent_Longitude)
|
||||
{
|
||||
g_signalCurrent_Longitude.Reset();
|
||||
}
|
||||
if (g_signalCurrent_Latitude)
|
||||
{
|
||||
g_signalCurrent_Latitude.Reset();
|
||||
}
|
||||
if (g_signalHeadLight_LowBeam)
|
||||
{
|
||||
g_signalHeadLight_LowBeam.Reset();
|
||||
}
|
||||
|
||||
SDV_LOG_INFO("Reset signals");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CreateCoreServiceTomlFile(const std::string& resources)
|
||||
{
|
||||
std::ofstream tomlFile("sdv_core_reloc.toml");
|
||||
if (tomlFile.is_open())
|
||||
{
|
||||
tomlFile << "# Location of the SDV binaries and configuration files\ndirectory = \"";
|
||||
tomlFile << resources;
|
||||
tomlFile << "\"\n";
|
||||
tomlFile.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool OpenAPILoad(const std::string& resources)
|
||||
{
|
||||
bool success = CreateCoreServiceTomlFile(resources);
|
||||
g_appcontrol = std::make_unique<sdv::app::CAppControl> ();
|
||||
|
||||
//
|
||||
// TODO: Dispatch service must be loaded first, adjust the correct toml file
|
||||
//
|
||||
success &= InitializeAppControl(resources, "data_dispatch_config_file.toml");
|
||||
if (!success)
|
||||
{
|
||||
std::cout << "Error: InitializeAppControl() failed" << std::endl;
|
||||
SDV_LOG_ERROR("Failed InitializeAppControl");
|
||||
return false;
|
||||
}
|
||||
success &= RegisterAllSignals() == sdv::core::EConfigProcessResult::successful;
|
||||
if (!success)
|
||||
{
|
||||
SDV_LOG_ERROR("Signals could not be registered");
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// TODO: Load all configurations files
|
||||
//
|
||||
//
|
||||
// Get the simulation task timer service if the simulation timer should be used
|
||||
success &= g_appcontrol->LoadConfig("simulation_task_timer_config_file.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
g_pTimerSimulationStep = sdv::core::GetObject<sdv::core::ITimerSimulationStep>("SimulationTaskTimerService");
|
||||
if (!g_pTimerSimulationStep)
|
||||
{
|
||||
SDV_LOG_WARNING("Simulation timer step not available, use normal task timer ");
|
||||
success &= g_appcontrol->LoadConfig("task_timer_config_file.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
}
|
||||
|
||||
success &= g_appcontrol->LoadConfig("fmu_autoheadlight_vd_bs.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
success &= g_appcontrol->LoadConfig("fmu_autoheadlight_cs.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
|
||||
g_appcontrol->SetRunningMode();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void OpenAPIShutdown()
|
||||
{
|
||||
ResetAllSignals();
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <float.h> // for DBL_EPSILON
|
||||
#include <math.h> // for fabs()
|
||||
#include "config.h"
|
||||
#include "model.h"
|
||||
|
||||
Status cleanup(ModelInstance*)
|
||||
{
|
||||
SDV_LOG_INFO("Shutting down...");
|
||||
OpenAPIShutdown();
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
bool setStartValues(ModelInstance* comp)
|
||||
{
|
||||
std::string path(comp->resourceLocation);
|
||||
std::string resourcePath = path.substr(8);
|
||||
std::replace(resourcePath.begin(), resourcePath.end(), '\\', '/');
|
||||
if (!OpenAPILoad(resourcePath))
|
||||
{
|
||||
std::cout << "Error: OpenAPILoad() failed." << std::endl;
|
||||
comp->terminateSimulation = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: move this to initialize()?
|
||||
comp->nextEventTime = 0;
|
||||
comp->nextEventTimeDefined = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
Status calculateValues(ModelInstance* comp)
|
||||
{
|
||||
UNUSED(comp);
|
||||
// nothing to do
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status getFloat64(ModelInstance* comp, [[maybe_unused]] ValueReference vr, [[maybe_unused]] double values[], [[maybe_unused]] size_t nValues, [[maybe_unused]] size_t* index)
|
||||
{
|
||||
ASSERT_NVALUES(1);
|
||||
|
||||
switch (vr)
|
||||
{
|
||||
case vr_Current_Longitude:
|
||||
values[(*index)++] = M(Current_Longitude);
|
||||
break;
|
||||
case vr_Current_Latitude:
|
||||
values[(*index)++] = M(Current_Latitude);
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(comp, "Get Float64 is not allowed for value reference u.", vr);
|
||||
return Error;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status getInt32(ModelInstance* comp, [[maybe_unused]] ValueReference vr, [[maybe_unused]] int32_t values[], [[maybe_unused]] size_t nValues, [[maybe_unused]] size_t* index)
|
||||
{
|
||||
ASSERT_NVALUES(1);
|
||||
|
||||
switch (vr)
|
||||
{
|
||||
case vr_HeadLight_LowBeam:
|
||||
values[(*index)++] = M(HeadLight_LowBeam);
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(comp, "Get Int32 is not allowed for value reference u.", vr);
|
||||
return Error;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status setFloat64(ModelInstance* comp, [[maybe_unused]] ValueReference vr, [[maybe_unused]] const double values[], [[maybe_unused]] size_t nValues, [[maybe_unused]] size_t* index)
|
||||
{
|
||||
ASSERT_NVALUES(1);
|
||||
|
||||
switch (vr)
|
||||
{
|
||||
case vr_Current_Longitude:
|
||||
M(Current_Longitude) = values[(*index)++];
|
||||
break;
|
||||
case vr_Current_Latitude:
|
||||
M(Current_Latitude) = values[(*index)++];
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(comp, "Set Float64 is not allowed for value reference u.", vr);
|
||||
return Error;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Status setInt32(ModelInstance* comp, [[maybe_unused]] ValueReference vr, [[maybe_unused]] const int32_t values[], [[maybe_unused]] size_t nValues, [[maybe_unused]] size_t* index)
|
||||
{
|
||||
ASSERT_NVALUES(1);
|
||||
|
||||
switch (vr)
|
||||
{
|
||||
case vr_HeadLight_LowBeam:
|
||||
M(HeadLight_LowBeam) = values[(*index)++];
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(comp, "Set Int32 is not allowed for value reference u.", vr);
|
||||
return Error;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void eventUpdate(ModelInstance* comp)
|
||||
{
|
||||
|
||||
if (g_pTimerSimulationStep) // in case the simulation timer was used, maybe the step size has to be adjusted
|
||||
{
|
||||
g_pTimerSimulationStep->SimulationStep(1000);
|
||||
}
|
||||
|
||||
g_signalCurrent_Longitude.Write( M(Current_Longitude));
|
||||
g_signalCurrent_Latitude.Write( M(Current_Latitude));
|
||||
M(HeadLight_LowBeam) = g_signalHeadLight_LowBeam.Read().get<uint32_t>();
|
||||
|
||||
double epsilon = (1.0 + fabs(comp->time)) * DBL_EPSILON;
|
||||
|
||||
if (comp->nextEventTimeDefined && comp->time + epsilon >= comp->nextEventTime) {
|
||||
comp->nextEventTime += FIXED_SOLVER_STEP;
|
||||
}
|
||||
|
||||
comp->valuesOfContinuousStatesChanged = false;
|
||||
comp->nominalsOfContinuousStatesChanged = false;
|
||||
comp->terminateSimulation = false;
|
||||
comp->nextEventTimeDefined = true;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "autoheadlight_service.sdv"
|
||||
Class = "Auto Headlight Service"
|
||||
tunnel_start_lat = 31.300
|
||||
tunnel_start_lon = 3.756
|
||||
tunnel_end_lat = 21.168
|
||||
tunnel_end_lon = 26.534
|
||||
@@ -0,0 +1,29 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_vd_currentlatitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLatitude_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_vd_currentlongitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLongitude_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_vd_headlightlowbeam_tx.sdv"
|
||||
Class = "Vehicle.Body.Light.Front.LowBeam_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_bs_currentlatitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLatitude_Service"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_bs_currentlongitude_rx.sdv"
|
||||
Class = "Vehicle.Position.CurrentLongitude_Service"
|
||||
|
||||
[[Component]]
|
||||
Path = "headlight_bs_headlightlowbeam_tx.sdv"
|
||||
Class = "Vehicle.Body.Light.Front.LowBeam_Service"
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
IF (get_process_state (..\CarlaBridge\carlabridge_coupecar.fmu) == 0)
|
||||
MESSAGE (Starting Carla Bridge fmu with 2 door scenario)
|
||||
START_PROCESS (..\CarlaBridge\carlabridge_coupecar.fmu)
|
||||
ENDIF
|
||||
|
||||
IF (get_process_state (carlabridge_coupecar.fmu) != 0)
|
||||
MESSAGE(2 door fmu started!)
|
||||
SET_BBVARI(CARLAin__toggle_view = 1)
|
||||
SET_BBVARI(CARLAin__operation_mode = 4)
|
||||
SET_BBVARI(CARLAin__toggle_display = 1)
|
||||
ENDIF
|
||||
|
||||
IF (get_process_state (..\vapifmus\Doors2ExampleFMU.fmu) == 0)
|
||||
MESSAGE (Starting VAPI 2 door Example fmu)
|
||||
START_PROCESS (..\vapifmus\Doors2ExampleFMU.fmu)
|
||||
ENDIF
|
||||
|
||||
START_EQUATION(1,vapiexamplestriggerfile.tri,Before,Doors2ExampleFMU.fmu)
|
||||
|
||||
IF (get_process_state (Doors2ExampleFMU.fmu) != 0)
|
||||
MESSAGE(2 door fmu started!)
|
||||
ENDIF
|
||||
@@ -0,0 +1,22 @@
|
||||
IF (get_process_state (..\CarlaBridge\carlabridge_patrolcar.fmu) == 0)
|
||||
MESSAGE (Starting Carla Bridge fmu with 4 door scenario)
|
||||
START_PROCESS (..\CarlaBridge\carlabridge_patrolcar.fmu)
|
||||
ENDIF
|
||||
|
||||
IF (get_process_state (carlabridge_patrolcar.fmu) != 0)
|
||||
MESSAGE(4 door fmu started!)
|
||||
SET_BBVARI(CARLAin__toggle_view = 1)
|
||||
SET_BBVARI(CARLAin__operation_mode = 4)
|
||||
SET_BBVARI(CARLAin__toggle_display = 1)
|
||||
ENDIF
|
||||
|
||||
IF (get_process_state (..\vapifmus\Doors4ExampleFMU.fmu) == 0)
|
||||
MESSAGE (Starting VAPI 4 door Example fmu)
|
||||
START_PROCESS (..\vapifmus\Doors4ExampleFMU.fmu)
|
||||
ENDIF
|
||||
|
||||
START_EQUATION(1,vapiexamplestriggerfile.tri,Before,Doors4ExampleFMU.fmu)
|
||||
|
||||
IF (get_process_state (Doors4ExampleFMU.fmu) != 0)
|
||||
MESSAGE(2 door fmu started!)
|
||||
ENDIF
|
||||
@@ -0,0 +1,7 @@
|
||||
Current_Latitude = CARLAout__act_pos_x;
|
||||
Current_Longitude = CARLAout__act_pos_y;
|
||||
CARLAin__Headlight_Lowbeam = HeadLight_LowBeam;
|
||||
CARLAin__DooropenStatus_FL = Door01LeftIsOpen;
|
||||
CARLAin__DooropenStatus_FR = Door01RightIsOpen;
|
||||
CARLAin__DooropenStatus_RL = Door02LeftIsOpen;
|
||||
CARLAin__DooropenStatus_RR = Door02RightIsOpen;
|
||||
@@ -0,0 +1,22 @@
|
||||
IF (get_process_state (..\CarlaBridge\carlabridge_coupecar.fmu) == 0)
|
||||
MESSAGE (Starting Carla Bridge fmu)
|
||||
START_PROCESS (..\CarlaBridge\carlabridge_coupecar.fmu)
|
||||
ENDIF
|
||||
|
||||
IF (get_process_state (carlabridge_coupecar.fmu) != 0)
|
||||
MESSAGE(Auto Headlight fmu started!)
|
||||
SET_BBVARI(CARLAin__toggle_view = 1)
|
||||
SET_BBVARI(CARLAin__operation_mode = 4)
|
||||
SET_BBVARI(CARLAin__toggle_display = 1)
|
||||
ENDIF
|
||||
|
||||
IF (get_process_state (..\vapifmus\AutoHeadlightFMU.fmu) == 0)
|
||||
MESSAGE (Starting VAPI Headlight Example fmu)
|
||||
START_PROCESS (..\vapifmus\AutoHeadlightFMU.fmu)
|
||||
ENDIF
|
||||
|
||||
START_EQUATION(1,vapiexamplestriggerfile.tri,Before,AutoHeadlightFMU.fmu)
|
||||
|
||||
IF (get_process_state (AutoHeadlightFMU.fmu) != 0)
|
||||
MESSAGE(Auto Headlight fmu started!)
|
||||
ENDIF
|
||||
@@ -0,0 +1,8 @@
|
||||
;Class name;Function name;Signal name;vss;Signal direction;type;DBC CAN name includes CAN message name
|
||||
;;;;;;;
|
||||
VD;CurrentLatitude;CurrentLatitude;fCurrentLatitude;Vehicle.Position.CurrentLatitude;RX;float;CAN_Input.Current_Latitude
|
||||
VD;CurrentLongitude;CurrentLongitude;fCurrentLongitude;Vehicle.Position.CurrentLongitude;RX;float;CAN_Input.Current_Longitude
|
||||
VD;HeadLightLowBeam;HeadLightLowBeam;bHeadLightLowBeam;Vehicle.Body.Light.Front.LowBeam;TX;boolean;CAN_Output.HeadLight_LowBeam
|
||||
BS;CurrentLatitude;CurrentLatitude;fCurrentLatitude;Vehicle.Position.CurrentLatitude;RX;float;Vehicle.Position.CurrentLatitude
|
||||
BS;CurrentLongitude;CurrentLongitude;fCurrentLongitude;Vehicle.Position.CurrentLongitude;RX;float;Vehicle.Position.CurrentLongitude
|
||||
BS;HeadLightLowBeam;HeadLightLowBeam;bHeadLightLowBeam;Vehicle.Body.Light.Front.LowBeam;TX;boolean;Vehicle.Body.Light.Front.LowBeam
|
||||
|
Reference in New Issue
Block a user