diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..69b782e --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,30 @@ + +# Project Roadmap + +The project is currently under active development and does not yet have a planned release date. +The roadmap is organized around development milestones rather than a fixed timeline. + +## Current Status + +The Open Vehicle API is already being used in several projects, and feedback from these projects is continuously incorporated into the development process. + +### Existing Functionality + +Examples are available demonstrating different deployment scenarios: + +- Running as a standalone application. +- Running a core instance with one or more attached applications. + +## Milestone 1: Support for Separate ASIL B and QM Instances + +This milestone introduces the ability to run vehicle functions in separate ASIL B and QM contexts, enabling the deployment of safety-related and non-safety-related functionality in independent instances. + +## Milestone 2: Project Restructuring + +The project currently relies on several build-time configuration options and requires developers to build the entire codebase, even when working on a specific application. + +To reduce complexity and improve usability, the project will be restructured into three separate components. Application developers should be able to develop and build their applications without needing to build the core framework itself. + +## Goal: First Release + +Once Milestone 1 and Milestone 2 are completed, the project will be prepared for its first public release. \ No newline at end of file diff --git a/examples/open_trunk_example/open_trunk_app/console.cpp b/examples/open_trunk_example/open_trunk_app/console.cpp index 612318b..790d9db 100644 --- a/examples/open_trunk_example/open_trunk_app/console.cpp +++ b/examples/open_trunk_example/open_trunk_app/console.cpp @@ -84,18 +84,22 @@ CConsole::~CConsole() #endif } -void CConsole::PrintHeader(uint32_t uiInstance) +void CConsole::PrintHeader(bool bSimulate, uint32_t uiInstance) { // Clear the screen... std::cout << "\x1b[2J"; std::string subTtitle = "Standalone application!"; - if (uiInstance != 0) + if (uiInstance > 1) { subTtitle = "Connected to core instance "; subTtitle.append(std::to_string(uiInstance)); subTtitle.append(" (not all interfaces available)"); } + else if (bSimulate) + { + subTtitle.append(" simulation mode"); + } // Print the titles PrintText(g_sTitle, "Open Trunk example: Open trunk when vehicle is not moving"); PrintText(g_sSubTitle, subTtitle); diff --git a/examples/open_trunk_example/open_trunk_app/console.h b/examples/open_trunk_example/open_trunk_app/console.h index 0ce6338..258dc0e 100644 --- a/examples/open_trunk_example/open_trunk_app/console.h +++ b/examples/open_trunk_example/open_trunk_app/console.h @@ -64,9 +64,11 @@ public: /** * @brief Print the header. + * @param[in] bSimulate used in case it is running as a standalone application + * if false an asc file is used for setting the input speed, otherwise a simulation thread * @param[in] uiInstance Instance number the application will connect to. 0 will start a standalone application */ - void PrintHeader(uint32_t uiInstance); + void PrintHeader(bool bSimulate, uint32_t uiInstance); /** * @brief Prepare the data consumers.. diff --git a/examples/open_trunk_example/open_trunk_app/trunk_application.cpp b/examples/open_trunk_example/open_trunk_app/trunk_application.cpp index abf946a..22bef69 100644 --- a/examples/open_trunk_example/open_trunk_app/trunk_application.cpp +++ b/examples/open_trunk_example/open_trunk_app/trunk_application.cpp @@ -43,7 +43,7 @@ bool CTrunkControl::IsSDVFrameworkEnvironmentSet() return false; } -bool CTrunkControl::Initialize(uint32_t uiInstance) +bool CTrunkControl::Initialize(bool bSimulate, uint32_t uiInstance) { if (m_bInitialized) return true; @@ -54,7 +54,7 @@ bool CTrunkControl::Initialize(uint32_t uiInstance) m_appcontrol.SetFrameworkRuntimeDirectory("../../bin"); } - if (uiInstance != 0) + if (uiInstance != 0 && !bSimulate) { std::stringstream sstreamAppConfig; sstreamAppConfig << "[Application]" << std::endl; @@ -76,8 +76,17 @@ bool CTrunkControl::Initialize(uint32_t uiInstance) bool bResult = LoadConfigFile("Load dispatch service: ", "data_dispatch_trunk.toml"); bResult &= LoadConfigFile("Load task_timer_trunk: ", "task_timer_trunk.toml"); - bResult &= LoadConfigFile("Load can_com_simulation_trunk: ", "can_com_simulation_trunk.toml"); - bResult &= LoadConfigFile("Load data_link_trunk: ", "data_link_trunk.toml"); + if (bSimulate) + { + sdv::core::CDispatchService dispatch; + m_signalSpeed = dispatch.RegisterRxSignal("CAN_Input.Speed"); + m_signalTrunk = dispatch.RegisterTxSignal("CAN_Output.OpenTrunk", 0); + } + else + { + bResult &= LoadConfigFile("Load can_com_simulation_trunk: ", "can_com_simulation_trunk.toml"); + bResult &= LoadConfigFile("Load data_link_trunk: ", "data_link_trunk.toml"); + } bResult &= LoadConfigFile("Load trunk_vehicle_device_and_basic_service: ", "trunk_vehicle_device_and_basic_service.toml"); //bResult &= LoadConfigFile("Load trunk service (complex service): ", "complex_service_trunk.toml"); @@ -96,6 +105,19 @@ bool CTrunkControl::Initialize(uint32_t uiInstance) void CTrunkControl::Shutdown() { + m_bSimulateRunning = false; + if (m_threadSimulate.joinable()) + m_threadSimulate.join(); + + if (m_signalSpeed) + { + m_signalSpeed.Reset(); + }; + if (m_signalTrunk) + { + m_signalTrunk.Reset(); + }; + if (!m_bInitialized) m_appcontrol.Shutdown(); m_bInitialized = false; @@ -105,4 +127,35 @@ void CTrunkControl::SetRunningMode() { m_appcontrol.SetRunningMode(); } +void CTrunkControl::StartSimulation() +{ + m_bSimulateRunning = true; + m_threadSimulate = sdv::core::secure_thread(&CTrunkControl::SimulateThreadFunction, this); +} + +void CTrunkControl::SimulateThreadFunction() +{ + bool bIsMoving = true; + uint32_t maxLoopCount = 20; + m_signalSpeed.Write(0); + + while (m_bSimulateRunning) + { + uint32_t loop = 0; + uint32_t speed = 0; + while (loop < maxLoopCount && m_bSimulateRunning) + { + if (bIsMoving) + { + speed = loop * 5; + } + + m_signalSpeed.Write(speed); + loop++; + std::this_thread::sleep_for(std::chrono::milliseconds(300)); + } + + bIsMoving = !bIsMoving; + } +} diff --git a/examples/open_trunk_example/open_trunk_app/trunk_application.h b/examples/open_trunk_example/open_trunk_app/trunk_application.h index 66fef65..082b24b 100644 --- a/examples/open_trunk_example/open_trunk_app/trunk_application.h +++ b/examples/open_trunk_example/open_trunk_app/trunk_application.h @@ -22,10 +22,12 @@ public: /** * @brief Start and initialize the application control and load vehicle devices and basic services + * @param[in] bSimulate used in case it is running as a standalone application + * if false an asc file is used for setting the input speed, otherwise a simulation thread * @param[in] uiInstance Instance number the application will connect to. 0 will start a standalone application * @return Return true on success otherwise false */ - bool Initialize(uint32_t uiInstance); + bool Initialize(bool bSimulate, uint32_t uiInstance); /** * @brief After initialization/configuration the system mode needs to be set to running mode @@ -37,6 +39,11 @@ public: */ void Shutdown(); + /** + * @brief Starts a thread to set the speed value. + */ + void StartSimulation(); + private: /** @@ -45,6 +52,11 @@ private: */ bool IsSDVFrameworkEnvironmentSet(); + /** + * @brief Provide simulated signals until m_bRunning is disabled. + */ + void SimulateThreadFunction(); + /** * @brief Load config file and register vehicle device and basic service. * @param[in] inputMsg message string to be printed on console in case of success and failure @@ -53,6 +65,11 @@ private: */ bool LoadConfigFile(const std::string& inputMsg, const std::string& configFileName); - sdv::app::CAppControl m_appcontrol; ///< App-control of SDV V-API. - bool m_bInitialized = false; ///< Set when initialized. + sdv::app::CAppControl m_appcontrol; ///< App-control of Eclipse Open Vehicle-API. + bool m_bInitialized = false; ///< Set when initialized. + + sdv::core::CSignal m_signalSpeed; ///< Vehicle speed signal (input) - simulated datalink + sdv::core::CSignal m_signalTrunk; ///< Trunk signal (output) - simulated datalink + std::atomic_bool m_bSimulateRunning = false; ///< When set, the simulation thread is running. + sdv::core::secure_thread m_threadSimulate; ///< Simulation datalink thread. }; diff --git a/examples/open_trunk_example/open_trunk_app/trunk_example.cpp b/examples/open_trunk_example/open_trunk_app/trunk_example.cpp index c55f6e6..17dffb1 100644 --- a/examples/open_trunk_example/open_trunk_app/trunk_example.cpp +++ b/examples/open_trunk_example/open_trunk_app/trunk_example.cpp @@ -16,15 +16,20 @@ #if defined(_WIN32) && defined(_UNICODE) extern "C" int wmain(int argc, wchar_t* argv[]) { + bool bSimulate = false; uint32_t uiInstance = 0; if (argc < 2) { - std::cout << "Missing instance number to connect to, '0' will run as standalone application" << std::endl; + std::cout << "Parameter (instance number to connect to) missing. 0 or 1 will run a standalone application." << std::endl; return 1; } try { uiInstance = std::stoi(argv[1]); + if (uiInstance == 1) + { + bSimulate = true; + } } catch (const std::exception& ) { @@ -34,15 +39,20 @@ extern "C" int wmain(int argc, wchar_t* argv[]) #else extern "C" int main(int argc, char* argv[]) { + bool bSimulate = false; uint32_t uiInstance = 0; if (argc < 2) { - std::cout << "Missing instance number to connect to, '0' will run as standalone application" << std::endl; + std::cout << "Parameter (instance number to connect to) missing. 0 or 1 will run a standalone application." << std::endl; return 1; } try { uiInstance = std::stoi(argv[1]); + if (uiInstance == 1) + { + bSimulate = true; + } } catch (const std::exception& ) { @@ -50,20 +60,27 @@ extern "C" int main(int argc, char* argv[]) } #endif CTrunkControl appobj; - if (!appobj.Initialize(uiInstance)) + if (!appobj.Initialize(bSimulate, uiInstance)) { std::cout << "ERROR: Failed to initialize application control." << std::endl; return 0; } CConsole visual_obj; - visual_obj.PrintHeader(uiInstance); + visual_obj.PrintHeader(bSimulate, uiInstance); visual_obj.PrepareDataConsumers(); appobj.SetRunningMode(); - visual_obj.RunUntilBreak(); - - visual_obj.ResetSignals(); + if (bSimulate) + { + appobj.StartSimulation(); + visual_obj.RunUntilBreak(); + } + else + { + visual_obj.RunUntilBreak(); + visual_obj.ResetSignals(); + } appobj.Shutdown(); return 0;