C
Qt Quick Ultralite Automotive Cluster Demo
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
#include "simulationcontroller.h"
#include "Automotive/MainModel.h"
#include "Automotive/TellTalesModel.h"
#include "statemachine.h"
#include "simulation/smfwd.h"
#include "simulation/states.h"
#include "simulation/drivestates.h"
#include "hmi_input.h"
#include <limits>
using namespace Simulation;
using namespace Automotive;
void introFinished(Machine &sm);
namespace {
// State Machine instance
Machine sm(State_Idle);
// State Instances
IntroState introState(introFinished);
DriveModeMenuState driveModeMenuState;
CarStatusMenuState carStatusMenuState;
LastTripMenuState lastTripMenuState;
NormalDriveState normalDriveState;
MediaPlayerState mediaPlayerState(State_Navi);
NaviState naviState(State_Phone);
PhoneState phoneState(State_DriveModeMenu);
SportDriveState sportDriveState;
InteractiveModeState interactiveModeState;
EndState endState(State_Intro);
} // namespace
SimulationController::SimulationController()
{
sm.registerState(State_Intro, &introState);
sm.registerState(State_NormalDrive, &normalDriveState);
sm.registerState(State_MediaPlayer, &mediaPlayerState);
sm.registerState(State_Navi, &naviState);
sm.registerState(State_Phone, &phoneState);
sm.registerState(State_DriveModeMenu, &driveModeMenuState);
sm.registerState(State_CarStatus, &carStatusMenuState);
sm.registerState(State_LastTrip, &lastTripMenuState);
sm.registerState(State_SportDrive, &sportDriveState);
sm.registerState(State_InteractiveMode, &interactiveModeState);
sm.registerState(State_End, &endState);
}
void SimulationController::start()
{
sm.changeState(State_Intro, Layer_Gauges);
sm.changeState(State_MediaPlayer, Layer_Menu, 5000);
}
void SimulationController::startInteractiveMode()
{
if (sm.getCurrentStateId(Layer_Menu) != State_InteractiveMode) {
sm.dismissUpdate(Layer_Menu);
sm.dismissScheduledStateChanges(Layer_Menu);
sm.changeState(State_InteractiveMode, Layer_Menu);
}
}
void SimulationController::stopInteractiveMode()
{
sm.requestUpdate(0, false, Layer_Menu);
}
void SimulationController::switchToNormalMode()
{
sm.changeState(State_NormalDrive, Layer_Gauges);
}
void SimulationController::switchToSportMode()
{
sm.changeState(State_SportDrive, Layer_Gauges);
}
void introFinished(Machine &sm)
{
sm.changeState(State_NormalDrive, Layer_Gauges);
sm.changeState(State_MediaPlayer, Layer_Menu);
if (MainModel::instance().forceInteractiveMode.value()) {
sm.dismissUpdate(Layer_Menu);
sm.dismissScheduledStateChanges(Layer_Menu);
sm.changeState(State_InteractiveMode, Layer_Menu);
}
}
extern "C" {
void qul_application_force_interactive_mode(bool force_interactive_mode)
{
MainModel::instance().forceInteractiveMode.setValue(force_interactive_mode);
}
static bool firstOdoUpdate = true;
void qul_application_show_simulated_drive_data(bool simulated_drive_data)
{
static float initialOdo = 0.0f;
static bool restoreInitialOdo = false;
if (simulated_drive_data != MainModel::instance().showSimulatedDriveData.value()) {
// Restore initial ODO value when switching back to simulated drive data
if (simulated_drive_data) {
if (restoreInitialOdo) {
MainModel::instance().initialOdo.setValue(initialOdo);
restoreInitialOdo = false;
}
} else {
initialOdo = MainModel::instance().initialOdo.value();
firstOdoUpdate = true;
restoreInitialOdo = true;
}
MainModel::instance().showSimulatedDriveData.setValue(simulated_drive_data);
}
}
void qul_application_set_speed(float speed)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
MainModel::instance().speed.setValue(speed);
}
}
void qul_application_set_rpm(float rpm)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
MainModel::instance().rpm.setValue(rpm);
}
}
void qul_application_set_gear(int gear)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
// 0 = parking gear
// 1-6 = drive gear
MainModel::instance().gear.setValue(gear);
}
}
void qul_application_set_odo(float odo)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
if (firstOdoUpdate) {
MainModel::instance().initialOdo.setValue(odo);
firstOdoUpdate = false;
}
MainModel::instance().odo.setValue(odo);
}
}
void qul_application_set_range(int range)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
MainModel::instance().range.setValue(range);
}
}
void qul_application_set_battery_level(float battery_level)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
MainModel::instance().batteryLevel.setValue(battery_level);
}
}
void qul_application_set_fuel_level(float fuel_level)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
MainModel::instance().fuelLevel.setValue(fuel_level);
}
}
void qul_application_set_coolant_temp(float coolant_temp)
{
if (!MainModel::instance().showSimulatedDriveData.value()) {
MainModel::instance().temp.setValue(coolant_temp);
}
}
void qul_application_set_lane_assistant_enabled(bool enabled)
{
MainModel::instance().laneAssistEnabled.setValue(enabled);
}
void qul_application_show_simulated_light_indicators(bool simulated_light_indicators)
{
TellTalesModel::instance().showSimulatedLightIndicators.setValue(simulated_light_indicators);
}
void qul_application_set_left_blinker_on(bool left_blinker_on)
{
if (!TellTalesModel::instance().showSimulatedLightIndicators.value()) {
TellTalesModel::instance().turnLeftBlinking.setValue(left_blinker_on);
}
}
void qul_application_set_right_blinker_on(bool right_blinker_on)
{
if (!TellTalesModel::instance().showSimulatedLightIndicators.value()) {
TellTalesModel::instance().turnRightBlinking.setValue(right_blinker_on);
}
}
void qul_application_set_parking_lights_on(bool parking_lights_on)
{
if (!TellTalesModel::instance().showSimulatedLightIndicators.value()) {
TellTalesModel::instance().parkingLightsActive.setValue(parking_lights_on);
}
}
void qul_application_set_low_beam_headlights_on(bool low_beam_headlights_on)
{
if (!TellTalesModel::instance().showSimulatedLightIndicators.value()) {
TellTalesModel::instance().lowBeamHeadlightsActive.setValue(low_beam_headlights_on);
}
}
void qul_application_control_navigate_up(bool pressed)
{
const HMIInputEvent event = HMIInputEvent(HMIInputEvent::HMI_BTN_UP,
pressed ? HMIInputEvent::KeyPress : HMIInputEvent::KeyRelease);
HMIInput::instance().onEvent(event);
}
void qul_application_control_navigate_down(bool pressed)
{
const HMIInputEvent event = HMIInputEvent(HMIInputEvent::HMI_BTN_DOWN,
pressed ? HMIInputEvent::KeyPress : HMIInputEvent::KeyRelease);
HMIInput::instance().onEvent(event);
}
void qul_application_control_navigate_left(bool pressed)
{
const HMIInputEvent event = HMIInputEvent(HMIInputEvent::HMI_BTN_LEFT,
pressed ? HMIInputEvent::KeyPress : HMIInputEvent::KeyRelease);
HMIInput::instance().onEvent(event);
}
void qul_application_control_navigate_right(bool pressed)
{
const HMIInputEvent event = HMIInputEvent(HMIInputEvent::HMI_BTN_RIGHT,
pressed ? HMIInputEvent::KeyPress : HMIInputEvent::KeyRelease);
HMIInput::instance().onEvent(event);
}
void qul_application_control_previous_page(bool pressed)
{
const HMIInputEvent event = HMIInputEvent(HMIInputEvent::HMI_KNOB_TURN_LEFT,
pressed ? HMIInputEvent::KeyPress : HMIInputEvent::KeyRelease);
HMIInput::instance().onEvent(event);
}
void qul_application_control_next_page(bool pressed)
{
const HMIInputEvent event = HMIInputEvent(HMIInputEvent::HMI_KNOB_TURN_RIGHT,
pressed ? HMIInputEvent::KeyPress : HMIInputEvent::KeyRelease);
HMIInput::instance().onEvent(event);
}
void qul_application_control_validate(bool pressed)
{
const HMIInputEvent event = HMIInputEvent(HMIInputEvent::HMI_KNOB_CENTER,
pressed ? HMIInputEvent::KeyPress : HMIInputEvent::KeyRelease);
HMIInput::instance().onEvent(event);
}
}