mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-02-05 15:18:45 +00:00
215
examples/door_demo_example/CMakeLists.txt
Normal file
215
examples/door_demo_example/CMakeLists.txt
Normal file
@@ -0,0 +1,215 @@
|
||||
project(DoorDemoExample)
|
||||
|
||||
# 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)
|
||||
|
||||
# Libary symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Include directory to the core framework
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
|
||||
# Copy the config files
|
||||
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/front_left_door_example.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/front_right_door_example.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/rear_left_door_example.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/rear_right_door_example.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/door_comple_service.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/config/data_link_door.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
|
||||
|
||||
# Copy the ASC files used by can_com_sim.sdv which includes the CAN messages
|
||||
# Required in both locations when running standalone or as instance
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/door_example_receiver.asc DESTINATION ${CMAKE_BINARY_DIR}/bin)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/door_example_receiver.asc DESTINATION ${CMAKE_BINARY_DIR}../../bin)
|
||||
|
||||
|
||||
######################################################################################################################################################################
|
||||
# preparation
|
||||
######################################################################################################################################################################
|
||||
|
||||
message("Compiling Interface Door01Left RX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01left_vd_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01left_bs_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
message("Compiling Interface Door01Right RX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01right_vd_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01right_bs_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
message("Compiling Interface Door02Left RX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02left_vd_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02left_bs_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
message("Compiling Interface Door02Right RX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02right_vd_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02right_bs_rx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
|
||||
message("Compiling Interface Door01Left TX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01left_vd_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01left_bs_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
message("Compiling Interface Door01Right TX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01right_vd_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle01right_bs_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
message("Compiling Interface Door02Left TX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02left_vd_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02left_bs_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
message("Compiling Interface Door02Right TX")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02right_vd_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --no_ps)
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/interfaces/vss_vehiclechassisdooraxle02right_bs_tx.idl" "-O${PROJECT_SOURCE_DIR}/interfaces/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Igenerated/vss_files/ --ps_lib_namedoors_proxystub)
|
||||
|
||||
# Execute the IDL compiler for the complex service to digest interface code.
|
||||
message("Compiling door_ifc.idl")
|
||||
execute_process(COMMAND "${SDV_IDL_COMPILER}" "${PROJECT_SOURCE_DIR}/door_service/door_ifc.idl" "-O${PROJECT_SOURCE_DIR}/generated/door_service/" "-I${SDV_FRAMEWORK_DEV_INCLUDE}" -Iexample_service/ --ps_lib_namedoors_service_proxystub)
|
||||
|
||||
add_subdirectory(interfaces/ps)
|
||||
|
||||
add_subdirectory(vd/vd_front_door_left)
|
||||
add_subdirectory(vd/vd_front_door_right)
|
||||
add_subdirectory(vd/vd_rear_door_left)
|
||||
add_subdirectory(vd/vd_rear_door_right)
|
||||
|
||||
add_subdirectory(bs/bs_front_door_left)
|
||||
add_subdirectory(bs/bs_front_door_right)
|
||||
add_subdirectory(bs/bs_rear_door_left)
|
||||
add_subdirectory(bs/bs_rear_door_right)
|
||||
|
||||
add_subdirectory(can_dl_door)
|
||||
|
||||
|
||||
######################################################################################################################################################################
|
||||
# complex service
|
||||
######################################################################################################################################################################
|
||||
|
||||
include_directories(interfaces)
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/door_app/include)
|
||||
|
||||
message("Include: proxy/stub for complex doors service")
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/generated/door_service)
|
||||
add_subdirectory(generated/door_service/ps)
|
||||
|
||||
add_library(door_complex_service SHARED
|
||||
door_service/complex_service.h
|
||||
door_service/complex_service.cpp
|
||||
door_service/lock_doors_thread.h)
|
||||
|
||||
set_target_properties(door_complex_service PROPERTIES OUTPUT_NAME "door_complex_service")
|
||||
set_target_properties(door_complex_service PROPERTIES PREFIX "")
|
||||
set_target_properties(door_complex_service PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
######################################################################################################################################################################
|
||||
# executable
|
||||
######################################################################################################################################################################
|
||||
|
||||
add_executable(door_demo_example
|
||||
"door_app/door_demo_example.cpp"
|
||||
"door_app/include/door_application.h"
|
||||
"door_app/door_application.cpp"
|
||||
"door_app/include/console.h"
|
||||
"door_app/console.cpp"
|
||||
"door_app/include/signal_names.h"
|
||||
"door_service/lock_doors_thread.h")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if (WIN32)
|
||||
target_link_libraries(door_demo_example Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(door_demo_example ${CMAKE_DL_LIBS} rt ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(door_demo_example Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
######################################################################################################################################################################
|
||||
# external application
|
||||
######################################################################################################################################################################
|
||||
|
||||
|
||||
add_executable(door_external_app
|
||||
"door_app/door_extern_example.cpp"
|
||||
"door_app/include/door_extern_application.h"
|
||||
"door_app/door_extern_application.cpp"
|
||||
"door_app/include/console.h"
|
||||
"door_app/console.cpp"
|
||||
"door_app/include/signal_names.h"
|
||||
"door_service/lock_doors_thread.h")
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if (WIN32)
|
||||
target_link_libraries(door_external_app Ws2_32 Winmm Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(door_external_app ${CMAKE_DL_LIBS} rt ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(door_external_app Rpcrt4.lib)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
######################################################################################################################################################################
|
||||
# create instance 3002 of door demo example
|
||||
######################################################################################################################################################################
|
||||
add_custom_target(vehicle_device_doors_config
|
||||
ALL
|
||||
DEPENDS
|
||||
can_dl_door
|
||||
doors_vd_frontdoorleft
|
||||
doors_vd_frontdoorright
|
||||
doors_vd_reardoorleft
|
||||
doors_vd_reardoorright
|
||||
COMMAND "${SDV_PACKAGER}" DIRECT_INSTALL VehicleDeviceDoors --instance3002 can_dl_door.sdv doors_vd_frontdoorleft.sdv doors_vd_frontdoorright.sdv doors_vd_reardoorleft.sdv doors_vd_reardoorright.sdv "-I${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" --interface_config --overwrite
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(basic_service_doors_config
|
||||
ALL
|
||||
DEPENDS
|
||||
doors_proxystub
|
||||
doors_bs_frontdoorleft
|
||||
doors_bs_frontdoorright
|
||||
doors_bs_reardoorleft
|
||||
doors_bs_reardoorright
|
||||
COMMAND "${SDV_PACKAGER}" DIRECT_INSTALL BasicServiceDoors --instance3002 doors_proxystub.sdv doors_bs_frontdoorleft.sdv doors_bs_frontdoorright.sdv doors_bs_reardoorleft.sdv doors_bs_reardoorright.sdv "-I${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" --abstract_config --overwrite
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(door_complex_service_config
|
||||
ALL
|
||||
DEPENDS
|
||||
door_complex_service
|
||||
doors_service_proxystub
|
||||
COMMAND "${SDV_PACKAGER}" DIRECT_INSTALL DoorComplexService --instance3002 door_complex_service.sdv doors_service_proxystub.sdv "-I${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" --user_config --overwrite
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
######################################################################################################################################################################
|
||||
# TODO: SDV_PACKAGER does not create the toml files, therefore we need to copy them
|
||||
######################################################################################################################################################################
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/coreconfig/door_demo.toml DESTINATION ${SDV_FRAMEWORK_RUNTIME}/3002)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/coreconfig/platform.toml DESTINATION ${SDV_FRAMEWORK_RUNTIME}/3002)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/coreconfig/settings.toml DESTINATION ${SDV_FRAMEWORK_RUNTIME}/3002)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/coreconfig/vehicle_abstract.toml DESTINATION ${SDV_FRAMEWORK_RUNTIME}/3002)
|
||||
file (COPY ${PROJECT_SOURCE_DIR}/coreconfig/vehicle_ifc.toml DESTINATION ${SDV_FRAMEWORK_RUNTIME}/3002)
|
||||
|
||||
######################################################################################################################################################################
|
||||
# the FMU files have been created via the dbc file
|
||||
# ..\\..\\build\\<configurePreset>\\bin\\sdv_dbc_util datalink_2doors_example.dbc -Ogenerated\\ --nodesdoors --version1.0.0.1 --moduleDoors2ExampleFMU --dl_lib_namecan_dl_door
|
||||
# ..\\..\\build\\<configurePreset>\\bin\\sdv_dbc_util datalink_4doors_example.dbc -Ogenerated\\ --nodesdoors --version1.0.0.1 --moduleDoors4ExampleFMU --dl_lib_namecan_dl_door
|
||||
#
|
||||
# following steps needs to be done:
|
||||
# required configuration files have to be put into the subfolder
|
||||
# ...\fmu_Doors2ExampleFMU\Doors2ExampleFMU\resources
|
||||
# ...\fmu_Doors2ExampleFMU\Doors4ExampleFMU\resources
|
||||
# function OpenAPILoad() needs to be updated in the model.cpp file
|
||||
# ...\fmu_Doors2ExampleFMU\Doors2ExampleFMU\model.cpp
|
||||
# ...\fmu_Doors2ExampleFMU\Doors4ExampleFMU\model.cpp
|
||||
######################################################################################################################################################################
|
||||
add_subdirectory(fmu_Doors2ExampleFMU)
|
||||
add_subdirectory(fmu_Doors4ExampleFMU)
|
||||
@@ -0,0 +1,49 @@
|
||||
# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# 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
|
||||
|
||||
# Define project
|
||||
project(doors_bs_frontdoorleft VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Libary symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set target name.
|
||||
set(TARGET_NAME doors_bs_frontdoorleft)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
include_directories(../../interfaces)
|
||||
|
||||
# Set platform specific compile flags
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/W4 /WX /wd4996 /wd4100 /permissive- /Zc:rvalueCast)
|
||||
else()
|
||||
add_compile_options(-Werror -Wall -Wextra -Wshadow -Wpedantic -Wunreachable-code -fno-common)
|
||||
endif()
|
||||
|
||||
# Add the dynamic library
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
bs_front_door_left.h
|
||||
bs_front_door_left.cpp)
|
||||
|
||||
# Set extension to .sdv
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# TODO: set target name.
|
||||
#add_dependencies(${TARGET_NAME} <add_cmake_target_this_depends_on>)
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file bs_front_door_left.cpp
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "bs_front_door_left.h"
|
||||
|
||||
/**
|
||||
* @brief ConstructorF
|
||||
*/
|
||||
CBasicServiceFrontDoorLeft::CBasicServiceFrontDoorLeft()
|
||||
{
|
||||
auto leftDoorIsOpen01Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_IsOpen>();
|
||||
if (!leftDoorIsOpen01Device)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_IsOpen': [CBasicServiceFrontDoorLeft]");
|
||||
throw std::runtime_error("Vehicle.Chassis.Door.Axle01.Left mode device not found");
|
||||
}
|
||||
leftDoorIsOpen01Device->RegisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
|
||||
m_ptrLock = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteLock>();
|
||||
if (!m_ptrLock)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_WriteLock': [CBasicServiceFrontDoorLeft]");
|
||||
throw std::runtime_error("Lock device not found");
|
||||
}
|
||||
|
||||
SDV_LOG_TRACE("CBasicServiceFrontDoorLeft created: [Vehicle.Chassis.Door.Axle01.Left_Device]");
|
||||
m_leftDoorIsOpen01 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
CBasicServiceFrontDoorLeft::~CBasicServiceFrontDoorLeft()
|
||||
{
|
||||
auto leftDoorIsOpen01Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_IsOpen>();
|
||||
if (leftDoorIsOpen01Device)
|
||||
{
|
||||
leftDoorIsOpen01Device->UnregisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
}
|
||||
leftDoorIsOpen01Device = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceFrontDoorLeft::SetIsOpenL1(bool value)
|
||||
{
|
||||
m_leftDoorIsOpen01 = value;
|
||||
std::lock_guard<std::mutex> lock(m_leftDoorIsOpen01MutexCallbacks);
|
||||
for (auto callback : m_leftDoorIsOpen01Callbacks)
|
||||
{
|
||||
callback->SetIsOpenL1(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write leftDoorIsOpen
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceFrontDoorLeft::WriteIsOpen(bool value)
|
||||
{
|
||||
SetIsOpenL1(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get leftDoorIsOpen
|
||||
* @return Returns the leftDoorIsOpen
|
||||
*/
|
||||
bool CBasicServiceFrontDoorLeft::GetIsOpen() const
|
||||
{
|
||||
return m_leftDoorIsOpen01;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceFrontDoorLeft::RegisterOnSignalChangeOfLeftDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event* leftDoorIsOpen01Callback)
|
||||
{
|
||||
if ( leftDoorIsOpen01Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_leftDoorIsOpen01MutexCallbacks);
|
||||
m_leftDoorIsOpen01Callbacks.insert(leftDoorIsOpen01Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceFrontDoorLeft::UnregisterOnSignalChangeOfLeftDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event* leftDoorIsOpen01Callback)
|
||||
{
|
||||
if (leftDoorIsOpen01Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_leftDoorIsOpen01MutexCallbacks);
|
||||
m_leftDoorIsOpen01Callbacks.erase(leftDoorIsOpen01Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool CBasicServiceFrontDoorLeft::SetLock(bool value)
|
||||
{
|
||||
return m_ptrLock->WriteLock(value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file bs_front_door_left.h
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#ifndef __VSS_GENERATED__BS_FRONTDOORLEFT_H_20250711_125718_601__
|
||||
#define __VSS_GENERATED__BS_FRONTDOORLEFT_H_20250711_125718_601__
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include "vss_vehiclechassisdooraxle01left_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle01left_vd_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle01left_bs_tx.h"
|
||||
|
||||
/**
|
||||
* @brief Basic Service Vehicle.Chassis.Door.Axle01.Left
|
||||
*/
|
||||
class CBasicServiceFrontDoorLeft
|
||||
: public sdv::CSdvObject
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetLock
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetLock)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Vehicle.Chassis.Door.Axle01.Left_Service")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicServiceFrontDoorLeft();
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
~CBasicServiceFrontDoorLeft();
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL1(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Get leftDoorIsOpen
|
||||
* @return Returns the leftDoorIsOpen
|
||||
*/
|
||||
bool GetIsOpen() const override;
|
||||
|
||||
/**
|
||||
* @brief Write leftDoorIsOpen signal
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set leftLatch signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool SetLock(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Register CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfLeftDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
/**
|
||||
* @brief Unregister CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfLeftDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
private:
|
||||
|
||||
bool m_leftDoorIsOpen01 { 0 };
|
||||
mutable std::mutex m_leftDoorIsOpen01MutexCallbacks; ///< Mutex protecting m_leftDoorIsOpen01Callbacks
|
||||
std::set<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> m_leftDoorIsOpen01Callbacks; ///< collection of events to be called
|
||||
vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteLock* m_ptrLock = nullptr;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CBasicServiceFrontDoorLeft)
|
||||
|
||||
#endif // !define __VSS_GENERATED__BS_FRONTDOORLEFT_H_20250711_125718_601__
|
||||
@@ -0,0 +1,49 @@
|
||||
# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# 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
|
||||
|
||||
# Define project
|
||||
project(doors_bs_frontdoorright VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Libary symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set target name.
|
||||
set(TARGET_NAME doors_bs_frontdoorright)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
include_directories(../../interfaces)
|
||||
|
||||
# Set platform specific compile flags
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/W4 /WX /wd4996 /wd4100 /permissive- /Zc:rvalueCast)
|
||||
else()
|
||||
add_compile_options(-Werror -Wall -Wextra -Wshadow -Wpedantic -Wunreachable-code -fno-common)
|
||||
endif()
|
||||
|
||||
# Add the dynamic library
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
bs_front_door_right.h
|
||||
bs_front_door_right.cpp)
|
||||
|
||||
# Set extension to .sdv
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# TODO: set target name.
|
||||
#add_dependencies(${TARGET_NAME} <add_cmake_target_this_depends_on>)
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file bs_front_door_right.cpp
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "bs_front_door_right.h"
|
||||
|
||||
/**
|
||||
* @brief ConstructorF
|
||||
*/
|
||||
CBasicServiceFrontDoorRight::CBasicServiceFrontDoorRight()
|
||||
{
|
||||
auto rightDoorIsOpen01Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightDevice::IVSS_IsOpen>();
|
||||
if (!rightDoorIsOpen01Device)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_IsOpen': [CBasicServiceFrontDoorRight]");
|
||||
throw std::runtime_error("Vehicle.Chassis.Door.Axle01.Right mode device not found");
|
||||
}
|
||||
rightDoorIsOpen01Device->RegisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::RightDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
|
||||
m_ptrLock = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightDevice::IVSS_WriteLock>();
|
||||
if (!m_ptrLock)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_WriteLock': [CBasicServiceFrontDoorRight]");
|
||||
throw std::runtime_error("Lock device not found");
|
||||
}
|
||||
|
||||
SDV_LOG_TRACE("CBasicServiceFrontDoorRight created: [Vehicle.Chassis.Door.Axle01.Right_Device]");
|
||||
m_rightDoorIsOpen01 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
CBasicServiceFrontDoorRight::~CBasicServiceFrontDoorRight()
|
||||
{
|
||||
auto rightDoorIsOpen01Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightDevice::IVSS_IsOpen>();
|
||||
if (rightDoorIsOpen01Device)
|
||||
{
|
||||
rightDoorIsOpen01Device->UnregisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::RightDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
}
|
||||
rightDoorIsOpen01Device = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceFrontDoorRight::SetIsOpenR1(bool value)
|
||||
{
|
||||
m_rightDoorIsOpen01 = value;
|
||||
std::lock_guard<std::mutex> lock(m_rightDoorIsOpen01MutexCallbacks);
|
||||
for (auto callback : m_rightDoorIsOpen01Callbacks)
|
||||
{
|
||||
callback->SetIsOpenR1(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write rightDoorIsOpen
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceFrontDoorRight::WriteIsOpen(bool value)
|
||||
{
|
||||
SetIsOpenR1(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
bool CBasicServiceFrontDoorRight::GetIsOpen() const
|
||||
{
|
||||
return m_rightDoorIsOpen01;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceFrontDoorRight::RegisterOnSignalChangeOfRightDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event* rightDoorIsOpen01Callback)
|
||||
{
|
||||
if ( rightDoorIsOpen01Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_rightDoorIsOpen01MutexCallbacks);
|
||||
m_rightDoorIsOpen01Callbacks.insert(rightDoorIsOpen01Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceFrontDoorRight::UnregisterOnSignalChangeOfRightDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event* rightDoorIsOpen01Callback)
|
||||
{
|
||||
if (rightDoorIsOpen01Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_rightDoorIsOpen01MutexCallbacks);
|
||||
m_rightDoorIsOpen01Callbacks.erase(rightDoorIsOpen01Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool CBasicServiceFrontDoorRight::SetLock(bool value)
|
||||
{
|
||||
return m_ptrLock->WriteLock(value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file bs_front_door_right.h
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#ifndef __VSS_GENERATED__BS_FRONTDOORRIGHT_H_20250711_125718_606__
|
||||
#define __VSS_GENERATED__BS_FRONTDOORRIGHT_H_20250711_125718_606__
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include "vss_vehiclechassisdooraxle01right_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle01right_vd_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle01right_bs_tx.h"
|
||||
|
||||
/**
|
||||
* @brief Basic Service Vehicle.Chassis.Door.Axle01.Right
|
||||
*/
|
||||
class CBasicServiceFrontDoorRight
|
||||
: public sdv::CSdvObject
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::RightDevice::IVSS_WriteIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetLock
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetLock)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Vehicle.Chassis.Door.Axle01.Right_Service")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicServiceFrontDoorRight();
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
~CBasicServiceFrontDoorRight();
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR1(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set signal
|
||||
* @param[in] value rightLatche
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool SetLock(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
bool GetIsOpen() const override;
|
||||
|
||||
/**
|
||||
* @brief Write rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Register CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfRightDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
/**
|
||||
* @brief Unregister CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfRightDoorIsOpen01(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
private:
|
||||
|
||||
bool m_rightDoorIsOpen01 { 0 };
|
||||
mutable std::mutex m_rightDoorIsOpen01MutexCallbacks; ///< Mutex protecting m_rightDoorIsOpen01Callbacks
|
||||
std::set<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> m_rightDoorIsOpen01Callbacks; ///< collection of events to be called
|
||||
vss::Vehicle::Chassis::Door::Axle01::RightDevice::IVSS_WriteLock* m_ptrLock = nullptr;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CBasicServiceFrontDoorRight)
|
||||
|
||||
#endif // !define __VSS_GENERATED__BS_FRONTDOORRIGHT_H_20250711_125718_606__
|
||||
@@ -0,0 +1,49 @@
|
||||
# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# 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
|
||||
|
||||
# Define project
|
||||
project(doors_bs_reardoorleft VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Libary symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set target name.
|
||||
set(TARGET_NAME doors_bs_reardoorleft)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
include_directories(../../interfaces)
|
||||
|
||||
# Set platform specific compile flags
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/W4 /WX /wd4996 /wd4100 /permissive- /Zc:rvalueCast)
|
||||
else()
|
||||
add_compile_options(-Werror -Wall -Wextra -Wshadow -Wpedantic -Wunreachable-code -fno-common)
|
||||
endif()
|
||||
|
||||
# Add the dynamic library
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
bs_rear_door_left.h
|
||||
bs_rear_door_left.cpp)
|
||||
|
||||
# Set extension to .sdv
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# TODO: set target name.
|
||||
#add_dependencies(${TARGET_NAME} <add_cmake_target_this_depends_on>)
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file bs_rear_door_left.cpp
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "bs_rear_door_left.h"
|
||||
|
||||
/**
|
||||
* @brief ConstructorF
|
||||
*/
|
||||
CBasicServiceRearDoorLeft::CBasicServiceRearDoorLeft()
|
||||
{
|
||||
auto leftDoorIsOpen02Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftDevice::IVSS_IsOpen>();
|
||||
if (!leftDoorIsOpen02Device)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_IsOpen': [CBasicServiceRearDoorLeft]");
|
||||
throw std::runtime_error("Vehicle.Chassis.Door.Axle02.Left mode device not found");
|
||||
}
|
||||
leftDoorIsOpen02Device->RegisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
|
||||
m_ptrLock = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftDevice::IVSS_WriteLock>();
|
||||
if (!m_ptrLock)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_WriteLock': [CBasicServiceRearDoorLeft]");
|
||||
throw std::runtime_error("Lock device not found");
|
||||
}
|
||||
|
||||
SDV_LOG_TRACE("CBasicServiceRearDoorLeft created: [Vehicle.Chassis.Door.Axle02.Left_Device]");
|
||||
m_leftDoorIsOpen02 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
CBasicServiceRearDoorLeft::~CBasicServiceRearDoorLeft()
|
||||
{
|
||||
auto leftDoorIsOpen02Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftDevice::IVSS_IsOpen>();
|
||||
if (leftDoorIsOpen02Device)
|
||||
{
|
||||
leftDoorIsOpen02Device->UnregisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
}
|
||||
leftDoorIsOpen02Device = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceRearDoorLeft::SetIsOpenL2(bool value)
|
||||
{
|
||||
m_leftDoorIsOpen02 = value;
|
||||
std::lock_guard<std::mutex> lock(m_leftDoorIsOpen02MutexCallbacks);
|
||||
for (auto callback : m_leftDoorIsOpen02Callbacks)
|
||||
{
|
||||
callback->SetIsOpenL2(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write rightDoorIsOpen
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceRearDoorLeft::WriteIsOpen(bool value)
|
||||
{
|
||||
SetIsOpenL2(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
bool CBasicServiceRearDoorLeft::GetIsOpen() const
|
||||
{
|
||||
return m_leftDoorIsOpen02;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceRearDoorLeft::RegisterOnSignalChangeOfLeftDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event* leftDoorIsOpen02Callback)
|
||||
{
|
||||
if ( leftDoorIsOpen02Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_leftDoorIsOpen02MutexCallbacks);
|
||||
m_leftDoorIsOpen02Callbacks.insert(leftDoorIsOpen02Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceRearDoorLeft::UnregisterOnSignalChangeOfLeftDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event* leftDoorIsOpen02Callback)
|
||||
{
|
||||
if (leftDoorIsOpen02Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_leftDoorIsOpen02MutexCallbacks);
|
||||
m_leftDoorIsOpen02Callbacks.erase(leftDoorIsOpen02Callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Lock
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool CBasicServiceRearDoorLeft::SetLock(bool value)
|
||||
{
|
||||
return m_ptrLock->WriteLock(value);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file bs_rear_door_left.h
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#ifndef __VSS_GENERATED__BS_REARDOORLEFT_H_20250711_125718_611__
|
||||
#define __VSS_GENERATED__BS_REARDOORLEFT_H_20250711_125718_611__
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include "vss_vehiclechassisdooraxle02left_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle02left_vd_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle02left_bs_tx.h"
|
||||
|
||||
/**
|
||||
* @brief Basic Service Vehicle.Chassis.Door.Axle02.Left
|
||||
*/
|
||||
class CBasicServiceRearDoorLeft
|
||||
: public sdv::CSdvObject
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::LeftDevice::IVSS_WriteIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetLock
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetLock)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Vehicle.Chassis.Door.Axle02.Left_Service")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicServiceRearDoorLeft();
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
~CBasicServiceRearDoorLeft();
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL2(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set leftLatch02 signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool SetLock(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
bool GetIsOpen() const override;
|
||||
|
||||
/**
|
||||
* @brief Write rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Register CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfLeftDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
/**
|
||||
* @brief Unregister CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfLeftDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
private:
|
||||
|
||||
bool m_leftDoorIsOpen02 { 0 };
|
||||
mutable std::mutex m_leftDoorIsOpen02MutexCallbacks; ///< Mutex protecting m_leftDoorIsOpen02Callbacks
|
||||
std::set<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> m_leftDoorIsOpen02Callbacks; ///< collection of events to be called
|
||||
vss::Vehicle::Chassis::Door::Axle02::LeftDevice::IVSS_WriteLock* m_ptrLock = nullptr;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CBasicServiceRearDoorLeft)
|
||||
|
||||
#endif // !define __VSS_GENERATED__BS_REARDOORLEFT_H_20250711_125718_611__
|
||||
@@ -0,0 +1,49 @@
|
||||
# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# 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
|
||||
|
||||
# Define project
|
||||
project(doors_bs_reardoorright VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Libary symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set target name.
|
||||
set(TARGET_NAME doors_bs_reardoorright)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
include_directories(../../interfaces)
|
||||
|
||||
# Set platform specific compile flags
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/W4 /WX /wd4996 /wd4100 /permissive- /Zc:rvalueCast)
|
||||
else()
|
||||
add_compile_options(-Werror -Wall -Wextra -Wshadow -Wpedantic -Wunreachable-code -fno-common)
|
||||
endif()
|
||||
|
||||
# Add the dynamic library
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
bs_rear_door_right.h
|
||||
bs_rear_door_right.cpp)
|
||||
|
||||
# Set extension to .sdv
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# TODO: set target name.
|
||||
#add_dependencies(${TARGET_NAME} <add_cmake_target_this_depends_on>)
|
||||
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file bs_rear_door_right.cpp
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "bs_rear_door_right.h"
|
||||
|
||||
/**
|
||||
* @brief ConstructorF
|
||||
*/
|
||||
CBasicServiceRearDoorRight::CBasicServiceRearDoorRight()
|
||||
{
|
||||
auto rightDoorIsOpen02Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightDevice::IVSS_IsOpen>();
|
||||
if (!rightDoorIsOpen02Device)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_IsOpen': [CBasicServiceRearDoorRight]");
|
||||
throw std::runtime_error("Vehicle.Chassis.Door.Axle02.Right mode device not found");
|
||||
}
|
||||
rightDoorIsOpen02Device->RegisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::RightDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
|
||||
m_ptrLock = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightDevice::IVSS_WriteLock>();
|
||||
if (!m_ptrLock)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_WriteLock': [CBasicServiceRearDoorRight]");
|
||||
throw std::runtime_error("Lock device not found");
|
||||
}
|
||||
|
||||
SDV_LOG_TRACE("CBasicServiceRearDoorRight created: [Vehicle.Chassis.Door.Axle02.Right_Device]");
|
||||
m_rightDoorIsOpen02 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
CBasicServiceRearDoorRight::~CBasicServiceRearDoorRight()
|
||||
{
|
||||
auto rightDoorIsOpen02Device = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightDevice::IVSS_IsOpen>();
|
||||
if (rightDoorIsOpen02Device)
|
||||
{
|
||||
rightDoorIsOpen02Device->UnregisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::RightDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
}
|
||||
rightDoorIsOpen02Device = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceRearDoorRight::SetIsOpenR2(bool value)
|
||||
{
|
||||
m_rightDoorIsOpen02 = value;
|
||||
std::lock_guard<std::mutex> lock(m_rightDoorIsOpen02MutexCallbacks);
|
||||
for (auto callback : m_rightDoorIsOpen02Callbacks)
|
||||
{
|
||||
callback->SetIsOpenR2(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write rightDoorIsOpen
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void CBasicServiceRearDoorRight::WriteIsOpen(bool value)
|
||||
{
|
||||
SetIsOpenR2(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
bool CBasicServiceRearDoorRight::GetIsOpen() const
|
||||
{
|
||||
return m_rightDoorIsOpen02;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceRearDoorRight::RegisterOnSignalChangeOfRightDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event* rightDoorIsOpen02Callback)
|
||||
{
|
||||
if ( rightDoorIsOpen02Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_rightDoorIsOpen02MutexCallbacks);
|
||||
m_rightDoorIsOpen02Callbacks.insert(rightDoorIsOpen02Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicServiceRearDoorRight::UnregisterOnSignalChangeOfRightDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event* rightDoorIsOpen02Callback)
|
||||
{
|
||||
if (rightDoorIsOpen02Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_rightDoorIsOpen02MutexCallbacks);
|
||||
m_rightDoorIsOpen02Callbacks.erase(rightDoorIsOpen02Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool CBasicServiceRearDoorRight::SetLock(bool value)
|
||||
{
|
||||
return m_ptrLock->WriteLock(value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file bs_rear_door_right.h
|
||||
* @date 2025-07-11 12:57:18
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#ifndef __VSS_GENERATED__BS_REARDOORRIGHT_H_20250711_125718_616__
|
||||
#define __VSS_GENERATED__BS_REARDOORRIGHT_H_20250711_125718_616__
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include "vss_vehiclechassisdooraxle02right_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle02right_vd_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle02right_bs_tx.h"
|
||||
|
||||
/**
|
||||
* @brief Basic Service Vehicle.Chassis.Door.Axle02.Right
|
||||
*/
|
||||
class CBasicServiceRearDoorRight
|
||||
: public sdv::CSdvObject
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::RightDevice::IVSS_WriteIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetLock
|
||||
{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetLock)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Vehicle.Chassis.Door.Axle02.Right_Service")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicServiceRearDoorRight();
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
~CBasicServiceRearDoorRight();
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR2(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set rightLatch02 signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool SetLock(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
bool GetIsOpen() const override;
|
||||
|
||||
/**
|
||||
* @brief Write rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Register CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfRightDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
/**
|
||||
* @brief Unregister CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfRightDoorIsOpen02(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event* callback) override;
|
||||
|
||||
private:
|
||||
|
||||
bool m_rightDoorIsOpen02 { 0 };
|
||||
mutable std::mutex m_rightDoorIsOpen02MutexCallbacks; ///< Mutex protecting m_rightDoorIsOpen02Callbacks
|
||||
std::set<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> m_rightDoorIsOpen02Callbacks; ///< collection of events to be called
|
||||
vss::Vehicle::Chassis::Door::Axle02::RightDevice::IVSS_WriteLock* m_ptrLock = nullptr;
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CBasicServiceRearDoorRight)
|
||||
|
||||
#endif // !define __VSS_GENERATED__BS_REARDOORRIGHT_H_20250711_125718_616__
|
||||
42
examples/door_demo_example/can_dl_door/CMakeLists.txt
Normal file
42
examples/door_demo_example/can_dl_door/CMakeLists.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# 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
|
||||
|
||||
# Define project
|
||||
project(can_dl_door VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Library symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
|
||||
# Set platform specific compile flags
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/W4 /WX /wd4996 /wd4100 /permissive- /Zc:rvalueCast)
|
||||
else()
|
||||
add_compile_options(-Werror -Wall -Wextra -Wshadow -Wpedantic -Wunreachable-code -fno-common)
|
||||
endif()
|
||||
|
||||
# Add the dynamic library
|
||||
add_library(can_dl_door SHARED
|
||||
datalink.cpp
|
||||
datalink.h)
|
||||
|
||||
# Set extension to .sdv
|
||||
set_target_properties(can_dl_door PROPERTIES PREFIX "")
|
||||
set_target_properties(can_dl_door PROPERTIES SUFFIX ".sdv")
|
||||
412
examples/door_demo_example/can_dl_door/datalink.cpp
Normal file
412
examples/door_demo_example/can_dl_door/datalink.cpp
Normal file
@@ -0,0 +1,412 @@
|
||||
/**
|
||||
* @file datalink.cpp
|
||||
* @date 2025-09-06 08:00:37
|
||||
* This file implements the data link object between CAN and the V-API devices.
|
||||
* This file was generated by the DBC utility from:
|
||||
* "", "datalink_4doors_example.dbc"
|
||||
* DBC file version: 1.0.0.1
|
||||
*/
|
||||
#include "datalink.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CDataLink::CDataLink() :
|
||||
m_sRxMsgCAN_Input_L1(m_dispatch),
|
||||
m_sRxMsgCAN_Input_R1(m_dispatch),
|
||||
m_sRxMsgCAN_Input_L2(m_dispatch),
|
||||
m_sRxMsgCAN_Input_R2(m_dispatch),
|
||||
m_sTxMsgCAN_Output(m_dispatch)
|
||||
{}
|
||||
|
||||
CDataLink::~CDataLink()
|
||||
{
|
||||
Shutdown(); // Just in case
|
||||
}
|
||||
|
||||
void CDataLink::Initialize(const sdv::u8string& /*ssObjectConfig*/)
|
||||
{
|
||||
if (m_eStatus != sdv::EObjectStatus::initialization_pending) return;
|
||||
|
||||
// Get the CAN communication object.
|
||||
sdv::TInterfaceAccessPtr ptrCANObject = sdv::core::GetObject("CAN_Communication_Object");
|
||||
if (!ptrCANObject)
|
||||
{
|
||||
SDV_LOG_ERROR("CDataLink::Initialize() failure, 'CAN_Communication_Object' not found");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the CAN receiver registration interface.
|
||||
m_pRegister = ptrCANObject.GetInterface<sdv::can::IRegisterReceiver>();
|
||||
if (!m_pRegister)
|
||||
{
|
||||
SDV_LOG_ERROR("CDataLink::Initialize() failure, 'sdv::can::IRegisterReceiver' interface not found");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
m_pRegister->RegisterReceiver(static_cast<sdv::can::IReceive*>(this));
|
||||
|
||||
// Get the CAN transmit interface
|
||||
m_pSend = ptrCANObject.GetInterface<sdv::can::ISend>();
|
||||
if (!m_pSend)
|
||||
{
|
||||
SDV_LOG_ERROR("CDataLink::Initialize() failure, 'sdv::can::ISend' interface not found");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize messages
|
||||
bool bSuccess = true;
|
||||
bSuccess &= m_sRxMsgCAN_Input_L1.Init();
|
||||
bSuccess &= m_sRxMsgCAN_Input_R1.Init();
|
||||
bSuccess &= m_sRxMsgCAN_Input_L2.Init();
|
||||
bSuccess &= m_sRxMsgCAN_Input_R2.Init();
|
||||
bSuccess &= m_sTxMsgCAN_Output.Init(m_pSend);
|
||||
|
||||
m_eStatus = bSuccess ? sdv::EObjectStatus::initialized : sdv::EObjectStatus::initialization_failure;
|
||||
}
|
||||
|
||||
sdv::EObjectStatus CDataLink::GetStatus() const
|
||||
{
|
||||
return m_eStatus;
|
||||
}
|
||||
|
||||
void CDataLink::SetOperationMode(sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_eStatus == sdv::EObjectStatus::running || m_eStatus == sdv::EObjectStatus::initialized)
|
||||
m_eStatus = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_eStatus == sdv::EObjectStatus::configuring || m_eStatus == sdv::EObjectStatus::initialized)
|
||||
m_eStatus = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CDataLink::Shutdown()
|
||||
{
|
||||
m_eStatus = sdv::EObjectStatus::shutdown_in_progress;
|
||||
|
||||
// Unregister receiver interface.
|
||||
if (m_pRegister) m_pRegister->UnregisterReceiver(static_cast<sdv::can::IReceive*>(this));
|
||||
m_pRegister = nullptr;
|
||||
|
||||
m_pSend = nullptr;
|
||||
|
||||
// Terminate messages
|
||||
m_sRxMsgCAN_Input_L1.Term();
|
||||
m_sRxMsgCAN_Input_R1.Term();
|
||||
m_sRxMsgCAN_Input_L2.Term();
|
||||
m_sRxMsgCAN_Input_R2.Term();
|
||||
m_sTxMsgCAN_Output.Term();
|
||||
|
||||
// Update the status
|
||||
m_eStatus = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
void CDataLink::Receive(/*in*/ [[maybe_unused]] const sdv::can::SMessage& sMsg, /*in*/ uint32_t uiIfcIndex)
|
||||
{
|
||||
if (static_cast<size_t>(uiIfcIndex) != m_nIfcIndex) return;
|
||||
|
||||
switch (sMsg.uiID)
|
||||
{
|
||||
case 1: // CAN_Input_L1
|
||||
m_sRxMsgCAN_Input_L1.Process(sMsg.seqData);
|
||||
break;
|
||||
case 2: // CAN_Input_R1
|
||||
m_sRxMsgCAN_Input_R1.Process(sMsg.seqData);
|
||||
break;
|
||||
case 3: // CAN_Input_L2
|
||||
m_sRxMsgCAN_Input_L2.Process(sMsg.seqData);
|
||||
break;
|
||||
case 4: // CAN_Input_R2
|
||||
m_sRxMsgCAN_Input_R2.Process(sMsg.seqData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CDataLink::Error(/*in*/ [[maybe_unused]] const sdv::can::SErrorFrame& sError, /*in*/ uint32_t uiIfcIndex)
|
||||
{
|
||||
if (static_cast<size_t>(uiIfcIndex) != m_nIfcIndex) return;
|
||||
|
||||
// TODO: Currently no error frame handling...
|
||||
}
|
||||
|
||||
|
||||
CDataLink::SRxMsg_CAN_Input_L1::SRxMsg_CAN_Input_L1(sdv::core::CDispatchService& rdispatch) :
|
||||
m_rdispatch(rdispatch)
|
||||
{}
|
||||
|
||||
bool CDataLink::SRxMsg_CAN_Input_L1::Init()
|
||||
{
|
||||
// Register signals
|
||||
[[maybe_unused]] bool bSuccess = true;
|
||||
m_sigDoor01LeftIsOpen = m_rdispatch.RegisterRxSignal("CAN_Input_L1.Door01LeftIsOpen");
|
||||
bSuccess &= m_sigDoor01LeftIsOpen ? true : false;
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_L1::Term()
|
||||
{
|
||||
// Unregister signals
|
||||
m_sigDoor01LeftIsOpen.Reset();
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_L1::Process(const sdv::sequence<uint8_t>& rseqData)
|
||||
{
|
||||
// Check for the correct size.
|
||||
if (rseqData.size() != 1)
|
||||
{
|
||||
// TODO: Error. Delivered data has different size as compared to the specification.
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper variable
|
||||
[[maybe_unused]] UValueHelper uValueHelper;
|
||||
|
||||
// Start a transaction
|
||||
sdv::core::CTransaction transaction = m_rdispatch.CreateTransaction();
|
||||
|
||||
// Process CAN_Input_L1.Door01LeftIsOpen
|
||||
uValueHelper.uiUint64Value = rseqData[0] & 3;
|
||||
uValueHelper.uiUint64Value >>= 1;
|
||||
m_sigDoor01LeftIsOpen.Write(std::min(std::max(uValueHelper.s32.u32.uiValue, 0u), 1u), transaction);
|
||||
|
||||
// Finalize the transaction
|
||||
transaction.Finish();
|
||||
}
|
||||
|
||||
CDataLink::SRxMsg_CAN_Input_R1::SRxMsg_CAN_Input_R1(sdv::core::CDispatchService& rdispatch) :
|
||||
m_rdispatch(rdispatch)
|
||||
{}
|
||||
|
||||
bool CDataLink::SRxMsg_CAN_Input_R1::Init()
|
||||
{
|
||||
// Register signals
|
||||
[[maybe_unused]] bool bSuccess = true;
|
||||
m_sigDoor01RightIsOpen = m_rdispatch.RegisterRxSignal("CAN_Input_R1.Door01RightIsOpen");
|
||||
bSuccess &= m_sigDoor01RightIsOpen ? true : false;
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_R1::Term()
|
||||
{
|
||||
// Unregister signals
|
||||
m_sigDoor01RightIsOpen.Reset();
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_R1::Process(const sdv::sequence<uint8_t>& rseqData)
|
||||
{
|
||||
// Check for the correct size.
|
||||
if (rseqData.size() != 1)
|
||||
{
|
||||
// TODO: Error. Delivered data has different size as compared to the specification.
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper variable
|
||||
[[maybe_unused]] UValueHelper uValueHelper;
|
||||
|
||||
// Start a transaction
|
||||
sdv::core::CTransaction transaction = m_rdispatch.CreateTransaction();
|
||||
|
||||
// Process CAN_Input_R1.Door01RightIsOpen
|
||||
uValueHelper.uiUint64Value = rseqData[0] & 15;
|
||||
uValueHelper.uiUint64Value >>= 3;
|
||||
m_sigDoor01RightIsOpen.Write(std::min(std::max(uValueHelper.s32.u32.uiValue, 0u), 1u), transaction);
|
||||
|
||||
// Finalize the transaction
|
||||
transaction.Finish();
|
||||
}
|
||||
|
||||
CDataLink::SRxMsg_CAN_Input_L2::SRxMsg_CAN_Input_L2(sdv::core::CDispatchService& rdispatch) :
|
||||
m_rdispatch(rdispatch)
|
||||
{}
|
||||
|
||||
bool CDataLink::SRxMsg_CAN_Input_L2::Init()
|
||||
{
|
||||
// Register signals
|
||||
[[maybe_unused]] bool bSuccess = true;
|
||||
m_sigDoor02LeftIsOpen = m_rdispatch.RegisterRxSignal("CAN_Input_L2.Door02LeftIsOpen");
|
||||
bSuccess &= m_sigDoor02LeftIsOpen ? true : false;
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_L2::Term()
|
||||
{
|
||||
// Unregister signals
|
||||
m_sigDoor02LeftIsOpen.Reset();
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_L2::Process(const sdv::sequence<uint8_t>& rseqData)
|
||||
{
|
||||
// Check for the correct size.
|
||||
if (rseqData.size() != 1)
|
||||
{
|
||||
// TODO: Error. Delivered data has different size as compared to the specification.
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper variable
|
||||
[[maybe_unused]] UValueHelper uValueHelper;
|
||||
|
||||
// Start a transaction
|
||||
sdv::core::CTransaction transaction = m_rdispatch.CreateTransaction();
|
||||
|
||||
// Process CAN_Input_L2.Door02LeftIsOpen
|
||||
uValueHelper.uiUint64Value = rseqData[0] & 63;
|
||||
uValueHelper.uiUint64Value >>= 5;
|
||||
m_sigDoor02LeftIsOpen.Write(std::min(std::max(uValueHelper.s32.u32.uiValue, 0u), 1u), transaction);
|
||||
|
||||
// Finalize the transaction
|
||||
transaction.Finish();
|
||||
}
|
||||
|
||||
CDataLink::SRxMsg_CAN_Input_R2::SRxMsg_CAN_Input_R2(sdv::core::CDispatchService& rdispatch) :
|
||||
m_rdispatch(rdispatch)
|
||||
{}
|
||||
|
||||
bool CDataLink::SRxMsg_CAN_Input_R2::Init()
|
||||
{
|
||||
// Register signals
|
||||
[[maybe_unused]] bool bSuccess = true;
|
||||
m_sigDoor02RightIsOpen = m_rdispatch.RegisterRxSignal("CAN_Input_R2.Door02RightIsOpen");
|
||||
bSuccess &= m_sigDoor02RightIsOpen ? true : false;
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_R2::Term()
|
||||
{
|
||||
// Unregister signals
|
||||
m_sigDoor02RightIsOpen.Reset();
|
||||
}
|
||||
|
||||
void CDataLink::SRxMsg_CAN_Input_R2::Process(const sdv::sequence<uint8_t>& rseqData)
|
||||
{
|
||||
// Check for the correct size.
|
||||
if (rseqData.size() != 1)
|
||||
{
|
||||
// TODO: Error. Delivered data has different size as compared to the specification.
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper variable
|
||||
[[maybe_unused]] UValueHelper uValueHelper;
|
||||
|
||||
// Start a transaction
|
||||
sdv::core::CTransaction transaction = m_rdispatch.CreateTransaction();
|
||||
|
||||
// Process CAN_Input_R2.Door02RightIsOpen
|
||||
uValueHelper.uiUint64Value = rseqData[0];
|
||||
uValueHelper.uiUint64Value >>= 7;
|
||||
m_sigDoor02RightIsOpen.Write(std::min(std::max(uValueHelper.s32.u32.uiValue, 0u), 1u), transaction);
|
||||
|
||||
// Finalize the transaction
|
||||
transaction.Finish();
|
||||
}
|
||||
|
||||
CDataLink::STxMsg_CAN_Output::STxMsg_CAN_Output(sdv::core::CDispatchService& rdispatch) :
|
||||
m_rdispatch(rdispatch)
|
||||
{}
|
||||
|
||||
bool CDataLink::STxMsg_CAN_Output::Init(sdv::can::ISend* pSend)
|
||||
{
|
||||
if (!pSend) return false;
|
||||
m_pSend = pSend;
|
||||
|
||||
// Register signals
|
||||
bool bSuccess = true;
|
||||
m_sigLockDoor02Right = m_rdispatch.RegisterTxSignal("CAN_Output.LockDoor02Right", sdv::any_t());
|
||||
bSuccess &= m_sigLockDoor02Right ? true : false;
|
||||
m_sigLockDoor02Left = m_rdispatch.RegisterTxSignal("CAN_Output.LockDoor02Left", sdv::any_t());
|
||||
bSuccess &= m_sigLockDoor02Left ? true : false;
|
||||
m_sigLockDoor01Right = m_rdispatch.RegisterTxSignal("CAN_Output.LockDoor01Right", sdv::any_t());
|
||||
bSuccess &= m_sigLockDoor01Right ? true : false;
|
||||
m_sigLockDoor01Left = m_rdispatch.RegisterTxSignal("CAN_Output.LockDoor01Left", sdv::any_t());
|
||||
bSuccess &= m_sigLockDoor01Left ? true : false;
|
||||
|
||||
// Initialize the trigger
|
||||
m_trigger = m_rdispatch.CreateTxTrigger([&] { Transmit(); }, false, 0, 10, false);
|
||||
m_trigger.AddSignal(m_sigLockDoor02Right);
|
||||
m_trigger.AddSignal(m_sigLockDoor02Left);
|
||||
m_trigger.AddSignal(m_sigLockDoor01Right);
|
||||
m_trigger.AddSignal(m_sigLockDoor01Left);
|
||||
bSuccess &= m_trigger;
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
void CDataLink::STxMsg_CAN_Output::Term()
|
||||
{
|
||||
// Reset the trigger
|
||||
m_trigger.Reset();
|
||||
|
||||
// Unregister signals
|
||||
m_sigLockDoor02Right.Reset();
|
||||
m_sigLockDoor02Left.Reset();
|
||||
m_sigLockDoor01Right.Reset();
|
||||
m_sigLockDoor01Left.Reset();
|
||||
}
|
||||
|
||||
void CDataLink::STxMsg_CAN_Output::Transmit()
|
||||
{
|
||||
if (!m_pSend) return;
|
||||
|
||||
// Compose CAN message
|
||||
sdv::can::SMessage msg;
|
||||
msg.uiID = 5;
|
||||
msg.bExtended = false;
|
||||
msg.bCanFd = false; // TODO: Currently not supported
|
||||
msg.seqData.resize(1);
|
||||
std::fill(msg.seqData.begin(), msg.seqData.end(), static_cast<uint8_t>(0));
|
||||
|
||||
// Helper variable
|
||||
[[maybe_unused]] UValueHelper uValueHelper;
|
||||
|
||||
// Start a transaction
|
||||
sdv::core::CTransaction transaction = m_rdispatch.CreateTransaction();
|
||||
|
||||
// Compose CAN_Output.LockDoor02Right
|
||||
uValueHelper.s32.u32.uiValue = static_cast<uint32_t>(std::min(std::max(static_cast<long long int>(m_sigLockDoor02Right.Read(transaction)), 0ll), 1ll));
|
||||
uValueHelper.uiUint64Value <<= 7;
|
||||
msg.seqData[0] |= uValueHelper.uiUint64Value & 0xff;
|
||||
|
||||
// Compose CAN_Output.LockDoor02Left
|
||||
uValueHelper.s32.u32.uiValue = static_cast<uint32_t>(std::min(std::max(static_cast<long long int>(m_sigLockDoor02Left.Read(transaction)), 0ll), 1ll));
|
||||
uValueHelper.uiUint64Value <<= 5;
|
||||
msg.seqData[0] |= uValueHelper.uiUint64Value & 63;
|
||||
|
||||
// Compose CAN_Output.LockDoor01Right
|
||||
uValueHelper.s32.u32.uiValue = static_cast<uint32_t>(std::min(std::max(static_cast<long long int>(m_sigLockDoor01Right.Read(transaction)), 0ll), 1ll));
|
||||
uValueHelper.uiUint64Value <<= 3;
|
||||
msg.seqData[0] |= uValueHelper.uiUint64Value & 15;
|
||||
|
||||
// Compose CAN_Output.LockDoor01Left
|
||||
uValueHelper.s32.u32.uiValue = static_cast<uint32_t>(std::min(std::max(static_cast<long long int>(m_sigLockDoor01Left.Read(transaction)), 0ll), 1ll));
|
||||
uValueHelper.uiUint64Value <<= 1;
|
||||
msg.seqData[0] |= uValueHelper.uiUint64Value & 3;
|
||||
|
||||
// Finalize the transaction
|
||||
transaction.Finish();
|
||||
|
||||
// Transmit the message
|
||||
// TODO: Determine CAN interface index...
|
||||
m_pSend->Send(msg, 0);
|
||||
}
|
||||
|
||||
300
examples/door_demo_example/can_dl_door/datalink.h
Normal file
300
examples/door_demo_example/can_dl_door/datalink.h
Normal file
@@ -0,0 +1,300 @@
|
||||
/**
|
||||
* @file datalink.h
|
||||
* @date 2025-09-06 08:00:37
|
||||
* This file defines the data link object between CAN and the V-API devices.
|
||||
* This file was generated by the DBC utility from:
|
||||
* "", "datalink_4doors_example.dbc"
|
||||
* DBC file version: 1.0.0.1
|
||||
*/
|
||||
#ifndef __DBC_GENERATED__DATALINK_H__20250906_080037_856__
|
||||
#define __DBC_GENERATED__DATALINK_H__20250906_080037_856__
|
||||
|
||||
#include <support/component_impl.h>
|
||||
#include <interfaces/can.h>
|
||||
#include <support/interface_ptr.h>
|
||||
#include <support/signal_support.h>
|
||||
|
||||
/**
|
||||
* @brief Data link class.
|
||||
*/
|
||||
class CDataLink : public sdv::CSdvObject, public sdv::IObjectControl, public sdv::can::IReceive
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CDataLink();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CDataLink();
|
||||
|
||||
// Interface map
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
SDV_INTERFACE_ENTRY(sdv::can::IReceive)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
// Declarations
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("CAN_data_link")
|
||||
DECLARE_DEFAULT_OBJECT_NAME("DataLink")
|
||||
DECLARE_OBJECT_SINGLETON()
|
||||
|
||||
/**
|
||||
* @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
void Initialize(const sdv::u8string& ssObjectConfig) override;
|
||||
|
||||
/**
|
||||
* @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
|
||||
* @return Return the current status of the object.
|
||||
*/
|
||||
sdv::EObjectStatus GetStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode) override;
|
||||
|
||||
/**
|
||||
* @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
|
||||
*/
|
||||
void Shutdown() override;
|
||||
|
||||
/**
|
||||
* @brief Process a receive a CAN message. Overload of sdv::can::IReceive::Receive.
|
||||
* @param[in] sMsg Message that was received.
|
||||
* @param[in] uiIfcIndex Interface index of the received message.
|
||||
*/
|
||||
virtual void Receive(/*in*/ const sdv::can::SMessage& sMsg, /*in*/ uint32_t uiIfcIndex) override;
|
||||
|
||||
/**
|
||||
* @brief Process an error frame. Overload of sdv::can::IReceive::Error.
|
||||
* @param[in] sError Error frame that was received.
|
||||
* @param[in] uiIfcIndex Interface index of the received message.
|
||||
*/
|
||||
virtual void Error(/*in*/ const sdv::can::SErrorFrame& sError, /*in*/ uint32_t uiIfcIndex) override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Union containing all the compound values needed to convert between the DBC defined types.
|
||||
*/
|
||||
union UValueHelper
|
||||
{
|
||||
uint64_t uiUint64Value; ///< The 64-bit unsingned value.
|
||||
int64_t iInt64Value; ///< The 64-bit signed value.
|
||||
|
||||
/**
|
||||
* @brief The structure mapping the 32-bit value types into the 64-bit.
|
||||
*/
|
||||
struct S32
|
||||
{
|
||||
#if (!defined(_MSC_VER) || defined(__clang__)) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
uint32_t uiPadding; ///< Padding for big endian byte ordering (MSB)
|
||||
#endif
|
||||
/**
|
||||
* @brief The 32-bit union containing the possible 32-bit values.
|
||||
*/
|
||||
union U32Value
|
||||
{
|
||||
int32_t iValue; ///< 32-bit signed integer.
|
||||
uint32_t uiValue; ///< 32-bit unsigned integer.
|
||||
float fValue; ///< 32-bit floating point number.
|
||||
} u32; ///< 32-bit union instance.
|
||||
|
||||
#if (defined(_MSC_VER) && !defined(__clang__)) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
uint32_t uiPadding; ///< Padding for little endian byte ordering (MSB)
|
||||
#endif
|
||||
} s32;
|
||||
|
||||
double dValue; ///< 64-bit double precision floating point number.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief RX CAN message definition of: CAN_Input_L1 [id=1]
|
||||
*/
|
||||
struct SRxMsg_CAN_Input_L1
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rdispatch Reference to the dispatch service.
|
||||
*/
|
||||
SRxMsg_CAN_Input_L1(sdv::core::CDispatchService& rdispatch);
|
||||
|
||||
/**
|
||||
* @brief Initialize the message by registering all signals.
|
||||
*/
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
* @brief Terminate the message by unregistering all signals.
|
||||
*/
|
||||
void Term();
|
||||
|
||||
/**
|
||||
* @brief Process received data.
|
||||
* @param[in] rseqData Reference to the message data to process.
|
||||
*/
|
||||
void Process(const sdv::sequence<uint8_t>& rseqData);
|
||||
|
||||
sdv::core::CDispatchService& m_rdispatch; ///< Reference to the dispatch service.
|
||||
|
||||
/// Signal Door01LeftIsOpen with unit
|
||||
sdv::core::CSignal m_sigDoor01LeftIsOpen;
|
||||
} m_sRxMsgCAN_Input_L1;
|
||||
|
||||
/**
|
||||
* @brief RX CAN message definition of: CAN_Input_R1 [id=2]
|
||||
*/
|
||||
struct SRxMsg_CAN_Input_R1
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rdispatch Reference to the dispatch service.
|
||||
*/
|
||||
SRxMsg_CAN_Input_R1(sdv::core::CDispatchService& rdispatch);
|
||||
|
||||
/**
|
||||
* @brief Initialize the message by registering all signals.
|
||||
*/
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
* @brief Terminate the message by unregistering all signals.
|
||||
*/
|
||||
void Term();
|
||||
|
||||
/**
|
||||
* @brief Process received data.
|
||||
* @param[in] rseqData Reference to the message data to process.
|
||||
*/
|
||||
void Process(const sdv::sequence<uint8_t>& rseqData);
|
||||
|
||||
sdv::core::CDispatchService& m_rdispatch; ///< Reference to the dispatch service.
|
||||
|
||||
/// Signal Door01RightIsOpen with unit
|
||||
sdv::core::CSignal m_sigDoor01RightIsOpen;
|
||||
} m_sRxMsgCAN_Input_R1;
|
||||
|
||||
/**
|
||||
* @brief RX CAN message definition of: CAN_Input_L2 [id=3]
|
||||
*/
|
||||
struct SRxMsg_CAN_Input_L2
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rdispatch Reference to the dispatch service.
|
||||
*/
|
||||
SRxMsg_CAN_Input_L2(sdv::core::CDispatchService& rdispatch);
|
||||
|
||||
/**
|
||||
* @brief Initialize the message by registering all signals.
|
||||
*/
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
* @brief Terminate the message by unregistering all signals.
|
||||
*/
|
||||
void Term();
|
||||
|
||||
/**
|
||||
* @brief Process received data.
|
||||
* @param[in] rseqData Reference to the message data to process.
|
||||
*/
|
||||
void Process(const sdv::sequence<uint8_t>& rseqData);
|
||||
|
||||
sdv::core::CDispatchService& m_rdispatch; ///< Reference to the dispatch service.
|
||||
|
||||
/// Signal Door02LeftIsOpen with unit
|
||||
sdv::core::CSignal m_sigDoor02LeftIsOpen;
|
||||
} m_sRxMsgCAN_Input_L2;
|
||||
|
||||
/**
|
||||
* @brief RX CAN message definition of: CAN_Input_R2 [id=4]
|
||||
*/
|
||||
struct SRxMsg_CAN_Input_R2
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rdispatch Reference to the dispatch service.
|
||||
*/
|
||||
SRxMsg_CAN_Input_R2(sdv::core::CDispatchService& rdispatch);
|
||||
|
||||
/**
|
||||
* @brief Initialize the message by registering all signals.
|
||||
*/
|
||||
bool Init();
|
||||
|
||||
/**
|
||||
* @brief Terminate the message by unregistering all signals.
|
||||
*/
|
||||
void Term();
|
||||
|
||||
/**
|
||||
* @brief Process received data.
|
||||
* @param[in] rseqData Reference to the message data to process.
|
||||
*/
|
||||
void Process(const sdv::sequence<uint8_t>& rseqData);
|
||||
|
||||
sdv::core::CDispatchService& m_rdispatch; ///< Reference to the dispatch service.
|
||||
|
||||
/// Signal Door02RightIsOpen with unit
|
||||
sdv::core::CSignal m_sigDoor02RightIsOpen;
|
||||
} m_sRxMsgCAN_Input_R2;
|
||||
|
||||
/**
|
||||
* @brief TX CAN message definition of: CAN_Output [id=5]
|
||||
*/
|
||||
struct STxMsg_CAN_Output
|
||||
{
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rdispatch Reference to the dispatch service.
|
||||
*/
|
||||
STxMsg_CAN_Output(sdv::core::CDispatchService& rdispatch);
|
||||
|
||||
/**
|
||||
* @brief Initialize the message by registering all signals.
|
||||
* @param[in] pSend The send-interface of the CAN.
|
||||
*/
|
||||
bool Init(sdv::can::ISend* pSend);
|
||||
|
||||
/**
|
||||
* @brief Terminate the message by unregistering all signals.
|
||||
*/
|
||||
void Term();
|
||||
|
||||
/**
|
||||
* @brief Transmit data.
|
||||
* @param[in] pCanSend Pointer to the CAN send interface.
|
||||
*/
|
||||
void Transmit();
|
||||
|
||||
sdv::core::CDispatchService& m_rdispatch; ///< Reference to the dispatch service.
|
||||
sdv::core::CTrigger m_trigger; ///< Message trigger being called by the dispatch service.
|
||||
sdv::can::ISend* m_pSend = nullptr; ///< Message sending interface.
|
||||
|
||||
/// Signal LockDoor02Right with unit
|
||||
sdv::core::CSignal m_sigLockDoor02Right;
|
||||
/// Signal LockDoor02Left with unit
|
||||
sdv::core::CSignal m_sigLockDoor02Left;
|
||||
/// Signal LockDoor01Right with unit
|
||||
sdv::core::CSignal m_sigLockDoor01Right;
|
||||
/// Signal LockDoor01Left with unit
|
||||
sdv::core::CSignal m_sigLockDoor01Left;
|
||||
} m_sTxMsgCAN_Output;
|
||||
|
||||
sdv::EObjectStatus m_eStatus = sdv::EObjectStatus::initialization_pending; ///< Keep track of the object status.
|
||||
size_t m_nIfcIndex = 0; ///< CAN Interface index.
|
||||
sdv::can::IRegisterReceiver* m_pRegister = nullptr; ///< CAN receiver registration interface.
|
||||
sdv::can::ISend* m_pSend = nullptr; ///< CAN sender interface.
|
||||
sdv::core::CDispatchService m_dispatch; ///< Dispatch service
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CDataLink)
|
||||
|
||||
#endif // !defined __DBC_GENERATED__DATALINK_H__20250906_080037_856__
|
||||
@@ -0,0 +1,8 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
|
||||
|
||||
12
examples/door_demo_example/config/data_link_door.toml
Normal file
12
examples/door_demo_example/config/data_link_door.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "can_com_sim.sdv"
|
||||
Class = "CAN_Com_Sim"
|
||||
Source="door_example_receiver.asc"
|
||||
Target="door_example_writer.asc"
|
||||
|
||||
[[Component]]
|
||||
Path = "can_dl_door.sdv"
|
||||
Class = "CAN_data_link"
|
||||
10
examples/door_demo_example/config/door_comple_service.toml
Normal file
10
examples/door_demo_example/config/door_comple_service.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "door_complex_service.sdv"
|
||||
Class = "Doors Example Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Service"
|
||||
@@ -0,0 +1,14 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_reardoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Left_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_reardoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Left_Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_reardoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Right_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_reardoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Right_Service"
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
12
examples/door_demo_example/coreconfig/door_demo.toml
Normal file
12
examples/door_demo_example/coreconfig/door_demo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "door_complex_service.sdv"
|
||||
Class = "Doors Example Service"
|
||||
Name = "Doors Example Service"
|
||||
|
||||
[[Module]]
|
||||
Path = "doors_service_proxystub.sdv"
|
||||
|
||||
|
||||
9
examples/door_demo_example/coreconfig/platform.toml
Normal file
9
examples/door_demo_example/coreconfig/platform.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "can_com_sim.sdv"
|
||||
Class = "CAN_Com_Sim"
|
||||
Source="door_example_receiver.asc"
|
||||
Target="door_example_writer.asc"
|
||||
|
||||
28
examples/door_demo_example/coreconfig/settings.toml
Normal file
28
examples/door_demo_example/coreconfig/settings.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
# Settings file
|
||||
[Settings]
|
||||
Version = 100
|
||||
|
||||
# The system config array can contain zero or more configurations that are loaded at the time
|
||||
# the system ist started. It is advisable to split the configurations in:
|
||||
# platform config - containing all the components needed to interact with the OS,
|
||||
# middleware, vehicle bus, Ethernet.
|
||||
# vehicle interface - containing the vehicle bus interpretation components like data link
|
||||
# based on DBC and devices for their abstraction.
|
||||
# vehicle abstraction - containing the basic services
|
||||
# Load the system configurations by providing the "SystemConfig" keyword as an array of strings.
|
||||
# A relative path is relative to the installation directory (being "exe_location/instance_id").
|
||||
#
|
||||
# Example:
|
||||
# SystemConfig = [ "platform.toml", "vehicle_ifc.toml", "vehicle_abstract.toml" ]
|
||||
|
||||
SystemConfig = [ "platform.toml", "vehicle_ifc.toml", "vehicle_abstract.toml"]
|
||||
|
||||
# The application config contains the configuration file that can be updated when services and
|
||||
# apps are being added to the system (or being removed from the system). Load the application
|
||||
# config by providing the "AppConfig" keyword as a string value. A relative path is relative to
|
||||
# the installation directory (being "exe_location/instance_id").
|
||||
#
|
||||
# Example
|
||||
# AppConfig = "app_config.toml"
|
||||
#
|
||||
AppConfig = "door_demo.toml"
|
||||
26
examples/door_demo_example/coreconfig/vehicle_abstract.toml
Normal file
26
examples/door_demo_example/coreconfig/vehicle_abstract.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Service"
|
||||
Name = "Vehicle.Chassis.Door.Axle01.Left_Service"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Service"
|
||||
Name = "Vehicle.Chassis.Door.Axle01.Right_Service"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_reardoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Left_Service"
|
||||
Name = "Vehicle.Chassis.Door.Axle02.Left_Service"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_reardoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Right_Service"
|
||||
Name = "Vehicle.Chassis.Door.Axle02.Right_Service"
|
||||
|
||||
[[Module]]
|
||||
Path = "doors_proxystub.sdv"
|
||||
|
||||
28
examples/door_demo_example/coreconfig/vehicle_ifc.toml
Normal file
28
examples/door_demo_example/coreconfig/vehicle_ifc.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "can_dl_door.sdv"
|
||||
Class = "CAN_data_link"
|
||||
Name = "DataLink"
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Device"
|
||||
Name = "Vehicle.Chassis.Door.Axle01.Left_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Device"
|
||||
Name = "Vehicle.Chassis.Door.Axle01.Right_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_reardoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Left_Device"
|
||||
Name = "Vehicle.Chassis.Door.Axle02.Left_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_reardoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Right_Device"
|
||||
Name = "Vehicle.Chassis.Door.Axle02.Right_Device"
|
||||
|
||||
|
||||
131
examples/door_demo_example/datalink_2doors_example.dbc
Normal file
131
examples/door_demo_example/datalink_2doors_example.dbc
Normal file
@@ -0,0 +1,131 @@
|
||||
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_: doors
|
||||
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_ 2 CAN_Input_R1: 1 Vector__XXX
|
||||
SG_ Door01RightIsOpen : 3|1@0+ (1,0) [0|1] "" doors
|
||||
|
||||
BO_ 1 CAN_Input_L1: 1 Vector__XXX
|
||||
SG_ Door01LeftIsOpen : 1|1@0+ (1,0) [0|1] "" doors
|
||||
|
||||
BO_ 5 CAN_Output: 1 doors
|
||||
SG_ LockDoor01Right : 3|1@0+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LockDoor01Left : 1|1@0+ (1,0) [0|1] "" Vector__XXX
|
||||
|
||||
|
||||
|
||||
CM_ SG_ 2 Door01RightIsOpen "Open / Closed signal of front right door";
|
||||
CM_ SG_ 1 Door01LeftIsOpen "Open / Closed signal of front left door";
|
||||
CM_ SG_ 5 LockDoor01Right "Lock / Unlock signal of front right door";
|
||||
CM_ SG_ 5 LockDoor01Left "Lock / Unlock signal of front left door";
|
||||
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_ "GenMsgCycleTime" BO_ 2 10;
|
||||
BA_ "GenMsgSendType" BO_ 2 0;
|
||||
BA_ "GenMsgSendType" BO_ 1 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 1 10;
|
||||
BA_ "GenMsgSendType" BO_ 5 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 5 10;
|
||||
|
||||
147
examples/door_demo_example/datalink_4doors_example.dbc
Normal file
147
examples/door_demo_example/datalink_4doors_example.dbc
Normal file
@@ -0,0 +1,147 @@
|
||||
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_: doors
|
||||
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_ 4 CAN_Input_R2: 1 Vector__XXX
|
||||
SG_ Door02RightIsOpen : 7|1@0+ (1,0) [0|1] "" doors
|
||||
|
||||
BO_ 3 CAN_Input_L2: 1 Vector__XXX
|
||||
SG_ Door02LeftIsOpen : 5|1@0+ (1,0) [0|1] "" doors
|
||||
|
||||
BO_ 2 CAN_Input_R1: 1 Vector__XXX
|
||||
SG_ Door01RightIsOpen : 3|1@0+ (1,0) [0|1] "" doors
|
||||
|
||||
BO_ 1 CAN_Input_L1: 1 Vector__XXX
|
||||
SG_ Door01LeftIsOpen : 1|1@0+ (1,0) [0|1] "" doors
|
||||
|
||||
BO_ 5 CAN_Output: 1 doors
|
||||
SG_ LockDoor02Right : 7|1@0+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LockDoor02Left : 5|1@0+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LockDoor01Right : 3|1@0+ (1,0) [0|1] "" Vector__XXX
|
||||
SG_ LockDoor01Left : 1|1@0+ (1,0) [0|1] "" Vector__XXX
|
||||
|
||||
|
||||
|
||||
CM_ SG_ 4 Door02RightIsOpen "Open / Closed signal of rear right door";
|
||||
CM_ SG_ 3 Door02LeftIsOpen "Open / Closed signal of rear left door";
|
||||
CM_ SG_ 2 Door01RightIsOpen "Open / Closed signal of front right door";
|
||||
CM_ SG_ 1 Door01LeftIsOpen "Open / Closed signal of front left door";
|
||||
CM_ SG_ 5 LockDoor02Right "Lock / Unlock signal of rear right door";
|
||||
CM_ SG_ 5 LockDoor02Left "Lock / Unlock signal of frear left door";
|
||||
CM_ SG_ 5 LockDoor01Right "Lock / Unlock signal of front right door";
|
||||
CM_ SG_ 5 LockDoor01Left "Lock / Unlock signal of front left door";
|
||||
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_ "GenMsgCycleTime" BO_ 4 10;
|
||||
BA_ "GenMsgSendType" BO_ 4 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 3 10;
|
||||
BA_ "GenMsgSendType" BO_ 3 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 2 10;
|
||||
BA_ "GenMsgSendType" BO_ 2 0;
|
||||
BA_ "GenMsgSendType" BO_ 1 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 1 10;
|
||||
BA_ "GenMsgSendType" BO_ 5 0;
|
||||
BA_ "GenMsgCycleTime" BO_ 5 10;
|
||||
|
||||
448
examples/door_demo_example/door_app/console.cpp
Normal file
448
examples/door_demo_example/door_app/console.cpp
Normal file
@@ -0,0 +1,448 @@
|
||||
#include "include/console.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <conio.h> // Needed for _kbhit
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
const CConsole::SConsolePos g_sTitle{ 1, 1 };
|
||||
const CConsole::SConsolePos g_sSubTitle{ 2, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator11{ 4, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator12{ 6, 1 };
|
||||
const CConsole::SConsolePos g_sFrontLeftDoorIsOpen{ 7, 1 };
|
||||
const CConsole::SConsolePos g_sFrontRightDoorIsOpen{ 8, 1 };
|
||||
const CConsole::SConsolePos g_sRearLeftDoorIsOpen{ 9, 1 };
|
||||
const CConsole::SConsolePos g_sRearRightDoorIsOpen{ 10, 1 };
|
||||
const CConsole::SConsolePos g_sFrontLeftDoorIsLocked{ 7, 42 };
|
||||
const CConsole::SConsolePos g_sFrontRightDoorIsLocked{ 8, 42 };
|
||||
const CConsole::SConsolePos g_sRearLeftDoorIsLocked{ 9, 42 };
|
||||
const CConsole::SConsolePos g_sRearRightDoorIsLocked{ 10, 42 };
|
||||
const CConsole::SConsolePos g_sSeparator21{ 12, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator22{ 14, 1 };
|
||||
const CConsole::SConsolePos g_sVehicleDevice{ 15, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator31{ 17, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator32{ 19, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceL1{ 20, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceR1{ 21, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceL2{ 22, 1 };
|
||||
const CConsole::SConsolePos g_sBasicServiceR2{ 23, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator41{ 25, 1 };
|
||||
const CConsole::SConsolePos g_sSeparator42{ 26, 1 };
|
||||
const CConsole::SConsolePos g_sComplexService{ 27, 1 };
|
||||
const CConsole::SConsolePos g_sControlDescription{ 29, 1 };
|
||||
const CConsole::SConsolePos g_sCursor{ 30, 1 };
|
||||
|
||||
CConsole::CConsole()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// Enable ANSI escape codes
|
||||
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hStdOut != INVALID_HANDLE_VALUE && GetConsoleMode(hStdOut, &m_dwConsoleOutMode))
|
||||
SetConsoleMode(hStdOut, m_dwConsoleOutMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (hStdIn != INVALID_HANDLE_VALUE && GetConsoleMode(hStdIn, &m_dwConsoleInMode))
|
||||
SetConsoleMode(hStdIn, m_dwConsoleInMode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT));
|
||||
#elif defined __unix__
|
||||
// Disable echo
|
||||
tcgetattr(STDIN_FILENO, &m_sTermAttr);
|
||||
struct termios sTermAttrTemp = m_sTermAttr;
|
||||
sTermAttrTemp.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &sTermAttrTemp);
|
||||
m_iFileStatus = fcntl(STDIN_FILENO, F_GETFL, 0);
|
||||
fcntl(STDIN_FILENO, F_SETFL, m_iFileStatus | O_NONBLOCK);
|
||||
#else
|
||||
#error The OS is not supported!
|
||||
#endif
|
||||
}
|
||||
|
||||
CConsole::~CConsole()
|
||||
{
|
||||
SetCursorPos(g_sCursor);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Return to the stored console mode
|
||||
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hStdOut != INVALID_HANDLE_VALUE)
|
||||
SetConsoleMode(hStdOut, m_dwConsoleOutMode);
|
||||
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (hStdIn != INVALID_HANDLE_VALUE)
|
||||
SetConsoleMode(hStdIn, m_dwConsoleInMode);
|
||||
#elif defined __unix__
|
||||
// Return the previous file status flags.
|
||||
fcntl(STDIN_FILENO, F_SETFL, m_iFileStatus);
|
||||
|
||||
// Return to previous terminal state
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &m_sTermAttr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CConsole::PrintHeader(const uint32_t numberOfDoors)
|
||||
{
|
||||
// Clear the screen...
|
||||
std::cout << "\x1b[2J";
|
||||
|
||||
std::string title = "Door demo example: Data link attached (4 doors) ";
|
||||
if (numberOfDoors <= 4)
|
||||
{
|
||||
title = "Door demo example: Vehicle has ";
|
||||
title.append(std::to_string(numberOfDoors));
|
||||
title.append(" doors.");
|
||||
}
|
||||
|
||||
// Print the titles
|
||||
PrintText(g_sTitle, title.c_str());
|
||||
PrintText(g_sSubTitle, " Doors are locked automatically after 2 seconds when all doors are closed.");
|
||||
PrintText(g_sSeparator11, "============================================================================");
|
||||
PrintText(g_sSeparator12, "Data dispatch service:");
|
||||
PrintText(g_sFrontLeftDoorIsOpen, "Front Left Door:.. not available");
|
||||
PrintText(g_sFrontRightDoorIsOpen, "Front Right Door:.. not available");
|
||||
PrintText(g_sRearLeftDoorIsOpen, "Rear Left Door:.. not available");
|
||||
PrintText(g_sRearRightDoorIsOpen, "Rear Right Door:.. not available");
|
||||
PrintText(g_sSeparator21, "----------------------------------------------------------------------------");
|
||||
PrintText(g_sSeparator22, "Vehicle device:");
|
||||
PrintText(g_sVehicleDevice, "Vehicle Device Interface not available.");
|
||||
PrintText(g_sSeparator31, "----------------------------------------------------------------------------");
|
||||
PrintText(g_sSeparator32, "Basic services:");
|
||||
PrintText(g_sBasicServiceL1, "Basic Service Interface not available.");
|
||||
PrintText(g_sSeparator41, "----------------------------------------------------------------------------");
|
||||
PrintText(g_sSeparator42, "Complex service:");
|
||||
PrintText(g_sComplexService, "Complex Service Interface not available.");
|
||||
if (!m_isExternalApp)
|
||||
{
|
||||
PrintText(g_sControlDescription, "Press 'X' to quit; '1', '2', '3', '4' to toggle doors...");
|
||||
}
|
||||
else
|
||||
{
|
||||
title.append(" [Connected to an instance]");
|
||||
PrintText(g_sTitle, title.c_str());
|
||||
PrintText(g_sControlDescription, "Press 'X' to quit; Doors are toggled automatically");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CConsole::PrepareDataConsumers()
|
||||
{
|
||||
if (!m_isExternalApp)
|
||||
{
|
||||
if(!(PrepareDataConsumersForStandAlone()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
auto basicServiceL1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (!basicServiceL1)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'LeftService::IVSS_IsOpen': [CConsole]");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Interface exists -> Clean the line for Console window */
|
||||
PrintText(g_sBasicServiceL1, " ");
|
||||
}
|
||||
basicServiceL1->RegisterOnSignalChangeOfLeftDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
bool value = false;
|
||||
PrintValue(g_sFrontLeftDoorIsLocked, "Front Left Latch:", value, (value ? "locked" : "unlocked"));
|
||||
|
||||
// all other doors are optional
|
||||
auto basicServiceR1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR1)
|
||||
{
|
||||
basicServiceR1->RegisterOnSignalChangeOfRightDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
PrintValue(g_sFrontRightDoorIsLocked, "Front Right Latch:", value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
|
||||
auto basicServiceL2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (basicServiceL2)
|
||||
{
|
||||
basicServiceL2->RegisterOnSignalChangeOfLeftDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
PrintValue(g_sRearLeftDoorIsLocked, "Rear Left Latch:", value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
|
||||
auto basicServiceR2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR2)
|
||||
{
|
||||
basicServiceR2->RegisterOnSignalChangeOfRightDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
PrintValue(g_sRearRightDoorIsLocked, "Rear Right Latch:", value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
|
||||
m_pDoorService = sdv::core::GetObject("Doors Example Service").GetInterface<IDoorService>();
|
||||
if (!m_pDoorService)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: Could not get complex service interface 'IDoorService'");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_isExternalApp)
|
||||
{
|
||||
PrintText(g_sFrontLeftDoorIsLocked, " ");
|
||||
PrintText(g_sFrontRightDoorIsLocked, " ");
|
||||
PrintText(g_sRearLeftDoorIsLocked, " ");
|
||||
PrintText(g_sRearRightDoorIsLocked, " ");
|
||||
PrintText(g_sFrontLeftDoorIsOpen, "External Application, no dispatch service.");
|
||||
PrintText(g_sFrontRightDoorIsOpen, " ");
|
||||
PrintText(g_sRearLeftDoorIsOpen, " ");
|
||||
PrintText(g_sRearRightDoorIsOpen, " ");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CConsole::ResetSignals()
|
||||
{
|
||||
// Set the cursor position at the end
|
||||
SetCursorPos(g_sCursor);
|
||||
|
||||
// Registrate for the vehicle device & basic service of the front left door. Front left door mzust exist, the others are optional
|
||||
auto vehicleDevice = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_IsOpen>();
|
||||
if (vehicleDevice)
|
||||
vehicleDevice->UnregisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceL1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (basicServiceL1)
|
||||
basicServiceL1->UnregisterOnSignalChangeOfLeftDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceR1 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR1)
|
||||
basicServiceR1->UnregisterOnSignalChangeOfRightDoorIsOpen01(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceL2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (basicServiceL2)
|
||||
basicServiceL2->UnregisterOnSignalChangeOfLeftDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
auto basicServiceR2 = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (basicServiceR2)
|
||||
basicServiceR2->UnregisterOnSignalChangeOfRightDoorIsOpen02(dynamic_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister the data link signalss
|
||||
if (m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsOpen.Reset();
|
||||
if (m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsOpen.Reset();
|
||||
if (m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsOpen.Reset();
|
||||
if (m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsOpen.Reset();
|
||||
if (m_SignalFrontLeftDoorIsLocked)
|
||||
m_SignalFrontLeftDoorIsLocked.Reset();
|
||||
if (m_SignalFrontRightDoorIsLocked)
|
||||
m_SignalFrontRightDoorIsLocked.Reset();
|
||||
if (m_SignalRearLeftDoorIsLocked)
|
||||
m_SignalRearLeftDoorIsLocked.Reset();
|
||||
if (m_SignalRearRightDoorIsLocked)
|
||||
m_SignalRearRightDoorIsLocked.Reset();
|
||||
}
|
||||
|
||||
void CConsole::StartUpdateDataThread()
|
||||
{
|
||||
if (m_bThreadStarted)
|
||||
return;
|
||||
|
||||
m_bThreadStarted = true;
|
||||
|
||||
m_bRunning = true;
|
||||
m_threadReadTxSignals = std::thread(&CConsole::UpdateDataThreadFunc, this);
|
||||
}
|
||||
|
||||
void CConsole::StopUpdateDataThread()
|
||||
{
|
||||
// Stop running and wait for any thread to finalize
|
||||
m_bRunning = false;
|
||||
if (m_threadReadTxSignals.joinable())
|
||||
m_threadReadTxSignals.join();
|
||||
}
|
||||
|
||||
void CConsole::SetExternalApp()
|
||||
{
|
||||
m_isExternalApp = true;
|
||||
}
|
||||
|
||||
void CConsole::WriteIsOpen(bool value)
|
||||
{
|
||||
PrintValue(g_sVehicleDevice, "Front Left Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenL1(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceL1, "Front Left Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenR1(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceR1, "Front Right Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenL2(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceL2, "Rear Left Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::SetIsOpenR2(bool value)
|
||||
{
|
||||
PrintValue(g_sBasicServiceR2, "Rear Right Door:", value, (value ? "open" : "closed"));
|
||||
}
|
||||
|
||||
bool CConsole::PrepareDataConsumersForStandAlone()
|
||||
{
|
||||
// Subscribe for the door and if available get TX signal. Either both exists or none of them
|
||||
sdv::core::CDispatchService dispatch;
|
||||
m_SignalFrontLeftDoorIsOpen = dispatch.Subscribe(doors::dsLeftDoorIsOpen01, [&](sdv::any_t value) { CallbackFrontLeftDoorIsOpen(value); });
|
||||
if(m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch01, 0);
|
||||
|
||||
m_SignalFrontRightDoorIsOpen = dispatch.Subscribe(doors::dsRightDoorIsOpen01, [&](sdv::any_t value) { CallbackFrontRightDoorIsOpen(value); });
|
||||
if(m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch01, 0);
|
||||
|
||||
m_SignalRearLeftDoorIsOpen = dispatch.Subscribe(doors::dsLeftDoorIsOpen02, [&](sdv::any_t value) {CallbackRearLeftDoorIsOpen(value); });
|
||||
if(m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch02, 0);
|
||||
|
||||
m_SignalRearRightDoorIsOpen = dispatch.Subscribe(doors::dsRightDoorIsOpen02, [&](sdv::any_t value) { CallbackRearRightDoorIsOpen(value); });
|
||||
if(m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch02, 0);
|
||||
|
||||
// Validate: Either both exists or none of them
|
||||
if (m_SignalFrontLeftDoorIsOpen != m_SignalFrontLeftDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalFrontLeftDoorIsOpen != m_SignalFrontLeftDoorIsLocked do not match, failed");
|
||||
return false;
|
||||
}
|
||||
if (m_SignalFrontRightDoorIsOpen != m_SignalFrontRightDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalFrontRightDoorIsOpen != m_SignalFrontRightDoorIsLocked do not match, failed");
|
||||
return false;
|
||||
}
|
||||
if (m_SignalRearLeftDoorIsOpen != m_SignalRearLeftDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalRearLeftDoorIsOpen != m_SignalRearLeftDoorIsLockeddo not match, failed");
|
||||
return false;
|
||||
}
|
||||
if (m_SignalRearRightDoorIsOpen != m_SignalRearRightDoorIsLocked)
|
||||
{
|
||||
SDV_LOG_ERROR("Console ERROR: m_SignalRearRightDoorIsOpen != m_SignalRearRightDoorIsLocked do not match, failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Registrate for the vehicle device & basic service of the front left door. Front left door mzust exist, the others are optional
|
||||
auto vehicleDevice = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Device").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_IsOpen>();
|
||||
if (!vehicleDevice)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'LeftDevice::IVSS_IsOpen': [CConsole]");
|
||||
return false;
|
||||
}
|
||||
vehicleDevice->RegisterIsOpenEvent(dynamic_cast<vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event*> (this));
|
||||
return true;
|
||||
}
|
||||
|
||||
void CConsole::CallbackFrontLeftDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_FrontLeftDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sFrontLeftDoorIsOpen, "Front Left Door:", m_FrontLeftDoorIsOpen, (m_FrontLeftDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
void CConsole::CallbackFrontRightDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_FrontRightDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sFrontRightDoorIsOpen, "Front Right Door:", m_FrontRightDoorIsOpen, (m_FrontRightDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
void CConsole::CallbackRearLeftDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_RearLeftDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sRearLeftDoorIsOpen, "Rear Left Door:", m_RearLeftDoorIsOpen, (m_RearLeftDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
void CConsole::CallbackRearRightDoorIsOpen(sdv::any_t value)
|
||||
{
|
||||
m_RearRightDoorIsOpen = value.get<bool>();
|
||||
PrintValue(g_sRearRightDoorIsOpen, "Rear Right Door:", m_RearRightDoorIsOpen, (m_RearRightDoorIsOpen ? "open" : "closed"));
|
||||
}
|
||||
|
||||
void CConsole::UpdateDataThreadFunc()
|
||||
{
|
||||
bool bDoorsAreLocked = true;
|
||||
bool bFirstStatusCheck = true;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
while (m_bRunning)
|
||||
{
|
||||
if (!m_isExternalApp)
|
||||
{
|
||||
UpdateTXSignal(g_sFrontLeftDoorIsLocked, "Front Left Latch:", m_SignalFrontLeftDoorIsLocked, m_FrontLeftDoorIsLocked);
|
||||
UpdateTXSignal(g_sFrontRightDoorIsLocked, "Front Right Latch:", m_SignalFrontRightDoorIsLocked, m_FrontRightDoorIsLocked);
|
||||
UpdateTXSignal(g_sRearLeftDoorIsLocked, "Rear Left Latch:", m_SignalRearLeftDoorIsLocked, m_RearLeftDoorIsLocked);
|
||||
UpdateTXSignal(g_sRearRightDoorIsLocked, "Rear Right Latch:", m_SignalRearRightDoorIsLocked, m_RearRightDoorIsLocked);
|
||||
}
|
||||
|
||||
if (m_pDoorService)
|
||||
{
|
||||
auto latch = m_pDoorService->GetDoorsStatus();
|
||||
if ((bDoorsAreLocked != latch) || (bFirstStatusCheck))
|
||||
{
|
||||
bDoorsAreLocked = latch;
|
||||
PrintText(g_sComplexService, bDoorsAreLocked ? "All doors are locked" :"All doors are unlocked");
|
||||
bFirstStatusCheck = false;
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
}
|
||||
|
||||
void CConsole::UpdateTXSignal(SConsolePos sPos, const std::string& label, sdv::core::CSignal& signal, bool& value)
|
||||
{
|
||||
// signal may be optional (door may not exist)
|
||||
if (signal)
|
||||
{
|
||||
auto frontLeftDoorIsLocked = value;
|
||||
value = signal.Read().get<bool>();
|
||||
if (frontLeftDoorIsLocked != value)
|
||||
{
|
||||
PrintValue(sPos, label , value, (value ? "locked" : "unlocked"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CConsole::SConsolePos CConsole::GetCursorPos() const
|
||||
{
|
||||
SConsolePos sPos{};
|
||||
std::cout << "\033[6n";
|
||||
|
||||
char buff[128];
|
||||
int indx = 0;
|
||||
for(;;) {
|
||||
int cc = std::cin.get();
|
||||
buff[indx] = (char)cc;
|
||||
indx++;
|
||||
if(cc == 'R') {
|
||||
buff[indx + 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
int iRow = 0, iCol = 0;
|
||||
sscanf(buff, "\x1b[%d;%dR", &iRow, &iCol);
|
||||
sPos.uiRow = static_cast<uint32_t>(iRow);
|
||||
sPos.uiCol = static_cast<uint32_t>(iCol);
|
||||
fseek(stdin, 0, SEEK_END);
|
||||
|
||||
return sPos;
|
||||
}
|
||||
|
||||
void CConsole::SetCursorPos(SConsolePos sPos)
|
||||
{
|
||||
std::cout << "\033[" << sPos.uiRow << ";" << sPos.uiCol << "H";
|
||||
}
|
||||
|
||||
void CConsole::PrintText(SConsolePos sPos, const std::string& rssText)
|
||||
{
|
||||
auto text = rssText;
|
||||
while (text.length() < 47)
|
||||
{
|
||||
text.append(" ");
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mtxPrintToConsole);
|
||||
SetCursorPos(sPos);
|
||||
std::cout << text;
|
||||
}
|
||||
246
examples/door_demo_example/door_app/door_application.cpp
Normal file
246
examples/door_demo_example/door_app/door_application.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
#include "../door_app/include/door_application.h"
|
||||
#include "../door_app/include/signal_names.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <conio.h> // Needed for _kbhit
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
bool CDoorControl::LoadConfigFile(const std::string& inputMsg, const std::string& configFileName)
|
||||
{
|
||||
std::string msg = inputMsg;
|
||||
if (m_appcontrol.LoadConfig(configFileName) == sdv::core::EConfigProcessResult::successful)
|
||||
{
|
||||
msg.append("ok\n");
|
||||
std::cout << msg.c_str();
|
||||
return true;
|
||||
}
|
||||
|
||||
msg.append("FAILED.\n");
|
||||
std::cout << msg.c_str();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CDoorControl::KeyHit()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _kbhit();
|
||||
#elif __unix__
|
||||
int ch = getchar();
|
||||
if (ch != EOF) {
|
||||
ungetc(ch, stdin);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
char CDoorControl::GetChar()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return static_cast<char>(_getch());
|
||||
#else
|
||||
return getchar();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CDoorControl::RegisterSignals()
|
||||
{
|
||||
sdv::core::CDispatchService dispatch;
|
||||
|
||||
m_SignalFrontLeftDoorIsOpen = dispatch.RegisterRxSignal(doors::dsLeftDoorIsOpen01);
|
||||
m_SignalFrontLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch01, 0);
|
||||
|
||||
if (m_iNumberOfDoors > 1)
|
||||
{
|
||||
m_SignalFrontRightDoorIsOpen = dispatch.RegisterRxSignal(doors::dsRightDoorIsOpen01);
|
||||
m_SignalFrontRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch01, 0);
|
||||
|
||||
if (m_iNumberOfDoors > 2)
|
||||
{
|
||||
m_SignalRearLeftDoorIsOpen = dispatch.RegisterRxSignal(doors::dsLeftDoorIsOpen02);
|
||||
m_SignalRearLeftDoorIsLocked = dispatch.RegisterTxSignal(doors::dsLeftLatch02, 0);
|
||||
|
||||
if (m_iNumberOfDoors > 3)
|
||||
{
|
||||
m_SignalRearRightDoorIsOpen = dispatch.RegisterRxSignal(doors::dsRightDoorIsOpen02);
|
||||
m_SignalRearRightDoorIsLocked = dispatch.RegisterTxSignal(doors::dsRightLatch02, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CDoorControl::IsSDVFrameworkEnvironmentSet()
|
||||
{
|
||||
const char* envVariable = std::getenv("SDV_FRAMEWORK_RUNTIME");
|
||||
if (envVariable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDoorControl::Initialize(const uint32_t numberOfDoors)
|
||||
{
|
||||
if (m_bInitialized)
|
||||
return true;
|
||||
|
||||
if ((numberOfDoors >= 1) && (numberOfDoors <= 4))
|
||||
{
|
||||
m_iNumberOfDoors = numberOfDoors;
|
||||
}
|
||||
|
||||
if (!IsSDVFrameworkEnvironmentSet())
|
||||
{
|
||||
// if SDV_FRAMEWORK_RUNTIME environment variable is not set we need to set the Framework Runtime directory
|
||||
m_appcontrol.SetFrameworkRuntimeDirectory("../../bin");
|
||||
}
|
||||
|
||||
if(!m_appcontrol.Startup(""))
|
||||
return false;
|
||||
|
||||
// Switch to config mode.
|
||||
m_appcontrol.SetConfigMode();
|
||||
bool bResult = LoadConfigFile("Load dispatch example: ", "data_dispatch_example.toml");
|
||||
|
||||
bResult &= LoadConfigFile("Load task timer: ", "task_timer_example.toml");
|
||||
bResult &= RegisterSignals();
|
||||
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for front left door: ", "front_left_door_example.toml");
|
||||
if (m_iNumberOfDoors > 1)
|
||||
{
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for front right door: ", "front_right_door_example.toml");
|
||||
if (m_iNumberOfDoors > 2)
|
||||
{
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for rear left door: ", "rear_left_door_example.toml");
|
||||
if (m_iNumberOfDoors > 3)
|
||||
{
|
||||
bResult &= LoadConfigFile("Load vehicle devices and basic services for rear right door: ", "rear_right_door_example.toml");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bResult &= LoadConfigFile("Load door service (complex service): ", "door_comple_service.toml");
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
SDV_LOG_ERROR("One or more configurations could not be loaded. Cannot continue.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t CDoorControl::GetNumberOfDoors() const
|
||||
{
|
||||
return m_iNumberOfDoors;
|
||||
}
|
||||
|
||||
void CDoorControl::Shutdown()
|
||||
{
|
||||
if (!m_bInitialized)
|
||||
m_appcontrol.Shutdown();
|
||||
m_bInitialized = false;
|
||||
}
|
||||
|
||||
void CDoorControl::SetRunningMode()
|
||||
{
|
||||
m_appcontrol.SetRunningMode();
|
||||
}
|
||||
|
||||
|
||||
void CDoorControl::RunUntilBreak()
|
||||
{
|
||||
bool bRunning = true;
|
||||
bool openFrontLeftDoor = true;
|
||||
bool openFrontRightDoor = true;
|
||||
bool openRearLeftDoor = true;
|
||||
bool openRearRightDoor = true;
|
||||
|
||||
// Update console by writing the first value if available
|
||||
if (m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsOpen.Write<bool>(openFrontLeftDoor);
|
||||
if (m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsOpen.Write<bool>(openFrontRightDoor);
|
||||
if (m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsOpen.Write<bool>(openRearLeftDoor);
|
||||
if (m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsOpen.Write<bool>(openRearRightDoor);
|
||||
|
||||
while (bRunning)
|
||||
{
|
||||
// Check for a key
|
||||
if (!KeyHit())
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get a keyboard value (if there is any).
|
||||
char c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
openFrontLeftDoor = !openFrontLeftDoor;
|
||||
if (m_SignalFrontLeftDoorIsOpen)
|
||||
m_SignalFrontLeftDoorIsOpen.Write<bool>(openFrontLeftDoor);
|
||||
break;
|
||||
case '2':
|
||||
openFrontRightDoor = !openFrontRightDoor;
|
||||
if (m_SignalFrontRightDoorIsOpen)
|
||||
m_SignalFrontRightDoorIsOpen.Write<bool>(openFrontRightDoor);
|
||||
break;
|
||||
case '3':
|
||||
openRearLeftDoor = !openRearLeftDoor;
|
||||
if (m_SignalRearLeftDoorIsOpen)
|
||||
m_SignalRearLeftDoorIsOpen.Write<bool>(openRearLeftDoor);
|
||||
break;
|
||||
case '4':
|
||||
openRearRightDoor = !openRearRightDoor;
|
||||
if (m_SignalRearRightDoorIsOpen)
|
||||
m_SignalRearRightDoorIsOpen.Write<bool>(openRearRightDoor);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
bRunning = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CDoorControl::UserInputNumberOfDoors()
|
||||
{
|
||||
uint32_t numberOfDoors = 4;
|
||||
// Clear the screen and goto top...
|
||||
std::cout << "\x1b[2J\033[0;0H";
|
||||
std::cout << "How many doors does the vehicle have? Press a number between 1 and 4: ";
|
||||
|
||||
// Get a keyboard value (if there is any).
|
||||
char c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case '1':
|
||||
numberOfDoors = 1;
|
||||
break;
|
||||
case '2':
|
||||
numberOfDoors = 2;
|
||||
break;
|
||||
case '3':
|
||||
numberOfDoors = 3;
|
||||
break;
|
||||
case '4':
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return numberOfDoors;
|
||||
}
|
||||
27
examples/door_demo_example/door_app/door_demo_example.cpp
Normal file
27
examples/door_demo_example/door_app/door_demo_example.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include "../door_app/include/door_application.h"
|
||||
#include "../door_app/include/console.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
CDoorControl appobj;
|
||||
if (!appobj.Initialize(appobj.UserInputNumberOfDoors()))
|
||||
{
|
||||
std::cout << "ERROR: Failed to initialize application control." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CConsole visual_obj;
|
||||
visual_obj.PrintHeader(appobj.GetNumberOfDoors());
|
||||
visual_obj.PrepareDataConsumers();
|
||||
visual_obj.StartUpdateDataThread();
|
||||
|
||||
appobj.SetRunningMode();
|
||||
appobj.RunUntilBreak();
|
||||
|
||||
visual_obj.StopUpdateDataThread();
|
||||
visual_obj.ResetSignals();
|
||||
|
||||
appobj.Shutdown();
|
||||
return 0;
|
||||
}
|
||||
102
examples/door_demo_example/door_app/door_extern_application.cpp
Normal file
102
examples/door_demo_example/door_app/door_extern_application.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "../door_app/include/door_extern_application.h"
|
||||
#include "../door_app/include/signal_names.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <conio.h> // Needed for _kbhit
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
bool CDoorExternControl::Initialize()
|
||||
{
|
||||
if (m_bInitialized)
|
||||
return true;
|
||||
|
||||
if (!IsSDVFrameworkEnvironmentSet())
|
||||
{
|
||||
// if SDV_FRAMEWORK_RUNTIME environment variable is not set we need to set the Framework Runtime directory
|
||||
m_appcontrol.SetFrameworkRuntimeDirectory("../../bin");
|
||||
}
|
||||
|
||||
std::stringstream sstreamAppConfig;
|
||||
sstreamAppConfig << "[Application]" << std::endl;
|
||||
sstreamAppConfig << "Mode=\"External\"" << std::endl;
|
||||
sstreamAppConfig << "Instance=\"3002\"" << std::endl;
|
||||
sstreamAppConfig << "Retries=" << 6 << std::endl;
|
||||
sstreamAppConfig << "[Console]" << std::endl;
|
||||
sstreamAppConfig << "Report=\"Silent\"" << std::endl;
|
||||
|
||||
if (!m_appcontrol.Startup(sstreamAppConfig.str()))
|
||||
return false;
|
||||
|
||||
m_bInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDoorExternControl::Shutdown()
|
||||
{
|
||||
if (!m_bInitialized)
|
||||
m_appcontrol.Shutdown();
|
||||
m_bInitialized = false;
|
||||
}
|
||||
|
||||
void CDoorExternControl::RunUntilBreak()
|
||||
{
|
||||
bool bRunning = true;
|
||||
|
||||
while (bRunning)
|
||||
{
|
||||
// Check for a key
|
||||
if (!KeyHit())
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get a keyboard value (if there is any).
|
||||
char c = GetChar();
|
||||
switch (c)
|
||||
{
|
||||
case 'x':
|
||||
case 'X':
|
||||
bRunning = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CDoorExternControl::IsSDVFrameworkEnvironmentSet()
|
||||
{
|
||||
const char* envVariable = std::getenv("SDV_FRAMEWORK_RUNTIME");
|
||||
if (envVariable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDoorExternControl::KeyHit()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _kbhit();
|
||||
#elif __unix__
|
||||
int ch = getchar();
|
||||
if (ch != EOF) {
|
||||
ungetc(ch, stdin);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
char CDoorExternControl::GetChar()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return static_cast<char>(_getch());
|
||||
#else
|
||||
return getchar();
|
||||
#endif
|
||||
}
|
||||
27
examples/door_demo_example/door_app/door_extern_example.cpp
Normal file
27
examples/door_demo_example/door_app/door_extern_example.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include "../door_app/include/door_extern_application.h"
|
||||
#include "../door_app/include/console.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
CDoorExternControl appobj;
|
||||
if (!appobj.Initialize())
|
||||
{
|
||||
std::cout << "ERROR: Failed to initialize application control." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CConsole visual_obj;
|
||||
visual_obj.SetExternalApp();
|
||||
visual_obj.PrintHeader(4);
|
||||
visual_obj.PrepareDataConsumers();
|
||||
visual_obj.StartUpdateDataThread();
|
||||
|
||||
appobj.RunUntilBreak();
|
||||
|
||||
visual_obj.StopUpdateDataThread();
|
||||
visual_obj.ResetSignals();
|
||||
|
||||
appobj.Shutdown();
|
||||
return 0;
|
||||
}
|
||||
271
examples/door_demo_example/door_app/include/console.h
Normal file
271
examples/door_demo_example/door_app/include/console.h
Normal file
@@ -0,0 +1,271 @@
|
||||
#ifndef CONSOLE_OUTPUT_H
|
||||
#define CONSOLE_OUTPUT_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <support/signal_support.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/timer.h>
|
||||
#include "signal_names.h"
|
||||
#include <fcntl.h>
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle01left_vd_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle01left_bs_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle01right_bs_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle02left_bs_rx.h"
|
||||
#include "../interfaces/vss_vehiclechassisdooraxle02right_bs_rx.h"
|
||||
|
||||
#ifdef __unix__
|
||||
#include <termios.h> // Needed for tcgetattr and fcntl
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "../generated/door_service/door_ifc.h"
|
||||
|
||||
/**
|
||||
* @brief Console operation class.
|
||||
* @details This class retrieves RX data from the data dispatch service, vehicle device & basic service of front left door on event change.
|
||||
* Furthermore, it shows TX value by polling the RX signals.
|
||||
*/
|
||||
class CConsole : public vss::Vehicle::Chassis::Door::Axle01::LeftDevice::IVSS_WriteIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Screen position structure
|
||||
*/
|
||||
struct SConsolePos
|
||||
{
|
||||
uint32_t uiRow; ///< Row position (starts at 1)
|
||||
uint32_t uiCol; ///< Column position (starts at 1)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CConsole();
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CConsole();
|
||||
|
||||
/**
|
||||
* @brief Print the header.
|
||||
* @param[in] numberOfDoors number of doors
|
||||
*/
|
||||
void PrintHeader(const uint32_t numberOfDoors);
|
||||
|
||||
/**
|
||||
* @brief Prepare the data consumers..
|
||||
* @details Gets all signals (4 RX signals showing Open/Closed doors and 4 TX signals if the doors are locked)
|
||||
* Open/Closed is done as input (user) while locking the doors is done automatically by complex service when all doors are closed
|
||||
* Need to work independent from the number of doors (1-4)
|
||||
* @return Returns whether the preparation of the data consumers was successful or not.
|
||||
*/
|
||||
bool PrepareDataConsumers();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write leftDoorIsOpen signal
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal (front door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL1(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (front door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR1(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal (rear door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL2(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (rear door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR2(bool value) override;
|
||||
|
||||
/**
|
||||
* @brief For gracefully shutdown all signals need to be reset.
|
||||
*/
|
||||
void ResetSignals();
|
||||
|
||||
/**
|
||||
* @brief Starts thread for polling the TX signals (if the doors are locked by the complex service)
|
||||
*/
|
||||
void StartUpdateDataThread();
|
||||
|
||||
/**
|
||||
* @brief Stops thread
|
||||
*/
|
||||
void StopUpdateDataThread();
|
||||
|
||||
/**
|
||||
* @brief Used to set a flag for when we use external App
|
||||
*/
|
||||
void SetExternalApp();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Prepare the data consumers for Standalone application
|
||||
* @return Returns whether the preparation of the Standalone data consumers was successful or not.
|
||||
*/
|
||||
bool PrepareDataConsumersForStandAlone();
|
||||
|
||||
/**
|
||||
* @brief Callback function when front left door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackFrontLeftDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Callback function when front right door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackFrontRightDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Callback function when rear left door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackRearLeftDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Callback function when rear right door is opened or closed (by user).
|
||||
* @param[in] value The value of the signal to update.
|
||||
*/
|
||||
void CallbackRearRightDoorIsOpen(sdv::any_t value);
|
||||
|
||||
/**
|
||||
* @brief Read the data link TX signals and print them into the console.
|
||||
*/
|
||||
void UpdateDataThreadFunc();
|
||||
|
||||
/**
|
||||
* @brief Update the signal on the console output depending on the signal
|
||||
* @details Check if the signal is valid. If invalid, ignore it.
|
||||
*/
|
||||
void UpdateTXSignal(SConsolePos sPos, const std::string& label, sdv::core::CSignal& signal, bool& value);
|
||||
|
||||
/**
|
||||
* @brief Get the cursor position of the console.
|
||||
* @return The cursor position.
|
||||
*/
|
||||
SConsolePos GetCursorPos() const;
|
||||
|
||||
/**
|
||||
* @brief Set the current cursor position for the console.
|
||||
* @param[in] sPos Console position to place the current cursor at.
|
||||
*/
|
||||
void SetCursorPos(SConsolePos sPos);
|
||||
|
||||
/**
|
||||
* @brief Print text at a specific location.
|
||||
* @param[in] sPos The location to print text at.
|
||||
* @param[in] rssText Reference to the text to print.
|
||||
*/
|
||||
void PrintText(SConsolePos sPos, const std::string& rssText);
|
||||
|
||||
/**
|
||||
* @brief Print a value string at a specific location.
|
||||
* @tparam TValue Type of value.
|
||||
* @param[in] sPos The location to print the value at.
|
||||
* @param[in] rssName Reference to the value.
|
||||
* @param[in] tValue The value.
|
||||
* @param[in] rssStatus Status, becuse we have signals of type bool
|
||||
*/
|
||||
template <typename TValue>
|
||||
void PrintValue(SConsolePos sPos, const std::string& rssName, TValue tValue, const std::string& rssStatus);
|
||||
|
||||
/**
|
||||
* @brief Align string between name and value.
|
||||
* @param[in] message Reference to the message to align.
|
||||
* @param[in] desiredLength The desired length or 0 when no length is specified.
|
||||
* @return The aligned string.
|
||||
*/
|
||||
std::string AlignString(const std::string& message, uint32_t desiredLength = 0);
|
||||
|
||||
mutable std::mutex m_mtxPrintToConsole; ///< Mutex to print complete message
|
||||
bool m_bThreadStarted = false; ///< Set when initialized.
|
||||
bool m_bRunning = false; ///< When set, the application is running.
|
||||
bool m_isExternalApp = false; ///< True when we have an external application
|
||||
mutable std::mutex m_mPrintToConsole; ///< Mutex to print complete message
|
||||
|
||||
std::thread m_threadReadTxSignals; ///< Simulation datalink thread.
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsOpen; ///< Front Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsOpen; ///< Front Right Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsOpen; ///< Rear Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsOpen; ///< Rear Right Door signal (RX input) - open / closed
|
||||
|
||||
bool m_FrontLeftDoorIsOpen = false; ///< Front Left Door value (RX input signal) - open / closed
|
||||
bool m_FrontRightDoorIsOpen = false; ///< Front Right Door value (RX input signal) - open / closed
|
||||
bool m_RearLeftDoorIsOpen = false; ///< Rear Left Door value (RX input signal) - open / closed
|
||||
bool m_RearRightDoorIsOpen = false; ///< Rear Right Door value (RX input signal) - open / closed
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsLocked; ///< Front Left Door signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsLocked; ///< Front Right Door signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsLocked; ///< Rear Left Door signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsLocked; ///< Rear Right Door signal (TX output) - locked / unlocked
|
||||
|
||||
bool m_FrontLeftDoorIsLocked = false; ///< Front Left Door value (TX output) - locked / unlocked
|
||||
bool m_FrontRightDoorIsLocked = false; ///< Front Right Door value (TX output) - locked / unlocked
|
||||
bool m_RearLeftDoorIsLocked = false; ///< Rear Left Door value (TX output) - locked / unlocked
|
||||
bool m_RearRightDoorIsLocked = false; ///< Rear Right Door value (TX output) - locked / unlocked
|
||||
|
||||
IDoorService* m_pDoorService = nullptr; ///< Door service interface pointer.
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD m_dwConsoleOutMode = 0u; ///< The console mode before switching on ANSI support.
|
||||
DWORD m_dwConsoleInMode = 0u; ///< The console mode before switching on ANSI support.
|
||||
#elif defined __unix__
|
||||
struct termios m_sTermAttr{}; ///< The terminal attributes before disabling echo.
|
||||
int m_iFileStatus = 0; ///< The file status flags for STDIN.
|
||||
#else
|
||||
#error The OS is not supported!
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template <typename TValue>
|
||||
inline void CConsole::PrintValue(SConsolePos sPos, const std::string& rssName, TValue tValue, const std::string& rssUnits)
|
||||
{
|
||||
std::string endName = " ";
|
||||
const size_t nEndNameLen = 14 - rssUnits.size();
|
||||
const size_t nValueNameLen = 26;
|
||||
std::stringstream sstreamValueText;
|
||||
sstreamValueText << rssName <<
|
||||
std::string(nValueNameLen - std::min(rssName.size(), static_cast<size_t>(nValueNameLen - 1)) - 1, '.') <<
|
||||
" " << std::fixed << std::setprecision(2) << tValue << " " << rssUnits <<
|
||||
std::string(nEndNameLen - std::min(endName.size(), static_cast<size_t>(nEndNameLen - 1)) - 1, ' ');
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mPrintToConsole);
|
||||
SetCursorPos(sPos);
|
||||
std::cout << sstreamValueText.str();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void CConsole::PrintValue<bool>(SConsolePos sPos, const std::string& rssName, bool bValue, const std::string& rssStatus)
|
||||
{;
|
||||
PrintValue(sPos, rssName, bValue ? "" : "", rssStatus);
|
||||
}
|
||||
|
||||
#endif // !define CONSOLE_OUTPUT_H
|
||||
@@ -0,0 +1,99 @@
|
||||
#include <string>
|
||||
#include <support/app_control.h>
|
||||
#include <support/signal_support.h>
|
||||
|
||||
/**
|
||||
* @brief Application Class of the door example
|
||||
*/
|
||||
class CDoorControl
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Start and initialize the application control and load vehicle devices and
|
||||
* basic services depending on the number of doors
|
||||
* @param[in] numberOfDoors number of doors (1-4), default 4
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool Initialize(const uint32_t numberOfDoors = 4);
|
||||
|
||||
/**
|
||||
* @brief After initialization/configuration the system mode needs to be set to running mode
|
||||
*/
|
||||
void SetRunningMode();
|
||||
|
||||
/**
|
||||
* @brief Ask user for input how many doors the vehicle should have (1-4)
|
||||
* @return Return number of doors (default 4)
|
||||
*/
|
||||
uint32_t UserInputNumberOfDoors();
|
||||
|
||||
/**
|
||||
* @brief Run loop as long as user input does not exit
|
||||
* Allow user to open/close each door.
|
||||
*/
|
||||
void RunUntilBreak();
|
||||
|
||||
/**
|
||||
* @brief Shutdown the system.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* @brief Get number of doors
|
||||
* @return Return number of doors (default 4)
|
||||
*/
|
||||
uint32_t GetNumberOfDoors() const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief check if SDV_FRAMEWORK_RUNTIME environment variable exists
|
||||
* @return Return true if environment variable is found otherwise false
|
||||
*/
|
||||
bool IsSDVFrameworkEnvironmentSet();
|
||||
|
||||
/**
|
||||
* @brief Loac config file and register vehicle device and basic service.
|
||||
* @remarks It is expected that each config file has the complete door:
|
||||
* vehicle device & basic service for input and output
|
||||
* @param[in] inputMsg message string to be printed on console in case of success and failure
|
||||
* @param[in] configFileName config toml file name
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool LoadConfigFile(const std::string& inputMsg, const std::string& configFileName);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Key hit check. Windows uses the _kbhit function; POSIX emulates this.
|
||||
* @return Returns whether a key has been pressed.
|
||||
*/
|
||||
bool KeyHit();
|
||||
|
||||
/**
|
||||
* @brief Get the character from the keyboard buffer if pressed.
|
||||
* @return Returns the character from the keyboard buffer.
|
||||
*/
|
||||
char GetChar();
|
||||
|
||||
/**
|
||||
* @brief Register/Create Signals in the dispatch service depending on the number of doors
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool RegisterSignals();
|
||||
|
||||
sdv::app::CAppControl m_appcontrol; ///< App-control of SDV V-API.
|
||||
bool m_bInitialized = false; ///< Set when initialized.
|
||||
uint32_t m_iNumberOfDoors = 4; ///< Number iof doors, maximuum 4
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsOpen; ///< Front Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsOpen; ///< Front Right Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsOpen; ///< Rear Left Door signal (RX input) - open / closed
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsOpen; ///< Rear Right Door signal (RX input) - open / closed
|
||||
|
||||
sdv::core::CSignal m_SignalFrontLeftDoorIsLocked; ///< Front Left Latch signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalFrontRightDoorIsLocked; ///< Front Right Latch signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearLeftDoorIsLocked; ///< Rear Left Latch signal (TX output) - locked / unlocked
|
||||
sdv::core::CSignal m_SignalRearRightDoorIsLocked; ///< Rear Right Latch signal (TX output) - locked / unlocked
|
||||
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
#include <string>
|
||||
#include <support/app_control.h>
|
||||
#include <support/signal_support.h>
|
||||
|
||||
/**
|
||||
* @brief Application Class of the door example
|
||||
*/
|
||||
class CDoorExternControl
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Start and initialize the application control and load vehicle devices and
|
||||
* basic services depending on the numerb of doors
|
||||
* @return Return true on success otherwise false
|
||||
*/
|
||||
bool Initialize();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Run loop as long as user input does not exit
|
||||
* Allow user to open/close each door.
|
||||
*/
|
||||
void RunUntilBreak();
|
||||
|
||||
/**
|
||||
* @brief Shutdown the system.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief check if SDV_FRAMEWORK_RUNTIME environment variable exists
|
||||
* @return Return true if environment variable is found otherwise false
|
||||
*/
|
||||
bool IsSDVFrameworkEnvironmentSet();
|
||||
|
||||
/**
|
||||
* @brief Key hit check. Windows uses the _kbhit function; POSIX emulates this.
|
||||
* @return Returns whether a key has been pressed.
|
||||
*/
|
||||
bool KeyHit();
|
||||
|
||||
/**
|
||||
* @brief Get the character from the keyboard buffer if pressed.
|
||||
* @return Returns the character from the keyboard buffer.
|
||||
*/
|
||||
char GetChar();
|
||||
|
||||
sdv::app::CAppControl m_appcontrol; ///< App-control of SDV V-API.
|
||||
bool m_bInitialized = false; ///< Set when initialized.
|
||||
uint32_t m_iNumberOfDoors = 4; ///< Number iof doors, maximuum 4
|
||||
|
||||
};
|
||||
30
examples/door_demo_example/door_app/include/signal_names.h
Normal file
30
examples/door_demo_example/door_app/include/signal_names.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* namespace for the signal names
|
||||
* in case /interfaces/signal_identifier.h
|
||||
* exists, use the file, otherwise define the namespace
|
||||
*/
|
||||
#ifndef SIGNAL_NAMES_H
|
||||
#define SIGNAL_NAMES_H
|
||||
|
||||
#ifdef __has_include
|
||||
#if __has_include("../interfaces/signal_identifier.h")
|
||||
#include "../interfaces/signal_identifier.h"
|
||||
#else
|
||||
|
||||
namespace doors
|
||||
{
|
||||
// Data Dispatch Service signal names to dbc variable names C-type RX/TX vss name space
|
||||
static std::string dsLeftDoorIsOpen01 = "CAN_Input_L1.Door01LeftIsOpen"; ///< bool RX Vehicle.Chassis.Door.Axle01.Left
|
||||
static std::string dsRightDoorIsOpen01 = "CAN_Input_R1.Door01RightIs"; ///< bool RX Vehicle.Chassis.Door.Axle01.Right
|
||||
static std::string dsLeftDoorIsOpen02 = "CAN_Input_L2.Door02LeftIsOpen"; ///< bool RX Vehicle.Chassis.Door.Axle02.Left
|
||||
static std::string dsRightDoorIsOpen02 = "CAN_Input_R2.Door02RightIsOpen"; ///< bool RX Vehicle.Chassis.Door.Axle02.Right
|
||||
static std::string dsLeftLatch01 = "CAN_Output.LockDoor01Left" ; ///< bool TX Vehicle.Chassis.TX.Door.Axle01.Left
|
||||
static std::string dsRightLatch01 = "CAN_Output.LockDoor01Right"; ///< bool TX Vehicle.Chassis.TX.Door.Axle01.Right
|
||||
static std::string dsLeftLatch02 = "CAN_Output.LockDoor02Left" ; ///< bool TX Vehicle.Chassis.TX.Door.Axle02.Left
|
||||
static std::string dsRightLatch02 = "CAN_Output.LockDoor02Right"; ///< bool TX Vehicle.Chassis.TX.Door.Axle02.Right
|
||||
} // doors
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // SIGNAL_NAMES_H
|
||||
42
examples/door_demo_example/door_example_receiver.asc
Normal file
42
examples/door_demo_example/door_example_receiver.asc
Normal file
@@ -0,0 +1,42 @@
|
||||
date 08/28/25 19:10:31
|
||||
base hex timestamps absolute
|
||||
Begin Triggerblock 08/28/25 19:10:31
|
||||
0.000000 Start of measurement
|
||||
0.021165 1 1 Rx d 1 02
|
||||
0.031165 1 2 Rx d 1 08
|
||||
0.041165 1 3 Rx d 1 20
|
||||
0.051165 1 4 Rx d 1 80
|
||||
3.002210 1 1 Rx d 1 00
|
||||
3.502858 1 2 Rx d 1 00
|
||||
4.002858 1 3 Rx d 1 00
|
||||
4.502858 1 4 Rx d 1 00
|
||||
9.021165 1 1 Rx d 1 02
|
||||
9.031165 1 2 Rx d 1 08
|
||||
9.041165 1 3 Rx d 1 20
|
||||
9.051165 1 4 Rx d 1 80
|
||||
13.021165 1 1 Rx d 1 00
|
||||
13.031165 1 2 Rx d 1 00
|
||||
13.041165 1 3 Rx d 1 00
|
||||
13.051165 1 4 Rx d 1 00
|
||||
17.021165 1 1 Rx d 1 02
|
||||
17.031165 1 2 Rx d 1 08
|
||||
17.041165 1 3 Rx d 1 20
|
||||
17.051165 1 4 Rx d 1 80
|
||||
19.002210 1 1 Rx d 1 00
|
||||
19.502858 1 2 Rx d 1 00
|
||||
20.002858 1 3 Rx d 1 00
|
||||
20.502858 1 4 Rx d 1 00
|
||||
24.021165 1 1 Rx d 1 02
|
||||
24.031165 1 2 Rx d 1 08
|
||||
24.041165 1 3 Rx d 1 20
|
||||
24.051165 1 4 Rx d 1 80
|
||||
27.021165 1 1 Rx d 1 00
|
||||
27.031165 1 2 Rx d 1 00
|
||||
27.041165 1 3 Rx d 1 00
|
||||
27.051165 1 4 Rx d 1 00
|
||||
30.021165 1 1 Rx d 1 02
|
||||
30.031165 1 2 Rx d 1 08
|
||||
30.041165 1 3 Rx d 1 20
|
||||
30.051165 1 4 Rx d 1 80
|
||||
|
||||
End TriggerBlock
|
||||
154
examples/door_demo_example/door_service/complex_service.cpp
Normal file
154
examples/door_demo_example/door_service/complex_service.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <iostream>
|
||||
#include "complex_service.h"
|
||||
|
||||
void CDoorsExampleService::Initialize(const sdv::u8string& /*ssObjectConfig*/)
|
||||
{
|
||||
m_eStatus = sdv::EObjectStatus::initializing;
|
||||
|
||||
// Request the basic service for front left door.
|
||||
auto pFrontLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (pFrontLeftDoorSvc)
|
||||
{
|
||||
// Register front left door change event handler.
|
||||
pFrontLeftDoorSvc->RegisterOnSignalChangeOfLeftDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for front right door.
|
||||
auto pFrontRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (pFrontRightDoorSvc)
|
||||
{
|
||||
// Register front right door change event handler.
|
||||
pFrontRightDoorSvc->RegisterOnSignalChangeOfRightDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for rear left door.
|
||||
auto pRearLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (pRearLeftDoorSvc)
|
||||
{
|
||||
// Register rear left door change event handler.
|
||||
pRearLeftDoorSvc->RegisterOnSignalChangeOfLeftDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for front right door.
|
||||
auto pRearRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (pRearRightDoorSvc)
|
||||
{
|
||||
// Register rear right door change event handler.
|
||||
pRearRightDoorSvc->RegisterOnSignalChangeOfRightDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
}
|
||||
|
||||
// Request the basic service for locking the front left door.
|
||||
m_pFrontLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetLock>();
|
||||
|
||||
// Request the basic service for locking the front right door.
|
||||
m_pFrontRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetLock>();
|
||||
|
||||
// Request the basic service for locking the rear left door.
|
||||
m_pRearLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetLock>();
|
||||
|
||||
// Request the basic service for locking the rear right door.
|
||||
m_pRearRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetLock>();
|
||||
|
||||
// Validate if we have the Open/Closed signal and the Lock/Unlock door signal, both must exist together or both must not exist
|
||||
// Front left door is an exception, it isalways required
|
||||
if ((!pFrontLeftDoorSvc) || (!m_pFrontLeftDoorSvc))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interfaces for 'Front left door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pFrontRightDoorSvc == nullptr) != (m_pFrontRightDoorSvc == nullptr))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get both interfaces for 'Front right door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pRearLeftDoorSvc == nullptr) != (m_pRearLeftDoorSvc == nullptr))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get both interfaces for 'Rear left door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pRearRightDoorSvc == nullptr) != (m_pRearRightDoorSvc == nullptr))
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get both interfaces for 'Rear right door': [CDoorsExampleService]");
|
||||
m_eStatus = sdv::EObjectStatus::initialization_failure;
|
||||
return;
|
||||
}
|
||||
|
||||
m_doorsThread.start(m_Interval);
|
||||
m_eStatus = sdv::EObjectStatus::initialized;
|
||||
}
|
||||
|
||||
sdv::EObjectStatus CDoorsExampleService::GetStatus() const
|
||||
{
|
||||
return m_eStatus;
|
||||
}
|
||||
|
||||
void CDoorsExampleService::SetOperationMode(sdv::EOperationMode /*eMode*/)
|
||||
{
|
||||
// Not applicable
|
||||
}
|
||||
|
||||
void CDoorsExampleService::Shutdown()
|
||||
{
|
||||
// Unregister front left door change event handler.
|
||||
auto pFrontLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_GetIsOpen>();
|
||||
if (pFrontLeftDoorSvc)
|
||||
pFrontLeftDoorSvc->UnregisterOnSignalChangeOfLeftDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister front right door change event handler.
|
||||
auto pFrontRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle01.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_GetIsOpen>();
|
||||
if (pFrontRightDoorSvc)
|
||||
pFrontRightDoorSvc->UnregisterOnSignalChangeOfRightDoorIsOpen01(static_cast<vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister rear left door change event handler.
|
||||
auto pRearLeftDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Left_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_GetIsOpen>();
|
||||
if (pRearLeftDoorSvc)
|
||||
pRearLeftDoorSvc->UnregisterOnSignalChangeOfLeftDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
// Unregister rear right door change event handler.
|
||||
auto pRearRightDoorSvc = sdv::core::GetObject("Vehicle.Chassis.Door.Axle02.Right_Service").GetInterface<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_GetIsOpen>();
|
||||
if (pRearRightDoorSvc)
|
||||
pRearRightDoorSvc->UnregisterOnSignalChangeOfRightDoorIsOpen02(static_cast<vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event*> (this));
|
||||
|
||||
m_doorsThread.stop();
|
||||
}
|
||||
|
||||
void CDoorsExampleService::AreAllDoorsClosed()
|
||||
{
|
||||
if (m_bFrontLeftDoorIsOpen || m_bFrontRightDoorIsOpen || m_bRearLeftDoorIsOpen || m_bRearRightDoorIsOpen)
|
||||
{
|
||||
m_doorsThread.stop();
|
||||
LockDoors(false);
|
||||
m_bAllDoorsAreLocked = false;
|
||||
return;
|
||||
}
|
||||
m_doorsThread.restart(m_Interval);
|
||||
}
|
||||
|
||||
void CDoorsExampleService::LockDoorsIfAllDoorsAreClosed()
|
||||
{
|
||||
if (m_bFrontLeftDoorIsOpen || m_bFrontRightDoorIsOpen || m_bRearLeftDoorIsOpen || m_bRearRightDoorIsOpen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bAllDoorsAreLocked = true;
|
||||
LockDoors(true);
|
||||
}
|
||||
|
||||
void CDoorsExampleService::LockDoors(const bool lock) const
|
||||
{
|
||||
if (m_pFrontLeftDoorSvc)
|
||||
m_pFrontLeftDoorSvc->SetLock(lock);
|
||||
if (m_pFrontRightDoorSvc)
|
||||
m_pFrontRightDoorSvc->SetLock(lock);
|
||||
if (m_pRearLeftDoorSvc)
|
||||
m_pRearLeftDoorSvc->SetLock(lock);
|
||||
if (m_pRearRightDoorSvc)
|
||||
m_pRearRightDoorSvc->SetLock(lock);
|
||||
}
|
||||
190
examples/door_demo_example/door_service/complex_service.h
Normal file
190
examples/door_demo_example/door_service/complex_service.h
Normal file
@@ -0,0 +1,190 @@
|
||||
#ifndef DOORS_COMPLEX_SERVICE_EXAMPLE_H
|
||||
#define DOORS_COMPLEX_SERVICE_EXAMPLE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// SDV framework support
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
#include <support/timer.h>
|
||||
|
||||
// VSS interfaces - located in ../interfaces
|
||||
#include "vss_vehiclechassisdooraxle01left_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle01left_bs_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle01right_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle01right_bs_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle02left_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle02left_bs_tx.h"
|
||||
#include "vss_vehiclechassisdooraxle02right_bs_rx.h"
|
||||
#include "vss_vehiclechassisdooraxle02right_bs_tx.h"
|
||||
|
||||
#include "lock_doors_thread.h"
|
||||
|
||||
#include "../generated/door_service/door_ifc.h"
|
||||
|
||||
/**
|
||||
* @brief Doors example service: locks/unlocks doors after closing/opening doors
|
||||
*/
|
||||
class CDoorsExampleService : public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event
|
||||
, public vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event
|
||||
, public IDoorService
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CDoorsExampleService() : m_doorsThread([&] { this->LockDoorsIfAllDoorsAreClosed(); }) {}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CDoorsExampleService()
|
||||
{
|
||||
// Just in case...
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
// Interface map
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event)
|
||||
SDV_INTERFACE_ENTRY(IDoorService)
|
||||
END_SDV_INTERFACE_MAP()
|
||||
|
||||
// Object declarations
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService)
|
||||
DECLARE_OBJECT_CLASS_NAME("Doors Example Service")
|
||||
DECLARE_OBJECT_SINGLETON()
|
||||
|
||||
/**
|
||||
* @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
|
||||
* @param[in] ssObjectConfig Optional configuration string.
|
||||
*/
|
||||
void Initialize(const sdv::u8string& ssObjectConfig) override;
|
||||
|
||||
/**
|
||||
* @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
|
||||
* @return Return the current status of the object.
|
||||
*/
|
||||
sdv::EObjectStatus GetStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(sdv::EOperationMode eMode) override;
|
||||
|
||||
/**
|
||||
* @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
|
||||
*/
|
||||
void Shutdown() override;
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal (front door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL1(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bFrontLeftDoorIsOpen != value);
|
||||
m_bFrontLeftDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (front door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR1(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bFrontRightDoorIsOpen != value);
|
||||
m_bFrontRightDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal (rear door)
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL2(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bRearLeftDoorIsOpen != value);
|
||||
m_bRearLeftDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal (rear door)
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR2(bool value) override
|
||||
{
|
||||
auto haschanged = (m_bRearRightDoorIsOpen != value);
|
||||
m_bRearRightDoorIsOpen = value;
|
||||
|
||||
if (haschanged)
|
||||
AreAllDoorsClosed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get doors state. If the doors are locked/unlocked
|
||||
*/
|
||||
virtual bool GetDoorsStatus() override
|
||||
{
|
||||
return m_bAllDoorsAreLocked;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Check if all doors are close
|
||||
* @details If all doors are not closed, unlock doors
|
||||
*/
|
||||
void AreAllDoorsClosed();
|
||||
|
||||
/**
|
||||
* @brief Check if all doors are close
|
||||
* @details If all doors are closed, lock doors, otherwise do nothing. This is a callback function for timer.
|
||||
*/
|
||||
void LockDoorsIfAllDoorsAreClosed();
|
||||
|
||||
/**
|
||||
* @brief Lock or unlock doors
|
||||
* @param[in] lock if true lock doors, otherwise unlock doors
|
||||
*/
|
||||
void LockDoors(const bool lock) const;
|
||||
|
||||
sdv::EObjectStatus m_eStatus = sdv::EObjectStatus::initialization_pending; ///< Current object status
|
||||
|
||||
bool m_bFrontLeftDoorIsOpen = false; ///< Front Left Door Status
|
||||
bool m_bFrontRightDoorIsOpen = false; ///< Front Right Door Status
|
||||
bool m_bRearLeftDoorIsOpen = false; ///< Rear Left Door Status
|
||||
bool m_bRearRightDoorIsOpen = false; ///< Rear Right Door Status
|
||||
|
||||
bool m_bAllDoorsAreLocked = false; ///< state for locked/unlocked of all doors
|
||||
|
||||
///< Door lock interfaces.
|
||||
vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetLock* m_pFrontLeftDoorSvc = nullptr; ///< Front Left Door
|
||||
vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetLock* m_pFrontRightDoorSvc = nullptr; ///< Front Right Door
|
||||
vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetLock* m_pRearLeftDoorSvc = nullptr; ///< Rear Left Door
|
||||
vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetLock* m_pRearRightDoorSvc = nullptr; ///< Rear Right Door
|
||||
|
||||
LockDoorsThread m_doorsThread; ///< timer thread
|
||||
uint32_t m_Interval = 18; ///< interval value * 100 = x milliseconds
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CDoorsExampleService)
|
||||
|
||||
#endif // !define DOORS_COMPLEX_SERVICE_EXAMPLE_H
|
||||
17
examples/door_demo_example/door_service/door_ifc.idl
Normal file
17
examples/door_demo_example/door_service/door_ifc.idl
Normal file
@@ -0,0 +1,17 @@
|
||||
/*******************************************************************************
|
||||
* @file door_ifc.idl
|
||||
* @details Door service interface definition.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief DoorService example service interface. The interface provides functions for the
|
||||
* Doors example complex service.
|
||||
*/
|
||||
interface IDoorService
|
||||
{
|
||||
/**
|
||||
* @brief Status of all doors together whether they are locked or unlocked.
|
||||
* @return true if all doors are locked, otherwise unlocked.
|
||||
*/
|
||||
boolean GetDoorsStatus();
|
||||
};
|
||||
95
examples/door_demo_example/door_service/lock_doors_thread.h
Normal file
95
examples/door_demo_example/door_service/lock_doors_thread.h
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
#ifndef LOCK_DOORS_THREAD_H
|
||||
#define LOCK_DOORS_THREAD_H
|
||||
|
||||
/**
|
||||
* @brief Thread to lock the doors (or execute any other callback the thread gets) after a certain time. can be restarted
|
||||
*/
|
||||
class LockDoorsThread
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor, set the callback function
|
||||
* @param[in] callback function to be called
|
||||
* @param[in] m_running when set to false end thread
|
||||
* @param[in] m_timeIn100MilliSeconds timespan * 100 in milliseconds before callback should be executed
|
||||
*/
|
||||
LockDoorsThread(std::function<void()> callback)
|
||||
: m_callback(callback), m_running(false), m_timeIn100MilliSeconds(0) {}
|
||||
|
||||
/**
|
||||
* @brief Stsrt thread
|
||||
* @param[in] timeSpan the time span before the callback will be executed
|
||||
*/
|
||||
void start(uint32_t timeSpan)
|
||||
{
|
||||
if (m_running)
|
||||
return;
|
||||
|
||||
m_timeIn100MilliSeconds = timeSpan;
|
||||
m_counter = 0;
|
||||
m_running = true;
|
||||
m_thread = std::thread(&LockDoorsThread::run, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop thread
|
||||
*/
|
||||
void stop()
|
||||
{
|
||||
m_running = false;
|
||||
if (m_thread.joinable())
|
||||
{
|
||||
m_thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop and restart thread with new time setting
|
||||
* @param[in] timeSpan the time span before the callback will be executed
|
||||
*/
|
||||
void restart(uint32_t timeSpan)
|
||||
{
|
||||
stop();
|
||||
m_counter = 0;
|
||||
start(timeSpan);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief destructor
|
||||
*/
|
||||
~LockDoorsThread()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief thread loop. If time span is reach, execute callback and reset. Only one execution required
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
while (m_running && m_counter <= m_timeIn100MilliSeconds)
|
||||
{
|
||||
m_counter++;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
}
|
||||
if (m_counter > m_timeIn100MilliSeconds && m_callback)
|
||||
{
|
||||
m_callback();
|
||||
m_counter = 0;
|
||||
}
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
std::function<void()> m_callback; ///< callback function
|
||||
std::atomic<bool> m_running; ///< status if loop is running
|
||||
std::thread m_thread; ///< timer thread
|
||||
uint32_t m_counter; ///< loop counter
|
||||
uint32_t m_timeIn100MilliSeconds; ///< time before the callback will be executed
|
||||
};
|
||||
|
||||
#endif // !define LOCK_DOORS_THREAD_H
|
||||
180
examples/door_demo_example/fmu_Doors2ExampleFMU/CMakeLists.txt
Normal file
180
examples/door_demo_example/fmu_Doors2ExampleFMU/CMakeLists.txt
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
# @file CMakeLists.txt
|
||||
# This file is cmake project file.
|
||||
# This file was generated by the DBC utility from:
|
||||
# datalink_2doors_example.dbc
|
||||
# DBC file version: 1.0.0.1
|
||||
|
||||
|
||||
# Based on CMakeLists.txt from https://github.com/modelica/Reference-FMUs
|
||||
# only FMI 2.0, only CoSimulation
|
||||
# without fumsim
|
||||
|
||||
|
||||
# Only valid for Windows
|
||||
if ( WIN32 )
|
||||
|
||||
# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# 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
|
||||
|
||||
project (Doors2ExampleFMUProject)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Library symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
set(VAPI_CORE_SDV_BINARY_DIR ${CMAKE_BINARY_DIR}/bin)
|
||||
set(MODEL_NAME Doors2ExampleFMU)
|
||||
set(TARGET_NAME ${MODEL_NAME})
|
||||
set(FMU_FULL_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/fmus/${MODEL_NAME}.fmu")
|
||||
|
||||
FUNCTION(cat IN_FILE OUT_FILE)
|
||||
file(READ ${IN_FILE} CONTENTS)
|
||||
file(APPEND ${OUT_FILE} "${CONTENTS}")
|
||||
ENDFUNCTION()
|
||||
|
||||
set(FMI_VERSION 2 CACHE STRING "FMI Version")
|
||||
set_property(CACHE FMI_VERSION PROPERTY STRINGS 2)
|
||||
|
||||
set(FMI_TYPE CS CACHE STRING "FMI Version")
|
||||
set_property(CACHE FMI_TYPE PROPERTY STRINGS CS)
|
||||
set(FMI_TYPE "")
|
||||
|
||||
set (FMI_PLATFORM win32)
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set (FMI_PLATFORM win64)
|
||||
endif ()
|
||||
|
||||
SET(HEADERS
|
||||
${MODEL_NAME}/config.h
|
||||
include/cosimulation.h
|
||||
include/model.h
|
||||
)
|
||||
|
||||
SET(HEADERS
|
||||
${HEADERS}
|
||||
include/fmi2Functions.h
|
||||
include/fmi2FunctionTypes.h
|
||||
include/fmi2TypesPlatform.h
|
||||
)
|
||||
|
||||
SET(SOURCES
|
||||
${MODEL_NAME}/model.cpp
|
||||
src/fmi${FMI_VERSION}Functions.c
|
||||
src/cosimulation.c
|
||||
)
|
||||
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
${HEADERS}
|
||||
${SOURCES}
|
||||
${MODEL_NAME}/FMI${FMI_VERSION}${FMI_TYPE}.xml
|
||||
${MODEL_NAME}/buildDescription.xml
|
||||
)
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/fmus)
|
||||
|
||||
set(FMU_BUILD_DIR temp/${MODEL_NAME})
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
FMI_VERSION=${FMI_VERSION}
|
||||
DISABLE_PREFIX
|
||||
)
|
||||
|
||||
#[[
|
||||
if (MSVC)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
|
||||
endif()
|
||||
]]
|
||||
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE FMI_COSIMULATION)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE include ${MODEL_NAME})
|
||||
target_link_libraries(${TARGET_NAME} Winmm Ws2_32 Rpcrt4.lib)
|
||||
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
)
|
||||
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${MODEL_NAME})
|
||||
|
||||
# modelDescription.xml
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${MODEL_NAME}/FMI${FMI_VERSION}${FMI_TYPE}.xml
|
||||
"${FMU_BUILD_DIR}/modelDescription.xml"
|
||||
)
|
||||
|
||||
set(ARCHIVE_FILES "modelDescription.xml" "binaries")
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${MODEL_NAME}/resources")
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${MODEL_NAME}/resources"
|
||||
"${FMU_BUILD_DIR}/resources/"
|
||||
)
|
||||
set(ARCHIVE_FILES ${ARCHIVE_FILES} "resources")
|
||||
endif()
|
||||
|
||||
# When windows robocopy command (using cmd.exe) is used to copy files its important to set the dependencies
|
||||
# to assure that the copy command is finished before the next custom action to avoid copy/file access failures
|
||||
|
||||
# Copy sdv binaries of this FMU
|
||||
set(DEST_DIR "${FMU_BUILD_DIR}/resources")
|
||||
set(SOURCE_DIR_EXAMPLES_BIN "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
add_custom_target(copy_function_sdv_files_${TARGET_NAME} DEPENDS ${TARGET_NAME})
|
||||
add_custom_command(TARGET copy_function_sdv_files_${TARGET_NAME}
|
||||
COMMAND cmd /C "robocopy \"${SOURCE_DIR_EXAMPLES_BIN}\" \"${DEST_DIR}\" *.pdb *.sdv /NP /R:3 /W:5 || exit /b 0"
|
||||
COMMENT "Copying contents from ${SOURCE_DIR_EXAMPLES_BIN} to ${DEST_DIR}, include only *.pdb *.sdv files"
|
||||
)
|
||||
add_dependencies(copy_function_sdv_files_${TARGET_NAME} ${TARGET_NAME})
|
||||
|
||||
|
||||
|
||||
# Copy framework sdv binaries
|
||||
set(SOURCE_DIR_CORE_BIN "${SDV_FRAMEWORK_RUNTIME}")
|
||||
add_custom_target(copy_framework_sdv_files_${TARGET_NAME} DEPENDS copy_function_sdv_files_${TARGET_NAME})
|
||||
add_custom_command(TARGET copy_framework_sdv_files_${TARGET_NAME}
|
||||
COMMAND cmd /C "robocopy \"${SOURCE_DIR_CORE_BIN}\" \"${DEST_DIR}\" *.pdb *.sdv /NP /R:3 /W:5 || exit /b 0"
|
||||
COMMENT "Copying contents from ${SOURCE_DIR_CORE_BIN} to ${DEST_DIR}, include only *.pdb *.sdv files"
|
||||
)
|
||||
add_dependencies(copy_framework_sdv_files_${TARGET_NAME} copy_function_sdv_files_${TARGET_NAME})
|
||||
|
||||
|
||||
|
||||
# FMU content created, all files copied
|
||||
# to zip the files create a new target 'create_zip' which is build after all files have been copied
|
||||
add_custom_target(create_zip_${TARGET_NAME} ALL DEPENDS copy_framework_sdv_files_${TARGET_NAME} )
|
||||
add_custom_command(TARGET create_zip_${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E tar "cfv" ${FMU_FULL_FILE_NAME} --format=zip ${ARCHIVE_FILES}
|
||||
WORKING_DIRECTORY ${FMU_BUILD_DIR}
|
||||
COMMENT "Creating ZIP ${FMU_FULL_FILE_NAME}"
|
||||
)
|
||||
add_dependencies(create_zip_${TARGET_NAME} copy_framework_sdv_files_${TARGET_NAME})
|
||||
|
||||
#TODO
|
||||
#add_dependencies(${TARGET_NAME} <add_cmake_target_this_depends_on>)
|
||||
endif ()
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fmiModelDescription
|
||||
fmiVersion = "2.0"
|
||||
modelName = "Doors2ExampleFMU"
|
||||
guid = "945aa152-f9fd-4d02-add5-a4320d05c0ab"
|
||||
description = "TargetLink FMU for Doors2ExampleFMU"
|
||||
generationTool = "TargetLink was generated by the DBC utility: datalink_2doors_example.dbc"
|
||||
generationDateAndTime = "2025-09-06 15:15:34"
|
||||
variableNamingConvention = "structured"
|
||||
numberOfEventIndicators = "0">
|
||||
<CoSimulation
|
||||
modelIdentifier = "Doors2ExampleFMU"
|
||||
canHandleVariableCommunicationStepSize = "false"
|
||||
canGetAndSetFMUstate = "false"
|
||||
canSerializeFMUstate = "false"
|
||||
providesDirectionalDerivative = "false"
|
||||
canBeInstantiatedOnlyOncePerProcess = "true"
|
||||
canInterpolateInputs = "false"
|
||||
canRunAsynchronuously = "false">
|
||||
<SourceFiles>
|
||||
<File name="all.c"/>
|
||||
</SourceFiles>
|
||||
</CoSimulation>
|
||||
<DefaultExperiment startTime="0" stepSize="0.01"/>
|
||||
<ModelVariables>
|
||||
<!--Index for next variable = 1 -->
|
||||
<ScalarVariable name = "Door01LeftIsOpen"
|
||||
valueReference = "0"
|
||||
description = " "
|
||||
causality = "input">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 2 -->
|
||||
<ScalarVariable name = "Door01RightIsOpen"
|
||||
valueReference = "1"
|
||||
description = " "
|
||||
causality = "input">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 3 -->
|
||||
<ScalarVariable name = "LockDoor01Right"
|
||||
valueReference = "2"
|
||||
description = " "
|
||||
causality = "output">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 4 -->
|
||||
<ScalarVariable name = "LockDoor01Left"
|
||||
valueReference = "3"
|
||||
description = " "
|
||||
causality = "output">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
|
||||
</ModelVariables>
|
||||
<ModelStructure>
|
||||
<Outputs>
|
||||
<Unknown index="0"/>
|
||||
</Outputs>
|
||||
</ModelStructure>
|
||||
</fmiModelDescription>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
@file buildDescription.xml
|
||||
@date 2025-09-06 15:15:34
|
||||
This file is the fmi Build Description xml.
|
||||
This file was generated by the DBC utility from:
|
||||
datalink_2doors_example.dbc
|
||||
DBC file version: 1.0.0.1
|
||||
-->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fmiBuildDescription fmiVersion="2.0">
|
||||
<BuildConfiguration modelIdentifier="Doors2ExampleFMU">
|
||||
<SourceFileSet language="C++17">
|
||||
<SourceFile name="fmi2Functions.c"/>
|
||||
<SourceFile name="model.c"/>
|
||||
<SourceFile name="cosimulation.c"/>
|
||||
<PreprocessorDefinition name="FMI_VERSION" value="2"/>
|
||||
</SourceFileSet>
|
||||
</BuildConfiguration>
|
||||
</fmiBuildDescription>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @date 2025-09-06 15:15:34
|
||||
* This file defines the data link object between CAN and the V-API devices.
|
||||
* This file was generated by the DBC utility from:
|
||||
* datalink_2doors_example.dbc
|
||||
* DBC file version: 1.0.0.1
|
||||
*/
|
||||
#ifndef __DBC_GENERATED__CONFIG_H__20250906_151534_698__
|
||||
#define __DBC_GENERATED__CONFIG_H__20250906_151534_698__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// define class name and unique id
|
||||
#define MODEL_IDENTIFIER Doors2ExampleFMU
|
||||
#define INSTANTIATION_TOKEN "945aa152-f9fd-4d02-add5-a4320d05c0ab"
|
||||
#define FMI_VERSION 2
|
||||
|
||||
#define CO_SIMULATION
|
||||
|
||||
// define model size
|
||||
#define NX 0
|
||||
#define NZ 0
|
||||
|
||||
#define GET_INT32
|
||||
#define SET_INT32
|
||||
#define GET_FLAOT64
|
||||
#define SET_FLOAT64
|
||||
#define EVENT_UPDATE
|
||||
#define CLEAN_UP
|
||||
|
||||
#define FIXED_SOLVER_STEP 0.04
|
||||
#define DEFAULT_STOP_TIME 10
|
||||
|
||||
typedef enum {
|
||||
|
||||
vr_Door01LeftIsOpen = 0,
|
||||
vr_Door01RightIsOpen = 1,
|
||||
vr_LockDoor01Right = 2,
|
||||
vr_LockDoor01Left = 3,
|
||||
|
||||
} ValueReference;
|
||||
|
||||
typedef struct {
|
||||
|
||||
int32_t Door01LeftIsOpen;
|
||||
int32_t Door01RightIsOpen;
|
||||
int32_t LockDoor01Right;
|
||||
int32_t LockDoor01Left;
|
||||
|
||||
} ModelData;
|
||||
|
||||
#endif // !defined __DBC_GENERATED__CONFIG_H__20250906_151534_698__
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* @file model.cpp
|
||||
* @date 2025-09-06 15:15:34
|
||||
* This file defines the data link object between CAN and the V-API devices.
|
||||
* This file was generated by the DBC utility from:
|
||||
* datalink_2doors_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_signalDoor01LeftIsOpen;
|
||||
sdv::core::CSignal g_signalDoor01RightIsOpen;
|
||||
sdv::core::CSignal g_signalLockDoor01Right;
|
||||
sdv::core::CSignal g_signalLockDoor01Left;
|
||||
|
||||
// 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_signalDoor01LeftIsOpen = dispatch.RegisterRxSignal("CAN_Input_L1.Door01LeftIsOpen");
|
||||
g_signalDoor01RightIsOpen = dispatch.RegisterRxSignal("CAN_Input_R1.Door01RightIsOpen");
|
||||
g_signalLockDoor01Right = dispatch.RegisterTxSignal("CAN_Output.LockDoor01Right",0);
|
||||
g_signalLockDoor01Left = dispatch.RegisterTxSignal("CAN_Output.LockDoor01Left",0);
|
||||
|
||||
if (g_signalDoor01LeftIsOpen && g_signalDoor01RightIsOpen && g_signalLockDoor01Right && g_signalLockDoor01Left)
|
||||
{
|
||||
return sdv::core::EConfigProcessResult::successful;
|
||||
}
|
||||
|
||||
return sdv::core::EConfigProcessResult::failed;
|
||||
}
|
||||
|
||||
bool ResetAllSignals()
|
||||
{
|
||||
sdv::core::CDispatchService dispatch;
|
||||
|
||||
if (g_signalDoor01LeftIsOpen)
|
||||
{
|
||||
g_signalDoor01LeftIsOpen.Reset();
|
||||
}
|
||||
if (g_signalDoor01RightIsOpen)
|
||||
{
|
||||
g_signalDoor01RightIsOpen.Reset();
|
||||
}
|
||||
if (g_signalLockDoor01Right)
|
||||
{
|
||||
g_signalLockDoor01Right.Reset();
|
||||
}
|
||||
if (g_signalLockDoor01Left)
|
||||
{
|
||||
g_signalLockDoor01Left.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("front_left_door_example.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
success &= g_appcontrol->LoadConfig("front_right_door_example.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
success &= g_appcontrol->LoadConfig("door_comple_service.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);
|
||||
|
||||
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_Door01LeftIsOpen:
|
||||
values[(*index)++] = M(Door01LeftIsOpen);
|
||||
break;
|
||||
case vr_Door01RightIsOpen:
|
||||
values[(*index)++] = M(Door01RightIsOpen);
|
||||
break;
|
||||
case vr_LockDoor01Right:
|
||||
values[(*index)++] = M(LockDoor01Right);
|
||||
break;
|
||||
case vr_LockDoor01Left:
|
||||
values[(*index)++] = M(LockDoor01Left);
|
||||
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);
|
||||
|
||||
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_Door01LeftIsOpen:
|
||||
M(Door01LeftIsOpen) = values[(*index)++];
|
||||
break;
|
||||
case vr_Door01RightIsOpen:
|
||||
M(Door01RightIsOpen) = values[(*index)++];
|
||||
break;
|
||||
case vr_LockDoor01Right:
|
||||
M(LockDoor01Right) = values[(*index)++];
|
||||
break;
|
||||
case vr_LockDoor01Left:
|
||||
M(LockDoor01Left) = 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_signalDoor01LeftIsOpen.Write( M(Door01LeftIsOpen));
|
||||
g_signalDoor01RightIsOpen.Write( M(Door01RightIsOpen));
|
||||
M(LockDoor01Right) = g_signalLockDoor01Right.Read().get<uint32_t>();
|
||||
M(LockDoor01Left) = g_signalLockDoor01Left.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,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "door_complex_service.sdv"
|
||||
Class = "Doors Example Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Service"
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "simulation_task_timer.sdv"
|
||||
Class = "SimulationTaskTimerService"
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
@file signal_identifier.h
|
||||
@date 2025-09-06 15:15:34
|
||||
This file is the signal identifier header.
|
||||
This file was generated by the DBC utility from:
|
||||
datalink_2doors_example.dbc
|
||||
DBC file version: 1.0.0.1
|
||||
*/
|
||||
#ifndef __DBC_GENERATED__SIGNALIDENTIFIER_H__20250906_151534_698__
|
||||
#define __DBC_GENERATED__SIGNALIDENTIFIER_H__20250906_151534_698__
|
||||
|
||||
namespace Doors2ExampleFMU
|
||||
{
|
||||
// Data Dispatch Service signal names to dbc variable names C-type RX/TX vss name space
|
||||
static std::string dsDoor01LeftIsOpen = "CAN_Input_L1.Door01LeftIsOpen";
|
||||
static std::string dsDoor01RightIsOpen = "CAN_Input_R1.Door01RightIsOpen";
|
||||
static std::string dsLockDoor01Right = "CAN_Output.LockDoor01Right";
|
||||
static std::string dsLockDoor01Left = "CAN_Output.LockDoor01Left";
|
||||
|
||||
} // Doors2ExampleFMU
|
||||
|
||||
#endif // __DBC_GENERATED__SIGNALIDENTIFIER_H__20250906_151534_698__
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "model.h"
|
||||
|
||||
#define EPSILON (FIXED_SOLVER_STEP * 1e-6)
|
||||
|
||||
void doFixedStep(ModelInstance *comp, bool* stateEvent, bool* timeEvent);
|
||||
@@ -0,0 +1,272 @@
|
||||
#ifndef fmi2FunctionTypes_h
|
||||
#define fmi2FunctionTypes_h
|
||||
|
||||
#include "fmi2TypesPlatform.h"
|
||||
|
||||
/* This header file must be utilized when compiling an FMU or an FMI master.
|
||||
It declares data and function types for FMI 2.0.1
|
||||
|
||||
Revisions:
|
||||
- Sep. 30, 2019: License changed to 2-clause BSD License (without extensions)
|
||||
- Jul. 5, 2019: Remove const modifier from fields of fmi2CallbackFunctions (#216)
|
||||
- Sep. 6, 2018: Parameter names added to function prototypes
|
||||
- Apr. 9, 2014: all prefixes "fmi" renamed to "fmi2" (decision from April 8)
|
||||
- Apr. 3, 2014: Added #include <stddef.h> for size_t definition
|
||||
- Mar. 27, 2014: Added #include "fmiTypesPlatform.h" (#179)
|
||||
- Mar. 26, 2014: Introduced function argument "void" for the functions (#171)
|
||||
fmiGetTypesPlatformTYPE and fmiGetVersionTYPE
|
||||
- Oct. 11, 2013: Functions of ModelExchange and CoSimulation merged:
|
||||
fmiInstantiateModelTYPE , fmiInstantiateSlaveTYPE -> fmiInstantiateTYPE
|
||||
fmiFreeModelInstanceTYPE, fmiFreeSlaveInstanceTYPE -> fmiFreeInstanceTYPE
|
||||
fmiEnterModelInitializationModeTYPE, fmiEnterSlaveInitializationModeTYPE -> fmiEnterInitializationModeTYPE
|
||||
fmiExitModelInitializationModeTYPE , fmiExitSlaveInitializationModeTYPE -> fmiExitInitializationModeTYPE
|
||||
fmiTerminateModelTYPE , fmiTerminateSlaveTYPE -> fmiTerminate
|
||||
fmiResetSlave -> fmiReset (now also for ModelExchange and not only for CoSimulation)
|
||||
Functions renamed
|
||||
fmiUpdateDiscreteStatesTYPE -> fmiNewDiscreteStatesTYPE
|
||||
Renamed elements of the enumeration fmiEventInfo
|
||||
upcomingTimeEvent -> nextEventTimeDefined // due to generic naming scheme: varDefined + var
|
||||
newUpdateDiscreteStatesNeeded -> newDiscreteStatesNeeded;
|
||||
- June 13, 2013: Changed type fmiEventInfo
|
||||
Functions removed:
|
||||
fmiInitializeModelTYPE
|
||||
fmiEventUpdateTYPE
|
||||
fmiCompletedEventIterationTYPE
|
||||
fmiInitializeSlaveTYPE
|
||||
Functions added:
|
||||
fmiEnterModelInitializationModeTYPE
|
||||
fmiExitModelInitializationModeTYPE
|
||||
fmiEnterEventModeTYPE
|
||||
fmiUpdateDiscreteStatesTYPE
|
||||
fmiEnterContinuousTimeModeTYPE
|
||||
fmiEnterSlaveInitializationModeTYPE;
|
||||
fmiExitSlaveInitializationModeTYPE;
|
||||
- Feb. 17, 2013: Added third argument to fmiCompletedIntegratorStepTYPE
|
||||
Changed function name "fmiTerminateType" to "fmiTerminateModelType" (due to #113)
|
||||
Changed function name "fmiGetNominalContinuousStateTYPE" to
|
||||
"fmiGetNominalsOfContinuousStatesTYPE"
|
||||
Removed fmiGetStateValueReferencesTYPE.
|
||||
- Nov. 14, 2011: First public Version
|
||||
|
||||
|
||||
Copyright (C) 2008-2011 MODELISAR consortium,
|
||||
2012-2019 Modelica Association Project "FMI"
|
||||
All rights reserved.
|
||||
|
||||
This file is licensed by the copyright holders under the 2-Clause BSD License
|
||||
(https://opensource.org/licenses/BSD-2-Clause):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* make sure all compiler use the same alignment policies for structures */
|
||||
#if defined _MSC_VER || defined __GNUC__
|
||||
#pragma pack(push,8)
|
||||
#endif
|
||||
|
||||
/* Include stddef.h, in order that size_t etc. is defined */
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* Type definitions */
|
||||
typedef enum {
|
||||
fmi2OK,
|
||||
fmi2Warning,
|
||||
fmi2Discard,
|
||||
fmi2Error,
|
||||
fmi2Fatal,
|
||||
fmi2Pending
|
||||
} fmi2Status;
|
||||
|
||||
typedef enum {
|
||||
fmi2ModelExchange,
|
||||
fmi2CoSimulation
|
||||
} fmi2Type;
|
||||
|
||||
typedef enum {
|
||||
fmi2DoStepStatus,
|
||||
fmi2PendingStatus,
|
||||
fmi2LastSuccessfulTime,
|
||||
fmi2Terminated
|
||||
} fmi2StatusKind;
|
||||
|
||||
typedef void (*fmi2CallbackLogger) (fmi2ComponentEnvironment componentEnvironment,
|
||||
fmi2String instanceName,
|
||||
fmi2Status status,
|
||||
fmi2String category,
|
||||
fmi2String message,
|
||||
...);
|
||||
typedef void* (*fmi2CallbackAllocateMemory)(size_t nobj, size_t size);
|
||||
typedef void (*fmi2CallbackFreeMemory) (void* obj);
|
||||
typedef void (*fmi2StepFinished) (fmi2ComponentEnvironment componentEnvironment,
|
||||
fmi2Status status);
|
||||
|
||||
typedef struct {
|
||||
fmi2CallbackLogger logger;
|
||||
fmi2CallbackAllocateMemory allocateMemory;
|
||||
fmi2CallbackFreeMemory freeMemory;
|
||||
fmi2StepFinished stepFinished;
|
||||
fmi2ComponentEnvironment componentEnvironment;
|
||||
} fmi2CallbackFunctions;
|
||||
|
||||
typedef struct {
|
||||
fmi2Boolean newDiscreteStatesNeeded;
|
||||
fmi2Boolean terminateSimulation;
|
||||
fmi2Boolean nominalsOfContinuousStatesChanged;
|
||||
fmi2Boolean valuesOfContinuousStatesChanged;
|
||||
fmi2Boolean nextEventTimeDefined;
|
||||
fmi2Real nextEventTime;
|
||||
} fmi2EventInfo;
|
||||
|
||||
|
||||
/* reset alignment policy to the one set before reading this file */
|
||||
#if defined _MSC_VER || defined __GNUC__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
|
||||
/* Define fmi2 function pointer types to simplify dynamic loading */
|
||||
|
||||
/***************************************************
|
||||
Types for Common Functions
|
||||
****************************************************/
|
||||
|
||||
/* Inquire version numbers of header files and setting logging status */
|
||||
typedef const char* fmi2GetTypesPlatformTYPE(void);
|
||||
typedef const char* fmi2GetVersionTYPE(void);
|
||||
typedef fmi2Status fmi2SetDebugLoggingTYPE(fmi2Component c,
|
||||
fmi2Boolean loggingOn,
|
||||
size_t nCategories,
|
||||
const fmi2String categories[]);
|
||||
|
||||
/* Creation and destruction of FMU instances and setting debug status */
|
||||
typedef fmi2Component fmi2InstantiateTYPE(fmi2String instanceName,
|
||||
fmi2Type fmuType,
|
||||
fmi2String fmuGUID,
|
||||
fmi2String fmuResourceLocation,
|
||||
const fmi2CallbackFunctions* functions,
|
||||
fmi2Boolean visible,
|
||||
fmi2Boolean loggingOn);
|
||||
typedef void fmi2FreeInstanceTYPE(fmi2Component c);
|
||||
|
||||
/* Enter and exit initialization mode, terminate and reset */
|
||||
typedef fmi2Status fmi2SetupExperimentTYPE (fmi2Component c,
|
||||
fmi2Boolean toleranceDefined,
|
||||
fmi2Real tolerance,
|
||||
fmi2Real startTime,
|
||||
fmi2Boolean stopTimeDefined,
|
||||
fmi2Real stopTime);
|
||||
typedef fmi2Status fmi2EnterInitializationModeTYPE(fmi2Component c);
|
||||
typedef fmi2Status fmi2ExitInitializationModeTYPE (fmi2Component c);
|
||||
typedef fmi2Status fmi2TerminateTYPE (fmi2Component c);
|
||||
typedef fmi2Status fmi2ResetTYPE (fmi2Component c);
|
||||
|
||||
/* Getting and setting variable values */
|
||||
typedef fmi2Status fmi2GetRealTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Real value[]);
|
||||
typedef fmi2Status fmi2GetIntegerTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[]);
|
||||
typedef fmi2Status fmi2GetBooleanTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Boolean value[]);
|
||||
typedef fmi2Status fmi2GetStringTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2String value[]);
|
||||
|
||||
typedef fmi2Status fmi2SetRealTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Real value[]);
|
||||
typedef fmi2Status fmi2SetIntegerTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[]);
|
||||
typedef fmi2Status fmi2SetBooleanTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Boolean value[]);
|
||||
typedef fmi2Status fmi2SetStringTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2String value[]);
|
||||
|
||||
/* Getting and setting the internal FMU state */
|
||||
typedef fmi2Status fmi2GetFMUstateTYPE (fmi2Component c, fmi2FMUstate* FMUstate);
|
||||
typedef fmi2Status fmi2SetFMUstateTYPE (fmi2Component c, fmi2FMUstate FMUstate);
|
||||
typedef fmi2Status fmi2FreeFMUstateTYPE (fmi2Component c, fmi2FMUstate* FMUstate);
|
||||
typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component c, fmi2FMUstate FMUstate, size_t* size);
|
||||
typedef fmi2Status fmi2SerializeFMUstateTYPE (fmi2Component c, fmi2FMUstate FMUstate, fmi2Byte[], size_t size);
|
||||
typedef fmi2Status fmi2DeSerializeFMUstateTYPE (fmi2Component c, const fmi2Byte serializedState[], size_t size, fmi2FMUstate* FMUstate);
|
||||
|
||||
/* Getting partial derivatives */
|
||||
typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component c,
|
||||
const fmi2ValueReference vUnknown_ref[], size_t nUnknown,
|
||||
const fmi2ValueReference vKnown_ref[], size_t nKnown,
|
||||
const fmi2Real dvKnown[],
|
||||
fmi2Real dvUnknown[]);
|
||||
|
||||
/***************************************************
|
||||
Types for Functions for FMI2 for Model Exchange
|
||||
****************************************************/
|
||||
|
||||
/* Enter and exit the different modes */
|
||||
typedef fmi2Status fmi2EnterEventModeTYPE (fmi2Component c);
|
||||
typedef fmi2Status fmi2NewDiscreteStatesTYPE (fmi2Component c, fmi2EventInfo* fmi2eventInfo);
|
||||
typedef fmi2Status fmi2EnterContinuousTimeModeTYPE(fmi2Component c);
|
||||
typedef fmi2Status fmi2CompletedIntegratorStepTYPE(fmi2Component c,
|
||||
fmi2Boolean noSetFMUStatePriorToCurrentPoint,
|
||||
fmi2Boolean* enterEventMode,
|
||||
fmi2Boolean* terminateSimulation);
|
||||
|
||||
/* Providing independent variables and re-initialization of caching */
|
||||
typedef fmi2Status fmi2SetTimeTYPE (fmi2Component c, fmi2Real time);
|
||||
typedef fmi2Status fmi2SetContinuousStatesTYPE(fmi2Component c, const fmi2Real x[], size_t nx);
|
||||
|
||||
/* Evaluation of the model equations */
|
||||
typedef fmi2Status fmi2GetDerivativesTYPE (fmi2Component c, fmi2Real derivatives[], size_t nx);
|
||||
typedef fmi2Status fmi2GetEventIndicatorsTYPE (fmi2Component c, fmi2Real eventIndicators[], size_t ni);
|
||||
typedef fmi2Status fmi2GetContinuousStatesTYPE (fmi2Component c, fmi2Real x[], size_t nx);
|
||||
typedef fmi2Status fmi2GetNominalsOfContinuousStatesTYPE(fmi2Component c, fmi2Real x_nominal[], size_t nx);
|
||||
|
||||
|
||||
/***************************************************
|
||||
Types for Functions for FMI2 for Co-Simulation
|
||||
****************************************************/
|
||||
|
||||
/* Simulating the slave */
|
||||
typedef fmi2Status fmi2SetRealInputDerivativesTYPE (fmi2Component c,
|
||||
const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[],
|
||||
const fmi2Real value[]);
|
||||
typedef fmi2Status fmi2GetRealOutputDerivativesTYPE(fmi2Component c,
|
||||
const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[],
|
||||
fmi2Real value[]);
|
||||
typedef fmi2Status fmi2DoStepTYPE (fmi2Component c,
|
||||
fmi2Real currentCommunicationPoint,
|
||||
fmi2Real communicationStepSize,
|
||||
fmi2Boolean noSetFMUStatePriorToCurrentPoint);
|
||||
typedef fmi2Status fmi2CancelStepTYPE(fmi2Component c);
|
||||
|
||||
/* Inquire slave status */
|
||||
typedef fmi2Status fmi2GetStatusTYPE (fmi2Component c, const fmi2StatusKind s, fmi2Status* value);
|
||||
typedef fmi2Status fmi2GetRealStatusTYPE (fmi2Component c, const fmi2StatusKind s, fmi2Real* value);
|
||||
typedef fmi2Status fmi2GetIntegerStatusTYPE(fmi2Component c, const fmi2StatusKind s, fmi2Integer* value);
|
||||
typedef fmi2Status fmi2GetBooleanStatusTYPE(fmi2Component c, const fmi2StatusKind s, fmi2Boolean* value);
|
||||
typedef fmi2Status fmi2GetStringStatusTYPE (fmi2Component c, const fmi2StatusKind s, fmi2String* value);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* fmi2FunctionTypes_h */
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
#ifndef fmi2Functions_h
|
||||
#define fmi2Functions_h
|
||||
|
||||
/* This header file must be utilized when compiling a FMU.
|
||||
It defines all functions of the
|
||||
FMI 2.0.1 Model Exchange and Co-Simulation Interface.
|
||||
|
||||
In order to have unique function names even if several FMUs
|
||||
are compiled together (e.g. for embedded systems), every "real" function name
|
||||
is constructed by prepending the function name by "FMI2_FUNCTION_PREFIX".
|
||||
Therefore, the typical usage is:
|
||||
|
||||
#define FMI2_FUNCTION_PREFIX MyModel_
|
||||
#include "fmi2Functions.h"
|
||||
|
||||
As a result, a function that is defined as "fmi2GetDerivatives" in this header file,
|
||||
is actually getting the name "MyModel_fmi2GetDerivatives".
|
||||
|
||||
This only holds if the FMU is shipped in C source code, or is compiled in a
|
||||
static link library. For FMUs compiled in a DLL/sharedObject, the "actual" function
|
||||
names are used and "FMI2_FUNCTION_PREFIX" must not be defined.
|
||||
|
||||
Revisions:
|
||||
- Sep. 29, 2019: License changed to 2-clause BSD License (without extensions)
|
||||
- Apr. 9, 2014: All prefixes "fmi" renamed to "fmi2" (decision from April 8)
|
||||
- Mar. 26, 2014: FMI_Export set to empty value if FMI_Export and FMI_FUNCTION_PREFIX
|
||||
are not defined (#173)
|
||||
- Oct. 11, 2013: Functions of ModelExchange and CoSimulation merged:
|
||||
fmiInstantiateModel , fmiInstantiateSlave -> fmiInstantiate
|
||||
fmiFreeModelInstance, fmiFreeSlaveInstance -> fmiFreeInstance
|
||||
fmiEnterModelInitializationMode, fmiEnterSlaveInitializationMode -> fmiEnterInitializationMode
|
||||
fmiExitModelInitializationMode , fmiExitSlaveInitializationMode -> fmiExitInitializationMode
|
||||
fmiTerminateModel, fmiTerminateSlave -> fmiTerminate
|
||||
fmiResetSlave -> fmiReset (now also for ModelExchange and not only for CoSimulation)
|
||||
Functions renamed:
|
||||
fmiUpdateDiscreteStates -> fmiNewDiscreteStates
|
||||
- June 13, 2013: Functions removed:
|
||||
fmiInitializeModel
|
||||
fmiEventUpdate
|
||||
fmiCompletedEventIteration
|
||||
fmiInitializeSlave
|
||||
Functions added:
|
||||
fmiEnterModelInitializationMode
|
||||
fmiExitModelInitializationMode
|
||||
fmiEnterEventMode
|
||||
fmiUpdateDiscreteStates
|
||||
fmiEnterContinuousTimeMode
|
||||
fmiEnterSlaveInitializationMode;
|
||||
fmiExitSlaveInitializationMode;
|
||||
- Feb. 17, 2013: Portability improvements:
|
||||
o DllExport changed to FMI_Export
|
||||
o FUNCTION_PREFIX changed to FMI_FUNCTION_PREFIX
|
||||
o Allow undefined FMI_FUNCTION_PREFIX (meaning no prefix is used)
|
||||
Changed function name "fmiTerminate" to "fmiTerminateModel" (due to #113)
|
||||
Changed function name "fmiGetNominalContinuousState" to
|
||||
"fmiGetNominalsOfContinuousStates"
|
||||
Removed fmiGetStateValueReferences.
|
||||
- Nov. 14, 2011: Adapted to FMI 2.0:
|
||||
o Split into two files (fmiFunctions.h, fmiTypes.h) in order
|
||||
that code that dynamically loads an FMU can directly
|
||||
utilize the header files).
|
||||
o Added C++ encapsulation of C-part, in order that the header
|
||||
file can be directly utilized in C++ code.
|
||||
o fmiCallbackFunctions is passed as pointer to fmiInstantiateXXX
|
||||
o stepFinished within fmiCallbackFunctions has as first
|
||||
argument "fmiComponentEnvironment" and not "fmiComponent".
|
||||
o New functions to get and set the complete FMU state
|
||||
and to compute partial derivatives.
|
||||
- Nov. 4, 2010: Adapted to specification text:
|
||||
o fmiGetModelTypesPlatform renamed to fmiGetTypesPlatform
|
||||
o fmiInstantiateSlave: Argument GUID replaced by fmuGUID
|
||||
Argument mimetype replaced by mimeType
|
||||
o tabs replaced by spaces
|
||||
- Oct. 16, 2010: Functions for FMI for Co-simulation added
|
||||
- Jan. 20, 2010: stateValueReferencesChanged added to struct fmiEventInfo (ticket #27)
|
||||
(by M. Otter, DLR)
|
||||
Added WIN32 pragma to define the struct layout (ticket #34)
|
||||
(by J. Mauss, QTronic)
|
||||
- Jan. 4, 2010: Removed argument intermediateResults from fmiInitialize
|
||||
Renamed macro fmiGetModelFunctionsVersion to fmiGetVersion
|
||||
Renamed macro fmiModelFunctionsVersion to fmiVersion
|
||||
Replaced fmiModel by fmiComponent in decl of fmiInstantiateModel
|
||||
(by J. Mauss, QTronic)
|
||||
- Dec. 17, 2009: Changed extension "me" to "fmi" (by Martin Otter, DLR).
|
||||
- Dez. 14, 2009: Added eventInfo to meInitialize and added
|
||||
meGetNominalContinuousStates (by Martin Otter, DLR)
|
||||
- Sept. 9, 2009: Added DllExport (according to Peter Nilsson's suggestion)
|
||||
(by A. Junghanns, QTronic)
|
||||
- Sept. 9, 2009: Changes according to FMI-meeting on July 21:
|
||||
meInquireModelTypesVersion -> meGetModelTypesPlatform
|
||||
meInquireModelFunctionsVersion -> meGetModelFunctionsVersion
|
||||
meSetStates -> meSetContinuousStates
|
||||
meGetStates -> meGetContinuousStates
|
||||
removal of meInitializeModelClass
|
||||
removal of meGetTime
|
||||
change of arguments of meInstantiateModel
|
||||
change of arguments of meCompletedIntegratorStep
|
||||
(by Martin Otter, DLR):
|
||||
- July 19, 2009: Added "me" as prefix to file names (by Martin Otter, DLR).
|
||||
- March 2, 2009: Changed function definitions according to the last design
|
||||
meeting with additional improvements (by Martin Otter, DLR).
|
||||
- Dec. 3 , 2008: First version by Martin Otter (DLR) and Hans Olsson (Dynasim).
|
||||
|
||||
|
||||
Copyright (C) 2008-2011 MODELISAR consortium,
|
||||
2012-2019 Modelica Association Project "FMI"
|
||||
All rights reserved.
|
||||
|
||||
This file is licensed by the copyright holders under the 2-Clause BSD License
|
||||
(https://opensource.org/licenses/BSD-2-Clause):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "fmi2TypesPlatform.h"
|
||||
#include "fmi2FunctionTypes.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*
|
||||
Export FMI2 API functions on Windows and under GCC.
|
||||
If custom linking is desired then the FMI2_Export must be
|
||||
defined before including this file. For instance,
|
||||
it may be set to __declspec(dllimport).
|
||||
*/
|
||||
#if !defined(FMI2_Export)
|
||||
#if !defined(FMI2_FUNCTION_PREFIX)
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
/* Note: both gcc & MSVC on Windows support this syntax. */
|
||||
#define FMI2_Export __declspec(dllexport)
|
||||
#else
|
||||
#if __GNUC__ >= 4
|
||||
#define FMI2_Export __attribute__ ((visibility ("default")))
|
||||
#else
|
||||
#define FMI2_Export
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define FMI2_Export
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Macros to construct the real function name
|
||||
(prepend function name by FMI2_FUNCTION_PREFIX) */
|
||||
#if defined(FMI2_FUNCTION_PREFIX)
|
||||
#define fmi2Paste(a,b) a ## b
|
||||
#define fmi2PasteB(a,b) fmi2Paste(a,b)
|
||||
#define fmi2FullName(name) fmi2PasteB(FMI2_FUNCTION_PREFIX, name)
|
||||
#else
|
||||
#define fmi2FullName(name) name
|
||||
#endif
|
||||
|
||||
/***************************************************
|
||||
Common Functions
|
||||
****************************************************/
|
||||
#define fmi2GetTypesPlatform fmi2FullName(fmi2GetTypesPlatform)
|
||||
#define fmi2GetVersion fmi2FullName(fmi2GetVersion)
|
||||
#define fmi2SetDebugLogging fmi2FullName(fmi2SetDebugLogging)
|
||||
#define fmi2Instantiate fmi2FullName(fmi2Instantiate)
|
||||
#define fmi2FreeInstance fmi2FullName(fmi2FreeInstance)
|
||||
#define fmi2SetupExperiment fmi2FullName(fmi2SetupExperiment)
|
||||
#define fmi2EnterInitializationMode fmi2FullName(fmi2EnterInitializationMode)
|
||||
#define fmi2ExitInitializationMode fmi2FullName(fmi2ExitInitializationMode)
|
||||
#define fmi2Terminate fmi2FullName(fmi2Terminate)
|
||||
#define fmi2Reset fmi2FullName(fmi2Reset)
|
||||
#define fmi2GetReal fmi2FullName(fmi2GetReal)
|
||||
#define fmi2GetInteger fmi2FullName(fmi2GetInteger)
|
||||
#define fmi2GetBoolean fmi2FullName(fmi2GetBoolean)
|
||||
#define fmi2GetString fmi2FullName(fmi2GetString)
|
||||
#define fmi2SetReal fmi2FullName(fmi2SetReal)
|
||||
#define fmi2SetInteger fmi2FullName(fmi2SetInteger)
|
||||
#define fmi2SetBoolean fmi2FullName(fmi2SetBoolean)
|
||||
#define fmi2SetString fmi2FullName(fmi2SetString)
|
||||
#define fmi2GetFMUstate fmi2FullName(fmi2GetFMUstate)
|
||||
#define fmi2SetFMUstate fmi2FullName(fmi2SetFMUstate)
|
||||
#define fmi2FreeFMUstate fmi2FullName(fmi2FreeFMUstate)
|
||||
#define fmi2SerializedFMUstateSize fmi2FullName(fmi2SerializedFMUstateSize)
|
||||
#define fmi2SerializeFMUstate fmi2FullName(fmi2SerializeFMUstate)
|
||||
#define fmi2DeSerializeFMUstate fmi2FullName(fmi2DeSerializeFMUstate)
|
||||
#define fmi2GetDirectionalDerivative fmi2FullName(fmi2GetDirectionalDerivative)
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Model Exchange
|
||||
****************************************************/
|
||||
#define fmi2EnterEventMode fmi2FullName(fmi2EnterEventMode)
|
||||
#define fmi2NewDiscreteStates fmi2FullName(fmi2NewDiscreteStates)
|
||||
#define fmi2EnterContinuousTimeMode fmi2FullName(fmi2EnterContinuousTimeMode)
|
||||
#define fmi2CompletedIntegratorStep fmi2FullName(fmi2CompletedIntegratorStep)
|
||||
#define fmi2SetTime fmi2FullName(fmi2SetTime)
|
||||
#define fmi2SetContinuousStates fmi2FullName(fmi2SetContinuousStates)
|
||||
#define fmi2GetDerivatives fmi2FullName(fmi2GetDerivatives)
|
||||
#define fmi2GetEventIndicators fmi2FullName(fmi2GetEventIndicators)
|
||||
#define fmi2GetContinuousStates fmi2FullName(fmi2GetContinuousStates)
|
||||
#define fmi2GetNominalsOfContinuousStates fmi2FullName(fmi2GetNominalsOfContinuousStates)
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Co-Simulation
|
||||
****************************************************/
|
||||
#define fmi2SetRealInputDerivatives fmi2FullName(fmi2SetRealInputDerivatives)
|
||||
#define fmi2GetRealOutputDerivatives fmi2FullName(fmi2GetRealOutputDerivatives)
|
||||
#define fmi2DoStep fmi2FullName(fmi2DoStep)
|
||||
#define fmi2CancelStep fmi2FullName(fmi2CancelStep)
|
||||
#define fmi2GetStatus fmi2FullName(fmi2GetStatus)
|
||||
#define fmi2GetRealStatus fmi2FullName(fmi2GetRealStatus)
|
||||
#define fmi2GetIntegerStatus fmi2FullName(fmi2GetIntegerStatus)
|
||||
#define fmi2GetBooleanStatus fmi2FullName(fmi2GetBooleanStatus)
|
||||
#define fmi2GetStringStatus fmi2FullName(fmi2GetStringStatus)
|
||||
|
||||
/* Version number */
|
||||
#define fmi2Version "2.0"
|
||||
|
||||
|
||||
/***************************************************
|
||||
Common Functions
|
||||
****************************************************/
|
||||
|
||||
/* Inquire version numbers of header files */
|
||||
FMI2_Export fmi2GetTypesPlatformTYPE fmi2GetTypesPlatform;
|
||||
FMI2_Export fmi2GetVersionTYPE fmi2GetVersion;
|
||||
FMI2_Export fmi2SetDebugLoggingTYPE fmi2SetDebugLogging;
|
||||
|
||||
/* Creation and destruction of FMU instances */
|
||||
FMI2_Export fmi2InstantiateTYPE fmi2Instantiate;
|
||||
FMI2_Export fmi2FreeInstanceTYPE fmi2FreeInstance;
|
||||
|
||||
/* Enter and exit initialization mode, terminate and reset */
|
||||
FMI2_Export fmi2SetupExperimentTYPE fmi2SetupExperiment;
|
||||
FMI2_Export fmi2EnterInitializationModeTYPE fmi2EnterInitializationMode;
|
||||
FMI2_Export fmi2ExitInitializationModeTYPE fmi2ExitInitializationMode;
|
||||
FMI2_Export fmi2TerminateTYPE fmi2Terminate;
|
||||
FMI2_Export fmi2ResetTYPE fmi2Reset;
|
||||
|
||||
/* Getting and setting variables values */
|
||||
FMI2_Export fmi2GetRealTYPE fmi2GetReal;
|
||||
FMI2_Export fmi2GetIntegerTYPE fmi2GetInteger;
|
||||
FMI2_Export fmi2GetBooleanTYPE fmi2GetBoolean;
|
||||
FMI2_Export fmi2GetStringTYPE fmi2GetString;
|
||||
|
||||
FMI2_Export fmi2SetRealTYPE fmi2SetReal;
|
||||
FMI2_Export fmi2SetIntegerTYPE fmi2SetInteger;
|
||||
FMI2_Export fmi2SetBooleanTYPE fmi2SetBoolean;
|
||||
FMI2_Export fmi2SetStringTYPE fmi2SetString;
|
||||
|
||||
/* Getting and setting the internal FMU state */
|
||||
FMI2_Export fmi2GetFMUstateTYPE fmi2GetFMUstate;
|
||||
FMI2_Export fmi2SetFMUstateTYPE fmi2SetFMUstate;
|
||||
FMI2_Export fmi2FreeFMUstateTYPE fmi2FreeFMUstate;
|
||||
FMI2_Export fmi2SerializedFMUstateSizeTYPE fmi2SerializedFMUstateSize;
|
||||
FMI2_Export fmi2SerializeFMUstateTYPE fmi2SerializeFMUstate;
|
||||
FMI2_Export fmi2DeSerializeFMUstateTYPE fmi2DeSerializeFMUstate;
|
||||
|
||||
/* Getting partial derivatives */
|
||||
FMI2_Export fmi2GetDirectionalDerivativeTYPE fmi2GetDirectionalDerivative;
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Model Exchange
|
||||
****************************************************/
|
||||
|
||||
/* Enter and exit the different modes */
|
||||
FMI2_Export fmi2EnterEventModeTYPE fmi2EnterEventMode;
|
||||
FMI2_Export fmi2NewDiscreteStatesTYPE fmi2NewDiscreteStates;
|
||||
FMI2_Export fmi2EnterContinuousTimeModeTYPE fmi2EnterContinuousTimeMode;
|
||||
FMI2_Export fmi2CompletedIntegratorStepTYPE fmi2CompletedIntegratorStep;
|
||||
|
||||
/* Providing independent variables and re-initialization of caching */
|
||||
FMI2_Export fmi2SetTimeTYPE fmi2SetTime;
|
||||
FMI2_Export fmi2SetContinuousStatesTYPE fmi2SetContinuousStates;
|
||||
|
||||
/* Evaluation of the model equations */
|
||||
FMI2_Export fmi2GetDerivativesTYPE fmi2GetDerivatives;
|
||||
FMI2_Export fmi2GetEventIndicatorsTYPE fmi2GetEventIndicators;
|
||||
FMI2_Export fmi2GetContinuousStatesTYPE fmi2GetContinuousStates;
|
||||
FMI2_Export fmi2GetNominalsOfContinuousStatesTYPE fmi2GetNominalsOfContinuousStates;
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Co-Simulation
|
||||
****************************************************/
|
||||
|
||||
/* Simulating the slave */
|
||||
FMI2_Export fmi2SetRealInputDerivativesTYPE fmi2SetRealInputDerivatives;
|
||||
FMI2_Export fmi2GetRealOutputDerivativesTYPE fmi2GetRealOutputDerivatives;
|
||||
|
||||
FMI2_Export fmi2DoStepTYPE fmi2DoStep;
|
||||
FMI2_Export fmi2CancelStepTYPE fmi2CancelStep;
|
||||
|
||||
/* Inquire slave status */
|
||||
FMI2_Export fmi2GetStatusTYPE fmi2GetStatus;
|
||||
FMI2_Export fmi2GetRealStatusTYPE fmi2GetRealStatus;
|
||||
FMI2_Export fmi2GetIntegerStatusTYPE fmi2GetIntegerStatus;
|
||||
FMI2_Export fmi2GetBooleanStatusTYPE fmi2GetBooleanStatus;
|
||||
FMI2_Export fmi2GetStringStatusTYPE fmi2GetStringStatus;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* fmi2Functions_h */
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#ifndef fmi2TypesPlatform_h
|
||||
#define fmi2TypesPlatform_h
|
||||
|
||||
/* Standard header file to define the argument types of the
|
||||
functions of the Functional Mock-up Interface 2.0.1
|
||||
This header file must be utilized both by the model and
|
||||
by the simulation engine.
|
||||
|
||||
Revisions:
|
||||
- Sep. 29, 2019: License changed to 2-clause BSD License (without extensions)
|
||||
- Apr. 9, 2014: All prefixes "fmi" renamed to "fmi2" (decision from April 8)
|
||||
- Mar 31, 2014: New datatype fmiChar introduced.
|
||||
- Feb. 17, 2013: Changed fmiTypesPlatform from "standard32" to "default".
|
||||
Removed fmiUndefinedValueReference since no longer needed
|
||||
(because every state is defined in ScalarVariables).
|
||||
- March 20, 2012: Renamed from fmiPlatformTypes.h to fmiTypesPlatform.h
|
||||
- Nov. 14, 2011: Use the header file "fmiPlatformTypes.h" for FMI 2.0
|
||||
both for "FMI for model exchange" and for "FMI for co-simulation"
|
||||
New types "fmiComponentEnvironment", "fmiState", and "fmiByte".
|
||||
The implementation of "fmiBoolean" is change from "char" to "int".
|
||||
The #define "fmiPlatform" changed to "fmiTypesPlatform"
|
||||
(in order that #define and function call are consistent)
|
||||
- Oct. 4, 2010: Renamed header file from "fmiModelTypes.h" to fmiPlatformTypes.h"
|
||||
for the co-simulation interface
|
||||
- Jan. 4, 2010: Renamed meModelTypes_h to fmiModelTypes_h (by Mauss, QTronic)
|
||||
- Dec. 21, 2009: Changed "me" to "fmi" and "meModel" to "fmiComponent"
|
||||
according to meeting on Dec. 18 (by Martin Otter, DLR)
|
||||
- Dec. 6, 2009: Added meUndefinedValueReference (by Martin Otter, DLR)
|
||||
- Sept. 9, 2009: Changes according to FMI-meeting on July 21:
|
||||
Changed "version" to "platform", "standard" to "standard32",
|
||||
Added a precise definition of "standard32" as comment
|
||||
(by Martin Otter, DLR)
|
||||
- July 19, 2009: Added "me" as prefix to file names, added meTrue/meFalse,
|
||||
and changed meValueReferenced from int to unsigned int
|
||||
(by Martin Otter, DLR).
|
||||
- March 2, 2009: Moved enums and function pointer definitions to
|
||||
ModelFunctions.h (by Martin Otter, DLR).
|
||||
- Dec. 3, 2008 : First version by Martin Otter (DLR) and
|
||||
Hans Olsson (Dynasim).
|
||||
|
||||
|
||||
Copyright (C) 2008-2011 MODELISAR consortium,
|
||||
2012-2019 Modelica Association Project "FMI"
|
||||
All rights reserved.
|
||||
|
||||
This file is licensed by the copyright holders under the 2-Clause BSD License
|
||||
(https://opensource.org/licenses/BSD-2-Clause):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Platform (unique identification of this header file) */
|
||||
#define fmi2TypesPlatform "default"
|
||||
|
||||
/* Type definitions of variables passed as arguments
|
||||
Version "default" means:
|
||||
|
||||
fmi2Component : an opaque object pointer
|
||||
fmi2ComponentEnvironment: an opaque object pointer
|
||||
fmi2FMUstate : an opaque object pointer
|
||||
fmi2ValueReference : handle to the value of a variable
|
||||
fmi2Real : double precision floating-point data type
|
||||
fmi2Integer : basic signed integer data type
|
||||
fmi2Boolean : basic signed integer data type
|
||||
fmi2Char : character data type
|
||||
fmi2String : a pointer to a vector of fmi2Char characters
|
||||
('\0' terminated, UTF8 encoded)
|
||||
fmi2Byte : smallest addressable unit of the machine, typically one byte.
|
||||
*/
|
||||
typedef void* fmi2Component; /* Pointer to FMU instance */
|
||||
typedef void* fmi2ComponentEnvironment; /* Pointer to FMU environment */
|
||||
typedef void* fmi2FMUstate; /* Pointer to internal FMU state */
|
||||
typedef unsigned int fmi2ValueReference;
|
||||
typedef double fmi2Real ;
|
||||
typedef int fmi2Integer;
|
||||
typedef int fmi2Boolean;
|
||||
typedef char fmi2Char;
|
||||
typedef const fmi2Char* fmi2String;
|
||||
typedef char fmi2Byte;
|
||||
|
||||
/* Values for fmi2Boolean */
|
||||
#define fmi2True 1
|
||||
#define fmi2False 0
|
||||
|
||||
|
||||
#endif /* fmi2TypesPlatform_h */
|
||||
|
||||
254
examples/door_demo_example/fmu_Doors2ExampleFMU/include/model.h
Normal file
254
examples/door_demo_example/fmu_Doors2ExampleFMU/include/model.h
Normal file
@@ -0,0 +1,254 @@
|
||||
#pragma once
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if FMI_VERSION != 1 && FMI_VERSION != 2 && FMI_VERSION != 3
|
||||
#error FMI_VERSION must be one of 1, 2 or 3
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdbool.h> // for bool
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if FMI_VERSION == 1
|
||||
|
||||
#define not_modelError (Instantiated| Initialized | Terminated)
|
||||
|
||||
typedef enum {
|
||||
Instantiated = 1 << 0,
|
||||
Initialized = 1 << 1,
|
||||
Terminated = 1 << 2,
|
||||
modelError = 1 << 3
|
||||
} ModelState;
|
||||
|
||||
#elif FMI_VERSION == 2
|
||||
|
||||
typedef enum {
|
||||
StartAndEnd = 1 << 0,
|
||||
Instantiated = 1 << 1,
|
||||
InitializationMode = 1 << 2,
|
||||
|
||||
// ME states
|
||||
EventMode = 1 << 3,
|
||||
ContinuousTimeMode = 1 << 4,
|
||||
|
||||
// CS states
|
||||
StepComplete = 1 << 5,
|
||||
StepInProgress = 1 << 6,
|
||||
StepFailed = 1 << 7,
|
||||
StepCanceled = 1 << 8,
|
||||
|
||||
Terminated = 1 << 9,
|
||||
modelError = 1 << 10,
|
||||
modelFatal = 1 << 11,
|
||||
} ModelState;
|
||||
|
||||
#else
|
||||
|
||||
typedef enum {
|
||||
StartAndEnd = 1 << 0,
|
||||
ConfigurationMode = 1 << 1,
|
||||
Instantiated = 1 << 2,
|
||||
InitializationMode = 1 << 3,
|
||||
EventMode = 1 << 4,
|
||||
ContinuousTimeMode = 1 << 5,
|
||||
StepMode = 1 << 6,
|
||||
ClockActivationMode = 1 << 7,
|
||||
StepDiscarded = 1 << 8,
|
||||
ReconfigurationMode = 1 << 9,
|
||||
IntermediateUpdateMode = 1 << 10,
|
||||
Terminated = 1 << 11,
|
||||
modelError = 1 << 12,
|
||||
modelFatal = 1 << 13,
|
||||
} ModelState;
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ModelExchange,
|
||||
CoSimulation,
|
||||
ScheduledExecution,
|
||||
} InterfaceType;
|
||||
|
||||
typedef enum {
|
||||
OK,
|
||||
Warning,
|
||||
Discard,
|
||||
Error,
|
||||
Fatal,
|
||||
Pending
|
||||
} Status;
|
||||
|
||||
#if FMI_VERSION < 3
|
||||
typedef void (*loggerType) (void* componentEnvironment, const char* instanceName, int status, const char* category, const char* message, ...);
|
||||
#else
|
||||
typedef void (*loggerType) (void* componentEnvironment, int status, const char* category, const char* message);
|
||||
#endif
|
||||
|
||||
typedef void (*lockPreemptionType) (void);
|
||||
typedef void (*unlockPreemptionType) (void);
|
||||
|
||||
|
||||
typedef void (*intermediateUpdateType) (void* instanceEnvironment,
|
||||
double intermediateUpdateTime,
|
||||
bool intermediateVariableSetRequested,
|
||||
bool intermediateVariableGetAllowed,
|
||||
bool intermediateStepFinished,
|
||||
bool canReturnEarly,
|
||||
bool* earlyReturnRequested,
|
||||
double* earlyReturnTime);
|
||||
|
||||
typedef void(*clockUpdateType) (void* instanceEnvironment);
|
||||
|
||||
typedef struct {
|
||||
|
||||
double startTime;
|
||||
double stopTime;
|
||||
double time;
|
||||
const char* instanceName;
|
||||
InterfaceType type;
|
||||
const char* resourceLocation;
|
||||
|
||||
Status status;
|
||||
|
||||
// callback functions
|
||||
loggerType logger;
|
||||
intermediateUpdateType intermediateUpdate;
|
||||
clockUpdateType clockUpdate;
|
||||
|
||||
lockPreemptionType lockPreemtion;
|
||||
unlockPreemptionType unlockPreemtion;
|
||||
|
||||
bool logEvents;
|
||||
bool logErrors;
|
||||
|
||||
void* componentEnvironment;
|
||||
ModelState state;
|
||||
|
||||
// event info
|
||||
bool newDiscreteStatesNeeded;
|
||||
bool terminateSimulation;
|
||||
bool nominalsOfContinuousStatesChanged;
|
||||
bool valuesOfContinuousStatesChanged;
|
||||
bool nextEventTimeDefined;
|
||||
double nextEventTime;
|
||||
bool clocksTicked;
|
||||
|
||||
bool isDirtyValues;
|
||||
|
||||
ModelData modelData;
|
||||
|
||||
#if NZ > 0
|
||||
// event indicators
|
||||
double z[NZ];
|
||||
#endif
|
||||
|
||||
// internal solver steps
|
||||
uint64_t nSteps;
|
||||
|
||||
// Co-Simulation
|
||||
bool earlyReturnAllowed;
|
||||
bool eventModeUsed;
|
||||
|
||||
} ModelInstance;
|
||||
|
||||
ModelInstance* createModelInstance(
|
||||
loggerType logger,
|
||||
intermediateUpdateType intermediateUpdate,
|
||||
void* componentEnvironment,
|
||||
const char* instanceName,
|
||||
const char* instantiationToken,
|
||||
const char* resourceLocation,
|
||||
bool loggingOn,
|
||||
InterfaceType interfaceType);
|
||||
|
||||
void freeModelInstance(ModelInstance* comp);
|
||||
|
||||
void reset(ModelInstance* comp);
|
||||
|
||||
|
||||
bool setStartValues(ModelInstance* comp);
|
||||
|
||||
Status calculateValues(ModelInstance* comp);
|
||||
|
||||
Status getFloat32(ModelInstance* comp, ValueReference vr, float values[], size_t nValues, size_t* index);
|
||||
Status getFloat64(ModelInstance* comp, ValueReference vr, double values[], size_t nValues, size_t* index);
|
||||
Status getInt8(ModelInstance* comp, ValueReference vr, int8_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt8(ModelInstance* comp, ValueReference vr, uint8_t values[], size_t nValues, size_t* index);
|
||||
Status getInt16(ModelInstance* comp, ValueReference vr, int16_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt16(ModelInstance* comp, ValueReference vr, uint16_t values[], size_t nValues, size_t* index);
|
||||
Status getInt32(ModelInstance* comp, ValueReference vr, int32_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt32(ModelInstance* comp, ValueReference vr, uint32_t values[], size_t nValues, size_t* index);
|
||||
Status getInt64(ModelInstance* comp, ValueReference vr, int64_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt64(ModelInstance* comp, ValueReference vr, uint64_t values[], size_t nValues, size_t* index);
|
||||
Status getBoolean(ModelInstance* comp, ValueReference vr, bool values[], size_t nValues, size_t* index);
|
||||
Status getString(ModelInstance* comp, ValueReference vr, const char* values[], size_t nValues, size_t* index);
|
||||
Status getBinary(ModelInstance* comp, ValueReference vr, size_t sizes[], const char* values[], size_t nValues, size_t* index);
|
||||
|
||||
Status setFloat32(ModelInstance* comp, ValueReference vr, const float values[], size_t nValues, size_t* index);
|
||||
Status setFloat64(ModelInstance* comp, ValueReference vr, const double values[], size_t nValues, size_t* index);
|
||||
Status setInt8(ModelInstance* comp, ValueReference vr, const int8_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt8(ModelInstance* comp, ValueReference vr, const uint8_t values[], size_t nValues, size_t* index);
|
||||
Status setInt16(ModelInstance* comp, ValueReference vr, const int16_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt16(ModelInstance* comp, ValueReference vr, const uint16_t values[], size_t nValues, size_t* index);
|
||||
Status setInt32(ModelInstance* comp, ValueReference vr, const int32_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt32(ModelInstance* comp, ValueReference vr, const uint32_t values[], size_t nValues, size_t* index);
|
||||
Status setInt64(ModelInstance* comp, ValueReference vr, const int64_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt64(ModelInstance* comp, ValueReference vr, const uint64_t values[], size_t nValues, size_t* index);
|
||||
Status setBoolean(ModelInstance* comp, ValueReference vr, const bool values[], size_t nValues, size_t* index);
|
||||
Status setString(ModelInstance* comp, ValueReference vr, const char* const values[], size_t nValues, size_t* index);
|
||||
Status setBinary(ModelInstance* comp, ValueReference vr, const size_t sizes[], const char* const values[], size_t nValues, size_t* index);
|
||||
|
||||
Status activateClock(ModelInstance* comp, ValueReference vr);
|
||||
Status getClock(ModelInstance* comp, ValueReference vr, bool* value);
|
||||
Status setClock(ModelInstance* comp, ValueReference vr, const bool* value);
|
||||
|
||||
Status getInterval(ModelInstance* comp, ValueReference vr, double* interval, int* qualifier);
|
||||
|
||||
Status activateModelPartition(ModelInstance* comp, ValueReference vr, double activationTime);
|
||||
|
||||
void getContinuousStates(ModelInstance* comp, double x[], size_t nx);
|
||||
void setContinuousStates(ModelInstance* comp, const double x[], size_t nx);
|
||||
void getDerivatives(ModelInstance* comp, double dx[], size_t nx);
|
||||
Status getOutputDerivative(ModelInstance* comp, ValueReference valueReference, int order, double* value);
|
||||
Status getPartialDerivative(ModelInstance* comp, ValueReference unknown, ValueReference known, double* partialDerivative);
|
||||
void getEventIndicators(ModelInstance* comp, double z[], size_t nz);
|
||||
void eventUpdate(ModelInstance* comp);
|
||||
//void updateEventTime(ModelInstance *comp);
|
||||
|
||||
bool invalidNumber(ModelInstance* comp, const char* f, const char* arg, size_t actual, size_t expected);
|
||||
bool invalidState(ModelInstance* comp, const char* f, int statesExpected);
|
||||
bool nullPointer(ModelInstance* comp, const char* f, const char* arg, const void* p);
|
||||
void logError(ModelInstance* comp, const char* message, ...);
|
||||
Status setDebugLogging(ModelInstance* comp, bool loggingOn, size_t nCategories, const char* const categories[]);
|
||||
void logEvent(ModelInstance* comp, const char* message, ...);
|
||||
void logError(ModelInstance* comp, const char* message, ...);
|
||||
|
||||
void* getFMUState(ModelInstance* comp);
|
||||
void setFMUState(ModelInstance* comp, void* FMUState);
|
||||
|
||||
// shorthand to access the variables
|
||||
#define M(v) (comp->modelData.v)
|
||||
|
||||
// "stringification" macros
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
// assert size of nValues for scalar variables
|
||||
#define ASSERT_NVALUES(N) do { \
|
||||
if (*index + (N) > nValues) { \
|
||||
logError(comp, "Expected nValues > %zu but was %zu.", *index, nValues); \
|
||||
return Error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,598 @@
|
||||
#include <stdlib.h> // for calloc(), free()
|
||||
#include <float.h> // for DBL_EPSILON
|
||||
#include <math.h> // for fabs()
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "cosimulation.h"
|
||||
|
||||
#if FMI_VERSION == 3
|
||||
#include "fmi3Functions.h"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
|
||||
ModelInstance *createModelInstance(
|
||||
loggerType cbLogger,
|
||||
intermediateUpdateType intermediateUpdate,
|
||||
void *componentEnvironment,
|
||||
const char *instanceName,
|
||||
const char *instantiationToken,
|
||||
const char *resourceLocation,
|
||||
bool loggingOn,
|
||||
InterfaceType interfaceType) {
|
||||
|
||||
ModelInstance *comp = NULL;
|
||||
|
||||
if (!instanceName || strlen(instanceName) == 0) {
|
||||
if (cbLogger) {
|
||||
#if FMI_VERSION < 3
|
||||
cbLogger(componentEnvironment, "?", Error, "error", "Missing instance name.");
|
||||
#else
|
||||
cbLogger(componentEnvironment, Error, "error", "Missing instance name.");
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!instantiationToken || strlen(instantiationToken) == 0) {
|
||||
if (cbLogger) {
|
||||
#if FMI_VERSION < 3
|
||||
cbLogger(componentEnvironment, instanceName, Error, "error", "Missing GUID.");
|
||||
#else
|
||||
cbLogger(componentEnvironment, Error, "error", "Missing instantiationToken.");
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(instantiationToken, INSTANTIATION_TOKEN)) {
|
||||
if (cbLogger) {
|
||||
#if FMI_VERSION < 3
|
||||
cbLogger(componentEnvironment, instanceName, Error, "error", "Wrong GUID.");
|
||||
#else
|
||||
cbLogger(componentEnvironment, Error, "error", "Wrong instantiationToken.");
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
comp = (ModelInstance *)calloc(1, sizeof(ModelInstance));
|
||||
|
||||
if (comp) {
|
||||
comp->componentEnvironment = componentEnvironment;
|
||||
comp->logger = cbLogger;
|
||||
comp->intermediateUpdate = intermediateUpdate;
|
||||
comp->lockPreemtion = NULL;
|
||||
comp->unlockPreemtion = NULL;
|
||||
comp->instanceName = strdup(instanceName);
|
||||
comp->resourceLocation = resourceLocation ? strdup(resourceLocation) : NULL;
|
||||
comp->status = OK;
|
||||
comp->logEvents = loggingOn;
|
||||
comp->logErrors = true; // always log errors
|
||||
comp->nSteps = 0;
|
||||
comp->earlyReturnAllowed = false;
|
||||
comp->eventModeUsed = false;
|
||||
}
|
||||
|
||||
if (!comp || !comp->instanceName) {
|
||||
logError(comp, "Out of memory.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
comp->time = 0.0; // overwrite in fmi*SetupExperiment, fmi*SetTime
|
||||
comp->type = interfaceType;
|
||||
|
||||
comp->state = Instantiated;
|
||||
|
||||
comp->newDiscreteStatesNeeded = false;
|
||||
comp->terminateSimulation = false;
|
||||
comp->nominalsOfContinuousStatesChanged = false;
|
||||
comp->valuesOfContinuousStatesChanged = false;
|
||||
comp->nextEventTimeDefined = false;
|
||||
comp->nextEventTime = 0;
|
||||
|
||||
if (!setStartValues(comp))
|
||||
{
|
||||
cbLogger(componentEnvironment, instanceName, Error, "error", "VAPI initialization failed.");
|
||||
}
|
||||
|
||||
comp->isDirtyValues = true;
|
||||
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
void freeModelInstance(ModelInstance *comp) {
|
||||
free((void *)comp->instanceName);
|
||||
free(comp);
|
||||
}
|
||||
|
||||
void reset(ModelInstance* comp) {
|
||||
comp->state = Instantiated;
|
||||
comp->startTime = 0.0;
|
||||
comp->time = 0.0;
|
||||
comp->nSteps = 0;
|
||||
comp->status = OK;
|
||||
setStartValues(comp);
|
||||
comp->isDirtyValues = true;
|
||||
}
|
||||
|
||||
bool invalidNumber(ModelInstance *comp, const char *f, const char *arg, size_t actual, size_t expected) {
|
||||
|
||||
if (actual != expected) {
|
||||
comp->state = modelError;
|
||||
logError(comp, "%s: Invalid argument %s = %d. Expected %d.", f, arg, actual, expected);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invalidState(ModelInstance *comp, const char *f, int statesExpected) {
|
||||
|
||||
UNUSED(f);
|
||||
UNUSED(statesExpected);
|
||||
|
||||
if (!comp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: add missing states and check state
|
||||
return false;
|
||||
|
||||
// if (!(comp->state & statesExpected)) {
|
||||
// comp->state = modelError;
|
||||
// logError(comp, "%s: Illegal call sequence.", f);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
}
|
||||
|
||||
bool nullPointer(ModelInstance* comp, const char *f, const char *arg, const void *p) {
|
||||
|
||||
if (!p) {
|
||||
comp->state = modelError;
|
||||
logError(comp, "%s: Invalid argument %s = NULL.", f, arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Status setDebugLogging(ModelInstance *comp, bool loggingOn, size_t nCategories, const char * const categories[]) {
|
||||
|
||||
if (nCategories > 0) {
|
||||
|
||||
if (categories == NULL) {
|
||||
logError(comp, "Argument categories must not be NULL.");
|
||||
return Error;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nCategories; i++) {
|
||||
|
||||
if (categories[i] == NULL) {
|
||||
logError(comp, "Argument categories[%zu] must not be NULL.", i);
|
||||
return Error;
|
||||
} else if (strcmp(categories[i], "logEvents") == 0) {
|
||||
comp->logEvents = loggingOn;
|
||||
} else if (strcmp(categories[i], "logStatusError") == 0) {
|
||||
comp->logErrors = loggingOn;
|
||||
} else {
|
||||
logError(comp, "Log categories[%zu] must be one of \"logEvents\" or \"logStatusError\" but was \"%s\".", i, categories[i]);
|
||||
return Error;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
comp->logEvents = loggingOn;
|
||||
comp->logErrors = loggingOn;
|
||||
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void logMessage(ModelInstance *comp, int status, const char *category, const char *message, va_list args) {
|
||||
|
||||
if (!comp->logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list args1;
|
||||
int len = 0;
|
||||
char *buf = "";
|
||||
|
||||
va_copy(args1, args);
|
||||
len = vsnprintf(buf, len, message, args1);
|
||||
va_end(args1);
|
||||
|
||||
if (len < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_copy(args1, args);
|
||||
buf = (char *)calloc(len + 1, sizeof(char));
|
||||
len = vsnprintf(buf, len + 1, message, args);
|
||||
va_end(args1);
|
||||
|
||||
if (len >= 0) {
|
||||
// no need to distinguish between FMI versions since we're not using variadic arguments
|
||||
#if FMI_VERSION < 3
|
||||
comp->logger(comp->componentEnvironment, comp->instanceName, status, category, buf);
|
||||
#else
|
||||
comp->logger(comp->componentEnvironment, status, category, buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void logEvent(ModelInstance *comp, const char *message, ...) {
|
||||
|
||||
if (!comp || !comp->logEvents) return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
logMessage(comp, OK, "logEvents", message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void logError(ModelInstance *comp, const char *message, ...) {
|
||||
|
||||
if (!comp || !comp->logErrors) return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
logMessage(comp, Error, "logStatusError", message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// default implementations
|
||||
#if NZ < 1
|
||||
void getEventIndicators(ModelInstance *comp, double z[], size_t nz) {
|
||||
UNUSED(comp);
|
||||
UNUSED(z);
|
||||
UNUSED(nz);
|
||||
// do nothing
|
||||
}
|
||||
#endif
|
||||
|
||||
#define GET_NOT_ALLOWED(t) do { \
|
||||
UNUSED(vr); \
|
||||
UNUSED(values); \
|
||||
UNUSED(nValues); \
|
||||
UNUSED(index); \
|
||||
logError(comp, "Getting " t " is not allowed.");\
|
||||
return Error; \
|
||||
} while (false)
|
||||
|
||||
#ifndef GET_FLOAT32
|
||||
Status getFloat32(ModelInstance* comp, ValueReference vr, float values[], size_t nValues, size_t* index) {
|
||||
GET_NOT_ALLOWED("Float32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT8
|
||||
Status getInt8(ModelInstance* comp, ValueReference vr, int8_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT8
|
||||
Status getUInt8(ModelInstance* comp, ValueReference vr, uint8_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT16
|
||||
Status getInt16(ModelInstance* comp, ValueReference vr, int16_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int16");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT16
|
||||
Status getUInt16(ModelInstance* comp, ValueReference vr, uint16_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt16");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT32
|
||||
Status getInt32(ModelInstance* comp, ValueReference vr, int32_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT32
|
||||
Status getUInt32(ModelInstance* comp, ValueReference vr, uint32_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT64
|
||||
Status getInt64(ModelInstance* comp, ValueReference vr, int64_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT64
|
||||
Status getUInt64(ModelInstance* comp, ValueReference vr, uint64_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_BOOLEAN
|
||||
Status getBoolean(ModelInstance* comp, ValueReference vr, bool values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Boolean");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_STRING
|
||||
Status getString(ModelInstance* comp, ValueReference vr, const char* values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("String");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_BINARY
|
||||
Status getBinary(ModelInstance* comp, ValueReference vr, size_t sizes[], const char* values[], size_t nValues, size_t *index) {
|
||||
UNUSED(sizes);
|
||||
GET_NOT_ALLOWED("Binary");
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SET_NOT_ALLOWED(t) do { \
|
||||
UNUSED(vr); \
|
||||
UNUSED(values); \
|
||||
UNUSED(nValues); \
|
||||
UNUSED(index); \
|
||||
logError(comp, "Setting " t " is not allowed.");\
|
||||
return Error; \
|
||||
} while (false)
|
||||
|
||||
#ifndef SET_FLOAT32
|
||||
Status setFloat32(ModelInstance* comp, ValueReference vr, const float values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Float32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_FLOAT64
|
||||
Status setFloat64(ModelInstance* comp, ValueReference vr, const double values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Float64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT8
|
||||
Status setInt8(ModelInstance* comp, ValueReference vr, const int8_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT8
|
||||
Status setUInt8(ModelInstance* comp, ValueReference vr, const uint8_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT16
|
||||
Status setInt16(ModelInstance* comp, ValueReference vr, const int16_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int16");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT16
|
||||
Status setUInt16(ModelInstance* comp, ValueReference vr, const uint16_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt16");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT32
|
||||
Status setInt32(ModelInstance* comp, ValueReference vr, const int32_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT32
|
||||
Status setUInt32(ModelInstance* comp, ValueReference vr, const uint32_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT64
|
||||
Status setInt64(ModelInstance* comp, ValueReference vr, const int64_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT64
|
||||
Status setUInt64(ModelInstance* comp, ValueReference vr, const uint64_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_BOOLEAN
|
||||
Status setBoolean(ModelInstance* comp, ValueReference vr, const bool values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Boolean");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_STRING
|
||||
Status setString(ModelInstance* comp, ValueReference vr, const char *const values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("String");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_BINARY
|
||||
Status setBinary(ModelInstance* comp, ValueReference vr, const size_t size[], const char *const values[], size_t nValues, size_t* index) {
|
||||
UNUSED(size);
|
||||
SET_NOT_ALLOWED("Binary");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ACTIVATE_CLOCK
|
||||
Status activateClock(ModelInstance* comp, ValueReference vr) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_CLOCK
|
||||
Status getClock(ModelInstance* comp, ValueReference vr, bool* value) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
UNUSED(value);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INTERVAL
|
||||
Status getInterval(ModelInstance* comp, ValueReference vr, double* interval, int* qualifier) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
UNUSED(interval);
|
||||
UNUSED(qualifier);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ACTIVATE_MODEL_PARTITION
|
||||
Status activateModelPartition(ModelInstance* comp, ValueReference vr, double activationTime) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
UNUSED(activationTime);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NX < 1
|
||||
void getContinuousStates(ModelInstance *comp, double x[], size_t nx) {
|
||||
UNUSED(comp);
|
||||
UNUSED(x);
|
||||
UNUSED(nx);
|
||||
}
|
||||
|
||||
void setContinuousStates(ModelInstance *comp, const double x[], size_t nx) {
|
||||
UNUSED(comp);
|
||||
UNUSED(x);
|
||||
UNUSED(nx);
|
||||
}
|
||||
|
||||
void getDerivatives(ModelInstance *comp, double dx[], size_t nx) {
|
||||
UNUSED(comp);
|
||||
UNUSED(dx);
|
||||
UNUSED(nx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_PARTIAL_DERIVATIVE
|
||||
Status getPartialDerivative(ModelInstance *comp, ValueReference unknown, ValueReference known, double *partialDerivative) {
|
||||
UNUSED(comp);
|
||||
UNUSED(unknown);
|
||||
UNUSED(known);
|
||||
UNUSED(partialDerivative);
|
||||
logError(comp, "Directional derivatives are not supported.");
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* getFMUState(ModelInstance* comp) {
|
||||
|
||||
ModelInstance* fmuState = (ModelInstance*)calloc(1, sizeof(ModelInstance));
|
||||
|
||||
if (fmuState) {
|
||||
memcpy(fmuState, comp, sizeof(ModelInstance));
|
||||
}
|
||||
|
||||
return fmuState;
|
||||
}
|
||||
|
||||
void setFMUState(ModelInstance* comp, void* FMUState) {
|
||||
|
||||
ModelInstance* s = (ModelInstance*)FMUState;
|
||||
|
||||
comp->startTime = s->startTime;
|
||||
comp->stopTime = s->stopTime;
|
||||
comp->time = s->time;
|
||||
comp->status = s->status;
|
||||
comp->state = s->state;
|
||||
comp->newDiscreteStatesNeeded = s->newDiscreteStatesNeeded;
|
||||
comp->terminateSimulation = s->terminateSimulation;
|
||||
comp->nominalsOfContinuousStatesChanged = s->nominalsOfContinuousStatesChanged;
|
||||
comp->valuesOfContinuousStatesChanged = s->valuesOfContinuousStatesChanged;
|
||||
comp->nextEventTimeDefined = s->nextEventTimeDefined;
|
||||
comp->nextEventTime = s->nextEventTime;
|
||||
comp->clocksTicked = s->clocksTicked;
|
||||
comp->isDirtyValues = s->isDirtyValues;
|
||||
comp->modelData = s->modelData;
|
||||
#if NZ > 0
|
||||
memcpy(comp->z, s->z, NZ * sizeof(double));
|
||||
#endif
|
||||
comp->nSteps = s->nSteps;
|
||||
}
|
||||
|
||||
void doFixedStep(ModelInstance *comp, bool* stateEvent, bool* timeEvent) {
|
||||
|
||||
#if NX > 0
|
||||
double x[NX] = { 0 };
|
||||
double dx[NX] = { 0 };
|
||||
|
||||
getContinuousStates(comp, x, NX);
|
||||
getDerivatives(comp, dx, NX);
|
||||
|
||||
// forward Euler step
|
||||
for (int i = 0; i < NX; i++) {
|
||||
x[i] += FIXED_SOLVER_STEP * dx[i];
|
||||
}
|
||||
|
||||
setContinuousStates(comp, x, NX);
|
||||
#endif
|
||||
|
||||
comp->nSteps++;
|
||||
|
||||
comp->time = comp->startTime + comp->nSteps * FIXED_SOLVER_STEP;
|
||||
|
||||
// state event
|
||||
*stateEvent = false;
|
||||
|
||||
#if NZ > 0
|
||||
double z[NZ] = { 0.0 };
|
||||
|
||||
getEventIndicators(comp, z, NZ);
|
||||
|
||||
// check for zero-crossings
|
||||
for (int i = 0; i < NZ; i++) {
|
||||
*stateEvent |= (comp->z[i] <= 0 && z[i] > 0) || (comp->z[i] > 0 && z[i] <= 0);
|
||||
}
|
||||
|
||||
// remember the current event indicators
|
||||
memcpy(comp->z, z, sizeof(double) * NZ);
|
||||
#endif
|
||||
|
||||
// time event
|
||||
*timeEvent = comp->nextEventTimeDefined && comp->time >= comp->nextEventTime;
|
||||
|
||||
bool earlyReturnRequested;
|
||||
double earlyReturnTime;
|
||||
|
||||
// intermediate update
|
||||
if (comp->intermediateUpdate) {
|
||||
comp->intermediateUpdate(
|
||||
comp->componentEnvironment, // instanceEnvironment
|
||||
comp->time, // intermediateUpdateTime
|
||||
false, // intermediateVariableSetRequested
|
||||
true, // intermediateVariableGetAllowed
|
||||
true, // intermediateStepFinished
|
||||
false, // canReturnEarly
|
||||
&earlyReturnRequested, // earlyReturnRequested
|
||||
&earlyReturnTime); // earlyReturnTime
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,887 @@
|
||||
#if FMI_VERSION != 2
|
||||
#error FMI_VERSION must be 2
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "model.h"
|
||||
#include "cosimulation.h"
|
||||
|
||||
|
||||
// C-code FMUs have functions names prefixed with MODEL_IDENTIFIER_.
|
||||
// Define DISABLE_PREFIX to build a binary FMU.
|
||||
#ifndef DISABLE_PREFIX
|
||||
#define pasteA(a,b) a ## b
|
||||
#define pasteB(a,b) pasteA(a,b)
|
||||
#define FMI2_FUNCTION_PREFIX pasteB(MODEL_IDENTIFIER, _)
|
||||
#endif
|
||||
#include "fmi2Functions.h"
|
||||
|
||||
#define ASSERT_NOT_NULL(p) \
|
||||
do { \
|
||||
if (!p) { \
|
||||
logError(S, "Argument %s must not be NULL.", xstr(p)); \
|
||||
S->state = modelError; \
|
||||
return (fmi2Status)Error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define GET_VARIABLES(T) \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
if (nvr == 0) return (fmi2Status)status; \
|
||||
ASSERT_NOT_NULL(vr); \
|
||||
ASSERT_NOT_NULL(value); \
|
||||
size_t index = 0; \
|
||||
if (S->isDirtyValues) { \
|
||||
Status s = calculateValues(S); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
S->isDirtyValues = false; \
|
||||
} \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
Status s = get ## T(S, vr[i], value, nvr, &index); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#define SET_VARIABLES(T) \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
if (nvr == 0) return (fmi2Status)status; \
|
||||
ASSERT_NOT_NULL(vr); \
|
||||
ASSERT_NOT_NULL(value); \
|
||||
size_t index = 0; \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
Status s = set ## T(S, vr[i], value, nvr, &index); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
if (nvr > 0) S->isDirtyValues = true; \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#define GET_BOOLEAN_VARIABLES \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
bool v = false; \
|
||||
size_t index = 0; \
|
||||
Status s = getBoolean(S, vr[i], &v, nvr, &index); \
|
||||
value[i] = v; \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#define SET_BOOLEAN_VARIABLES \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
bool v = value[i]; \
|
||||
size_t index = 0; \
|
||||
Status s = setBoolean(S, vr[i], &v, nvr, &index); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a)>(b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef DT_EVENT_DETECT
|
||||
#define DT_EVENT_DETECT 1e-10
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Function calls allowed state masks for both Model-exchange and Co-simulation
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MASK_fmi2GetTypesPlatform (StartAndEnd | Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepInProgress | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetVersion MASK_fmi2GetTypesPlatform
|
||||
#define MASK_fmi2SetDebugLogging (Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepInProgress | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2Instantiate (StartAndEnd)
|
||||
#define MASK_fmi2FreeInstance (Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2SetupExperiment Instantiated
|
||||
#define MASK_fmi2EnterInitializationMode Instantiated
|
||||
#define MASK_fmi2ExitInitializationMode InitializationMode
|
||||
#define MASK_fmi2Terminate (EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed)
|
||||
#define MASK_fmi2Reset MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2GetReal (InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetInteger MASK_fmi2GetReal
|
||||
#define MASK_fmi2GetBoolean MASK_fmi2GetReal
|
||||
#define MASK_fmi2GetString MASK_fmi2GetReal
|
||||
#define MASK_fmi2SetReal (Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete)
|
||||
#define MASK_fmi2SetInteger (Instantiated | InitializationMode \
|
||||
| EventMode \
|
||||
| StepComplete)
|
||||
#define MASK_fmi2SetBoolean MASK_fmi2SetInteger
|
||||
#define MASK_fmi2SetString MASK_fmi2SetInteger
|
||||
#define MASK_fmi2GetFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2SetFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2FreeFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2SerializedFMUstateSize MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2SerializeFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2DeSerializeFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2GetDirectionalDerivative (InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Function calls allowed state masks for Model-exchange
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MASK_fmi2EnterEventMode (EventMode | ContinuousTimeMode)
|
||||
#define MASK_fmi2NewDiscreteStates EventMode
|
||||
#define MASK_fmi2EnterContinuousTimeMode EventMode
|
||||
#define MASK_fmi2CompletedIntegratorStep ContinuousTimeMode
|
||||
#define MASK_fmi2SetTime (EventMode | ContinuousTimeMode)
|
||||
#define MASK_fmi2SetContinuousStates ContinuousTimeMode
|
||||
#define MASK_fmi2GetEventIndicators (InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetContinuousStates MASK_fmi2GetEventIndicators
|
||||
#define MASK_fmi2GetDerivatives (EventMode | ContinuousTimeMode \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetNominalsOfContinuousStates ( Instantiated \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| Terminated | modelError)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Function calls allowed state masks for Co-simulation
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MASK_fmi2SetRealInputDerivatives (Instantiated | InitializationMode \
|
||||
| StepComplete)
|
||||
#define MASK_fmi2GetRealOutputDerivatives (StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | Error)
|
||||
#define MASK_fmi2DoStep StepComplete
|
||||
#define MASK_fmi2CancelStep StepInProgress
|
||||
#define MASK_fmi2GetStatus (StepComplete | StepInProgress | StepFailed \
|
||||
| Terminated)
|
||||
#define MASK_fmi2GetRealStatus MASK_fmi2GetStatus
|
||||
#define MASK_fmi2GetIntegerStatus MASK_fmi2GetStatus
|
||||
#define MASK_fmi2GetBooleanStatus MASK_fmi2GetStatus
|
||||
#define MASK_fmi2GetStringStatus MASK_fmi2GetStatus
|
||||
|
||||
// shorthand to access the instance
|
||||
#define S ((ModelInstance *)c)
|
||||
|
||||
#define ASSERT_STATE(S) \
|
||||
if (!allowedState(c, MASK_fmi2##S, #S)) \
|
||||
return fmi2Error;
|
||||
|
||||
static bool allowedState(ModelInstance *instance, int statesExpected, char *name) {
|
||||
|
||||
if (!instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(instance->state & statesExpected)) {
|
||||
logError(instance, "fmi2%s: Illegal call sequence.", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FMI functions
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2String fmuGUID,
|
||||
fmi2String fmuResourceLocation, const fmi2CallbackFunctions *functions,
|
||||
fmi2Boolean visible, fmi2Boolean loggingOn) {
|
||||
|
||||
UNUSED(visible);
|
||||
|
||||
if (!functions || !functions->logger) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return createModelInstance(
|
||||
(loggerType)functions->logger,
|
||||
NULL,
|
||||
functions->componentEnvironment,
|
||||
instanceName,
|
||||
fmuGUID,
|
||||
fmuResourceLocation,
|
||||
loggingOn,
|
||||
(InterfaceType)fmuType);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetupExperiment(fmi2Component c, fmi2Boolean toleranceDefined, fmi2Real tolerance,
|
||||
fmi2Real startTime, fmi2Boolean stopTimeDefined, fmi2Real stopTime) {
|
||||
|
||||
UNUSED(toleranceDefined);
|
||||
UNUSED(tolerance);
|
||||
|
||||
ASSERT_STATE(SetupExperiment)
|
||||
|
||||
S->startTime = startTime;
|
||||
S->stopTime = stopTimeDefined ? stopTime : INFINITY;
|
||||
S->time = startTime;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2EnterInitializationMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(EnterInitializationMode)
|
||||
|
||||
S->state = InitializationMode;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2ExitInitializationMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(ExitInitializationMode);
|
||||
|
||||
fmi2Status status = fmi2OK;
|
||||
|
||||
// if values were set and no fmi2GetXXX triggered update before,
|
||||
// ensure calculated values are updated now
|
||||
if (S->isDirtyValues) {
|
||||
status = (fmi2Status)calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
if (S->type == ModelExchange) {
|
||||
S->state = EventMode;
|
||||
} else {
|
||||
S->state = StepComplete;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
fmi2Status fmi2Terminate(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(Terminate)
|
||||
|
||||
S->state = Terminated;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2Reset(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(Reset);
|
||||
|
||||
reset(S);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
void fmi2FreeInstance(fmi2Component c) {
|
||||
|
||||
if (S) {
|
||||
freeModelInstance(S);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FMI functions: class methods not depending of a specific model instance
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const char* fmi2GetVersion(void) {
|
||||
return fmi2Version;
|
||||
}
|
||||
|
||||
const char* fmi2GetTypesPlatform(void) {
|
||||
return fmi2TypesPlatform;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FMI functions: logging control, setters and getters for Real, Integer,
|
||||
// Boolean, String
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
fmi2Status fmi2SetDebugLogging(fmi2Component c, fmi2Boolean loggingOn, size_t nCategories, const fmi2String categories[]) {
|
||||
|
||||
ASSERT_STATE(SetDebugLogging)
|
||||
|
||||
return (fmi2Status)setDebugLogging(S, loggingOn, nCategories, categories);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetReal(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Real value[]) {
|
||||
|
||||
ASSERT_STATE(GetReal)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetReal", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetReal", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_VARIABLES(Float64);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetInteger(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[]) {
|
||||
|
||||
ASSERT_STATE(GetInteger)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetInteger", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetInteger", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_VARIABLES(Int32);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetBoolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Boolean value[]) {
|
||||
|
||||
ASSERT_STATE(GetBoolean)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetBoolean", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetBoolean", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_BOOLEAN_VARIABLES;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetString (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2String value[]) {
|
||||
|
||||
ASSERT_STATE(GetString)
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2GetString", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2GetString", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_VARIABLES(String);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetReal (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Real value[]) {
|
||||
|
||||
ASSERT_STATE(SetReal)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetReal", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetReal", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_VARIABLES(Float64);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetInteger(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[]) {
|
||||
|
||||
ASSERT_STATE(SetInteger)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetInteger", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetInteger", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_VARIABLES(Int32);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetBoolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Boolean value[]) {
|
||||
|
||||
ASSERT_STATE(SetBoolean)
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetBoolean", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetBoolean", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_BOOLEAN_VARIABLES;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetString (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2String value[]) {
|
||||
|
||||
ASSERT_STATE(SetString);
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetString", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetString", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_VARIABLES(String);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetFMUstate (fmi2Component c, fmi2FMUstate* FMUstate) {
|
||||
|
||||
ASSERT_STATE(GetFMUstate);
|
||||
|
||||
*FMUstate = getFMUState(S);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetFMUstate(fmi2Component c, fmi2FMUstate FMUstate) {
|
||||
|
||||
ASSERT_STATE(SetFMUstate);
|
||||
|
||||
if (nullPointer(S, "fmi2SetFMUstate", "FMUstate", FMUstate)) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
setFMUState(S, FMUstate);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2FreeFMUstate(fmi2Component c, fmi2FMUstate* FMUstate) {
|
||||
|
||||
ASSERT_STATE(FreeFMUstate);
|
||||
|
||||
free(*FMUstate);
|
||||
|
||||
*FMUstate = NULL;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SerializedFMUstateSize(fmi2Component c, fmi2FMUstate FMUstate, size_t *size) {
|
||||
|
||||
UNUSED(c);
|
||||
UNUSED(FMUstate);
|
||||
|
||||
ASSERT_STATE(SerializedFMUstateSize);
|
||||
|
||||
*size = sizeof(ModelInstance);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SerializeFMUstate(fmi2Component c, fmi2FMUstate FMUstate, fmi2Byte serializedState[], size_t size) {
|
||||
|
||||
ASSERT_STATE(SerializeFMUstate);
|
||||
|
||||
if (nullPointer(S, "fmi2SerializeFMUstate", "FMUstate", FMUstate)) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
if (invalidNumber(S, "fmi2SerializeFMUstate", "size", size, sizeof(ModelInstance))) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
memcpy(serializedState, FMUstate, sizeof(ModelInstance));
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2DeSerializeFMUstate (fmi2Component c, const fmi2Byte serializedState[], size_t size, fmi2FMUstate* FMUstate) {
|
||||
|
||||
ASSERT_STATE(DeSerializeFMUstate);
|
||||
|
||||
if (invalidNumber(S, "fmi2DeSerializeFMUstate", "size", size, sizeof(ModelInstance))) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
if (*FMUstate == NULL) {
|
||||
*FMUstate = calloc(1, sizeof(ModelInstance));
|
||||
}
|
||||
|
||||
memcpy(*FMUstate, serializedState, sizeof(ModelInstance));
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetDirectionalDerivative(fmi2Component c, const fmi2ValueReference vUnknown_ref[], size_t nUnknown,
|
||||
const fmi2ValueReference vKnown_ref[] , size_t nKnown,
|
||||
const fmi2Real dvKnown[], fmi2Real dvUnknown[]) {
|
||||
|
||||
ASSERT_STATE(GetDirectionalDerivative);
|
||||
|
||||
// TODO: check value references
|
||||
// TODO: assert nUnknowns == nDeltaOfUnknowns
|
||||
// TODO: assert nKnowns == nDeltaKnowns
|
||||
|
||||
Status status = OK;
|
||||
|
||||
for (size_t i = 0; i < nUnknown; i++) {
|
||||
dvUnknown[i] = 0;
|
||||
for (size_t j = 0; j < nKnown; j++) {
|
||||
double partialDerivative = 0;
|
||||
Status s = getPartialDerivative(S, vUnknown_ref[i], vKnown_ref[j], &partialDerivative);
|
||||
status = max(status, s);
|
||||
if (status > Warning) {
|
||||
return (fmi2Status)status;
|
||||
}
|
||||
dvUnknown[i] += partialDerivative * dvKnown[j];
|
||||
}
|
||||
}
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Functions for FMI for Co-Simulation
|
||||
// ---------------------------------------------------------------------------
|
||||
/* Simulating the slave */
|
||||
fmi2Status fmi2SetRealInputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[], const fmi2Real value[]) {
|
||||
|
||||
UNUSED(vr);
|
||||
UNUSED(nvr);
|
||||
UNUSED(order);
|
||||
UNUSED(value);
|
||||
|
||||
ASSERT_STATE(SetRealInputDerivatives);
|
||||
|
||||
logError(S, "fmi2SetRealInputDerivatives: ignoring function call."
|
||||
" This model cannot interpolate inputs: canInterpolateInputs=\"fmi2False\"");
|
||||
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetRealOutputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[], fmi2Real value[]) {
|
||||
|
||||
ASSERT_STATE(GetRealOutputDerivatives);
|
||||
|
||||
#ifdef GET_OUTPUT_DERIVATIVE
|
||||
Status status = OK;
|
||||
|
||||
for (size_t i = 0; i < nvr; i++) {
|
||||
const Status s = getOutputDerivative(S, vr[i], order[i], &value[i]);
|
||||
status = max(status, s);
|
||||
if (status > Warning) {
|
||||
return (fmi2Status)status;
|
||||
}
|
||||
}
|
||||
|
||||
return (fmi2Status)status;
|
||||
#else
|
||||
UNUSED(vr);
|
||||
UNUSED(nvr);
|
||||
UNUSED(order);
|
||||
UNUSED(value);
|
||||
|
||||
logError(S, "fmi2GetRealOutputDerivatives: ignoring function call."
|
||||
" This model cannot compute derivatives of outputs: MaxOutputDerivativeOrder=\"0\"");
|
||||
|
||||
return fmi2Error;
|
||||
#endif
|
||||
}
|
||||
|
||||
fmi2Status fmi2CancelStep(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(CancelStep);
|
||||
|
||||
logError(S, "fmi2CancelStep: Can be called when fmi2DoStep returned fmi2Pending."
|
||||
" This is not the case.");
|
||||
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint,
|
||||
fmi2Real communicationStepSize, fmi2Boolean noSetFMUStatePriorToCurrentPoint) {
|
||||
|
||||
UNUSED(noSetFMUStatePriorToCurrentPoint);
|
||||
|
||||
ASSERT_STATE(DoStep);
|
||||
|
||||
if (communicationStepSize <= 0) {
|
||||
logError(S, "Communication step size must be > 0 but was %g.", communicationStepSize);
|
||||
S->state = modelError;
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
if (currentCommunicationPoint + communicationStepSize > S->stopTime + EPSILON) {
|
||||
logError(S, "At communication point %.16g a step size of %.16g was requested but stop time is %.16g.",
|
||||
currentCommunicationPoint, communicationStepSize, S->stopTime);
|
||||
S->state = modelError;
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
const fmi2Real nextCommunicationPoint = currentCommunicationPoint + communicationStepSize + EPSILON;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (S->time + FIXED_SOLVER_STEP > nextCommunicationPoint) {
|
||||
break; // next communication point reached
|
||||
}
|
||||
|
||||
bool stateEvent, timeEvent;
|
||||
|
||||
doFixedStep(S, &stateEvent, &timeEvent);
|
||||
|
||||
#ifdef EVENT_UPDATE
|
||||
if (stateEvent || timeEvent) {
|
||||
eventUpdate(S);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return S->terminateSimulation ? fmi2Discard : fmi2OK;
|
||||
}
|
||||
|
||||
/* Inquire slave status */
|
||||
static fmi2Status getStatus(char* fname, fmi2Component c, const fmi2StatusKind s) {
|
||||
|
||||
switch(s) {
|
||||
case fmi2DoStepStatus: logError(S,
|
||||
"%s: Can be called with fmi2DoStepStatus when fmi2DoStep returned fmi2Pending."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
case fmi2PendingStatus: logError(S,
|
||||
"%s: Can be called with fmi2PendingStatus when fmi2DoStep returned fmi2Pending."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
case fmi2LastSuccessfulTime: logError(S,
|
||||
"%s: Can be called with fmi2LastSuccessfulTime when fmi2DoStep returned fmi2Discard."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
case fmi2Terminated: logError(S,
|
||||
"%s: Can be called with fmi2Terminated when fmi2DoStep returned fmi2Discard."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
}
|
||||
|
||||
return fmi2Discard;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetStatus(fmi2Component c, const fmi2StatusKind s, fmi2Status *value) {
|
||||
|
||||
UNUSED(value);
|
||||
|
||||
ASSERT_STATE(GetStatus);
|
||||
|
||||
return getStatus("fmi2GetStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetRealStatus(fmi2Component c, const fmi2StatusKind s, fmi2Real *value) {
|
||||
|
||||
ASSERT_STATE(GetRealStatus);
|
||||
|
||||
if (s == fmi2LastSuccessfulTime) {
|
||||
*value = S->time;
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
return getStatus("fmi2GetRealStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetIntegerStatus(fmi2Component c, const fmi2StatusKind s, fmi2Integer *value) {
|
||||
|
||||
UNUSED(value);
|
||||
|
||||
ASSERT_STATE(GetIntegerStatus);
|
||||
|
||||
return getStatus("fmi2GetIntegerStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetBooleanStatus(fmi2Component c, const fmi2StatusKind s, fmi2Boolean *value) {
|
||||
|
||||
ASSERT_STATE(GetBooleanStatus);
|
||||
|
||||
if (s == fmi2Terminated) {
|
||||
*value = S->terminateSimulation;
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
return getStatus("fmi2GetBooleanStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetStringStatus(fmi2Component c, const fmi2StatusKind s, fmi2String *value) {
|
||||
UNUSED(value);
|
||||
ASSERT_STATE(GetStringStatus);
|
||||
return getStatus("fmi2GetStringStatus", c, s);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Functions for FMI2 for Model Exchange
|
||||
// ---------------------------------------------------------------------------
|
||||
/* Enter and exit the different modes */
|
||||
fmi2Status fmi2EnterEventMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(EnterEventMode);
|
||||
|
||||
S->state = EventMode;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2NewDiscreteStates(fmi2Component c, fmi2EventInfo *eventInfo) {
|
||||
|
||||
ASSERT_STATE(NewDiscreteStates);
|
||||
|
||||
#ifdef EVENT_UPDATE
|
||||
eventUpdate(S);
|
||||
#endif
|
||||
|
||||
eventInfo->newDiscreteStatesNeeded = S->newDiscreteStatesNeeded;
|
||||
eventInfo->terminateSimulation = S->terminateSimulation;
|
||||
eventInfo->nominalsOfContinuousStatesChanged = S->nominalsOfContinuousStatesChanged;
|
||||
eventInfo->valuesOfContinuousStatesChanged = S->valuesOfContinuousStatesChanged;
|
||||
eventInfo->nextEventTimeDefined = S->nextEventTimeDefined;
|
||||
eventInfo->nextEventTime = S->nextEventTime;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2EnterContinuousTimeMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(EnterContinuousTimeMode);
|
||||
|
||||
S->state = ContinuousTimeMode;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2CompletedIntegratorStep(fmi2Component c, fmi2Boolean noSetFMUStatePriorToCurrentPoint,
|
||||
fmi2Boolean *enterEventMode, fmi2Boolean *terminateSimulation) {
|
||||
|
||||
|
||||
|
||||
UNUSED(noSetFMUStatePriorToCurrentPoint);
|
||||
|
||||
ASSERT_STATE(CompletedIntegratorStep);
|
||||
|
||||
if (nullPointer(S, "fmi2CompletedIntegratorStep", "enterEventMode", enterEventMode))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2CompletedIntegratorStep", "terminateSimulation", terminateSimulation))
|
||||
return fmi2Error;
|
||||
|
||||
*enterEventMode = fmi2False;
|
||||
*terminateSimulation = fmi2False;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
/* Providing independent variables and re-initialization of caching */
|
||||
fmi2Status fmi2SetTime(fmi2Component c, fmi2Real time) {
|
||||
|
||||
ASSERT_STATE(SetTime);
|
||||
|
||||
S->time = time;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetContinuousStates(fmi2Component c, const fmi2Real x[], size_t nx){
|
||||
|
||||
ASSERT_STATE(SetContinuousStates);
|
||||
|
||||
if (invalidNumber(S, "fmi2SetContinuousStates", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2SetContinuousStates", "x[]", x))
|
||||
return fmi2Error;
|
||||
|
||||
setContinuousStates(S, x, nx);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
/* Evaluation of the model equations */
|
||||
fmi2Status fmi2GetDerivatives(fmi2Component c, fmi2Real derivatives[], size_t nx) {
|
||||
|
||||
ASSERT_STATE(GetDerivatives);
|
||||
|
||||
if (invalidNumber(S, "fmi2GetDerivatives", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2GetDerivatives", "derivatives[]", derivatives))
|
||||
return fmi2Error;
|
||||
|
||||
getDerivatives(S, derivatives, nx);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetEventIndicators(fmi2Component c, fmi2Real eventIndicators[], size_t ni) {
|
||||
|
||||
ASSERT_STATE(GetEventIndicators);
|
||||
|
||||
#if NZ > 0
|
||||
|
||||
if (invalidNumber(S, "fmi2GetEventIndicators", "ni", ni, NZ))
|
||||
return fmi2Error;
|
||||
|
||||
getEventIndicators(S, eventIndicators, ni);
|
||||
#else
|
||||
UNUSED(c);
|
||||
UNUSED(eventIndicators);
|
||||
if (ni > 0) return fmi2Error;
|
||||
#endif
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetContinuousStates(fmi2Component c, fmi2Real states[], size_t nx) {
|
||||
|
||||
ASSERT_STATE(GetContinuousStates);
|
||||
|
||||
if (invalidNumber(S, "fmi2GetContinuousStates", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2GetContinuousStates", "states[]", states))
|
||||
return fmi2Error;
|
||||
|
||||
getContinuousStates(S, states, nx);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetNominalsOfContinuousStates(fmi2Component c, fmi2Real x_nominal[], size_t nx) {
|
||||
|
||||
ASSERT_STATE(GetNominalsOfContinuousStates);
|
||||
|
||||
if (invalidNumber(S, "fmi2GetNominalContinuousStates", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2GetNominalContinuousStates", "x_nominal[]", x_nominal))
|
||||
return fmi2Error;
|
||||
|
||||
for (size_t i = 0; i < nx; i++)
|
||||
x_nominal[i] = 1;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
|
||||
/* */
|
||||
/* This script file uses the Doors4ExampleFMU.fmu to be run in OpenXiL */
|
||||
/* */
|
||||
ADD_BBVARI(Loop, UDWORD)
|
||||
SET_BBVARI(Loop = 0)
|
||||
|
||||
/* */
|
||||
/* Door01Left = 1 represents a open door */
|
||||
/* wait more then 2 seconds */
|
||||
/* Open all doors */
|
||||
/* */
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 1)
|
||||
SET_BBVARI(Door01RightIsOpen = 1)
|
||||
|
||||
/* */
|
||||
/* Close each door one by one */
|
||||
/* wait more then 2 seconds */
|
||||
/* Open all doors */
|
||||
/* */
|
||||
|
||||
|
||||
WHILE(Loop < 10)
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 0)
|
||||
DELAY(100)
|
||||
|
||||
SET_BBVARI(Door01RightIsOpen = 0)
|
||||
DELAY(100)
|
||||
|
||||
SET_BBVARI(Door02LeftIsOpen = 0)
|
||||
DELAY(100)
|
||||
|
||||
SET_BBVARI(Door02RightIsOpen = 0)
|
||||
|
||||
/* */
|
||||
/* wait until the doors are locked, < 2 seconds */
|
||||
/* */
|
||||
DELAY(1000)
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 1)
|
||||
SET_BBVARI(Door01RightIsOpen = 1)
|
||||
SET_BBVARI(Door02LeftIsOpen = 1)
|
||||
SET_BBVARI(Door02RightIsOpen = 1)
|
||||
|
||||
DELAY(100)
|
||||
SET(Loop = Loop + 1)
|
||||
ENDWHILE
|
||||
|
||||
|
||||
/* */
|
||||
/* This script file uses the Doors4ExampleFMU.fmu to be run in OpenXiL */
|
||||
/* */
|
||||
ADD_BBVARI(Loop, UDWORD)
|
||||
SET_BBVARI(Loop = 0)
|
||||
|
||||
/* */
|
||||
/* Door01Left = 1 represents a open door */
|
||||
/* wait more then 2 seconds */
|
||||
/* Open all doors */
|
||||
/* */
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 1)
|
||||
SET_BBVARI(Door01RightIsOpen = 1)
|
||||
|
||||
/* */
|
||||
/* Close each door one by one */
|
||||
/* wait more then 2 seconds */
|
||||
/* Open all doors */
|
||||
/* */
|
||||
|
||||
WHILE(Loop < 10)
|
||||
SET_BBVARI(Door01LeftIsOpen = 0)
|
||||
DELAY(100)
|
||||
SET_BBVARI(Door01RightIsOpen = 0)
|
||||
DELAY(100)
|
||||
|
||||
DELAY(2000)
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 1)
|
||||
SET_BBVARI(Door01RightIsOpen = 1)
|
||||
|
||||
DELAY(100)
|
||||
SET(Loop = Loop + 1)
|
||||
ENDWHILE
|
||||
|
||||
180
examples/door_demo_example/fmu_Doors4ExampleFMU/CMakeLists.txt
Normal file
180
examples/door_demo_example/fmu_Doors4ExampleFMU/CMakeLists.txt
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
# @file CMakeLists.txt
|
||||
# This file is cmake project file.
|
||||
# This file was generated by the DBC utility from:
|
||||
# datalink_4doors_example.dbc
|
||||
# DBC file version: 1.0.0.1
|
||||
|
||||
|
||||
# Based on CMakeLists.txt from https://github.com/modelica/Reference-FMUs
|
||||
# only FMI 2.0, only CoSimulation
|
||||
# without fumsim
|
||||
|
||||
|
||||
# Only valid for Windows
|
||||
if ( WIN32 )
|
||||
|
||||
# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# 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
|
||||
|
||||
project (Doors4ExampleFMUProject)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Library symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
set(VAPI_CORE_SDV_BINARY_DIR ${CMAKE_BINARY_DIR}/bin)
|
||||
set(MODEL_NAME Doors4ExampleFMU)
|
||||
set(TARGET_NAME ${MODEL_NAME})
|
||||
set(FMU_FULL_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/fmus/${MODEL_NAME}.fmu")
|
||||
|
||||
FUNCTION(cat IN_FILE OUT_FILE)
|
||||
file(READ ${IN_FILE} CONTENTS)
|
||||
file(APPEND ${OUT_FILE} "${CONTENTS}")
|
||||
ENDFUNCTION()
|
||||
|
||||
set(FMI_VERSION 2 CACHE STRING "FMI Version")
|
||||
set_property(CACHE FMI_VERSION PROPERTY STRINGS 2)
|
||||
|
||||
set(FMI_TYPE CS CACHE STRING "FMI Version")
|
||||
set_property(CACHE FMI_TYPE PROPERTY STRINGS CS)
|
||||
set(FMI_TYPE "")
|
||||
|
||||
set (FMI_PLATFORM win32)
|
||||
if ("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set (FMI_PLATFORM win64)
|
||||
endif ()
|
||||
|
||||
SET(HEADERS
|
||||
${MODEL_NAME}/config.h
|
||||
include/cosimulation.h
|
||||
include/model.h
|
||||
)
|
||||
|
||||
SET(HEADERS
|
||||
${HEADERS}
|
||||
include/fmi2Functions.h
|
||||
include/fmi2FunctionTypes.h
|
||||
include/fmi2TypesPlatform.h
|
||||
)
|
||||
|
||||
SET(SOURCES
|
||||
${MODEL_NAME}/model.cpp
|
||||
src/fmi${FMI_VERSION}Functions.c
|
||||
src/cosimulation.c
|
||||
)
|
||||
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
${HEADERS}
|
||||
${SOURCES}
|
||||
${MODEL_NAME}/FMI${FMI_VERSION}${FMI_TYPE}.xml
|
||||
${MODEL_NAME}/buildDescription.xml
|
||||
)
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/fmus)
|
||||
|
||||
set(FMU_BUILD_DIR temp/${MODEL_NAME})
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE
|
||||
FMI_VERSION=${FMI_VERSION}
|
||||
DISABLE_PREFIX
|
||||
)
|
||||
|
||||
#[[
|
||||
if (MSVC)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++ -static-libgcc")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
|
||||
endif()
|
||||
]]
|
||||
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE FMI_COSIMULATION)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE include ${MODEL_NAME})
|
||||
target_link_libraries(${TARGET_NAME} Winmm Ws2_32 Rpcrt4.lib)
|
||||
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${FMU_BUILD_DIR}/binaries/${FMI_PLATFORM}"
|
||||
)
|
||||
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${MODEL_NAME})
|
||||
|
||||
# modelDescription.xml
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${MODEL_NAME}/FMI${FMI_VERSION}${FMI_TYPE}.xml
|
||||
"${FMU_BUILD_DIR}/modelDescription.xml"
|
||||
)
|
||||
|
||||
set(ARCHIVE_FILES "modelDescription.xml" "binaries")
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${MODEL_NAME}/resources")
|
||||
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${MODEL_NAME}/resources"
|
||||
"${FMU_BUILD_DIR}/resources/"
|
||||
)
|
||||
set(ARCHIVE_FILES ${ARCHIVE_FILES} "resources")
|
||||
endif()
|
||||
|
||||
# When windows robocopy command (using cmd.exe) is used to copy files its important to set the dependencies
|
||||
# to assure that the copy command is finished before the next custom action to avoid copy/file access failures
|
||||
|
||||
# Copy sdv binaries of this FMU
|
||||
set(DEST_DIR "${FMU_BUILD_DIR}/resources")
|
||||
set(SOURCE_DIR_EXAMPLES_BIN "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
add_custom_target(copy_function_sdv_files_${TARGET_NAME} DEPENDS ${TARGET_NAME})
|
||||
add_custom_command(TARGET copy_function_sdv_files_${TARGET_NAME}
|
||||
COMMAND cmd /C "robocopy \"${SOURCE_DIR_EXAMPLES_BIN}\" \"${DEST_DIR}\" *.pdb *.sdv /NP /R:3 /W:5 || exit /b 0"
|
||||
COMMENT "Copying contents from ${SOURCE_DIR_EXAMPLES_BIN} to ${DEST_DIR}, include only *.pdb *.sdv files"
|
||||
)
|
||||
add_dependencies(copy_function_sdv_files_${TARGET_NAME} ${TARGET_NAME})
|
||||
|
||||
|
||||
|
||||
# Copy framework sdv binaries
|
||||
set(SOURCE_DIR_CORE_BIN "${SDV_FRAMEWORK_RUNTIME}")
|
||||
add_custom_target(copy_framework_sdv_files_${TARGET_NAME} DEPENDS copy_function_sdv_files_${TARGET_NAME})
|
||||
add_custom_command(TARGET copy_framework_sdv_files_${TARGET_NAME}
|
||||
COMMAND cmd /C "robocopy \"${SOURCE_DIR_CORE_BIN}\" \"${DEST_DIR}\" *.pdb *.sdv /NP /R:3 /W:5 || exit /b 0"
|
||||
COMMENT "Copying contents from ${SOURCE_DIR_CORE_BIN} to ${DEST_DIR}, include only *.pdb *.sdv files"
|
||||
)
|
||||
add_dependencies(copy_framework_sdv_files_${TARGET_NAME} copy_function_sdv_files_${TARGET_NAME})
|
||||
|
||||
|
||||
|
||||
# FMU content created, all files copied
|
||||
# to zip the files create a new target 'create_zip' which is build after all files have been copied
|
||||
add_custom_target(create_zip_${TARGET_NAME} ALL DEPENDS copy_framework_sdv_files_${TARGET_NAME} )
|
||||
add_custom_command(TARGET create_zip_${TARGET_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E tar "cfv" ${FMU_FULL_FILE_NAME} --format=zip ${ARCHIVE_FILES}
|
||||
WORKING_DIRECTORY ${FMU_BUILD_DIR}
|
||||
COMMENT "Creating ZIP ${FMU_FULL_FILE_NAME}"
|
||||
)
|
||||
add_dependencies(create_zip_${TARGET_NAME} copy_framework_sdv_files_${TARGET_NAME})
|
||||
|
||||
#TODO
|
||||
#add_dependencies(${TARGET_NAME} <add_cmake_target_this_depends_on>)
|
||||
endif ()
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fmiModelDescription
|
||||
fmiVersion = "2.0"
|
||||
modelName = "Doors4ExampleFMU"
|
||||
guid = "3fbc9066-6c16-4b98-b5fc-7a7c0735f200"
|
||||
description = "TargetLink FMU for Doors4ExampleFMU"
|
||||
generationTool = "TargetLink was generated by the DBC utility: datalink_4doors_example.dbc"
|
||||
generationDateAndTime = "2025-09-06 14:55:42"
|
||||
variableNamingConvention = "structured"
|
||||
numberOfEventIndicators = "0">
|
||||
<CoSimulation
|
||||
modelIdentifier = "Doors4ExampleFMU"
|
||||
canHandleVariableCommunicationStepSize = "false"
|
||||
canGetAndSetFMUstate = "false"
|
||||
canSerializeFMUstate = "false"
|
||||
providesDirectionalDerivative = "false"
|
||||
canBeInstantiatedOnlyOncePerProcess = "true"
|
||||
canInterpolateInputs = "false"
|
||||
canRunAsynchronuously = "false">
|
||||
<SourceFiles>
|
||||
<File name="all.c"/>
|
||||
</SourceFiles>
|
||||
</CoSimulation>
|
||||
<DefaultExperiment startTime="0" stepSize="0.01"/>
|
||||
<ModelVariables>
|
||||
<!--Index for next variable = 1 -->
|
||||
<ScalarVariable name = "Door01LeftIsOpen"
|
||||
valueReference = "0"
|
||||
description = " "
|
||||
causality = "input">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 2 -->
|
||||
<ScalarVariable name = "Door01RightIsOpen"
|
||||
valueReference = "1"
|
||||
description = " "
|
||||
causality = "input">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 3 -->
|
||||
<ScalarVariable name = "Door02LeftIsOpen"
|
||||
valueReference = "2"
|
||||
description = " "
|
||||
causality = "input">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 4 -->
|
||||
<ScalarVariable name = "Door02RightIsOpen"
|
||||
valueReference = "3"
|
||||
description = " "
|
||||
causality = "input">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 5 -->
|
||||
<ScalarVariable name = "LockDoor02Right"
|
||||
valueReference = "4"
|
||||
description = " "
|
||||
causality = "output">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 6 -->
|
||||
<ScalarVariable name = "LockDoor02Left"
|
||||
valueReference = "5"
|
||||
description = " "
|
||||
causality = "output">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 7 -->
|
||||
<ScalarVariable name = "LockDoor01Right"
|
||||
valueReference = "6"
|
||||
description = " "
|
||||
causality = "output">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
<!--Index for next variable = 8 -->
|
||||
<ScalarVariable name = "LockDoor01Left"
|
||||
valueReference = "7"
|
||||
description = " "
|
||||
causality = "output">
|
||||
<Integer start = "0"
|
||||
min = "0u"
|
||||
max = "1u" />
|
||||
</ScalarVariable>
|
||||
|
||||
</ModelVariables>
|
||||
<ModelStructure>
|
||||
<Outputs>
|
||||
<Unknown index="0"/>
|
||||
</Outputs>
|
||||
</ModelStructure>
|
||||
</fmiModelDescription>
|
||||
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
@file buildDescription.xml
|
||||
@date 2025-09-06 14:55:42
|
||||
This file is the fmi Build Description xml.
|
||||
This file was generated by the DBC utility from:
|
||||
datalink_4doors_example.dbc
|
||||
DBC file version: 1.0.0.1
|
||||
-->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fmiBuildDescription fmiVersion="2.0">
|
||||
<BuildConfiguration modelIdentifier="Doors4ExampleFMU">
|
||||
<SourceFileSet language="C++17">
|
||||
<SourceFile name="fmi2Functions.c"/>
|
||||
<SourceFile name="model.c"/>
|
||||
<SourceFile name="cosimulation.c"/>
|
||||
<PreprocessorDefinition name="FMI_VERSION" value="2"/>
|
||||
</SourceFileSet>
|
||||
</BuildConfiguration>
|
||||
</fmiBuildDescription>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @file config.h
|
||||
* @date 2025-09-06 14:55:42
|
||||
* This file defines the data link object between CAN and the V-API devices.
|
||||
* This file was generated by the DBC utility from:
|
||||
* datalink_4doors_example.dbc
|
||||
* DBC file version: 1.0.0.1
|
||||
*/
|
||||
#ifndef __DBC_GENERATED__CONFIG_H__20250906_145542_578__
|
||||
#define __DBC_GENERATED__CONFIG_H__20250906_145542_578__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// define class name and unique id
|
||||
#define MODEL_IDENTIFIER Doors4ExampleFMU
|
||||
#define INSTANTIATION_TOKEN "3fbc9066-6c16-4b98-b5fc-7a7c0735f200"
|
||||
#define FMI_VERSION 2
|
||||
|
||||
#define CO_SIMULATION
|
||||
|
||||
// define model size
|
||||
#define NX 0
|
||||
#define NZ 0
|
||||
|
||||
#define GET_INT32
|
||||
#define SET_INT32
|
||||
#define GET_FLAOT64
|
||||
#define SET_FLOAT64
|
||||
#define EVENT_UPDATE
|
||||
#define CLEAN_UP
|
||||
|
||||
#define FIXED_SOLVER_STEP 0.04
|
||||
#define DEFAULT_STOP_TIME 10
|
||||
|
||||
typedef enum {
|
||||
|
||||
vr_Door01LeftIsOpen = 0,
|
||||
vr_Door01RightIsOpen = 1,
|
||||
vr_Door02LeftIsOpen = 2,
|
||||
vr_Door02RightIsOpen = 3,
|
||||
vr_LockDoor02Right = 4,
|
||||
vr_LockDoor02Left = 5,
|
||||
vr_LockDoor01Right = 6,
|
||||
vr_LockDoor01Left = 7,
|
||||
|
||||
} ValueReference;
|
||||
|
||||
typedef struct {
|
||||
|
||||
int32_t Door01LeftIsOpen;
|
||||
int32_t Door01RightIsOpen;
|
||||
int32_t Door02LeftIsOpen;
|
||||
int32_t Door02RightIsOpen;
|
||||
int32_t LockDoor02Right;
|
||||
int32_t LockDoor02Left;
|
||||
int32_t LockDoor01Right;
|
||||
int32_t LockDoor01Left;
|
||||
|
||||
} ModelData;
|
||||
|
||||
#endif // !defined __DBC_GENERATED__CONFIG_H__20250906_145542_578__
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
/**
|
||||
* @file model.cpp
|
||||
* @date 2025-09-06 14:55:42
|
||||
* This file defines the data link object between CAN and the V-API devices.
|
||||
* This file was generated by the DBC utility from:
|
||||
* datalink_4doors_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_signalDoor01LeftIsOpen;
|
||||
sdv::core::CSignal g_signalDoor01RightIsOpen;
|
||||
sdv::core::CSignal g_signalDoor02LeftIsOpen;
|
||||
sdv::core::CSignal g_signalDoor02RightIsOpen;
|
||||
sdv::core::CSignal g_signalLockDoor02Right;
|
||||
sdv::core::CSignal g_signalLockDoor02Left;
|
||||
sdv::core::CSignal g_signalLockDoor01Right;
|
||||
sdv::core::CSignal g_signalLockDoor01Left;
|
||||
|
||||
// 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_signalDoor01LeftIsOpen = dispatch.RegisterRxSignal("CAN_Input_L1.Door01LeftIsOpen");
|
||||
g_signalDoor01RightIsOpen = dispatch.RegisterRxSignal("CAN_Input_R1.Door01RightIsOpen");
|
||||
g_signalDoor02LeftIsOpen = dispatch.RegisterRxSignal("CAN_Input_L2.Door02LeftIsOpen");
|
||||
g_signalDoor02RightIsOpen = dispatch.RegisterRxSignal("CAN_Input_R2.Door02RightIsOpen");
|
||||
g_signalLockDoor02Right = dispatch.RegisterTxSignal("CAN_Output.LockDoor02Right",0);
|
||||
g_signalLockDoor02Left = dispatch.RegisterTxSignal("CAN_Output.LockDoor02Left",0);
|
||||
g_signalLockDoor01Right = dispatch.RegisterTxSignal("CAN_Output.LockDoor01Right",0);
|
||||
g_signalLockDoor01Left = dispatch.RegisterTxSignal("CAN_Output.LockDoor01Left",0);
|
||||
|
||||
if (g_signalDoor01LeftIsOpen && g_signalDoor01RightIsOpen && g_signalDoor02LeftIsOpen && g_signalDoor02RightIsOpen && g_signalLockDoor02Right && g_signalLockDoor02Left
|
||||
&& g_signalLockDoor01Right && g_signalLockDoor01Left)
|
||||
{
|
||||
return sdv::core::EConfigProcessResult::successful;
|
||||
}
|
||||
|
||||
return sdv::core::EConfigProcessResult::failed;
|
||||
}
|
||||
|
||||
bool ResetAllSignals()
|
||||
{
|
||||
sdv::core::CDispatchService dispatch;
|
||||
|
||||
if (g_signalDoor01LeftIsOpen)
|
||||
{
|
||||
g_signalDoor01LeftIsOpen.Reset();
|
||||
}
|
||||
if (g_signalDoor01RightIsOpen)
|
||||
{
|
||||
g_signalDoor01RightIsOpen.Reset();
|
||||
}
|
||||
if (g_signalDoor02LeftIsOpen)
|
||||
{
|
||||
g_signalDoor02LeftIsOpen.Reset();
|
||||
}
|
||||
if (g_signalDoor02RightIsOpen)
|
||||
{
|
||||
g_signalDoor02RightIsOpen.Reset();
|
||||
}
|
||||
if (g_signalLockDoor02Right)
|
||||
{
|
||||
g_signalLockDoor02Right.Reset();
|
||||
}
|
||||
if (g_signalLockDoor02Left)
|
||||
{
|
||||
g_signalLockDoor02Left.Reset();
|
||||
}
|
||||
if (g_signalLockDoor01Right)
|
||||
{
|
||||
g_signalLockDoor01Right.Reset();
|
||||
}
|
||||
if (g_signalLockDoor01Left)
|
||||
{
|
||||
g_signalLockDoor01Left.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("front_left_door_example.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
success &= g_appcontrol->LoadConfig("front_right_door_example.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
success &= g_appcontrol->LoadConfig("rear_left_door_example.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
success &= g_appcontrol->LoadConfig("rear_right_door_example.toml") == sdv::core::EConfigProcessResult::successful;
|
||||
success &= g_appcontrol->LoadConfig("door_comple_service.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);
|
||||
|
||||
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_Door01LeftIsOpen:
|
||||
values[(*index)++] = M(Door01LeftIsOpen);
|
||||
break;
|
||||
case vr_Door01RightIsOpen:
|
||||
values[(*index)++] = M(Door01RightIsOpen);
|
||||
break;
|
||||
case vr_Door02LeftIsOpen:
|
||||
values[(*index)++] = M(Door02LeftIsOpen);
|
||||
break;
|
||||
case vr_Door02RightIsOpen:
|
||||
values[(*index)++] = M(Door02RightIsOpen);
|
||||
break;
|
||||
case vr_LockDoor02Right:
|
||||
values[(*index)++] = M(LockDoor02Right);
|
||||
break;
|
||||
case vr_LockDoor02Left:
|
||||
values[(*index)++] = M(LockDoor02Left);
|
||||
break;
|
||||
case vr_LockDoor01Right:
|
||||
values[(*index)++] = M(LockDoor01Right);
|
||||
break;
|
||||
case vr_LockDoor01Left:
|
||||
values[(*index)++] = M(LockDoor01Left);
|
||||
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);
|
||||
|
||||
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_Door01LeftIsOpen:
|
||||
M(Door01LeftIsOpen) = values[(*index)++];
|
||||
break;
|
||||
case vr_Door01RightIsOpen:
|
||||
M(Door01RightIsOpen) = values[(*index)++];
|
||||
break;
|
||||
case vr_Door02LeftIsOpen:
|
||||
M(Door02LeftIsOpen) = values[(*index)++];
|
||||
break;
|
||||
case vr_Door02RightIsOpen:
|
||||
M(Door02RightIsOpen) = values[(*index)++];
|
||||
break;
|
||||
case vr_LockDoor02Right:
|
||||
M(LockDoor02Right) = values[(*index)++];
|
||||
break;
|
||||
case vr_LockDoor02Left:
|
||||
M(LockDoor02Left) = values[(*index)++];
|
||||
break;
|
||||
case vr_LockDoor01Right:
|
||||
M(LockDoor01Right) = values[(*index)++];
|
||||
break;
|
||||
case vr_LockDoor01Left:
|
||||
M(LockDoor01Left) = 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_signalDoor01LeftIsOpen.Write( M(Door01LeftIsOpen));
|
||||
g_signalDoor01RightIsOpen.Write( M(Door01RightIsOpen));
|
||||
g_signalDoor02LeftIsOpen.Write( M(Door02LeftIsOpen));
|
||||
g_signalDoor02RightIsOpen.Write( M(Door02RightIsOpen));
|
||||
M(LockDoor02Right) = g_signalLockDoor02Right.Read().get<uint32_t>();
|
||||
M(LockDoor02Left) = g_signalLockDoor02Left.Read().get<uint32_t>();
|
||||
M(LockDoor01Right) = g_signalLockDoor01Right.Read().get<uint32_t>();
|
||||
M(LockDoor01Left) = g_signalLockDoor01Left.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,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "door_complex_service.sdv"
|
||||
Class = "Doors Example Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Left_Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_frontdoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle01.Right_Service"
|
||||
@@ -0,0 +1,14 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_reardoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Left_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_reardoorleft.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Left_Service"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_vd_reardoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Right_Device"
|
||||
|
||||
[[Component]]
|
||||
Path = "doors_bs_reardoorright.sdv"
|
||||
Class = "Vehicle.Chassis.Door.Axle02.Right_Service"
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "simulation_task_timer.sdv"
|
||||
Class = "SimulationTaskTimerService"
|
||||
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "task_timer.sdv"
|
||||
Class = "TaskTimerService"
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
@file signal_identifier.h
|
||||
@date 2025-09-06 14:55:42
|
||||
This file is the signal identifier header.
|
||||
This file was generated by the DBC utility from:
|
||||
datalink_4doors_example.dbc
|
||||
DBC file version: 1.0.0.1
|
||||
*/
|
||||
#ifndef __DBC_GENERATED__SIGNALIDENTIFIER_H__20250906_145542_578__
|
||||
#define __DBC_GENERATED__SIGNALIDENTIFIER_H__20250906_145542_578__
|
||||
|
||||
namespace Doors4ExampleFMU
|
||||
{
|
||||
// Data Dispatch Service signal names to dbc variable names C-type RX/TX vss name space
|
||||
static std::string dsDoor01LeftIsOpen = "CAN_Input_L1.Door01LeftIsOpen";
|
||||
static std::string dsDoor01RightIsOpen = "CAN_Input_R1.Door01RightIsOpen";
|
||||
static std::string dsDoor02LeftIsOpen = "CAN_Input_L2.Door02LeftIsOpen";
|
||||
static std::string dsDoor02RightIsOpen = "CAN_Input_R2.Door02RightIsOpen";
|
||||
static std::string dsLockDoor02Right = "CAN_Output.LockDoor02Right";
|
||||
static std::string dsLockDoor02Left = "CAN_Output.LockDoor02Left";
|
||||
static std::string dsLockDoor01Right = "CAN_Output.LockDoor01Right";
|
||||
static std::string dsLockDoor01Left = "CAN_Output.LockDoor01Left";
|
||||
|
||||
} // Doors4ExampleFMU
|
||||
|
||||
#endif // __DBC_GENERATED__SIGNALIDENTIFIER_H__20250906_145542_578__
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "model.h"
|
||||
|
||||
#define EPSILON (FIXED_SOLVER_STEP * 1e-6)
|
||||
|
||||
void doFixedStep(ModelInstance *comp, bool* stateEvent, bool* timeEvent);
|
||||
@@ -0,0 +1,272 @@
|
||||
#ifndef fmi2FunctionTypes_h
|
||||
#define fmi2FunctionTypes_h
|
||||
|
||||
#include "fmi2TypesPlatform.h"
|
||||
|
||||
/* This header file must be utilized when compiling an FMU or an FMI master.
|
||||
It declares data and function types for FMI 2.0.1
|
||||
|
||||
Revisions:
|
||||
- Sep. 30, 2019: License changed to 2-clause BSD License (without extensions)
|
||||
- Jul. 5, 2019: Remove const modifier from fields of fmi2CallbackFunctions (#216)
|
||||
- Sep. 6, 2018: Parameter names added to function prototypes
|
||||
- Apr. 9, 2014: all prefixes "fmi" renamed to "fmi2" (decision from April 8)
|
||||
- Apr. 3, 2014: Added #include <stddef.h> for size_t definition
|
||||
- Mar. 27, 2014: Added #include "fmiTypesPlatform.h" (#179)
|
||||
- Mar. 26, 2014: Introduced function argument "void" for the functions (#171)
|
||||
fmiGetTypesPlatformTYPE and fmiGetVersionTYPE
|
||||
- Oct. 11, 2013: Functions of ModelExchange and CoSimulation merged:
|
||||
fmiInstantiateModelTYPE , fmiInstantiateSlaveTYPE -> fmiInstantiateTYPE
|
||||
fmiFreeModelInstanceTYPE, fmiFreeSlaveInstanceTYPE -> fmiFreeInstanceTYPE
|
||||
fmiEnterModelInitializationModeTYPE, fmiEnterSlaveInitializationModeTYPE -> fmiEnterInitializationModeTYPE
|
||||
fmiExitModelInitializationModeTYPE , fmiExitSlaveInitializationModeTYPE -> fmiExitInitializationModeTYPE
|
||||
fmiTerminateModelTYPE , fmiTerminateSlaveTYPE -> fmiTerminate
|
||||
fmiResetSlave -> fmiReset (now also for ModelExchange and not only for CoSimulation)
|
||||
Functions renamed
|
||||
fmiUpdateDiscreteStatesTYPE -> fmiNewDiscreteStatesTYPE
|
||||
Renamed elements of the enumeration fmiEventInfo
|
||||
upcomingTimeEvent -> nextEventTimeDefined // due to generic naming scheme: varDefined + var
|
||||
newUpdateDiscreteStatesNeeded -> newDiscreteStatesNeeded;
|
||||
- June 13, 2013: Changed type fmiEventInfo
|
||||
Functions removed:
|
||||
fmiInitializeModelTYPE
|
||||
fmiEventUpdateTYPE
|
||||
fmiCompletedEventIterationTYPE
|
||||
fmiInitializeSlaveTYPE
|
||||
Functions added:
|
||||
fmiEnterModelInitializationModeTYPE
|
||||
fmiExitModelInitializationModeTYPE
|
||||
fmiEnterEventModeTYPE
|
||||
fmiUpdateDiscreteStatesTYPE
|
||||
fmiEnterContinuousTimeModeTYPE
|
||||
fmiEnterSlaveInitializationModeTYPE;
|
||||
fmiExitSlaveInitializationModeTYPE;
|
||||
- Feb. 17, 2013: Added third argument to fmiCompletedIntegratorStepTYPE
|
||||
Changed function name "fmiTerminateType" to "fmiTerminateModelType" (due to #113)
|
||||
Changed function name "fmiGetNominalContinuousStateTYPE" to
|
||||
"fmiGetNominalsOfContinuousStatesTYPE"
|
||||
Removed fmiGetStateValueReferencesTYPE.
|
||||
- Nov. 14, 2011: First public Version
|
||||
|
||||
|
||||
Copyright (C) 2008-2011 MODELISAR consortium,
|
||||
2012-2019 Modelica Association Project "FMI"
|
||||
All rights reserved.
|
||||
|
||||
This file is licensed by the copyright holders under the 2-Clause BSD License
|
||||
(https://opensource.org/licenses/BSD-2-Clause):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* make sure all compiler use the same alignment policies for structures */
|
||||
#if defined _MSC_VER || defined __GNUC__
|
||||
#pragma pack(push,8)
|
||||
#endif
|
||||
|
||||
/* Include stddef.h, in order that size_t etc. is defined */
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* Type definitions */
|
||||
typedef enum {
|
||||
fmi2OK,
|
||||
fmi2Warning,
|
||||
fmi2Discard,
|
||||
fmi2Error,
|
||||
fmi2Fatal,
|
||||
fmi2Pending
|
||||
} fmi2Status;
|
||||
|
||||
typedef enum {
|
||||
fmi2ModelExchange,
|
||||
fmi2CoSimulation
|
||||
} fmi2Type;
|
||||
|
||||
typedef enum {
|
||||
fmi2DoStepStatus,
|
||||
fmi2PendingStatus,
|
||||
fmi2LastSuccessfulTime,
|
||||
fmi2Terminated
|
||||
} fmi2StatusKind;
|
||||
|
||||
typedef void (*fmi2CallbackLogger) (fmi2ComponentEnvironment componentEnvironment,
|
||||
fmi2String instanceName,
|
||||
fmi2Status status,
|
||||
fmi2String category,
|
||||
fmi2String message,
|
||||
...);
|
||||
typedef void* (*fmi2CallbackAllocateMemory)(size_t nobj, size_t size);
|
||||
typedef void (*fmi2CallbackFreeMemory) (void* obj);
|
||||
typedef void (*fmi2StepFinished) (fmi2ComponentEnvironment componentEnvironment,
|
||||
fmi2Status status);
|
||||
|
||||
typedef struct {
|
||||
fmi2CallbackLogger logger;
|
||||
fmi2CallbackAllocateMemory allocateMemory;
|
||||
fmi2CallbackFreeMemory freeMemory;
|
||||
fmi2StepFinished stepFinished;
|
||||
fmi2ComponentEnvironment componentEnvironment;
|
||||
} fmi2CallbackFunctions;
|
||||
|
||||
typedef struct {
|
||||
fmi2Boolean newDiscreteStatesNeeded;
|
||||
fmi2Boolean terminateSimulation;
|
||||
fmi2Boolean nominalsOfContinuousStatesChanged;
|
||||
fmi2Boolean valuesOfContinuousStatesChanged;
|
||||
fmi2Boolean nextEventTimeDefined;
|
||||
fmi2Real nextEventTime;
|
||||
} fmi2EventInfo;
|
||||
|
||||
|
||||
/* reset alignment policy to the one set before reading this file */
|
||||
#if defined _MSC_VER || defined __GNUC__
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
|
||||
/* Define fmi2 function pointer types to simplify dynamic loading */
|
||||
|
||||
/***************************************************
|
||||
Types for Common Functions
|
||||
****************************************************/
|
||||
|
||||
/* Inquire version numbers of header files and setting logging status */
|
||||
typedef const char* fmi2GetTypesPlatformTYPE(void);
|
||||
typedef const char* fmi2GetVersionTYPE(void);
|
||||
typedef fmi2Status fmi2SetDebugLoggingTYPE(fmi2Component c,
|
||||
fmi2Boolean loggingOn,
|
||||
size_t nCategories,
|
||||
const fmi2String categories[]);
|
||||
|
||||
/* Creation and destruction of FMU instances and setting debug status */
|
||||
typedef fmi2Component fmi2InstantiateTYPE(fmi2String instanceName,
|
||||
fmi2Type fmuType,
|
||||
fmi2String fmuGUID,
|
||||
fmi2String fmuResourceLocation,
|
||||
const fmi2CallbackFunctions* functions,
|
||||
fmi2Boolean visible,
|
||||
fmi2Boolean loggingOn);
|
||||
typedef void fmi2FreeInstanceTYPE(fmi2Component c);
|
||||
|
||||
/* Enter and exit initialization mode, terminate and reset */
|
||||
typedef fmi2Status fmi2SetupExperimentTYPE (fmi2Component c,
|
||||
fmi2Boolean toleranceDefined,
|
||||
fmi2Real tolerance,
|
||||
fmi2Real startTime,
|
||||
fmi2Boolean stopTimeDefined,
|
||||
fmi2Real stopTime);
|
||||
typedef fmi2Status fmi2EnterInitializationModeTYPE(fmi2Component c);
|
||||
typedef fmi2Status fmi2ExitInitializationModeTYPE (fmi2Component c);
|
||||
typedef fmi2Status fmi2TerminateTYPE (fmi2Component c);
|
||||
typedef fmi2Status fmi2ResetTYPE (fmi2Component c);
|
||||
|
||||
/* Getting and setting variable values */
|
||||
typedef fmi2Status fmi2GetRealTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Real value[]);
|
||||
typedef fmi2Status fmi2GetIntegerTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[]);
|
||||
typedef fmi2Status fmi2GetBooleanTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Boolean value[]);
|
||||
typedef fmi2Status fmi2GetStringTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2String value[]);
|
||||
|
||||
typedef fmi2Status fmi2SetRealTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Real value[]);
|
||||
typedef fmi2Status fmi2SetIntegerTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[]);
|
||||
typedef fmi2Status fmi2SetBooleanTYPE(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Boolean value[]);
|
||||
typedef fmi2Status fmi2SetStringTYPE (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2String value[]);
|
||||
|
||||
/* Getting and setting the internal FMU state */
|
||||
typedef fmi2Status fmi2GetFMUstateTYPE (fmi2Component c, fmi2FMUstate* FMUstate);
|
||||
typedef fmi2Status fmi2SetFMUstateTYPE (fmi2Component c, fmi2FMUstate FMUstate);
|
||||
typedef fmi2Status fmi2FreeFMUstateTYPE (fmi2Component c, fmi2FMUstate* FMUstate);
|
||||
typedef fmi2Status fmi2SerializedFMUstateSizeTYPE(fmi2Component c, fmi2FMUstate FMUstate, size_t* size);
|
||||
typedef fmi2Status fmi2SerializeFMUstateTYPE (fmi2Component c, fmi2FMUstate FMUstate, fmi2Byte[], size_t size);
|
||||
typedef fmi2Status fmi2DeSerializeFMUstateTYPE (fmi2Component c, const fmi2Byte serializedState[], size_t size, fmi2FMUstate* FMUstate);
|
||||
|
||||
/* Getting partial derivatives */
|
||||
typedef fmi2Status fmi2GetDirectionalDerivativeTYPE(fmi2Component c,
|
||||
const fmi2ValueReference vUnknown_ref[], size_t nUnknown,
|
||||
const fmi2ValueReference vKnown_ref[], size_t nKnown,
|
||||
const fmi2Real dvKnown[],
|
||||
fmi2Real dvUnknown[]);
|
||||
|
||||
/***************************************************
|
||||
Types for Functions for FMI2 for Model Exchange
|
||||
****************************************************/
|
||||
|
||||
/* Enter and exit the different modes */
|
||||
typedef fmi2Status fmi2EnterEventModeTYPE (fmi2Component c);
|
||||
typedef fmi2Status fmi2NewDiscreteStatesTYPE (fmi2Component c, fmi2EventInfo* fmi2eventInfo);
|
||||
typedef fmi2Status fmi2EnterContinuousTimeModeTYPE(fmi2Component c);
|
||||
typedef fmi2Status fmi2CompletedIntegratorStepTYPE(fmi2Component c,
|
||||
fmi2Boolean noSetFMUStatePriorToCurrentPoint,
|
||||
fmi2Boolean* enterEventMode,
|
||||
fmi2Boolean* terminateSimulation);
|
||||
|
||||
/* Providing independent variables and re-initialization of caching */
|
||||
typedef fmi2Status fmi2SetTimeTYPE (fmi2Component c, fmi2Real time);
|
||||
typedef fmi2Status fmi2SetContinuousStatesTYPE(fmi2Component c, const fmi2Real x[], size_t nx);
|
||||
|
||||
/* Evaluation of the model equations */
|
||||
typedef fmi2Status fmi2GetDerivativesTYPE (fmi2Component c, fmi2Real derivatives[], size_t nx);
|
||||
typedef fmi2Status fmi2GetEventIndicatorsTYPE (fmi2Component c, fmi2Real eventIndicators[], size_t ni);
|
||||
typedef fmi2Status fmi2GetContinuousStatesTYPE (fmi2Component c, fmi2Real x[], size_t nx);
|
||||
typedef fmi2Status fmi2GetNominalsOfContinuousStatesTYPE(fmi2Component c, fmi2Real x_nominal[], size_t nx);
|
||||
|
||||
|
||||
/***************************************************
|
||||
Types for Functions for FMI2 for Co-Simulation
|
||||
****************************************************/
|
||||
|
||||
/* Simulating the slave */
|
||||
typedef fmi2Status fmi2SetRealInputDerivativesTYPE (fmi2Component c,
|
||||
const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[],
|
||||
const fmi2Real value[]);
|
||||
typedef fmi2Status fmi2GetRealOutputDerivativesTYPE(fmi2Component c,
|
||||
const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[],
|
||||
fmi2Real value[]);
|
||||
typedef fmi2Status fmi2DoStepTYPE (fmi2Component c,
|
||||
fmi2Real currentCommunicationPoint,
|
||||
fmi2Real communicationStepSize,
|
||||
fmi2Boolean noSetFMUStatePriorToCurrentPoint);
|
||||
typedef fmi2Status fmi2CancelStepTYPE(fmi2Component c);
|
||||
|
||||
/* Inquire slave status */
|
||||
typedef fmi2Status fmi2GetStatusTYPE (fmi2Component c, const fmi2StatusKind s, fmi2Status* value);
|
||||
typedef fmi2Status fmi2GetRealStatusTYPE (fmi2Component c, const fmi2StatusKind s, fmi2Real* value);
|
||||
typedef fmi2Status fmi2GetIntegerStatusTYPE(fmi2Component c, const fmi2StatusKind s, fmi2Integer* value);
|
||||
typedef fmi2Status fmi2GetBooleanStatusTYPE(fmi2Component c, const fmi2StatusKind s, fmi2Boolean* value);
|
||||
typedef fmi2Status fmi2GetStringStatusTYPE (fmi2Component c, const fmi2StatusKind s, fmi2String* value);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* fmi2FunctionTypes_h */
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
#ifndef fmi2Functions_h
|
||||
#define fmi2Functions_h
|
||||
|
||||
/* This header file must be utilized when compiling a FMU.
|
||||
It defines all functions of the
|
||||
FMI 2.0.1 Model Exchange and Co-Simulation Interface.
|
||||
|
||||
In order to have unique function names even if several FMUs
|
||||
are compiled together (e.g. for embedded systems), every "real" function name
|
||||
is constructed by prepending the function name by "FMI2_FUNCTION_PREFIX".
|
||||
Therefore, the typical usage is:
|
||||
|
||||
#define FMI2_FUNCTION_PREFIX MyModel_
|
||||
#include "fmi2Functions.h"
|
||||
|
||||
As a result, a function that is defined as "fmi2GetDerivatives" in this header file,
|
||||
is actually getting the name "MyModel_fmi2GetDerivatives".
|
||||
|
||||
This only holds if the FMU is shipped in C source code, or is compiled in a
|
||||
static link library. For FMUs compiled in a DLL/sharedObject, the "actual" function
|
||||
names are used and "FMI2_FUNCTION_PREFIX" must not be defined.
|
||||
|
||||
Revisions:
|
||||
- Sep. 29, 2019: License changed to 2-clause BSD License (without extensions)
|
||||
- Apr. 9, 2014: All prefixes "fmi" renamed to "fmi2" (decision from April 8)
|
||||
- Mar. 26, 2014: FMI_Export set to empty value if FMI_Export and FMI_FUNCTION_PREFIX
|
||||
are not defined (#173)
|
||||
- Oct. 11, 2013: Functions of ModelExchange and CoSimulation merged:
|
||||
fmiInstantiateModel , fmiInstantiateSlave -> fmiInstantiate
|
||||
fmiFreeModelInstance, fmiFreeSlaveInstance -> fmiFreeInstance
|
||||
fmiEnterModelInitializationMode, fmiEnterSlaveInitializationMode -> fmiEnterInitializationMode
|
||||
fmiExitModelInitializationMode , fmiExitSlaveInitializationMode -> fmiExitInitializationMode
|
||||
fmiTerminateModel, fmiTerminateSlave -> fmiTerminate
|
||||
fmiResetSlave -> fmiReset (now also for ModelExchange and not only for CoSimulation)
|
||||
Functions renamed:
|
||||
fmiUpdateDiscreteStates -> fmiNewDiscreteStates
|
||||
- June 13, 2013: Functions removed:
|
||||
fmiInitializeModel
|
||||
fmiEventUpdate
|
||||
fmiCompletedEventIteration
|
||||
fmiInitializeSlave
|
||||
Functions added:
|
||||
fmiEnterModelInitializationMode
|
||||
fmiExitModelInitializationMode
|
||||
fmiEnterEventMode
|
||||
fmiUpdateDiscreteStates
|
||||
fmiEnterContinuousTimeMode
|
||||
fmiEnterSlaveInitializationMode;
|
||||
fmiExitSlaveInitializationMode;
|
||||
- Feb. 17, 2013: Portability improvements:
|
||||
o DllExport changed to FMI_Export
|
||||
o FUNCTION_PREFIX changed to FMI_FUNCTION_PREFIX
|
||||
o Allow undefined FMI_FUNCTION_PREFIX (meaning no prefix is used)
|
||||
Changed function name "fmiTerminate" to "fmiTerminateModel" (due to #113)
|
||||
Changed function name "fmiGetNominalContinuousState" to
|
||||
"fmiGetNominalsOfContinuousStates"
|
||||
Removed fmiGetStateValueReferences.
|
||||
- Nov. 14, 2011: Adapted to FMI 2.0:
|
||||
o Split into two files (fmiFunctions.h, fmiTypes.h) in order
|
||||
that code that dynamically loads an FMU can directly
|
||||
utilize the header files).
|
||||
o Added C++ encapsulation of C-part, in order that the header
|
||||
file can be directly utilized in C++ code.
|
||||
o fmiCallbackFunctions is passed as pointer to fmiInstantiateXXX
|
||||
o stepFinished within fmiCallbackFunctions has as first
|
||||
argument "fmiComponentEnvironment" and not "fmiComponent".
|
||||
o New functions to get and set the complete FMU state
|
||||
and to compute partial derivatives.
|
||||
- Nov. 4, 2010: Adapted to specification text:
|
||||
o fmiGetModelTypesPlatform renamed to fmiGetTypesPlatform
|
||||
o fmiInstantiateSlave: Argument GUID replaced by fmuGUID
|
||||
Argument mimetype replaced by mimeType
|
||||
o tabs replaced by spaces
|
||||
- Oct. 16, 2010: Functions for FMI for Co-simulation added
|
||||
- Jan. 20, 2010: stateValueReferencesChanged added to struct fmiEventInfo (ticket #27)
|
||||
(by M. Otter, DLR)
|
||||
Added WIN32 pragma to define the struct layout (ticket #34)
|
||||
(by J. Mauss, QTronic)
|
||||
- Jan. 4, 2010: Removed argument intermediateResults from fmiInitialize
|
||||
Renamed macro fmiGetModelFunctionsVersion to fmiGetVersion
|
||||
Renamed macro fmiModelFunctionsVersion to fmiVersion
|
||||
Replaced fmiModel by fmiComponent in decl of fmiInstantiateModel
|
||||
(by J. Mauss, QTronic)
|
||||
- Dec. 17, 2009: Changed extension "me" to "fmi" (by Martin Otter, DLR).
|
||||
- Dez. 14, 2009: Added eventInfo to meInitialize and added
|
||||
meGetNominalContinuousStates (by Martin Otter, DLR)
|
||||
- Sept. 9, 2009: Added DllExport (according to Peter Nilsson's suggestion)
|
||||
(by A. Junghanns, QTronic)
|
||||
- Sept. 9, 2009: Changes according to FMI-meeting on July 21:
|
||||
meInquireModelTypesVersion -> meGetModelTypesPlatform
|
||||
meInquireModelFunctionsVersion -> meGetModelFunctionsVersion
|
||||
meSetStates -> meSetContinuousStates
|
||||
meGetStates -> meGetContinuousStates
|
||||
removal of meInitializeModelClass
|
||||
removal of meGetTime
|
||||
change of arguments of meInstantiateModel
|
||||
change of arguments of meCompletedIntegratorStep
|
||||
(by Martin Otter, DLR):
|
||||
- July 19, 2009: Added "me" as prefix to file names (by Martin Otter, DLR).
|
||||
- March 2, 2009: Changed function definitions according to the last design
|
||||
meeting with additional improvements (by Martin Otter, DLR).
|
||||
- Dec. 3 , 2008: First version by Martin Otter (DLR) and Hans Olsson (Dynasim).
|
||||
|
||||
|
||||
Copyright (C) 2008-2011 MODELISAR consortium,
|
||||
2012-2019 Modelica Association Project "FMI"
|
||||
All rights reserved.
|
||||
|
||||
This file is licensed by the copyright holders under the 2-Clause BSD License
|
||||
(https://opensource.org/licenses/BSD-2-Clause):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "fmi2TypesPlatform.h"
|
||||
#include "fmi2FunctionTypes.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/*
|
||||
Export FMI2 API functions on Windows and under GCC.
|
||||
If custom linking is desired then the FMI2_Export must be
|
||||
defined before including this file. For instance,
|
||||
it may be set to __declspec(dllimport).
|
||||
*/
|
||||
#if !defined(FMI2_Export)
|
||||
#if !defined(FMI2_FUNCTION_PREFIX)
|
||||
#if defined _WIN32 || defined __CYGWIN__
|
||||
/* Note: both gcc & MSVC on Windows support this syntax. */
|
||||
#define FMI2_Export __declspec(dllexport)
|
||||
#else
|
||||
#if __GNUC__ >= 4
|
||||
#define FMI2_Export __attribute__ ((visibility ("default")))
|
||||
#else
|
||||
#define FMI2_Export
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define FMI2_Export
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Macros to construct the real function name
|
||||
(prepend function name by FMI2_FUNCTION_PREFIX) */
|
||||
#if defined(FMI2_FUNCTION_PREFIX)
|
||||
#define fmi2Paste(a,b) a ## b
|
||||
#define fmi2PasteB(a,b) fmi2Paste(a,b)
|
||||
#define fmi2FullName(name) fmi2PasteB(FMI2_FUNCTION_PREFIX, name)
|
||||
#else
|
||||
#define fmi2FullName(name) name
|
||||
#endif
|
||||
|
||||
/***************************************************
|
||||
Common Functions
|
||||
****************************************************/
|
||||
#define fmi2GetTypesPlatform fmi2FullName(fmi2GetTypesPlatform)
|
||||
#define fmi2GetVersion fmi2FullName(fmi2GetVersion)
|
||||
#define fmi2SetDebugLogging fmi2FullName(fmi2SetDebugLogging)
|
||||
#define fmi2Instantiate fmi2FullName(fmi2Instantiate)
|
||||
#define fmi2FreeInstance fmi2FullName(fmi2FreeInstance)
|
||||
#define fmi2SetupExperiment fmi2FullName(fmi2SetupExperiment)
|
||||
#define fmi2EnterInitializationMode fmi2FullName(fmi2EnterInitializationMode)
|
||||
#define fmi2ExitInitializationMode fmi2FullName(fmi2ExitInitializationMode)
|
||||
#define fmi2Terminate fmi2FullName(fmi2Terminate)
|
||||
#define fmi2Reset fmi2FullName(fmi2Reset)
|
||||
#define fmi2GetReal fmi2FullName(fmi2GetReal)
|
||||
#define fmi2GetInteger fmi2FullName(fmi2GetInteger)
|
||||
#define fmi2GetBoolean fmi2FullName(fmi2GetBoolean)
|
||||
#define fmi2GetString fmi2FullName(fmi2GetString)
|
||||
#define fmi2SetReal fmi2FullName(fmi2SetReal)
|
||||
#define fmi2SetInteger fmi2FullName(fmi2SetInteger)
|
||||
#define fmi2SetBoolean fmi2FullName(fmi2SetBoolean)
|
||||
#define fmi2SetString fmi2FullName(fmi2SetString)
|
||||
#define fmi2GetFMUstate fmi2FullName(fmi2GetFMUstate)
|
||||
#define fmi2SetFMUstate fmi2FullName(fmi2SetFMUstate)
|
||||
#define fmi2FreeFMUstate fmi2FullName(fmi2FreeFMUstate)
|
||||
#define fmi2SerializedFMUstateSize fmi2FullName(fmi2SerializedFMUstateSize)
|
||||
#define fmi2SerializeFMUstate fmi2FullName(fmi2SerializeFMUstate)
|
||||
#define fmi2DeSerializeFMUstate fmi2FullName(fmi2DeSerializeFMUstate)
|
||||
#define fmi2GetDirectionalDerivative fmi2FullName(fmi2GetDirectionalDerivative)
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Model Exchange
|
||||
****************************************************/
|
||||
#define fmi2EnterEventMode fmi2FullName(fmi2EnterEventMode)
|
||||
#define fmi2NewDiscreteStates fmi2FullName(fmi2NewDiscreteStates)
|
||||
#define fmi2EnterContinuousTimeMode fmi2FullName(fmi2EnterContinuousTimeMode)
|
||||
#define fmi2CompletedIntegratorStep fmi2FullName(fmi2CompletedIntegratorStep)
|
||||
#define fmi2SetTime fmi2FullName(fmi2SetTime)
|
||||
#define fmi2SetContinuousStates fmi2FullName(fmi2SetContinuousStates)
|
||||
#define fmi2GetDerivatives fmi2FullName(fmi2GetDerivatives)
|
||||
#define fmi2GetEventIndicators fmi2FullName(fmi2GetEventIndicators)
|
||||
#define fmi2GetContinuousStates fmi2FullName(fmi2GetContinuousStates)
|
||||
#define fmi2GetNominalsOfContinuousStates fmi2FullName(fmi2GetNominalsOfContinuousStates)
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Co-Simulation
|
||||
****************************************************/
|
||||
#define fmi2SetRealInputDerivatives fmi2FullName(fmi2SetRealInputDerivatives)
|
||||
#define fmi2GetRealOutputDerivatives fmi2FullName(fmi2GetRealOutputDerivatives)
|
||||
#define fmi2DoStep fmi2FullName(fmi2DoStep)
|
||||
#define fmi2CancelStep fmi2FullName(fmi2CancelStep)
|
||||
#define fmi2GetStatus fmi2FullName(fmi2GetStatus)
|
||||
#define fmi2GetRealStatus fmi2FullName(fmi2GetRealStatus)
|
||||
#define fmi2GetIntegerStatus fmi2FullName(fmi2GetIntegerStatus)
|
||||
#define fmi2GetBooleanStatus fmi2FullName(fmi2GetBooleanStatus)
|
||||
#define fmi2GetStringStatus fmi2FullName(fmi2GetStringStatus)
|
||||
|
||||
/* Version number */
|
||||
#define fmi2Version "2.0"
|
||||
|
||||
|
||||
/***************************************************
|
||||
Common Functions
|
||||
****************************************************/
|
||||
|
||||
/* Inquire version numbers of header files */
|
||||
FMI2_Export fmi2GetTypesPlatformTYPE fmi2GetTypesPlatform;
|
||||
FMI2_Export fmi2GetVersionTYPE fmi2GetVersion;
|
||||
FMI2_Export fmi2SetDebugLoggingTYPE fmi2SetDebugLogging;
|
||||
|
||||
/* Creation and destruction of FMU instances */
|
||||
FMI2_Export fmi2InstantiateTYPE fmi2Instantiate;
|
||||
FMI2_Export fmi2FreeInstanceTYPE fmi2FreeInstance;
|
||||
|
||||
/* Enter and exit initialization mode, terminate and reset */
|
||||
FMI2_Export fmi2SetupExperimentTYPE fmi2SetupExperiment;
|
||||
FMI2_Export fmi2EnterInitializationModeTYPE fmi2EnterInitializationMode;
|
||||
FMI2_Export fmi2ExitInitializationModeTYPE fmi2ExitInitializationMode;
|
||||
FMI2_Export fmi2TerminateTYPE fmi2Terminate;
|
||||
FMI2_Export fmi2ResetTYPE fmi2Reset;
|
||||
|
||||
/* Getting and setting variables values */
|
||||
FMI2_Export fmi2GetRealTYPE fmi2GetReal;
|
||||
FMI2_Export fmi2GetIntegerTYPE fmi2GetInteger;
|
||||
FMI2_Export fmi2GetBooleanTYPE fmi2GetBoolean;
|
||||
FMI2_Export fmi2GetStringTYPE fmi2GetString;
|
||||
|
||||
FMI2_Export fmi2SetRealTYPE fmi2SetReal;
|
||||
FMI2_Export fmi2SetIntegerTYPE fmi2SetInteger;
|
||||
FMI2_Export fmi2SetBooleanTYPE fmi2SetBoolean;
|
||||
FMI2_Export fmi2SetStringTYPE fmi2SetString;
|
||||
|
||||
/* Getting and setting the internal FMU state */
|
||||
FMI2_Export fmi2GetFMUstateTYPE fmi2GetFMUstate;
|
||||
FMI2_Export fmi2SetFMUstateTYPE fmi2SetFMUstate;
|
||||
FMI2_Export fmi2FreeFMUstateTYPE fmi2FreeFMUstate;
|
||||
FMI2_Export fmi2SerializedFMUstateSizeTYPE fmi2SerializedFMUstateSize;
|
||||
FMI2_Export fmi2SerializeFMUstateTYPE fmi2SerializeFMUstate;
|
||||
FMI2_Export fmi2DeSerializeFMUstateTYPE fmi2DeSerializeFMUstate;
|
||||
|
||||
/* Getting partial derivatives */
|
||||
FMI2_Export fmi2GetDirectionalDerivativeTYPE fmi2GetDirectionalDerivative;
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Model Exchange
|
||||
****************************************************/
|
||||
|
||||
/* Enter and exit the different modes */
|
||||
FMI2_Export fmi2EnterEventModeTYPE fmi2EnterEventMode;
|
||||
FMI2_Export fmi2NewDiscreteStatesTYPE fmi2NewDiscreteStates;
|
||||
FMI2_Export fmi2EnterContinuousTimeModeTYPE fmi2EnterContinuousTimeMode;
|
||||
FMI2_Export fmi2CompletedIntegratorStepTYPE fmi2CompletedIntegratorStep;
|
||||
|
||||
/* Providing independent variables and re-initialization of caching */
|
||||
FMI2_Export fmi2SetTimeTYPE fmi2SetTime;
|
||||
FMI2_Export fmi2SetContinuousStatesTYPE fmi2SetContinuousStates;
|
||||
|
||||
/* Evaluation of the model equations */
|
||||
FMI2_Export fmi2GetDerivativesTYPE fmi2GetDerivatives;
|
||||
FMI2_Export fmi2GetEventIndicatorsTYPE fmi2GetEventIndicators;
|
||||
FMI2_Export fmi2GetContinuousStatesTYPE fmi2GetContinuousStates;
|
||||
FMI2_Export fmi2GetNominalsOfContinuousStatesTYPE fmi2GetNominalsOfContinuousStates;
|
||||
|
||||
|
||||
/***************************************************
|
||||
Functions for FMI2 for Co-Simulation
|
||||
****************************************************/
|
||||
|
||||
/* Simulating the slave */
|
||||
FMI2_Export fmi2SetRealInputDerivativesTYPE fmi2SetRealInputDerivatives;
|
||||
FMI2_Export fmi2GetRealOutputDerivativesTYPE fmi2GetRealOutputDerivatives;
|
||||
|
||||
FMI2_Export fmi2DoStepTYPE fmi2DoStep;
|
||||
FMI2_Export fmi2CancelStepTYPE fmi2CancelStep;
|
||||
|
||||
/* Inquire slave status */
|
||||
FMI2_Export fmi2GetStatusTYPE fmi2GetStatus;
|
||||
FMI2_Export fmi2GetRealStatusTYPE fmi2GetRealStatus;
|
||||
FMI2_Export fmi2GetIntegerStatusTYPE fmi2GetIntegerStatus;
|
||||
FMI2_Export fmi2GetBooleanStatusTYPE fmi2GetBooleanStatus;
|
||||
FMI2_Export fmi2GetStringStatusTYPE fmi2GetStringStatus;
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* fmi2Functions_h */
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#ifndef fmi2TypesPlatform_h
|
||||
#define fmi2TypesPlatform_h
|
||||
|
||||
/* Standard header file to define the argument types of the
|
||||
functions of the Functional Mock-up Interface 2.0.1
|
||||
This header file must be utilized both by the model and
|
||||
by the simulation engine.
|
||||
|
||||
Revisions:
|
||||
- Sep. 29, 2019: License changed to 2-clause BSD License (without extensions)
|
||||
- Apr. 9, 2014: All prefixes "fmi" renamed to "fmi2" (decision from April 8)
|
||||
- Mar 31, 2014: New datatype fmiChar introduced.
|
||||
- Feb. 17, 2013: Changed fmiTypesPlatform from "standard32" to "default".
|
||||
Removed fmiUndefinedValueReference since no longer needed
|
||||
(because every state is defined in ScalarVariables).
|
||||
- March 20, 2012: Renamed from fmiPlatformTypes.h to fmiTypesPlatform.h
|
||||
- Nov. 14, 2011: Use the header file "fmiPlatformTypes.h" for FMI 2.0
|
||||
both for "FMI for model exchange" and for "FMI for co-simulation"
|
||||
New types "fmiComponentEnvironment", "fmiState", and "fmiByte".
|
||||
The implementation of "fmiBoolean" is change from "char" to "int".
|
||||
The #define "fmiPlatform" changed to "fmiTypesPlatform"
|
||||
(in order that #define and function call are consistent)
|
||||
- Oct. 4, 2010: Renamed header file from "fmiModelTypes.h" to fmiPlatformTypes.h"
|
||||
for the co-simulation interface
|
||||
- Jan. 4, 2010: Renamed meModelTypes_h to fmiModelTypes_h (by Mauss, QTronic)
|
||||
- Dec. 21, 2009: Changed "me" to "fmi" and "meModel" to "fmiComponent"
|
||||
according to meeting on Dec. 18 (by Martin Otter, DLR)
|
||||
- Dec. 6, 2009: Added meUndefinedValueReference (by Martin Otter, DLR)
|
||||
- Sept. 9, 2009: Changes according to FMI-meeting on July 21:
|
||||
Changed "version" to "platform", "standard" to "standard32",
|
||||
Added a precise definition of "standard32" as comment
|
||||
(by Martin Otter, DLR)
|
||||
- July 19, 2009: Added "me" as prefix to file names, added meTrue/meFalse,
|
||||
and changed meValueReferenced from int to unsigned int
|
||||
(by Martin Otter, DLR).
|
||||
- March 2, 2009: Moved enums and function pointer definitions to
|
||||
ModelFunctions.h (by Martin Otter, DLR).
|
||||
- Dec. 3, 2008 : First version by Martin Otter (DLR) and
|
||||
Hans Olsson (Dynasim).
|
||||
|
||||
|
||||
Copyright (C) 2008-2011 MODELISAR consortium,
|
||||
2012-2019 Modelica Association Project "FMI"
|
||||
All rights reserved.
|
||||
|
||||
This file is licensed by the copyright holders under the 2-Clause BSD License
|
||||
(https://opensource.org/licenses/BSD-2-Clause):
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Platform (unique identification of this header file) */
|
||||
#define fmi2TypesPlatform "default"
|
||||
|
||||
/* Type definitions of variables passed as arguments
|
||||
Version "default" means:
|
||||
|
||||
fmi2Component : an opaque object pointer
|
||||
fmi2ComponentEnvironment: an opaque object pointer
|
||||
fmi2FMUstate : an opaque object pointer
|
||||
fmi2ValueReference : handle to the value of a variable
|
||||
fmi2Real : double precision floating-point data type
|
||||
fmi2Integer : basic signed integer data type
|
||||
fmi2Boolean : basic signed integer data type
|
||||
fmi2Char : character data type
|
||||
fmi2String : a pointer to a vector of fmi2Char characters
|
||||
('\0' terminated, UTF8 encoded)
|
||||
fmi2Byte : smallest addressable unit of the machine, typically one byte.
|
||||
*/
|
||||
typedef void* fmi2Component; /* Pointer to FMU instance */
|
||||
typedef void* fmi2ComponentEnvironment; /* Pointer to FMU environment */
|
||||
typedef void* fmi2FMUstate; /* Pointer to internal FMU state */
|
||||
typedef unsigned int fmi2ValueReference;
|
||||
typedef double fmi2Real ;
|
||||
typedef int fmi2Integer;
|
||||
typedef int fmi2Boolean;
|
||||
typedef char fmi2Char;
|
||||
typedef const fmi2Char* fmi2String;
|
||||
typedef char fmi2Byte;
|
||||
|
||||
/* Values for fmi2Boolean */
|
||||
#define fmi2True 1
|
||||
#define fmi2False 0
|
||||
|
||||
|
||||
#endif /* fmi2TypesPlatform_h */
|
||||
|
||||
254
examples/door_demo_example/fmu_Doors4ExampleFMU/include/model.h
Normal file
254
examples/door_demo_example/fmu_Doors4ExampleFMU/include/model.h
Normal file
@@ -0,0 +1,254 @@
|
||||
#pragma once
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if FMI_VERSION != 1 && FMI_VERSION != 2 && FMI_VERSION != 3
|
||||
#error FMI_VERSION must be one of 1, 2 or 3
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdbool.h> // for bool
|
||||
#include <stdint.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if FMI_VERSION == 1
|
||||
|
||||
#define not_modelError (Instantiated| Initialized | Terminated)
|
||||
|
||||
typedef enum {
|
||||
Instantiated = 1 << 0,
|
||||
Initialized = 1 << 1,
|
||||
Terminated = 1 << 2,
|
||||
modelError = 1 << 3
|
||||
} ModelState;
|
||||
|
||||
#elif FMI_VERSION == 2
|
||||
|
||||
typedef enum {
|
||||
StartAndEnd = 1 << 0,
|
||||
Instantiated = 1 << 1,
|
||||
InitializationMode = 1 << 2,
|
||||
|
||||
// ME states
|
||||
EventMode = 1 << 3,
|
||||
ContinuousTimeMode = 1 << 4,
|
||||
|
||||
// CS states
|
||||
StepComplete = 1 << 5,
|
||||
StepInProgress = 1 << 6,
|
||||
StepFailed = 1 << 7,
|
||||
StepCanceled = 1 << 8,
|
||||
|
||||
Terminated = 1 << 9,
|
||||
modelError = 1 << 10,
|
||||
modelFatal = 1 << 11,
|
||||
} ModelState;
|
||||
|
||||
#else
|
||||
|
||||
typedef enum {
|
||||
StartAndEnd = 1 << 0,
|
||||
ConfigurationMode = 1 << 1,
|
||||
Instantiated = 1 << 2,
|
||||
InitializationMode = 1 << 3,
|
||||
EventMode = 1 << 4,
|
||||
ContinuousTimeMode = 1 << 5,
|
||||
StepMode = 1 << 6,
|
||||
ClockActivationMode = 1 << 7,
|
||||
StepDiscarded = 1 << 8,
|
||||
ReconfigurationMode = 1 << 9,
|
||||
IntermediateUpdateMode = 1 << 10,
|
||||
Terminated = 1 << 11,
|
||||
modelError = 1 << 12,
|
||||
modelFatal = 1 << 13,
|
||||
} ModelState;
|
||||
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ModelExchange,
|
||||
CoSimulation,
|
||||
ScheduledExecution,
|
||||
} InterfaceType;
|
||||
|
||||
typedef enum {
|
||||
OK,
|
||||
Warning,
|
||||
Discard,
|
||||
Error,
|
||||
Fatal,
|
||||
Pending
|
||||
} Status;
|
||||
|
||||
#if FMI_VERSION < 3
|
||||
typedef void (*loggerType) (void* componentEnvironment, const char* instanceName, int status, const char* category, const char* message, ...);
|
||||
#else
|
||||
typedef void (*loggerType) (void* componentEnvironment, int status, const char* category, const char* message);
|
||||
#endif
|
||||
|
||||
typedef void (*lockPreemptionType) (void);
|
||||
typedef void (*unlockPreemptionType) (void);
|
||||
|
||||
|
||||
typedef void (*intermediateUpdateType) (void* instanceEnvironment,
|
||||
double intermediateUpdateTime,
|
||||
bool intermediateVariableSetRequested,
|
||||
bool intermediateVariableGetAllowed,
|
||||
bool intermediateStepFinished,
|
||||
bool canReturnEarly,
|
||||
bool* earlyReturnRequested,
|
||||
double* earlyReturnTime);
|
||||
|
||||
typedef void(*clockUpdateType) (void* instanceEnvironment);
|
||||
|
||||
typedef struct {
|
||||
|
||||
double startTime;
|
||||
double stopTime;
|
||||
double time;
|
||||
const char* instanceName;
|
||||
InterfaceType type;
|
||||
const char* resourceLocation;
|
||||
|
||||
Status status;
|
||||
|
||||
// callback functions
|
||||
loggerType logger;
|
||||
intermediateUpdateType intermediateUpdate;
|
||||
clockUpdateType clockUpdate;
|
||||
|
||||
lockPreemptionType lockPreemtion;
|
||||
unlockPreemptionType unlockPreemtion;
|
||||
|
||||
bool logEvents;
|
||||
bool logErrors;
|
||||
|
||||
void* componentEnvironment;
|
||||
ModelState state;
|
||||
|
||||
// event info
|
||||
bool newDiscreteStatesNeeded;
|
||||
bool terminateSimulation;
|
||||
bool nominalsOfContinuousStatesChanged;
|
||||
bool valuesOfContinuousStatesChanged;
|
||||
bool nextEventTimeDefined;
|
||||
double nextEventTime;
|
||||
bool clocksTicked;
|
||||
|
||||
bool isDirtyValues;
|
||||
|
||||
ModelData modelData;
|
||||
|
||||
#if NZ > 0
|
||||
// event indicators
|
||||
double z[NZ];
|
||||
#endif
|
||||
|
||||
// internal solver steps
|
||||
uint64_t nSteps;
|
||||
|
||||
// Co-Simulation
|
||||
bool earlyReturnAllowed;
|
||||
bool eventModeUsed;
|
||||
|
||||
} ModelInstance;
|
||||
|
||||
ModelInstance* createModelInstance(
|
||||
loggerType logger,
|
||||
intermediateUpdateType intermediateUpdate,
|
||||
void* componentEnvironment,
|
||||
const char* instanceName,
|
||||
const char* instantiationToken,
|
||||
const char* resourceLocation,
|
||||
bool loggingOn,
|
||||
InterfaceType interfaceType);
|
||||
|
||||
void freeModelInstance(ModelInstance* comp);
|
||||
|
||||
void reset(ModelInstance* comp);
|
||||
|
||||
|
||||
bool setStartValues(ModelInstance* comp);
|
||||
|
||||
Status calculateValues(ModelInstance* comp);
|
||||
|
||||
Status getFloat32(ModelInstance* comp, ValueReference vr, float values[], size_t nValues, size_t* index);
|
||||
Status getFloat64(ModelInstance* comp, ValueReference vr, double values[], size_t nValues, size_t* index);
|
||||
Status getInt8(ModelInstance* comp, ValueReference vr, int8_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt8(ModelInstance* comp, ValueReference vr, uint8_t values[], size_t nValues, size_t* index);
|
||||
Status getInt16(ModelInstance* comp, ValueReference vr, int16_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt16(ModelInstance* comp, ValueReference vr, uint16_t values[], size_t nValues, size_t* index);
|
||||
Status getInt32(ModelInstance* comp, ValueReference vr, int32_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt32(ModelInstance* comp, ValueReference vr, uint32_t values[], size_t nValues, size_t* index);
|
||||
Status getInt64(ModelInstance* comp, ValueReference vr, int64_t values[], size_t nValues, size_t* index);
|
||||
Status getUInt64(ModelInstance* comp, ValueReference vr, uint64_t values[], size_t nValues, size_t* index);
|
||||
Status getBoolean(ModelInstance* comp, ValueReference vr, bool values[], size_t nValues, size_t* index);
|
||||
Status getString(ModelInstance* comp, ValueReference vr, const char* values[], size_t nValues, size_t* index);
|
||||
Status getBinary(ModelInstance* comp, ValueReference vr, size_t sizes[], const char* values[], size_t nValues, size_t* index);
|
||||
|
||||
Status setFloat32(ModelInstance* comp, ValueReference vr, const float values[], size_t nValues, size_t* index);
|
||||
Status setFloat64(ModelInstance* comp, ValueReference vr, const double values[], size_t nValues, size_t* index);
|
||||
Status setInt8(ModelInstance* comp, ValueReference vr, const int8_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt8(ModelInstance* comp, ValueReference vr, const uint8_t values[], size_t nValues, size_t* index);
|
||||
Status setInt16(ModelInstance* comp, ValueReference vr, const int16_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt16(ModelInstance* comp, ValueReference vr, const uint16_t values[], size_t nValues, size_t* index);
|
||||
Status setInt32(ModelInstance* comp, ValueReference vr, const int32_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt32(ModelInstance* comp, ValueReference vr, const uint32_t values[], size_t nValues, size_t* index);
|
||||
Status setInt64(ModelInstance* comp, ValueReference vr, const int64_t values[], size_t nValues, size_t* index);
|
||||
Status setUInt64(ModelInstance* comp, ValueReference vr, const uint64_t values[], size_t nValues, size_t* index);
|
||||
Status setBoolean(ModelInstance* comp, ValueReference vr, const bool values[], size_t nValues, size_t* index);
|
||||
Status setString(ModelInstance* comp, ValueReference vr, const char* const values[], size_t nValues, size_t* index);
|
||||
Status setBinary(ModelInstance* comp, ValueReference vr, const size_t sizes[], const char* const values[], size_t nValues, size_t* index);
|
||||
|
||||
Status activateClock(ModelInstance* comp, ValueReference vr);
|
||||
Status getClock(ModelInstance* comp, ValueReference vr, bool* value);
|
||||
Status setClock(ModelInstance* comp, ValueReference vr, const bool* value);
|
||||
|
||||
Status getInterval(ModelInstance* comp, ValueReference vr, double* interval, int* qualifier);
|
||||
|
||||
Status activateModelPartition(ModelInstance* comp, ValueReference vr, double activationTime);
|
||||
|
||||
void getContinuousStates(ModelInstance* comp, double x[], size_t nx);
|
||||
void setContinuousStates(ModelInstance* comp, const double x[], size_t nx);
|
||||
void getDerivatives(ModelInstance* comp, double dx[], size_t nx);
|
||||
Status getOutputDerivative(ModelInstance* comp, ValueReference valueReference, int order, double* value);
|
||||
Status getPartialDerivative(ModelInstance* comp, ValueReference unknown, ValueReference known, double* partialDerivative);
|
||||
void getEventIndicators(ModelInstance* comp, double z[], size_t nz);
|
||||
void eventUpdate(ModelInstance* comp);
|
||||
//void updateEventTime(ModelInstance *comp);
|
||||
|
||||
bool invalidNumber(ModelInstance* comp, const char* f, const char* arg, size_t actual, size_t expected);
|
||||
bool invalidState(ModelInstance* comp, const char* f, int statesExpected);
|
||||
bool nullPointer(ModelInstance* comp, const char* f, const char* arg, const void* p);
|
||||
void logError(ModelInstance* comp, const char* message, ...);
|
||||
Status setDebugLogging(ModelInstance* comp, bool loggingOn, size_t nCategories, const char* const categories[]);
|
||||
void logEvent(ModelInstance* comp, const char* message, ...);
|
||||
void logError(ModelInstance* comp, const char* message, ...);
|
||||
|
||||
void* getFMUState(ModelInstance* comp);
|
||||
void setFMUState(ModelInstance* comp, void* FMUState);
|
||||
|
||||
// shorthand to access the variables
|
||||
#define M(v) (comp->modelData.v)
|
||||
|
||||
// "stringification" macros
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
// assert size of nValues for scalar variables
|
||||
#define ASSERT_NVALUES(N) do { \
|
||||
if (*index + (N) > nValues) { \
|
||||
logError(comp, "Expected nValues > %zu but was %zu.", *index, nValues); \
|
||||
return Error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // end of extern "C"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,598 @@
|
||||
#include <stdlib.h> // for calloc(), free()
|
||||
#include <float.h> // for DBL_EPSILON
|
||||
#include <math.h> // for fabs()
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include "config.h"
|
||||
#include "cosimulation.h"
|
||||
|
||||
#if FMI_VERSION == 3
|
||||
#include "fmi3Functions.h"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
|
||||
ModelInstance *createModelInstance(
|
||||
loggerType cbLogger,
|
||||
intermediateUpdateType intermediateUpdate,
|
||||
void *componentEnvironment,
|
||||
const char *instanceName,
|
||||
const char *instantiationToken,
|
||||
const char *resourceLocation,
|
||||
bool loggingOn,
|
||||
InterfaceType interfaceType) {
|
||||
|
||||
ModelInstance *comp = NULL;
|
||||
|
||||
if (!instanceName || strlen(instanceName) == 0) {
|
||||
if (cbLogger) {
|
||||
#if FMI_VERSION < 3
|
||||
cbLogger(componentEnvironment, "?", Error, "error", "Missing instance name.");
|
||||
#else
|
||||
cbLogger(componentEnvironment, Error, "error", "Missing instance name.");
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!instantiationToken || strlen(instantiationToken) == 0) {
|
||||
if (cbLogger) {
|
||||
#if FMI_VERSION < 3
|
||||
cbLogger(componentEnvironment, instanceName, Error, "error", "Missing GUID.");
|
||||
#else
|
||||
cbLogger(componentEnvironment, Error, "error", "Missing instantiationToken.");
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(instantiationToken, INSTANTIATION_TOKEN)) {
|
||||
if (cbLogger) {
|
||||
#if FMI_VERSION < 3
|
||||
cbLogger(componentEnvironment, instanceName, Error, "error", "Wrong GUID.");
|
||||
#else
|
||||
cbLogger(componentEnvironment, Error, "error", "Wrong instantiationToken.");
|
||||
#endif
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
comp = (ModelInstance *)calloc(1, sizeof(ModelInstance));
|
||||
|
||||
if (comp) {
|
||||
comp->componentEnvironment = componentEnvironment;
|
||||
comp->logger = cbLogger;
|
||||
comp->intermediateUpdate = intermediateUpdate;
|
||||
comp->lockPreemtion = NULL;
|
||||
comp->unlockPreemtion = NULL;
|
||||
comp->instanceName = strdup(instanceName);
|
||||
comp->resourceLocation = resourceLocation ? strdup(resourceLocation) : NULL;
|
||||
comp->status = OK;
|
||||
comp->logEvents = loggingOn;
|
||||
comp->logErrors = true; // always log errors
|
||||
comp->nSteps = 0;
|
||||
comp->earlyReturnAllowed = false;
|
||||
comp->eventModeUsed = false;
|
||||
}
|
||||
|
||||
if (!comp || !comp->instanceName) {
|
||||
logError(comp, "Out of memory.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
comp->time = 0.0; // overwrite in fmi*SetupExperiment, fmi*SetTime
|
||||
comp->type = interfaceType;
|
||||
|
||||
comp->state = Instantiated;
|
||||
|
||||
comp->newDiscreteStatesNeeded = false;
|
||||
comp->terminateSimulation = false;
|
||||
comp->nominalsOfContinuousStatesChanged = false;
|
||||
comp->valuesOfContinuousStatesChanged = false;
|
||||
comp->nextEventTimeDefined = false;
|
||||
comp->nextEventTime = 0;
|
||||
|
||||
if (!setStartValues(comp))
|
||||
{
|
||||
cbLogger(componentEnvironment, instanceName, Error, "error", "VAPI initialization failed.");
|
||||
}
|
||||
|
||||
comp->isDirtyValues = true;
|
||||
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
void freeModelInstance(ModelInstance *comp) {
|
||||
free((void *)comp->instanceName);
|
||||
free(comp);
|
||||
}
|
||||
|
||||
void reset(ModelInstance* comp) {
|
||||
comp->state = Instantiated;
|
||||
comp->startTime = 0.0;
|
||||
comp->time = 0.0;
|
||||
comp->nSteps = 0;
|
||||
comp->status = OK;
|
||||
setStartValues(comp);
|
||||
comp->isDirtyValues = true;
|
||||
}
|
||||
|
||||
bool invalidNumber(ModelInstance *comp, const char *f, const char *arg, size_t actual, size_t expected) {
|
||||
|
||||
if (actual != expected) {
|
||||
comp->state = modelError;
|
||||
logError(comp, "%s: Invalid argument %s = %d. Expected %d.", f, arg, actual, expected);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool invalidState(ModelInstance *comp, const char *f, int statesExpected) {
|
||||
|
||||
UNUSED(f);
|
||||
UNUSED(statesExpected);
|
||||
|
||||
if (!comp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: add missing states and check state
|
||||
return false;
|
||||
|
||||
// if (!(comp->state & statesExpected)) {
|
||||
// comp->state = modelError;
|
||||
// logError(comp, "%s: Illegal call sequence.", f);
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
}
|
||||
|
||||
bool nullPointer(ModelInstance* comp, const char *f, const char *arg, const void *p) {
|
||||
|
||||
if (!p) {
|
||||
comp->state = modelError;
|
||||
logError(comp, "%s: Invalid argument %s = NULL.", f, arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Status setDebugLogging(ModelInstance *comp, bool loggingOn, size_t nCategories, const char * const categories[]) {
|
||||
|
||||
if (nCategories > 0) {
|
||||
|
||||
if (categories == NULL) {
|
||||
logError(comp, "Argument categories must not be NULL.");
|
||||
return Error;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nCategories; i++) {
|
||||
|
||||
if (categories[i] == NULL) {
|
||||
logError(comp, "Argument categories[%zu] must not be NULL.", i);
|
||||
return Error;
|
||||
} else if (strcmp(categories[i], "logEvents") == 0) {
|
||||
comp->logEvents = loggingOn;
|
||||
} else if (strcmp(categories[i], "logStatusError") == 0) {
|
||||
comp->logErrors = loggingOn;
|
||||
} else {
|
||||
logError(comp, "Log categories[%zu] must be one of \"logEvents\" or \"logStatusError\" but was \"%s\".", i, categories[i]);
|
||||
return Error;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
comp->logEvents = loggingOn;
|
||||
comp->logErrors = loggingOn;
|
||||
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void logMessage(ModelInstance *comp, int status, const char *category, const char *message, va_list args) {
|
||||
|
||||
if (!comp->logger) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_list args1;
|
||||
int len = 0;
|
||||
char *buf = "";
|
||||
|
||||
va_copy(args1, args);
|
||||
len = vsnprintf(buf, len, message, args1);
|
||||
va_end(args1);
|
||||
|
||||
if (len < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_copy(args1, args);
|
||||
buf = (char *)calloc(len + 1, sizeof(char));
|
||||
len = vsnprintf(buf, len + 1, message, args);
|
||||
va_end(args1);
|
||||
|
||||
if (len >= 0) {
|
||||
// no need to distinguish between FMI versions since we're not using variadic arguments
|
||||
#if FMI_VERSION < 3
|
||||
comp->logger(comp->componentEnvironment, comp->instanceName, status, category, buf);
|
||||
#else
|
||||
comp->logger(comp->componentEnvironment, status, category, buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void logEvent(ModelInstance *comp, const char *message, ...) {
|
||||
|
||||
if (!comp || !comp->logEvents) return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
logMessage(comp, OK, "logEvents", message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void logError(ModelInstance *comp, const char *message, ...) {
|
||||
|
||||
if (!comp || !comp->logErrors) return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
logMessage(comp, Error, "logStatusError", message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// default implementations
|
||||
#if NZ < 1
|
||||
void getEventIndicators(ModelInstance *comp, double z[], size_t nz) {
|
||||
UNUSED(comp);
|
||||
UNUSED(z);
|
||||
UNUSED(nz);
|
||||
// do nothing
|
||||
}
|
||||
#endif
|
||||
|
||||
#define GET_NOT_ALLOWED(t) do { \
|
||||
UNUSED(vr); \
|
||||
UNUSED(values); \
|
||||
UNUSED(nValues); \
|
||||
UNUSED(index); \
|
||||
logError(comp, "Getting " t " is not allowed.");\
|
||||
return Error; \
|
||||
} while (false)
|
||||
|
||||
#ifndef GET_FLOAT32
|
||||
Status getFloat32(ModelInstance* comp, ValueReference vr, float values[], size_t nValues, size_t* index) {
|
||||
GET_NOT_ALLOWED("Float32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT8
|
||||
Status getInt8(ModelInstance* comp, ValueReference vr, int8_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT8
|
||||
Status getUInt8(ModelInstance* comp, ValueReference vr, uint8_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT16
|
||||
Status getInt16(ModelInstance* comp, ValueReference vr, int16_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int16");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT16
|
||||
Status getUInt16(ModelInstance* comp, ValueReference vr, uint16_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt16");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT32
|
||||
Status getInt32(ModelInstance* comp, ValueReference vr, int32_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT32
|
||||
Status getUInt32(ModelInstance* comp, ValueReference vr, uint32_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INT64
|
||||
Status getInt64(ModelInstance* comp, ValueReference vr, int64_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Int64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_UINT64
|
||||
Status getUInt64(ModelInstance* comp, ValueReference vr, uint64_t values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("UInt64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_BOOLEAN
|
||||
Status getBoolean(ModelInstance* comp, ValueReference vr, bool values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("Boolean");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_STRING
|
||||
Status getString(ModelInstance* comp, ValueReference vr, const char* values[], size_t nValues, size_t *index) {
|
||||
GET_NOT_ALLOWED("String");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_BINARY
|
||||
Status getBinary(ModelInstance* comp, ValueReference vr, size_t sizes[], const char* values[], size_t nValues, size_t *index) {
|
||||
UNUSED(sizes);
|
||||
GET_NOT_ALLOWED("Binary");
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SET_NOT_ALLOWED(t) do { \
|
||||
UNUSED(vr); \
|
||||
UNUSED(values); \
|
||||
UNUSED(nValues); \
|
||||
UNUSED(index); \
|
||||
logError(comp, "Setting " t " is not allowed.");\
|
||||
return Error; \
|
||||
} while (false)
|
||||
|
||||
#ifndef SET_FLOAT32
|
||||
Status setFloat32(ModelInstance* comp, ValueReference vr, const float values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Float32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_FLOAT64
|
||||
Status setFloat64(ModelInstance* comp, ValueReference vr, const double values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Float64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT8
|
||||
Status setInt8(ModelInstance* comp, ValueReference vr, const int8_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT8
|
||||
Status setUInt8(ModelInstance* comp, ValueReference vr, const uint8_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt8");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT16
|
||||
Status setInt16(ModelInstance* comp, ValueReference vr, const int16_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int16");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT16
|
||||
Status setUInt16(ModelInstance* comp, ValueReference vr, const uint16_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt16");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT32
|
||||
Status setInt32(ModelInstance* comp, ValueReference vr, const int32_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT32
|
||||
Status setUInt32(ModelInstance* comp, ValueReference vr, const uint32_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt32");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_INT64
|
||||
Status setInt64(ModelInstance* comp, ValueReference vr, const int64_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Int64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_UINT64
|
||||
Status setUInt64(ModelInstance* comp, ValueReference vr, const uint64_t values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("UInt64");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_BOOLEAN
|
||||
Status setBoolean(ModelInstance* comp, ValueReference vr, const bool values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("Boolean");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_STRING
|
||||
Status setString(ModelInstance* comp, ValueReference vr, const char *const values[], size_t nValues, size_t* index) {
|
||||
SET_NOT_ALLOWED("String");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SET_BINARY
|
||||
Status setBinary(ModelInstance* comp, ValueReference vr, const size_t size[], const char *const values[], size_t nValues, size_t* index) {
|
||||
UNUSED(size);
|
||||
SET_NOT_ALLOWED("Binary");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ACTIVATE_CLOCK
|
||||
Status activateClock(ModelInstance* comp, ValueReference vr) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_CLOCK
|
||||
Status getClock(ModelInstance* comp, ValueReference vr, bool* value) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
UNUSED(value);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_INTERVAL
|
||||
Status getInterval(ModelInstance* comp, ValueReference vr, double* interval, int* qualifier) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
UNUSED(interval);
|
||||
UNUSED(qualifier);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef ACTIVATE_MODEL_PARTITION
|
||||
Status activateModelPartition(ModelInstance* comp, ValueReference vr, double activationTime) {
|
||||
UNUSED(comp);
|
||||
UNUSED(vr);
|
||||
UNUSED(activationTime);
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NX < 1
|
||||
void getContinuousStates(ModelInstance *comp, double x[], size_t nx) {
|
||||
UNUSED(comp);
|
||||
UNUSED(x);
|
||||
UNUSED(nx);
|
||||
}
|
||||
|
||||
void setContinuousStates(ModelInstance *comp, const double x[], size_t nx) {
|
||||
UNUSED(comp);
|
||||
UNUSED(x);
|
||||
UNUSED(nx);
|
||||
}
|
||||
|
||||
void getDerivatives(ModelInstance *comp, double dx[], size_t nx) {
|
||||
UNUSED(comp);
|
||||
UNUSED(dx);
|
||||
UNUSED(nx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef GET_PARTIAL_DERIVATIVE
|
||||
Status getPartialDerivative(ModelInstance *comp, ValueReference unknown, ValueReference known, double *partialDerivative) {
|
||||
UNUSED(comp);
|
||||
UNUSED(unknown);
|
||||
UNUSED(known);
|
||||
UNUSED(partialDerivative);
|
||||
logError(comp, "Directional derivatives are not supported.");
|
||||
return Error;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* getFMUState(ModelInstance* comp) {
|
||||
|
||||
ModelInstance* fmuState = (ModelInstance*)calloc(1, sizeof(ModelInstance));
|
||||
|
||||
if (fmuState) {
|
||||
memcpy(fmuState, comp, sizeof(ModelInstance));
|
||||
}
|
||||
|
||||
return fmuState;
|
||||
}
|
||||
|
||||
void setFMUState(ModelInstance* comp, void* FMUState) {
|
||||
|
||||
ModelInstance* s = (ModelInstance*)FMUState;
|
||||
|
||||
comp->startTime = s->startTime;
|
||||
comp->stopTime = s->stopTime;
|
||||
comp->time = s->time;
|
||||
comp->status = s->status;
|
||||
comp->state = s->state;
|
||||
comp->newDiscreteStatesNeeded = s->newDiscreteStatesNeeded;
|
||||
comp->terminateSimulation = s->terminateSimulation;
|
||||
comp->nominalsOfContinuousStatesChanged = s->nominalsOfContinuousStatesChanged;
|
||||
comp->valuesOfContinuousStatesChanged = s->valuesOfContinuousStatesChanged;
|
||||
comp->nextEventTimeDefined = s->nextEventTimeDefined;
|
||||
comp->nextEventTime = s->nextEventTime;
|
||||
comp->clocksTicked = s->clocksTicked;
|
||||
comp->isDirtyValues = s->isDirtyValues;
|
||||
comp->modelData = s->modelData;
|
||||
#if NZ > 0
|
||||
memcpy(comp->z, s->z, NZ * sizeof(double));
|
||||
#endif
|
||||
comp->nSteps = s->nSteps;
|
||||
}
|
||||
|
||||
void doFixedStep(ModelInstance *comp, bool* stateEvent, bool* timeEvent) {
|
||||
|
||||
#if NX > 0
|
||||
double x[NX] = { 0 };
|
||||
double dx[NX] = { 0 };
|
||||
|
||||
getContinuousStates(comp, x, NX);
|
||||
getDerivatives(comp, dx, NX);
|
||||
|
||||
// forward Euler step
|
||||
for (int i = 0; i < NX; i++) {
|
||||
x[i] += FIXED_SOLVER_STEP * dx[i];
|
||||
}
|
||||
|
||||
setContinuousStates(comp, x, NX);
|
||||
#endif
|
||||
|
||||
comp->nSteps++;
|
||||
|
||||
comp->time = comp->startTime + comp->nSteps * FIXED_SOLVER_STEP;
|
||||
|
||||
// state event
|
||||
*stateEvent = false;
|
||||
|
||||
#if NZ > 0
|
||||
double z[NZ] = { 0.0 };
|
||||
|
||||
getEventIndicators(comp, z, NZ);
|
||||
|
||||
// check for zero-crossings
|
||||
for (int i = 0; i < NZ; i++) {
|
||||
*stateEvent |= (comp->z[i] <= 0 && z[i] > 0) || (comp->z[i] > 0 && z[i] <= 0);
|
||||
}
|
||||
|
||||
// remember the current event indicators
|
||||
memcpy(comp->z, z, sizeof(double) * NZ);
|
||||
#endif
|
||||
|
||||
// time event
|
||||
*timeEvent = comp->nextEventTimeDefined && comp->time >= comp->nextEventTime;
|
||||
|
||||
bool earlyReturnRequested;
|
||||
double earlyReturnTime;
|
||||
|
||||
// intermediate update
|
||||
if (comp->intermediateUpdate) {
|
||||
comp->intermediateUpdate(
|
||||
comp->componentEnvironment, // instanceEnvironment
|
||||
comp->time, // intermediateUpdateTime
|
||||
false, // intermediateVariableSetRequested
|
||||
true, // intermediateVariableGetAllowed
|
||||
true, // intermediateStepFinished
|
||||
false, // canReturnEarly
|
||||
&earlyReturnRequested, // earlyReturnRequested
|
||||
&earlyReturnTime); // earlyReturnTime
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,887 @@
|
||||
#if FMI_VERSION != 2
|
||||
#error FMI_VERSION must be 2
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "model.h"
|
||||
#include "cosimulation.h"
|
||||
|
||||
|
||||
// C-code FMUs have functions names prefixed with MODEL_IDENTIFIER_.
|
||||
// Define DISABLE_PREFIX to build a binary FMU.
|
||||
#ifndef DISABLE_PREFIX
|
||||
#define pasteA(a,b) a ## b
|
||||
#define pasteB(a,b) pasteA(a,b)
|
||||
#define FMI2_FUNCTION_PREFIX pasteB(MODEL_IDENTIFIER, _)
|
||||
#endif
|
||||
#include "fmi2Functions.h"
|
||||
|
||||
#define ASSERT_NOT_NULL(p) \
|
||||
do { \
|
||||
if (!p) { \
|
||||
logError(S, "Argument %s must not be NULL.", xstr(p)); \
|
||||
S->state = modelError; \
|
||||
return (fmi2Status)Error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define GET_VARIABLES(T) \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
if (nvr == 0) return (fmi2Status)status; \
|
||||
ASSERT_NOT_NULL(vr); \
|
||||
ASSERT_NOT_NULL(value); \
|
||||
size_t index = 0; \
|
||||
if (S->isDirtyValues) { \
|
||||
Status s = calculateValues(S); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
S->isDirtyValues = false; \
|
||||
} \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
Status s = get ## T(S, vr[i], value, nvr, &index); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#define SET_VARIABLES(T) \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
if (nvr == 0) return (fmi2Status)status; \
|
||||
ASSERT_NOT_NULL(vr); \
|
||||
ASSERT_NOT_NULL(value); \
|
||||
size_t index = 0; \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
Status s = set ## T(S, vr[i], value, nvr, &index); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
if (nvr > 0) S->isDirtyValues = true; \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#define GET_BOOLEAN_VARIABLES \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
bool v = false; \
|
||||
size_t index = 0; \
|
||||
Status s = getBoolean(S, vr[i], &v, nvr, &index); \
|
||||
value[i] = v; \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#define SET_BOOLEAN_VARIABLES \
|
||||
do { \
|
||||
Status status = OK; \
|
||||
for (size_t i = 0; i < nvr; i++) { \
|
||||
bool v = value[i]; \
|
||||
size_t index = 0; \
|
||||
Status s = setBoolean(S, vr[i], &v, nvr, &index); \
|
||||
status = max(status, s); \
|
||||
if (status > Warning) return (fmi2Status)status; \
|
||||
} \
|
||||
return (fmi2Status)status; \
|
||||
} while (0)
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a)>(b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef DT_EVENT_DETECT
|
||||
#define DT_EVENT_DETECT 1e-10
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Function calls allowed state masks for both Model-exchange and Co-simulation
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MASK_fmi2GetTypesPlatform (StartAndEnd | Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepInProgress | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetVersion MASK_fmi2GetTypesPlatform
|
||||
#define MASK_fmi2SetDebugLogging (Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepInProgress | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2Instantiate (StartAndEnd)
|
||||
#define MASK_fmi2FreeInstance (Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2SetupExperiment Instantiated
|
||||
#define MASK_fmi2EnterInitializationMode Instantiated
|
||||
#define MASK_fmi2ExitInitializationMode InitializationMode
|
||||
#define MASK_fmi2Terminate (EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed)
|
||||
#define MASK_fmi2Reset MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2GetReal (InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetInteger MASK_fmi2GetReal
|
||||
#define MASK_fmi2GetBoolean MASK_fmi2GetReal
|
||||
#define MASK_fmi2GetString MASK_fmi2GetReal
|
||||
#define MASK_fmi2SetReal (Instantiated | InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete)
|
||||
#define MASK_fmi2SetInteger (Instantiated | InitializationMode \
|
||||
| EventMode \
|
||||
| StepComplete)
|
||||
#define MASK_fmi2SetBoolean MASK_fmi2SetInteger
|
||||
#define MASK_fmi2SetString MASK_fmi2SetInteger
|
||||
#define MASK_fmi2GetFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2SetFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2FreeFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2SerializedFMUstateSize MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2SerializeFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2DeSerializeFMUstate MASK_fmi2FreeInstance
|
||||
#define MASK_fmi2GetDirectionalDerivative (InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | modelError)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Function calls allowed state masks for Model-exchange
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MASK_fmi2EnterEventMode (EventMode | ContinuousTimeMode)
|
||||
#define MASK_fmi2NewDiscreteStates EventMode
|
||||
#define MASK_fmi2EnterContinuousTimeMode EventMode
|
||||
#define MASK_fmi2CompletedIntegratorStep ContinuousTimeMode
|
||||
#define MASK_fmi2SetTime (EventMode | ContinuousTimeMode)
|
||||
#define MASK_fmi2SetContinuousStates ContinuousTimeMode
|
||||
#define MASK_fmi2GetEventIndicators (InitializationMode \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetContinuousStates MASK_fmi2GetEventIndicators
|
||||
#define MASK_fmi2GetDerivatives (EventMode | ContinuousTimeMode \
|
||||
| Terminated | modelError)
|
||||
#define MASK_fmi2GetNominalsOfContinuousStates ( Instantiated \
|
||||
| EventMode | ContinuousTimeMode \
|
||||
| Terminated | modelError)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Function calls allowed state masks for Co-simulation
|
||||
// ---------------------------------------------------------------------------
|
||||
#define MASK_fmi2SetRealInputDerivatives (Instantiated | InitializationMode \
|
||||
| StepComplete)
|
||||
#define MASK_fmi2GetRealOutputDerivatives (StepComplete | StepFailed | StepCanceled \
|
||||
| Terminated | Error)
|
||||
#define MASK_fmi2DoStep StepComplete
|
||||
#define MASK_fmi2CancelStep StepInProgress
|
||||
#define MASK_fmi2GetStatus (StepComplete | StepInProgress | StepFailed \
|
||||
| Terminated)
|
||||
#define MASK_fmi2GetRealStatus MASK_fmi2GetStatus
|
||||
#define MASK_fmi2GetIntegerStatus MASK_fmi2GetStatus
|
||||
#define MASK_fmi2GetBooleanStatus MASK_fmi2GetStatus
|
||||
#define MASK_fmi2GetStringStatus MASK_fmi2GetStatus
|
||||
|
||||
// shorthand to access the instance
|
||||
#define S ((ModelInstance *)c)
|
||||
|
||||
#define ASSERT_STATE(S) \
|
||||
if (!allowedState(c, MASK_fmi2##S, #S)) \
|
||||
return fmi2Error;
|
||||
|
||||
static bool allowedState(ModelInstance *instance, int statesExpected, char *name) {
|
||||
|
||||
if (!instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(instance->state & statesExpected)) {
|
||||
logError(instance, "fmi2%s: Illegal call sequence.", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FMI functions
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2String fmuGUID,
|
||||
fmi2String fmuResourceLocation, const fmi2CallbackFunctions *functions,
|
||||
fmi2Boolean visible, fmi2Boolean loggingOn) {
|
||||
|
||||
UNUSED(visible);
|
||||
|
||||
if (!functions || !functions->logger) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return createModelInstance(
|
||||
(loggerType)functions->logger,
|
||||
NULL,
|
||||
functions->componentEnvironment,
|
||||
instanceName,
|
||||
fmuGUID,
|
||||
fmuResourceLocation,
|
||||
loggingOn,
|
||||
(InterfaceType)fmuType);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetupExperiment(fmi2Component c, fmi2Boolean toleranceDefined, fmi2Real tolerance,
|
||||
fmi2Real startTime, fmi2Boolean stopTimeDefined, fmi2Real stopTime) {
|
||||
|
||||
UNUSED(toleranceDefined);
|
||||
UNUSED(tolerance);
|
||||
|
||||
ASSERT_STATE(SetupExperiment)
|
||||
|
||||
S->startTime = startTime;
|
||||
S->stopTime = stopTimeDefined ? stopTime : INFINITY;
|
||||
S->time = startTime;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2EnterInitializationMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(EnterInitializationMode)
|
||||
|
||||
S->state = InitializationMode;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2ExitInitializationMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(ExitInitializationMode);
|
||||
|
||||
fmi2Status status = fmi2OK;
|
||||
|
||||
// if values were set and no fmi2GetXXX triggered update before,
|
||||
// ensure calculated values are updated now
|
||||
if (S->isDirtyValues) {
|
||||
status = (fmi2Status)calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
if (S->type == ModelExchange) {
|
||||
S->state = EventMode;
|
||||
} else {
|
||||
S->state = StepComplete;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
fmi2Status fmi2Terminate(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(Terminate)
|
||||
|
||||
S->state = Terminated;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2Reset(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(Reset);
|
||||
|
||||
reset(S);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
void fmi2FreeInstance(fmi2Component c) {
|
||||
|
||||
if (S) {
|
||||
freeModelInstance(S);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FMI functions: class methods not depending of a specific model instance
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const char* fmi2GetVersion(void) {
|
||||
return fmi2Version;
|
||||
}
|
||||
|
||||
const char* fmi2GetTypesPlatform(void) {
|
||||
return fmi2TypesPlatform;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// FMI functions: logging control, setters and getters for Real, Integer,
|
||||
// Boolean, String
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
fmi2Status fmi2SetDebugLogging(fmi2Component c, fmi2Boolean loggingOn, size_t nCategories, const fmi2String categories[]) {
|
||||
|
||||
ASSERT_STATE(SetDebugLogging)
|
||||
|
||||
return (fmi2Status)setDebugLogging(S, loggingOn, nCategories, categories);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetReal(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Real value[]) {
|
||||
|
||||
ASSERT_STATE(GetReal)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetReal", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetReal", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_VARIABLES(Float64);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetInteger(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Integer value[]) {
|
||||
|
||||
ASSERT_STATE(GetInteger)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetInteger", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetInteger", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_VARIABLES(Int32);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetBoolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2Boolean value[]) {
|
||||
|
||||
ASSERT_STATE(GetBoolean)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetBoolean", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2GetBoolean", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_BOOLEAN_VARIABLES;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetString (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, fmi2String value[]) {
|
||||
|
||||
ASSERT_STATE(GetString)
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2GetString", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2GetString", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && S->isDirtyValues) {
|
||||
calculateValues(S);
|
||||
S->isDirtyValues = false;
|
||||
}
|
||||
|
||||
GET_VARIABLES(String);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetReal (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Real value[]) {
|
||||
|
||||
ASSERT_STATE(SetReal)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetReal", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetReal", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_VARIABLES(Float64);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetInteger(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Integer value[]) {
|
||||
|
||||
ASSERT_STATE(SetInteger)
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetInteger", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr > 0 && nullPointer(S, "fmi2SetInteger", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_VARIABLES(Int32);
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetBoolean(fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2Boolean value[]) {
|
||||
|
||||
ASSERT_STATE(SetBoolean)
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetBoolean", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetBoolean", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_BOOLEAN_VARIABLES;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetString (fmi2Component c, const fmi2ValueReference vr[], size_t nvr, const fmi2String value[]) {
|
||||
|
||||
ASSERT_STATE(SetString);
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetString", "vr[]", vr))
|
||||
return fmi2Error;
|
||||
|
||||
if (nvr>0 && nullPointer(S, "fmi2SetString", "value[]", value))
|
||||
return fmi2Error;
|
||||
|
||||
SET_VARIABLES(String);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetFMUstate (fmi2Component c, fmi2FMUstate* FMUstate) {
|
||||
|
||||
ASSERT_STATE(GetFMUstate);
|
||||
|
||||
*FMUstate = getFMUState(S);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetFMUstate(fmi2Component c, fmi2FMUstate FMUstate) {
|
||||
|
||||
ASSERT_STATE(SetFMUstate);
|
||||
|
||||
if (nullPointer(S, "fmi2SetFMUstate", "FMUstate", FMUstate)) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
setFMUState(S, FMUstate);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2FreeFMUstate(fmi2Component c, fmi2FMUstate* FMUstate) {
|
||||
|
||||
ASSERT_STATE(FreeFMUstate);
|
||||
|
||||
free(*FMUstate);
|
||||
|
||||
*FMUstate = NULL;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SerializedFMUstateSize(fmi2Component c, fmi2FMUstate FMUstate, size_t *size) {
|
||||
|
||||
UNUSED(c);
|
||||
UNUSED(FMUstate);
|
||||
|
||||
ASSERT_STATE(SerializedFMUstateSize);
|
||||
|
||||
*size = sizeof(ModelInstance);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SerializeFMUstate(fmi2Component c, fmi2FMUstate FMUstate, fmi2Byte serializedState[], size_t size) {
|
||||
|
||||
ASSERT_STATE(SerializeFMUstate);
|
||||
|
||||
if (nullPointer(S, "fmi2SerializeFMUstate", "FMUstate", FMUstate)) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
if (invalidNumber(S, "fmi2SerializeFMUstate", "size", size, sizeof(ModelInstance))) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
memcpy(serializedState, FMUstate, sizeof(ModelInstance));
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2DeSerializeFMUstate (fmi2Component c, const fmi2Byte serializedState[], size_t size, fmi2FMUstate* FMUstate) {
|
||||
|
||||
ASSERT_STATE(DeSerializeFMUstate);
|
||||
|
||||
if (invalidNumber(S, "fmi2DeSerializeFMUstate", "size", size, sizeof(ModelInstance))) {
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
if (*FMUstate == NULL) {
|
||||
*FMUstate = calloc(1, sizeof(ModelInstance));
|
||||
}
|
||||
|
||||
memcpy(*FMUstate, serializedState, sizeof(ModelInstance));
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetDirectionalDerivative(fmi2Component c, const fmi2ValueReference vUnknown_ref[], size_t nUnknown,
|
||||
const fmi2ValueReference vKnown_ref[] , size_t nKnown,
|
||||
const fmi2Real dvKnown[], fmi2Real dvUnknown[]) {
|
||||
|
||||
ASSERT_STATE(GetDirectionalDerivative);
|
||||
|
||||
// TODO: check value references
|
||||
// TODO: assert nUnknowns == nDeltaOfUnknowns
|
||||
// TODO: assert nKnowns == nDeltaKnowns
|
||||
|
||||
Status status = OK;
|
||||
|
||||
for (size_t i = 0; i < nUnknown; i++) {
|
||||
dvUnknown[i] = 0;
|
||||
for (size_t j = 0; j < nKnown; j++) {
|
||||
double partialDerivative = 0;
|
||||
Status s = getPartialDerivative(S, vUnknown_ref[i], vKnown_ref[j], &partialDerivative);
|
||||
status = max(status, s);
|
||||
if (status > Warning) {
|
||||
return (fmi2Status)status;
|
||||
}
|
||||
dvUnknown[i] += partialDerivative * dvKnown[j];
|
||||
}
|
||||
}
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Functions for FMI for Co-Simulation
|
||||
// ---------------------------------------------------------------------------
|
||||
/* Simulating the slave */
|
||||
fmi2Status fmi2SetRealInputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[], const fmi2Real value[]) {
|
||||
|
||||
UNUSED(vr);
|
||||
UNUSED(nvr);
|
||||
UNUSED(order);
|
||||
UNUSED(value);
|
||||
|
||||
ASSERT_STATE(SetRealInputDerivatives);
|
||||
|
||||
logError(S, "fmi2SetRealInputDerivatives: ignoring function call."
|
||||
" This model cannot interpolate inputs: canInterpolateInputs=\"fmi2False\"");
|
||||
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetRealOutputDerivatives(fmi2Component c, const fmi2ValueReference vr[], size_t nvr,
|
||||
const fmi2Integer order[], fmi2Real value[]) {
|
||||
|
||||
ASSERT_STATE(GetRealOutputDerivatives);
|
||||
|
||||
#ifdef GET_OUTPUT_DERIVATIVE
|
||||
Status status = OK;
|
||||
|
||||
for (size_t i = 0; i < nvr; i++) {
|
||||
const Status s = getOutputDerivative(S, vr[i], order[i], &value[i]);
|
||||
status = max(status, s);
|
||||
if (status > Warning) {
|
||||
return (fmi2Status)status;
|
||||
}
|
||||
}
|
||||
|
||||
return (fmi2Status)status;
|
||||
#else
|
||||
UNUSED(vr);
|
||||
UNUSED(nvr);
|
||||
UNUSED(order);
|
||||
UNUSED(value);
|
||||
|
||||
logError(S, "fmi2GetRealOutputDerivatives: ignoring function call."
|
||||
" This model cannot compute derivatives of outputs: MaxOutputDerivativeOrder=\"0\"");
|
||||
|
||||
return fmi2Error;
|
||||
#endif
|
||||
}
|
||||
|
||||
fmi2Status fmi2CancelStep(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(CancelStep);
|
||||
|
||||
logError(S, "fmi2CancelStep: Can be called when fmi2DoStep returned fmi2Pending."
|
||||
" This is not the case.");
|
||||
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint,
|
||||
fmi2Real communicationStepSize, fmi2Boolean noSetFMUStatePriorToCurrentPoint) {
|
||||
|
||||
UNUSED(noSetFMUStatePriorToCurrentPoint);
|
||||
|
||||
ASSERT_STATE(DoStep);
|
||||
|
||||
if (communicationStepSize <= 0) {
|
||||
logError(S, "Communication step size must be > 0 but was %g.", communicationStepSize);
|
||||
S->state = modelError;
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
if (currentCommunicationPoint + communicationStepSize > S->stopTime + EPSILON) {
|
||||
logError(S, "At communication point %.16g a step size of %.16g was requested but stop time is %.16g.",
|
||||
currentCommunicationPoint, communicationStepSize, S->stopTime);
|
||||
S->state = modelError;
|
||||
return fmi2Error;
|
||||
}
|
||||
|
||||
const fmi2Real nextCommunicationPoint = currentCommunicationPoint + communicationStepSize + EPSILON;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (S->time + FIXED_SOLVER_STEP > nextCommunicationPoint) {
|
||||
break; // next communication point reached
|
||||
}
|
||||
|
||||
bool stateEvent, timeEvent;
|
||||
|
||||
doFixedStep(S, &stateEvent, &timeEvent);
|
||||
|
||||
#ifdef EVENT_UPDATE
|
||||
if (stateEvent || timeEvent) {
|
||||
eventUpdate(S);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return S->terminateSimulation ? fmi2Discard : fmi2OK;
|
||||
}
|
||||
|
||||
/* Inquire slave status */
|
||||
static fmi2Status getStatus(char* fname, fmi2Component c, const fmi2StatusKind s) {
|
||||
|
||||
switch(s) {
|
||||
case fmi2DoStepStatus: logError(S,
|
||||
"%s: Can be called with fmi2DoStepStatus when fmi2DoStep returned fmi2Pending."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
case fmi2PendingStatus: logError(S,
|
||||
"%s: Can be called with fmi2PendingStatus when fmi2DoStep returned fmi2Pending."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
case fmi2LastSuccessfulTime: logError(S,
|
||||
"%s: Can be called with fmi2LastSuccessfulTime when fmi2DoStep returned fmi2Discard."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
case fmi2Terminated: logError(S,
|
||||
"%s: Can be called with fmi2Terminated when fmi2DoStep returned fmi2Discard."
|
||||
" This is not the case.", fname);
|
||||
break;
|
||||
}
|
||||
|
||||
return fmi2Discard;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetStatus(fmi2Component c, const fmi2StatusKind s, fmi2Status *value) {
|
||||
|
||||
UNUSED(value);
|
||||
|
||||
ASSERT_STATE(GetStatus);
|
||||
|
||||
return getStatus("fmi2GetStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetRealStatus(fmi2Component c, const fmi2StatusKind s, fmi2Real *value) {
|
||||
|
||||
ASSERT_STATE(GetRealStatus);
|
||||
|
||||
if (s == fmi2LastSuccessfulTime) {
|
||||
*value = S->time;
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
return getStatus("fmi2GetRealStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetIntegerStatus(fmi2Component c, const fmi2StatusKind s, fmi2Integer *value) {
|
||||
|
||||
UNUSED(value);
|
||||
|
||||
ASSERT_STATE(GetIntegerStatus);
|
||||
|
||||
return getStatus("fmi2GetIntegerStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetBooleanStatus(fmi2Component c, const fmi2StatusKind s, fmi2Boolean *value) {
|
||||
|
||||
ASSERT_STATE(GetBooleanStatus);
|
||||
|
||||
if (s == fmi2Terminated) {
|
||||
*value = S->terminateSimulation;
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
return getStatus("fmi2GetBooleanStatus", c, s);
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetStringStatus(fmi2Component c, const fmi2StatusKind s, fmi2String *value) {
|
||||
UNUSED(value);
|
||||
ASSERT_STATE(GetStringStatus);
|
||||
return getStatus("fmi2GetStringStatus", c, s);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Functions for FMI2 for Model Exchange
|
||||
// ---------------------------------------------------------------------------
|
||||
/* Enter and exit the different modes */
|
||||
fmi2Status fmi2EnterEventMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(EnterEventMode);
|
||||
|
||||
S->state = EventMode;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2NewDiscreteStates(fmi2Component c, fmi2EventInfo *eventInfo) {
|
||||
|
||||
ASSERT_STATE(NewDiscreteStates);
|
||||
|
||||
#ifdef EVENT_UPDATE
|
||||
eventUpdate(S);
|
||||
#endif
|
||||
|
||||
eventInfo->newDiscreteStatesNeeded = S->newDiscreteStatesNeeded;
|
||||
eventInfo->terminateSimulation = S->terminateSimulation;
|
||||
eventInfo->nominalsOfContinuousStatesChanged = S->nominalsOfContinuousStatesChanged;
|
||||
eventInfo->valuesOfContinuousStatesChanged = S->valuesOfContinuousStatesChanged;
|
||||
eventInfo->nextEventTimeDefined = S->nextEventTimeDefined;
|
||||
eventInfo->nextEventTime = S->nextEventTime;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2EnterContinuousTimeMode(fmi2Component c) {
|
||||
|
||||
ASSERT_STATE(EnterContinuousTimeMode);
|
||||
|
||||
S->state = ContinuousTimeMode;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2CompletedIntegratorStep(fmi2Component c, fmi2Boolean noSetFMUStatePriorToCurrentPoint,
|
||||
fmi2Boolean *enterEventMode, fmi2Boolean *terminateSimulation) {
|
||||
|
||||
|
||||
|
||||
UNUSED(noSetFMUStatePriorToCurrentPoint);
|
||||
|
||||
ASSERT_STATE(CompletedIntegratorStep);
|
||||
|
||||
if (nullPointer(S, "fmi2CompletedIntegratorStep", "enterEventMode", enterEventMode))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2CompletedIntegratorStep", "terminateSimulation", terminateSimulation))
|
||||
return fmi2Error;
|
||||
|
||||
*enterEventMode = fmi2False;
|
||||
*terminateSimulation = fmi2False;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
/* Providing independent variables and re-initialization of caching */
|
||||
fmi2Status fmi2SetTime(fmi2Component c, fmi2Real time) {
|
||||
|
||||
ASSERT_STATE(SetTime);
|
||||
|
||||
S->time = time;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2SetContinuousStates(fmi2Component c, const fmi2Real x[], size_t nx){
|
||||
|
||||
ASSERT_STATE(SetContinuousStates);
|
||||
|
||||
if (invalidNumber(S, "fmi2SetContinuousStates", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2SetContinuousStates", "x[]", x))
|
||||
return fmi2Error;
|
||||
|
||||
setContinuousStates(S, x, nx);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
/* Evaluation of the model equations */
|
||||
fmi2Status fmi2GetDerivatives(fmi2Component c, fmi2Real derivatives[], size_t nx) {
|
||||
|
||||
ASSERT_STATE(GetDerivatives);
|
||||
|
||||
if (invalidNumber(S, "fmi2GetDerivatives", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2GetDerivatives", "derivatives[]", derivatives))
|
||||
return fmi2Error;
|
||||
|
||||
getDerivatives(S, derivatives, nx);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetEventIndicators(fmi2Component c, fmi2Real eventIndicators[], size_t ni) {
|
||||
|
||||
ASSERT_STATE(GetEventIndicators);
|
||||
|
||||
#if NZ > 0
|
||||
|
||||
if (invalidNumber(S, "fmi2GetEventIndicators", "ni", ni, NZ))
|
||||
return fmi2Error;
|
||||
|
||||
getEventIndicators(S, eventIndicators, ni);
|
||||
#else
|
||||
UNUSED(c);
|
||||
UNUSED(eventIndicators);
|
||||
if (ni > 0) return fmi2Error;
|
||||
#endif
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetContinuousStates(fmi2Component c, fmi2Real states[], size_t nx) {
|
||||
|
||||
ASSERT_STATE(GetContinuousStates);
|
||||
|
||||
if (invalidNumber(S, "fmi2GetContinuousStates", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2GetContinuousStates", "states[]", states))
|
||||
return fmi2Error;
|
||||
|
||||
getContinuousStates(S, states, nx);
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
|
||||
fmi2Status fmi2GetNominalsOfContinuousStates(fmi2Component c, fmi2Real x_nominal[], size_t nx) {
|
||||
|
||||
ASSERT_STATE(GetNominalsOfContinuousStates);
|
||||
|
||||
if (invalidNumber(S, "fmi2GetNominalContinuousStates", "nx", nx, NX))
|
||||
return fmi2Error;
|
||||
|
||||
if (nullPointer(S, "fmi2GetNominalContinuousStates", "x_nominal[]", x_nominal))
|
||||
return fmi2Error;
|
||||
|
||||
for (size_t i = 0; i < nx; i++)
|
||||
x_nominal[i] = 1;
|
||||
|
||||
return fmi2OK;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
/* */
|
||||
/* This script file uses the Doors4ExampleFMU.fmu to be run in OpenXiL */
|
||||
/* */
|
||||
ADD_BBVARI(Loop, UDWORD)
|
||||
SET_BBVARI(Loop = 0)
|
||||
|
||||
/* */
|
||||
/* Door01Left = 1 represents a open door */
|
||||
/* wait more then 2 seconds */
|
||||
/* Open all doors */
|
||||
/* */
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 1)
|
||||
SET_BBVARI(Door01RightIsOpen = 1)
|
||||
SET_BBVARI(Door02LeftIsOpen = 1)
|
||||
SET_BBVARI(Door02RightIsOpen = 1)
|
||||
|
||||
/* */
|
||||
/* Close each door one by one */
|
||||
/* wait more then 2 seconds */
|
||||
/* Open all doors */
|
||||
/* */
|
||||
|
||||
|
||||
WHILE(Loop < 10)
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 0)
|
||||
DELAY(100)
|
||||
|
||||
SET_BBVARI(Door01RightIsOpen = 0)
|
||||
DELAY(100)
|
||||
|
||||
SET_BBVARI(Door02LeftIsOpen = 0)
|
||||
DELAY(100)
|
||||
|
||||
SET_BBVARI(Door02RightIsOpen = 0)
|
||||
|
||||
/* */
|
||||
/* wait until the doors are locked, < 2 seconds */
|
||||
/* */
|
||||
DELAY(1000)
|
||||
|
||||
SET_BBVARI(Door01LeftIsOpen = 1)
|
||||
SET_BBVARI(Door01RightIsOpen = 1)
|
||||
SET_BBVARI(Door02LeftIsOpen = 1)
|
||||
SET_BBVARI(Door02RightIsOpen = 1)
|
||||
|
||||
DELAY(100)
|
||||
SET(Loop = Loop + 1)
|
||||
ENDWHILE
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01left_bs_rx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
#include "vss_vehiclechassisdooraxle01left_vd_rx.idl"
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module LeftService
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_SetIsOpen event interface
|
||||
*/
|
||||
interface IVSS_SetIsOpen_Event
|
||||
{
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL1(in boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IVSS_GetIsOpen Service interface
|
||||
*/
|
||||
interface IVSS_GetIsOpen
|
||||
{
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen signal
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
boolean GetIsOpen() const;
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfLeftDoorIsOpen01(in vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event callback);
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfLeftDoorIsOpen01(in vss::Vehicle::Chassis::Door::Axle01::LeftService::IVSS_SetIsOpen_Event callback);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01left_bs_tx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module LeftService
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_SetLock Service interface
|
||||
*/
|
||||
interface IVSS_SetLock
|
||||
{
|
||||
/**
|
||||
* @brief Set leftLatch02 signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
boolean SetLock(in boolean value);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01left_vd_rx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module LeftDevice
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_WriteIsOpen event interface
|
||||
*/
|
||||
interface IVSS_WriteIsOpen_Event
|
||||
{
|
||||
/**
|
||||
* @brief Write leftDoorIsOpen signal
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(in boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IVSS_IsOpen abstract Device interface
|
||||
*/
|
||||
interface IVSS_IsOpen
|
||||
{
|
||||
/**
|
||||
* @brief Register WriteIsOpen event on signal change
|
||||
* Register all events and call them on signal change
|
||||
* @param[in] event function
|
||||
*/
|
||||
void RegisterIsOpenEvent(in IVSS_WriteIsOpen_Event event);
|
||||
|
||||
/**
|
||||
* @brief Unregister IsOpen event
|
||||
* @param[in] event function
|
||||
*/
|
||||
void UnregisterIsOpenEvent(in IVSS_WriteIsOpen_Event event);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01left_vd_tx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module LeftDevice
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_WriteLock Device interface
|
||||
*/
|
||||
interface IVSS_WriteLock
|
||||
{
|
||||
/**
|
||||
* @brief Write leftLatch01 signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
boolean WriteLock(in boolean value);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01right_bs_rx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
#include "vss_vehiclechassisdooraxle01right_vd_rx.idl"
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module RightService
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_SetIsOpen event interface
|
||||
*/
|
||||
interface IVSS_SetIsOpen_Event
|
||||
{
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR1(in boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IVSS_GetIsOpen Service interface
|
||||
*/
|
||||
interface IVSS_GetIsOpen
|
||||
{
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen signal
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
boolean GetIsOpen() const;
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfRightDoorIsOpen01(in vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event callback);
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfRightDoorIsOpen01(in vss::Vehicle::Chassis::Door::Axle01::RightService::IVSS_SetIsOpen_Event callback);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01right_bs_tx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module RightService
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_SetLock Service interface
|
||||
*/
|
||||
interface IVSS_SetLock
|
||||
{
|
||||
/**
|
||||
* @brief Set rightLatch signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
boolean SetLock(in boolean value);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01right_vd_rx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module RightDevice
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_WriteIsOpen event interface
|
||||
*/
|
||||
interface IVSS_WriteIsOpen_Event
|
||||
{
|
||||
/**
|
||||
* @brief Write rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(in boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IVSS_IsOpen abstract Device interface
|
||||
*/
|
||||
interface IVSS_IsOpen
|
||||
{
|
||||
/**
|
||||
* @brief Register WriteIsOpen event on signal change
|
||||
* Register all events and call them on signal change
|
||||
* @param[in] event function
|
||||
*/
|
||||
void RegisterIsOpenEvent(in IVSS_WriteIsOpen_Event event);
|
||||
|
||||
/**
|
||||
* @brief Unregister IsOpen event
|
||||
* @param[in] event function
|
||||
*/
|
||||
void UnregisterIsOpenEvent(in IVSS_WriteIsOpen_Event event);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle01right_vd_tx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle01
|
||||
{
|
||||
module RightDevice
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_WriteLock Device interface
|
||||
*/
|
||||
interface IVSS_WriteLock
|
||||
{
|
||||
/**
|
||||
* @brief Write rightLatch signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
boolean WriteLock(in boolean value);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle02left_bs_rx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
#include "vss_vehiclechassisdooraxle02left_vd_rx.idl"
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle02
|
||||
{
|
||||
module LeftService
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_SetIsOpen event interface
|
||||
*/
|
||||
interface IVSS_SetIsOpen_Event
|
||||
{
|
||||
/**
|
||||
* @brief Set leftDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenL2(in boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IVSS_GetIsOpen Service interface
|
||||
*/
|
||||
interface IVSS_GetIsOpen
|
||||
{
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen signal
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
boolean GetIsOpen() const;
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfLeftDoorIsOpen02(in vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event callback);
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfLeftDoorIsOpen02(in vss::Vehicle::Chassis::Door::Axle02::LeftService::IVSS_SetIsOpen_Event callback);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle02left_bs_tx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle02
|
||||
{
|
||||
module LeftService
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_SetLock Service interface
|
||||
*/
|
||||
interface IVSS_SetLock
|
||||
{
|
||||
/**
|
||||
* @brief Set leftLatch02 signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
boolean SetLock(in boolean value);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle02left_vd_rx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle02
|
||||
{
|
||||
module LeftDevice
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_WriteIsOpen event interface
|
||||
*/
|
||||
interface IVSS_WriteIsOpen_Event
|
||||
{
|
||||
/**
|
||||
* @brief Write leftDoorIsOpen signal
|
||||
* @param[in] value leftDoorIsOpen
|
||||
*/
|
||||
void WriteIsOpen(in boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IVSS_IsOpen abstract Device interface
|
||||
*/
|
||||
interface IVSS_IsOpen
|
||||
{
|
||||
/**
|
||||
* @brief Register WriteIsOpen event on signal change
|
||||
* Register all events and call them on signal change
|
||||
* @param[in] event function
|
||||
*/
|
||||
void RegisterIsOpenEvent(in IVSS_WriteIsOpen_Event event);
|
||||
|
||||
/**
|
||||
* @brief Unregister IsOpen event
|
||||
* @param[in] event function
|
||||
*/
|
||||
void UnregisterIsOpenEvent(in IVSS_WriteIsOpen_Event event);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle02left_vd_tx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle02
|
||||
{
|
||||
module LeftDevice
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_WriteLock Device interface
|
||||
*/
|
||||
interface IVSS_WriteLock
|
||||
{
|
||||
/**
|
||||
* @brief Write leftLatch02 signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
boolean WriteLock(in boolean value);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
/**
|
||||
* @file vss_vehiclechassisdooraxle02right_bs_rx.idl
|
||||
* @date 2025-07-11 11:03:55
|
||||
* File is auto generated from VSS utility.
|
||||
* VSS Version:1.0.0.1
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
#include "vss_vehiclechassisdooraxle02right_vd_rx.idl"
|
||||
|
||||
module vss
|
||||
{
|
||||
module Vehicle
|
||||
{
|
||||
module Chassis
|
||||
{
|
||||
module Door
|
||||
{
|
||||
module Axle02
|
||||
{
|
||||
module RightService
|
||||
{
|
||||
/**
|
||||
* @brief IVSS_SetIsOpen event interface
|
||||
*/
|
||||
interface IVSS_SetIsOpen_Event
|
||||
{
|
||||
/**
|
||||
* @brief Set rightDoorIsOpen signal
|
||||
* @param[in] value rightDoorIsOpen
|
||||
*/
|
||||
void SetIsOpenR2(in boolean value);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief IVSS_GetIsOpen Service interface
|
||||
*/
|
||||
interface IVSS_GetIsOpen
|
||||
{
|
||||
/**
|
||||
* @brief Get rightDoorIsOpen signal
|
||||
* @return Returns the rightDoorIsOpen
|
||||
*/
|
||||
boolean GetIsOpen() const;
|
||||
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOfRightDoorIsOpen02(in vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event callback);
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOfRightDoorIsOpen02(in vss::Vehicle::Chassis::Door::Axle02::RightService::IVSS_SetIsOpen_Event callback);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user