VR-Engage  2.2
Loading...
Searching...
No Matches
Vehicle Blinker Example

Overview

Purpose: This example implements a vehicle turn signal system to illustrate frontend-backend component coordination in VR-Engage. The implementation handles user input in the frontend, transmits commands through joystick messages to the simulation backend, and modifies entity state that propagates across the network.

Observable Behavior: Running this example produces keyboard-triggered blinker activation using ',' for left and '.' for right turn signals. The frontend component captures input and sends joystick messages to the backend actuator, which toggles blinker state and updates vehicle lighting. Visual dashboard indicators display blinker status through QML overlay bindings to entity state properties. Vehicle lighting state changes transmit automatically via DIS/HLA network protocols to remote visualizations.

Prerequisites:

Related Examples:


Key Concepts Demonstrated

The vehicle blinker implementation covers frontend-backend component coordination by separating user interface concerns from simulation logic. The DtVehicleBlinkerControlLogic frontend component handles user input and UI integration, while the DtVehicleBlinkerActuator backend component modifies simulation state and vehicle lighting. This separation follows the standard VR-Engage architecture pattern where UI responsiveness remains independent of simulation tick rates.

Joystick message transmission provides the standard command mechanism between frontend and backend processes. The frontend converts input actions ("left-blinker", "right-blinker") to joystick messages that the backend routes via input ports to actuator logic. This messaging pattern decouples UI implementation from simulation logic while ensuring reliable command delivery across process boundaries.

The actuator component architecture extends VR-Forces with custom functionality through input ports that receive external commands. The implementation uses a toggle pattern where button presses invert current state, with state persistence maintained across simulation ticks through entity properties. This approach allows other components to access the blinker state for dependent functionality.

Vehicle state modification integrates with the networked simulation environment through the DtGroundVehicleLightingStateComponent. The QML dashboard overlay displays real-time blinker status via property bindings to entity state attributes. State changes transmit automatically via DIS/HLA to remote visualizations, ensuring consistent behavior across distributed simulation environments.


Architecture

The vehicle blinker system consists of two plugins that coordinate through the VR-Engage messaging infrastructure. The frontend process handles user interaction and visual feedback, while the backend process manages simulation state and network propagation.

flowchart TB
    subgraph Frontend["VR-Engage Frontend Process"]
        Control["DtVehicleBlinkerControlLogic<br/>Captures keyboard input<br/>Maps to joystick message"]
        Dashboard["QML Dashboard Overlay<br/>Shows blinker indicators<br/>Bound to state attributes"]
    end

    subgraph Backend["VR-Engage Backend Process<br/>(VR-Forces Simulation Engine)"]
        Actuator["DtVehicleBlinkerActuator<br/>Receives via input ports<br/>Toggles blinker state<br/>Updates lighting state"]
        Lighting["DtGroundVehicleLightingState<br/>Transmitted via DIS/HLA"]
        Properties["Entity State Properties<br/>left-blinker-active<br/>right-blinker-active"]
        Actuator --> Lighting
        Actuator --> Properties
    end

    Control -->|"JoystickMessage<br/>(Network message)"| Actuator
    Properties -.->|"State sync"| Dashboard

The frontend control logic handles keyboard input and converts user actions to standardized joystick messages. The backend actuator receives these commands, toggles persistent state properties, and updates vehicle lighting components. Visual feedback occurs through QML dashboard elements bound to entity state properties, providing real-time blinker status display. Network propagation transmits lighting state automatically to remote viewers via DIS/HLA protocols.

Message Flow: User input triggers a defined sequence of operations that spans frontend and backend processes. Keyboard presses (',' for left blinker, '.' for right blinker) activate input system actions that call DtVehicleBlinkerControlLogic::setLeftBlinker() or setRightBlinker() methods. The frontend sends JoystickMessage instances with function names "LeftBlinker" or "RightBlinker" to the backend process. The backend routes these messages to actuator input ports via the joystick controller system. The actuator toggles corresponding state properties (left-blinker-active or right-blinker-active) and updates the lighting state component. Dashboard QML overlay elements reflect state changes through property bindings, while DIS Entity State PDUs transmit the changes to remote viewers for synchronized indicator display.


Code Walkthrough

Frontend: Control Logic Component

The control logic handles input and converts to joystick messages:

// filepath: examples/vehicleBlinker/vehicleBlinkerFrontend/vehicleBlinkerControlLogic.h
{
public:
// Handler for the "left-blinker" player input action
virtual void setLeftBlinker(double val);
// Handler for the "right-blinker" player input action
virtual void setRightBlinker(double val);
protected:
// Sends a JoystickMessage to the sim engine
virtual void sendJoystickMessage(const std::string& function, double val, double delay = 0);
std::string myMainJoystickGroup;
};
VR-Engage frontend component that handles input for vehicle turn signals.
Definition vehicleBlinkerControlLogic.h:27
virtual void setRightBlinker(double val)
virtual void setLeftBlinker(double val)
virtual bool initialize(makVre::DtPlayerStation *player, makVre::DtInitTable &config) override
Initializes the entity control logic.
std::string myMainJoystickGroup
Definition vehicleBlinkerControlLogic.h:59
makVre::DtInputLogic myInputLogic
Definition vehicleBlinkerControlLogic.h:51
virtual void sendJoystickMessage(const std::string &function, double val, double delay=0)
Component that provides entity control functionality.
Definition entityControlLogic.h:60
Table-based access to Lua state for configuration data.
Definition initializer.h:38
Class for managing input configuration and handling in VR-Engage.
Definition inputLogic.h:35
virtual DtPlayerStation & player()
Gets the player station.
Class for managing the user interface for engaged roles.
Definition playerStation.h:51

The class inherits from DtEntityControlLogic, which provides the base vehicle control component functionality. The DtInputLogic member handles mapping input configuration to action handlers, while myMainJoystickGroup caches the joystick function group name used for message routing.

Frontend: Input Action Registration

The initialization process establishes the connection between input configuration and handler methods. The component caches the first joystick group name from role configuration and sets up input logic for loading action-handler mappings. Input configuration loading requires the file specified in the role configuration and uses the "lights" input group to match keyboard.lua configuration.

// filepath: examples/vehicleBlinker/vehicleBlinkerFrontend/vehicleBlinkerControlLogic.cxx
bool DtVehicleBlinkerControlLogic::initialize(DtPlayerStation* player, DtInitTable& config)
{
if (!DtEntityControlLogic::initialize(player, config))
return false;
// Cache the first joystick group name (from role configuration)
if (myJoystickFunctionGroups.size() > 0)
{
myMainJoystickGroup = myJoystickFunctionGroups[0]; // "Vehicle-Blinkers"
}
// Set up input logic for loading action-handler mappings
// Input group name (must match keyboard.lua configuration)
const std::string inputGroup = "lights";
// Load input configuration file specified in role
// Map action names to handler functions
myInputLogic.addActionHandler(inputGroup, "left-blinker",
myInputLogic.addActionHandler(inputGroup, "right-blinker",
return true;
}
std::string myInputConfigFile
Name of the input configuration file.
Definition entityControlLogic.h:256
std::vector< std::string > myJoystickFunctionGroups
List of joystick function groups used by this controller.
Definition entityControlLogic.h:246
virtual void initialize()
Initializes the input logic system.
virtual void addActionHandler(const std::string &group, const std::string &action, const DtActionDelegate &handler)
Registers a callback function to handle an input-triggered action.
virtual bool loadInputConfig(const std::string &config, const std::string &group, bool alwaysOnTop=false, bool alwaysEnabled=false)
Loads input mappings from a configuration file.

The myInputConfigFile variable contains the filename from role configuration (vehicleBlinkerInput.lua), which defines key bindings that map ',' to "left-blinker" and '.' to "right-blinker" actions. The DtActionDelegate creates type-safe callback bindings to member functions. This design separates input binding configuration from handler logic implementation, enabling reconfiguration without code changes.

Frontend: Sending Joystick Messages

Action handlers convert input to backend commands:

// filepath: examples/vehicleBlinker/vehicleBlinkerFrontend/vehicleBlinkerControlLogic.cxx
{
sendJoystickMessage("LeftBlinker", val);
}
{
sendJoystickMessage("RightBlinker", val);
}
void DtVehicleBlinkerControlLogic::sendJoystickMessage(const std::string& function, double val, double delay)
{
JoystickMessage* msg = JoystickMessage::create();
msg->setEntityId(DtPlayerComponent::player().entityId());
msg->setFunctionGroup(myMainJoystickGroup);
msg->setFunction(function);
msg->setValue(val);
DtVreMessageManager::instance().queueMessage(msg, delay);
}

The val parameter typically contains 1.0 for button press events and 0.0 for release events. The entity ID ensures the message routes to the correct backend entity, while the combination of function group and function name identifies the specific command. The message manager queues the message for transmission to the backend process.

Backend: Actuator Structure

The actuator receives commands and modifies state:

// filepath: examples/vehicleBlinker/vehicleBlinkerSim/vehicleBlinkerActuator.h
class DtVehicleBlinkerActuator : public DtActuatorComponent
{
public:
DtVehicleBlinkerActuator(const DtString& name, DtLocalObject* owner,
DtSimulationServices* simManager,
DtComponentDescriptor* desc = nullptr,
DtReaderWriterRegistry* parentRegistry = nullptr);
virtual bool init() override;
virtual void tick() override;
virtual const char* type() const override;
static DtSimComponent* creator(...);
protected:
bool createPorts() override;
void updateLeftBlinker();
void updateRightBlinker();
protected:
DtBooleanInputPort* myLeftBlinkerPort;
DtBooleanInputPort* myRightBlinkerPort;
DtRwBoolean* myLeftBlinkerActive; // State property
DtRwBoolean* myRightBlinkerActive; // State property
};

The DtBooleanInputPort members receive joystick message data routed from the frontend. The DtRwBoolean properties persist the blinker on/off state across simulation ticks, making them accessible to other components. Separate update methods for each blinker enable independent control of left and right indicators.

Backend: Creating Input Ports

Input ports route joystick messages to the actuator:

// filepath: examples/vehicleBlinker/vehicleBlinkerSim/vehicleBlinkerActuator.cxx
bool DtVehicleBlinkerActuator::createPorts()
{
myLeftBlinkerPort = new DtBooleanInputPort("left-blinker");
addInputPort(myLeftBlinkerPort);
myRightBlinkerPort = new DtBooleanInputPort("right-blinker");
addInputPort(myRightBlinkerPort);
return DtActuatorComponent::createPorts();
}

The port names "left-blinker" and "right-blinker" must match the component descriptor configuration for proper message routing. The addInputPort() method registers each port with the actuator framework, enabling the joystick controller system to route messages by function name to the matching port.

Backend: Accessing State Properties

Initialize retrieves persistent state properties:

// filepath: examples/vehicleBlinker/vehicleBlinkerSim/vehicleBlinkerActuator.cxx
bool DtVehicleBlinkerActuator::init()
{
if (!DtActuatorComponent::init())
{
return false;
}
// Find blinker state properties on the entity
myLeftBlinkerActive = entity()->nextFrameStateProperties().findProperty<DtRwBoolean>("left-blinker-active");
myRightBlinkerActive = entity()->nextFrameStateProperties().findProperty<DtRwBoolean>("right-blinker-active");
return true;
}

The properties are defined in the component descriptor or entity configuration files. The nextFrameStateProperties() method accesses properties for the current simulation step, and these properties persist across ticks, making them readable by other components that need to query blinker status.

Backend: Processing Input and Toggling State

The tick method processes input port data and manages state transitions. The implementation checks for active connections and new data on each input port, acknowledging received messages and processing only button press events (ignoring releases).

// filepath: examples/vehicleBlinker/vehicleBlinkerSim/vehicleBlinkerActuator.cxx
void DtVehicleBlinkerActuator::tick()
{
// Left blinker
if (myLeftBlinkerPort->activeConnection() && myLeftBlinkerPort->newData())
{
myLeftBlinkerPort->dataReceived();
if (myLeftBlinkerPort->value() == true)
{
myLeftBlinkerActive->setValue(!myLeftBlinkerActive->value());
updateLeftBlinker();
}
}
// Right blinker
if (myRightBlinkerPort->activeConnection() && myRightBlinkerPort->newData())
{
myRightBlinkerPort->dataReceived();
if (myRightBlinkerPort->value() == true)
{
myRightBlinkerActive->setValue(!myRightBlinkerActive->value());
updateRightBlinker();
}
}
}

The activeConnection() method confirms port connectivity to input sources, while newData() indicates message receipt since the last tick. The dataReceived() call acknowledges message processing and clears the new data flag. Toggle logic inverts current state on each button press, providing familiar turn signal behavior where repeated activation cycles the blinker on and off.

Backend: Modifying Vehicle Lighting State

State update methods modify the networked lighting component to reflect blinker status changes. The implementation retrieves the ground vehicle lighting state component and updates indicator light flags based on current property values.

// filepath: examples/vehicleBlinker/vehicleBlinkerSim/vehicleBlinkerActuator.cxx
void DtVehicleBlinkerActuator::updateLeftBlinker()
{
makVrf::DtGroundVehicleLightingStateComponent* groundVehicleLightingStateData = nullptr;
if (entity()->hasStateComponent<makVrf::DtGroundVehicleLightingStateComponent>())
{
groundVehicleLightingStateData = entity()->getNextFrameStateComponent<makVrf::DtGroundVehicleLightingStateComponent>();
}
if (groundVehicleLightingStateData)
{
const bool value = myLeftBlinkerActive->value();
LOG_WARN("Example Vehicle Blinker") << "Setting left blinker to " << value << std::endl;
groundVehicleLightingStateData->setLeftIndicatorLightsOn(value);
}
}
#define LOG_WARN(channel)
Macro to log a warning message to log files.
Definition logger.h:69

The DtGroundVehicleLightingStateComponent manages all vehicle lighting including headlights, brake lights, and indicators. The getNextFrameStateComponent<>() method retrieves the component for modification during the current simulation step. Lighting state changes transmit automatically via DIS Entity State PDUs, enabling remote visualization systems to render synchronized blinker indicators.

Backend: Component Registration and System Definition

Plugin registration establishes component availability within the VR-Forces factory system. The backend plugin registers both actuator and descriptor components through the factory manager hierarchy.

// filepath: examples/vehicleBlinker/vehicleBlinkerSim/plugin.cxx
extern "C"
{
bool DT_VRF_DLL_PLUGIN DtInitializeVrfPlugin(const DtCgf* cgf)
{
// Register actuator and descriptor with backend factories
cgf->factoryManager()->componentFactory()->addCreatorFcn(
cgf->factoryManager()->componentDescriptorFactory()->addCreatorFcn(
return true;
}
}
static DtSimComponent * creator(const DtString &name, DtLocalObject *owner, DtSimulationServices *simManager, DtComponentDescriptor *desc=nullptr, DtReaderWriterRegistry *parentRegistry=nullptr)
static DtComponentDescriptor * creator()
constexpr char DtVehicleBlinkerActuatorType[]
Definition vehicleBlinkerActuator.h:22
constexpr char DtVehicleBlinkerDescriptorType[]
Definition vehicleBlinkerDescriptor.h:19

The system definition file configures joystick controller and actuator components with their connections. The joystick controller defines function groups and individual controls, while the actuator provides input ports for receiving commands. Connection specifications link joystick output ports to actuator input ports.

System definition configuration requires both actuator and descriptor registration for proper component instantiation. The frontend uses DtPlayerStationApp::componentFactory() for UI components, while the backend uses DtCgf::factoryManager() for simulation components.


Deployment and Testing

Installation

Build both components (see Environment Setup & Build Guide):

cd examples\build
cmake --build . --config RelWithDebInfo --target vehicleBlinkerFrontend
cmake --build . --config RelWithDebInfo --target vehicleBlinkerSim

Install both plugins to the VR-Engage installation:

cmake --install . --config RelWithDebInfo

This copies:

  • Frontend plugin to <VR-Engage-Install-Dir>\plugins64\vrEngage\release\exampleVehicleBlinkerFrontend.dll
  • Backend plugin to <VR-Engage-Install-Dir>\plugins64\vrForces\release\exampleVehicleBlinkerSim.dll

Verify installation:

dir "<VR-Engage-Install-Dir>\plugins64\vrEngage\release\exampleVehicleBlinkerFrontend.dll"
dir "<VR-Engage-Install-Dir>\plugins64\vrForces\release\exampleVehicleBlinkerSim.dll"

Configuration

Plugin loading occurs automatically through the VR-Engage discovery system. Frontend plugins in plugins64/vrEngage/release/ load at startup without manifest configuration. Backend plugin configuration files install automatically through the VR-Engage toolkit installer.

Role configuration integration requires component specification in the driver role file. The configuration defines the control logic component with input file references and joystick function groups. Extended state logic configuration establishes the state properties that persist blinker status.

components = {
["vehicleBlinkerControlLogic"] = {
componentType = "DtVehicleBlinkerControlLogic";
priority = 5;
inputConfigFile = "vehicleBlinkerInput.lua";
joystickFunctionGroups = {"Vehicle-Blinkers"};
};
-- Extended state logic defines state properties
["extendedStateLogic"] = {
componentType = "DtExtendedStateLogic";
stateProperties = {
{ name = "left-blinker-active", type = "bool" };
{ name = "right-blinker-active", type = "bool" };
};
};
};

Input configuration maps keyboard keys to action names through device-specific mappings. The configuration uses the "lights" group to organize related input actions and specifies key-to-action bindings for left and right blinker controls.

Entity configuration includes the vehicle blinker system reference and establishes the driver role relationship. The system definition reference (vehicle-blinkers.sysdef) provides the joystick controller and actuator configuration, while the role specification links to the driver configuration file.

Testing Procedure

  1. Launch VR-Engage with the vehicle blinker example configuration
  2. Load a scenario containing the Light Strike Vehicle MK II entity configured with the blinker system
  3. Select the "Driver" role from the entity's vrEngageRoles configuration
  4. Engage the vehicle using normal VR-Engage procedures
  5. Test the left blinker:
    • Press the ',' key
    • Verify console output displays "Setting left blinker to 1"
    • Confirm the left dashboard indicator displays green coloring
    • Press ',' again to toggle off
    • Verify console output displays "Setting left blinker to 0" and indicator returns to gray
  6. Test the right blinker using the '.' key following the same pattern
  7. Verify dashboard integration by confirming QML overlay elements show blinker status in real-time with immediate response to key presses
  8. For network verification (optional):
    • Connect a second VR-Engage or VR-Vantage instance to the same DIS/HLA exercise
    • Verify remote views display vehicle blinkers synchronized with local state

Verification:

  • Check VR-Engage frontend log for plugin initialization:
    [Example Vehicle Blinker] Initializing...
    [Component Factory] Registered DtVehicleBlinkerControlLogic
  • Check VR-Forces backend log for system setup:
    [Plugin] Loaded vehicle blinker simulation plugin
    [Component Factory] Registered vehicle-blinker-actuator
    [System] Loaded vehicle-blinkers.sysdef
    [Example Vehicle Blinker] Setting left blinker to 1
  • Verify QML dashboard displays correctly with responsive indicators

Troubleshooting

Frontend plugin not loading:

  • Verify DLL in <VR-Engage-Install-Dir>\plugins64\vrEngage\release\
  • Check plugin package configuration includes correct path
  • Review VR-Engage log for load errors

Backend plugin not loading:

  • Verify DLL in <VR-Engage-Install-Dir>\plugins64\vrForces\release\
  • Check VR-Forces log for dependency issues
  • Ensure component and descriptor both registered

Key press not triggering blinker: Input system failures typically result from configuration mismatches or missing action handler registration. The input configuration file (vehicleBlinkerInput.lua) must exist in the role configuration path, and the input group name "lights" must match between handler registration and keyboard.lua configuration. Key mapping verification requires confirming that ',' maps to "left-blinker" and '.' maps to "right-blinker" actions.

Blinker state not changing: State modification failures occur when entities lack required components or state properties. Ground vehicle entities (domain=1, kind=1) should include DtGroundVehicleLightingStateComponent automatically. State properties left-blinker-active and right-blinker-active require definition in role configuration through the extended state logic component.

Dashboard indicators not working: Visual feedback failures result from incorrect property bindings or QML file loading issues. The bindQmlPropertyToAttribute table must include leftBlinkerActive and rightBlinkerActive mappings to their respective state properties. QML file path verification requires confirming qmlFilename = "examples/dashboard-with-blinkers.qml" accuracy, and the QML object name must match qmlDataItemObjectName = "state" specification.


Technical Reference

File Structure

examples/vehicleBlinker/
├── README.md # This documentation
├── vehicleBlinkerFrontend/ # Frontend plugin source
│ ├── CMakeLists.txt # Build configuration
│ ├── export.h # DLL export definitions
│ ├── plugin.cxx # Frontend plugin entry point
│ ├── vehicleBlinkerControlLogic.h # Control logic header
│ └── vehicleBlinkerControlLogic.cxx # Control logic implementation
├── vehicleBlinkerSim/ # Backend plugin source
│ ├── CMakeLists.txt # Build configuration
│ ├── plugin.h # Plugin header declarations
│ ├── plugin.cxx # Backend plugin entry point
│ ├── vehicleBlinkerActuator.h # Actuator component header
│ ├── vehicleBlinkerActuator.cxx # Actuator implementation
│ ├── vehicleBlinkerDescriptor.h # Component descriptor header
│ └── vehicleBlinkerDescriptor.cxx # Descriptor implementation
└── data/ # Configuration and assets
├── simulationModelSets/examples/vehicleBlinker/
│ ├── vrfSim.opd # Simulation operation
│ ├── roles/driver-with-blinkers.lua # Role configuration
│ ├── input/vehicleBlinker/keyboard.lua # Input mapping
│ ├── vrfSim/Light Strike Vehicle MK II.entity # Entity definition
│ └── vrfSim/systems/other/vehicle-blinkers.sysdef # System definition
└── UI/HUDS/examples/vehicleBlinker/
├── dashboard-with-blinkers.qml # QML dashboard overlay
└── images/ # Dashboard indicator images
├── LeftArrowGreen.svg, LeftArrowGrey.svg
└── RightArrowGreen.svg, RightArrowGrey.svg

Key Classes

Class Base Class Purpose Location
DtVehicleBlinkerControlLogic DtEntityControlLogic Frontend input handling and UI integration vehicleBlinkerFrontend/
DtVehicleBlinkerActuator DtActuatorComponent Backend state modification and lighting control vehicleBlinkerSim/
DtVehicleBlinkerDescriptor DtActuatorComponentDescriptor Actuator configuration and port mapping vehicleBlinkerSim/

Configuration Files

File Purpose Key Content
driver-with-blinkers.lua Role configuration with blinker support Component setup, state properties, QML bindings
vehicleBlinkerInput.lua Input device mapping Keyboard bindings: ',' → left, '.' → right
vehicle-blinkers.sysdef VR-Forces system definition Joystick controller, actuator, port connections
dashboard-with-blinkers.qml Visual dashboard overlay Blinker indicators, property bindings
Light Strike Vehicle MK II.entity Entity definition Vehicle configuration with blinker system

API Methods Used

Frontend APIs:

  • DtEntityControlLogic::initialize() - Component initialization
  • DtInputLogic::loadInputConfig() - Load key/button mappings
  • DtInputLogic::addActionHandler() - Register action callback
  • JoystickMessage::create() - Create command message
  • JoystickMessage::setEntityId() - Set target entity
  • JoystickMessage::setFunctionGroup() - Set command group
  • JoystickMessage::setFunction() - Set command function name
  • JoystickMessage::setValue() - Set command value (button state)
  • DtVreMessageManager::queueMessage() - Send message to backend

Backend APIs:

  • DtActuatorComponent::createPorts() - Create input ports
  • DtActuatorComponent::addInputPort() - Register input port
  • DtBooleanInputPort::activeConnection() - Check if port connected
  • DtBooleanInputPort::newData() - Check for new message
  • DtBooleanInputPort::dataReceived() - Acknowledge message
  • DtBooleanInputPort::value() - Get port value
  • DtLocalObject::nextFrameStateProperties() - Access entity properties
  • DtStateProperties::findProperty<>() - Retrieve property by name
  • DtRwBoolean::value() - Read boolean property
  • DtRwBoolean::setValue() - Write boolean property
  • DtLocalObject::hasStateComponent<>() - Check for state component
  • DtLocalObject::getNextFrameStateComponent<>() - Get state component
  • DtGroundVehicleLightingStateComponent::setLeftIndicatorLightsOn() - Set left blinker
  • DtGroundVehicleLightingStateComponent::setRightIndicatorLightsOn() - Set right blinker

Joystick Message Structure

Field Description Example Value
Entity ID Target entity identifier Player's current entity
Function Group Command group name "Vehicle-Blinkers"
Function Specific command "LeftBlinker", "RightBlinker"
Value Command parameter 1.0 (pressed), 0.0 (released)

Input Port Mapping

Input ports connect joystick functions to actuator logic via system definition:

Port Name Joystick Function Function Group Purpose
left-blinker LeftBlinker Vehicle-Blinkers Toggles left turn signal
right-blinker RightBlinker Vehicle-Blinkers Toggles right turn signal

Connections configured in vehicle-blinkers.sysdef:

(connect joystick:vehicle-blinker-control:left-blinker vehicle-blinker-actuator:left-blinker)
(connect joystick:vehicle-blinker-control:right-blinker vehicle-blinker-actuator:right-blinker)

State Properties and QML Bindings

Entity state properties providing persistent blinker state:

Property Name Type Default QML Binding Purpose
left-blinker-active bool false leftBlinkerActive Left turn signal status
right-blinker-active bool false rightBlinkerActive Right turn signal status

Properties defined in role configuration and bound to QML dashboard for real-time visual feedback.

Build Targets

  • Frontend Plugin: vehicleBlinkerFrontendexampleVehicleBlinkerFrontend.dll
  • Backend Plugin: vehicleBlinkerSimexampleVehicleBlinkerSim.dll
  • Install Locations:
    • Frontend: plugins64/vrEngage/release/
    • Backend: plugins64/vrForces/release/

Related Documentation: