Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VT]: add a numeric value tracker and updater for working sets of a VT client #405

Merged
merged 4 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions examples/virtual_terminal/version3_object_pool/main.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#include "isobus/hardware_integration/available_can_drivers.hpp"
#include "isobus/hardware_integration/can_hardware_interface.hpp"
#include "isobus/isobus/can_general_parameter_group_numbers.hpp"
#include "isobus/isobus/can_network_manager.hpp"
#include "isobus/isobus/can_partnered_control_function.hpp"
#include "isobus/isobus/can_stack_logger.hpp"
#include "isobus/isobus/isobus_virtual_terminal_client.hpp"
#include "isobus/isobus/isobus_virtual_terminal_client_update_helper.hpp"
#include "isobus/utility/iop_file_interface.hpp"

#include "console_logger.cpp"
Expand All @@ -17,7 +17,8 @@
#include <memory>

//! It is discouraged to use global variables, but it is done here for simplicity.
static std::shared_ptr<isobus::VirtualTerminalClient> TestVirtualTerminalClient = nullptr;
static std::shared_ptr<isobus::VirtualTerminalClient> virtualTerminalClient = nullptr;
static std::shared_ptr<isobus::VirtualTerminalClientUpdateHelper> virtualTerminalUpdateHelper = nullptr;
static std::atomic_bool running = { true };

void signal_handler(int)
Expand All @@ -28,35 +29,34 @@ void signal_handler(int)
// This callback will provide us with event driven notifications of button presses from the stack
void handleVTKeyEvents(const isobus::VirtualTerminalClient::VTKeyEvent &event)
{
static std::uint32_t exampleNumberOutput = 214748364; // In the object pool the output number has an offset of -214748364 so we use this to represent 0.

switch (event.keyEvent)
{
case isobus::VirtualTerminalClient::KeyActivationCode::ButtonUnlatchedOrReleased:
case isobus::VirtualTerminalClient::KeyActivationCode::ButtonStillHeld:
{
switch (event.objectID)
{
case Plus_Button:
{
TestVirtualTerminalClient->send_change_numeric_value(ButtonExampleNumber_VarNum, ++exampleNumberOutput);
virtualTerminalUpdateHelper->increase_numeric_value(ButtonExampleNumber_VarNum);
}
break;

case Minus_Button:
{
TestVirtualTerminalClient->send_change_numeric_value(ButtonExampleNumber_VarNum, --exampleNumberOutput);
virtualTerminalUpdateHelper->decrease_numeric_value(ButtonExampleNumber_VarNum);
}
break;

case alarm_SoftKey:
{
TestVirtualTerminalClient->send_change_active_mask(example_WorkingSet, example_AlarmMask);
virtualTerminalClient->send_change_active_mask(example_WorkingSet, example_AlarmMask);
}
break;

case acknowledgeAlarm_SoftKey:
{
TestVirtualTerminalClient->send_change_active_mask(example_WorkingSet, mainRunscreen_DataMask);
virtualTerminalClient->send_change_active_mask(example_WorkingSet, mainRunscreen_DataMask);
}
break;

Expand Down Expand Up @@ -138,19 +138,23 @@ int main()
auto TestInternalECU = isobus::InternalControlFunction::create(TestDeviceNAME, 0x1C, 0);
auto TestPartnerVT = isobus::PartneredControlFunction::create(0, vtNameFilters);

TestVirtualTerminalClient = std::make_shared<isobus::VirtualTerminalClient>(TestPartnerVT, TestInternalECU);
TestVirtualTerminalClient->set_object_pool(0, testPool.data(), testPool.size(), objectPoolHash);
auto softKeyListener = TestVirtualTerminalClient->add_vt_soft_key_event_listener(handleVTKeyEvents);
auto buttonListener = TestVirtualTerminalClient->add_vt_button_event_listener(handleVTKeyEvents);
TestVirtualTerminalClient->initialize(true);
virtualTerminalClient = std::make_shared<isobus::VirtualTerminalClient>(TestPartnerVT, TestInternalECU);
virtualTerminalClient->set_object_pool(0, testPool.data(), testPool.size(), objectPoolHash);
auto softKeyListener = virtualTerminalClient->add_vt_soft_key_event_listener(handleVTKeyEvents);
auto buttonListener = virtualTerminalClient->add_vt_button_event_listener(handleVTKeyEvents);
virtualTerminalClient->initialize(true);

virtualTerminalUpdateHelper = std::make_shared<isobus::VirtualTerminalClientUpdateHelper>(virtualTerminalClient);
virtualTerminalUpdateHelper->add_tracked_numeric_value(ButtonExampleNumber_VarNum, 214748364); // In the object pool the output number has an offset of -214748364 so we use this to represent 0.
virtualTerminalUpdateHelper->initialize();

while (running)
{
// CAN stack runs in other threads. Do nothing forever.
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

TestVirtualTerminalClient->terminate();
virtualTerminalClient->terminate();
isobus::CANHardwareInterface::stop();
return 0;
}
4 changes: 4 additions & 0 deletions isobus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ set(ISOBUS_SRC
"isobus_speed_distance_messages.cpp"
"isobus_maintain_power_interface.cpp"
"isobus_virtual_terminal_objects.cpp"
"isobus_virtual_terminal_client_state_tracker.cpp"
"isobus_virtual_terminal_client_update_helper.cpp"
"nmea2000_message_definitions.cpp"
"nmea2000_message_interface.cpp"
"can_message_data.cpp")
Expand Down Expand Up @@ -84,6 +86,8 @@ set(ISOBUS_INCLUDE
"isobus_speed_distance_messages.hpp"
"isobus_maintain_power_interface.hpp"
"isobus_virtual_terminal_objects.hpp"
"isobus_virtual_terminal_client_state_tracker.hpp"
"isobus_virtual_terminal_client_update_helper.hpp"
"nmea2000_message_definitions.hpp"
"nmea2000_message_interface.hpp"
"can_message_data.hpp")
Expand Down
6 changes: 6 additions & 0 deletions isobus/include/isobus/isobus/can_message.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define CAN_MESSAGE_HPP

#include "isobus/isobus/can_control_function.hpp"
#include "isobus/isobus/can_general_parameter_group_numbers.hpp"
#include "isobus/isobus/can_identifier.hpp"
#include "isobus/utility/data_span.hpp"

Expand Down Expand Up @@ -103,6 +104,11 @@ namespace isobus
/// @returns The identifier of the message
CANIdentifier get_identifier() const;

/// @brief Compares the identifier of the message to the parameter group number (PGN) supplied
/// @param[in] parameterGroupNumber The parameter group number to compare to
/// @returns True if the message identifier matches the parameter group number, false otherwise
bool is_parameter_group_number(CANLibParameterGroupNumber parameterGroupNumber) const;

/// @brief Returns the CAN channel index associated with the message
/// @returns The CAN channel index associated with the message
std::uint8_t get_can_port_index() const;
Expand Down
156 changes: 78 additions & 78 deletions isobus/include/isobus/isobus/isobus_virtual_terminal_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,84 @@ namespace isobus
class VirtualTerminalClient
{
public:
/// @brief Enumerates the multiplexor byte values for VT commands
enum class Function : std::uint8_t
{
SoftKeyActivationMessage = 0x00,
ButtonActivationMessage = 0x01,
PointingEventMessage = 0x02,
VTSelectInputObjectMessage = 0x03,
VTESCMessage = 0x04,
VTChangeNumericValueMessage = 0x05,
VTChangeActiveMaskMessage = 0x06,
VTChangeSoftKeyMaskMessage = 0x07,
VTChangeStringValueMessage = 0x08,
VTOnUserLayoutHideShowMessage = 0x09,
VTControlAudioSignalTerminationMessage = 0x0A,
ObjectPoolTransferMessage = 0x11,
EndOfObjectPoolMessage = 0x12,
AuxiliaryAssignmentTypeOneCommand = 0x20,
AuxiliaryInputTypeOneStatus = 0x21,
PreferredAssignmentCommand = 0x22,
AuxiliaryInputTypeTwoMaintenanceMessage = 0x23,
AuxiliaryAssignmentTypeTwoCommand = 0x24,
AuxiliaryInputStatusTypeTwoEnableCommand = 0x25,
AuxiliaryInputTypeTwoStatusMessage = 0x26,
AuxiliaryCapabilitiesRequest = 0x27,
SelectActiveWorkingSet = 0x90,
ESCCommand = 0x92,
HideShowObjectCommand = 0xA0,
EnableDisableObjectCommand = 0xA1,
SelectInputObjectCommand = 0xA2,
ControlAudioSignalCommand = 0xA3,
SetAudioVolumeCommand = 0xA4,
ChangeChildLocationCommand = 0xA5,
ChangeSizeCommand = 0xA6,
ChangeBackgroundColourCommand = 0xA7,
ChangeNumericValueCommand = 0xA8,
ChangeEndPointCommand = 0xA9,
ChangeFontAttributesCommand = 0xAA,
ChangeLineAttributesCommand = 0xAB,
ChangeFillAttributesCommand = 0xAC,
ChangeActiveMaskCommand = 0xAD,
ChangeSoftKeyMaskCommand = 0xAE,
ChangeAttributeCommand = 0xAF,
ChangePriorityCommand = 0xB0,
ChangeListItemCommand = 0xB1,
DeleteObjectPoolCommand = 0xB2,
ChangeStringValueCommand = 0xB3,
ChangeChildPositionCommand = 0xB4,
ChangeObjectLabelCommand = 0xB5,
ChangePolygonPointCommand = 0xB6,
ChangePolygonScaleCommand = 0xB7,
GraphicsContextCommand = 0xB8,
GetAttributeValueMessage = 0xB9,
SelectColourMapCommand = 0xBA,
IdentifyVTMessage = 0xBB,
ExecuteExtendedMacroCommand = 0xBC,
LockUnlockMaskCommand = 0xBD,
ExecuteMacroCommand = 0xBE,
GetMemoryMessage = 0xC0,
GetSupportedWidecharsMessage = 0xC1,
GetNumberOfSoftKeysMessage = 0xC2,
GetTextFontDataMessage = 0xC3,
GetWindowMaskDataMessage = 0xC4,
GetSupportedObjectsMessage = 0xC5,
GetHardwareMessage = 0xC7,
StoreVersionCommand = 0xD0,
LoadVersionCommand = 0xD1,
DeleteVersionCommand = 0xD2,
ExtendedGetVersionsMessage = 0xD3,
ExtendedStoreVersionCommand = 0xD4,
ExtendedLoadVersionCommand = 0xD5,
ExtendedDeleteVersionCommand = 0xD6,
GetVersionsMessage = 0xDF,
GetVersionsResponse = 0xE0,
UnsupportedVTFunctionMessage = 0xFD,
VTStatusMessage = 0xFE,
WorkingSetMaintenanceMessage = 0xFF
};

/// @brief Enumerates the states that can be sent with a hide/show object command
enum class HideShowObjectCommand : std::uint8_t
{
Expand Down Expand Up @@ -1197,84 +1275,6 @@ namespace isobus
LanguageCommandInterface languageCommandInterface;

protected:
/// @brief Enumerates the multiplexor byte values for VT commands
enum class Function : std::uint8_t
{
SoftKeyActivationMessage = 0x00,
ButtonActivationMessage = 0x01,
PointingEventMessage = 0x02,
VTSelectInputObjectMessage = 0x03,
VTESCMessage = 0x04,
VTChangeNumericValueMessage = 0x05,
VTChangeActiveMaskMessage = 0x06,
VTChangeSoftKeyMaskMessage = 0x07,
VTChangeStringValueMessage = 0x08,
VTOnUserLayoutHideShowMessage = 0x09,
VTControlAudioSignalTerminationMessage = 0x0A,
ObjectPoolTransferMessage = 0x11,
EndOfObjectPoolMessage = 0x12,
AuxiliaryAssignmentTypeOneCommand = 0x20,
AuxiliaryInputTypeOneStatus = 0x21,
PreferredAssignmentCommand = 0x22,
AuxiliaryInputTypeTwoMaintenanceMessage = 0x23,
AuxiliaryAssignmentTypeTwoCommand = 0x24,
AuxiliaryInputStatusTypeTwoEnableCommand = 0x25,
AuxiliaryInputTypeTwoStatusMessage = 0x26,
AuxiliaryCapabilitiesRequest = 0x27,
SelectActiveWorkingSet = 0x90,
ESCCommand = 0x92,
HideShowObjectCommand = 0xA0,
EnableDisableObjectCommand = 0xA1,
SelectInputObjectCommand = 0xA2,
ControlAudioSignalCommand = 0xA3,
SetAudioVolumeCommand = 0xA4,
ChangeChildLocationCommand = 0xA5,
ChangeSizeCommand = 0xA6,
ChangeBackgroundColourCommand = 0xA7,
ChangeNumericValueCommand = 0xA8,
ChangeEndPointCommand = 0xA9,
ChangeFontAttributesCommand = 0xAA,
ChangeLineAttributesCommand = 0xAB,
ChangeFillAttributesCommand = 0xAC,
ChangeActiveMaskCommand = 0xAD,
ChangeSoftKeyMaskCommand = 0xAE,
ChangeAttributeCommand = 0xAF,
ChangePriorityCommand = 0xB0,
ChangeListItemCommand = 0xB1,
DeleteObjectPoolCommand = 0xB2,
ChangeStringValueCommand = 0xB3,
ChangeChildPositionCommand = 0xB4,
ChangeObjectLabelCommand = 0xB5,
ChangePolygonPointCommand = 0xB6,
ChangePolygonScaleCommand = 0xB7,
GraphicsContextCommand = 0xB8,
GetAttributeValueMessage = 0xB9,
SelectColourMapCommand = 0xBA,
IdentifyVTMessage = 0xBB,
ExecuteExtendedMacroCommand = 0xBC,
LockUnlockMaskCommand = 0xBD,
ExecuteMacroCommand = 0xBE,
GetMemoryMessage = 0xC0,
GetSupportedWidecharsMessage = 0xC1,
GetNumberOfSoftKeysMessage = 0xC2,
GetTextFontDataMessage = 0xC3,
GetWindowMaskDataMessage = 0xC4,
GetSupportedObjectsMessage = 0xC5,
GetHardwareMessage = 0xC7,
StoreVersionCommand = 0xD0,
LoadVersionCommand = 0xD1,
DeleteVersionCommand = 0xD2,
ExtendedGetVersionsMessage = 0xD3,
ExtendedStoreVersionCommand = 0xD4,
ExtendedLoadVersionCommand = 0xD5,
ExtendedDeleteVersionCommand = 0xD6,
GetVersionsMessage = 0xDF,
GetVersionsResponse = 0xE0,
UnsupportedVTFunctionMessage = 0xFD,
VTStatusMessage = 0xFE,
WorkingSetMaintenanceMessage = 0xFF
};

/// @brief Enumerates the command types for graphics context objects
enum class GraphicsContextSubCommandID : std::uint8_t
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
//================================================================================================
/// @file isobus_virtual_terminal_client_state_tracker.hpp
///
/// @brief A helper class to track the state of an active working set.
/// @author Daan Steenbergen
///
/// @copyright 2023 The Open-Agriculture Developers
//================================================================================================

#ifndef ISOBUS_VIRTUAL_TERMINAL_CLIENT_STATE_TRACKER_HPP
#define ISOBUS_VIRTUAL_TERMINAL_CLIENT_STATE_TRACKER_HPP

#include "isobus/isobus/can_control_function.hpp"
#include "isobus/isobus/can_message.hpp"

#include <map>
#include <vector>

namespace isobus
{
/// @brief A helper class to update and track the state of an active working set.
/// @details The state is from the client's perspective. It might not be the same
/// as the state of the server, but tries to be as close as possible.
class VirtualTerminalClientStateTracker
{
public:
/// @brief The constructor to track the state of an active working set provided by a client.
/// @param[in] client The control function of the client. May be external.
explicit VirtualTerminalClientStateTracker(std::shared_ptr<ControlFunction> client);

/// @brief The destructor.
~VirtualTerminalClientStateTracker();

/// @brief Initializes the state tracker.
void initialize();

/// @brief Terminate the state tracker.
void terminate();

//! TODO: void initialize_with_defaults(ObjectPool &objectPool);

/// @brief Adds a numeric value to track.
/// @param[in] objectId The object id of the numeric value to track.
/// @param[in] initialValue The initial value of the numeric value to track.
void add_tracked_numeric_value(std::uint16_t objectId, std::uint32_t initialValue = 0);

/// @brief Removes a numeric value from tracking.
/// @param[in] objectId The object id of the numeric value to remove from tracking.
void remove_tracked_numeric_value(std::uint16_t objectId);

/// @brief Gets the current numeric value of a tracked object.
/// @param[in] objectId The object id of the numeric value to get.
/// @return The current numeric value of the tracked object.
std::uint32_t get_numeric_value(std::uint16_t objectId) const;

protected:
std::shared_ptr<ControlFunction> client; ///< The control function of the virtual terminal client to track.

//! TODO: std::map<std::uint16_t, bool> shownStates; ///< Holds the 'hide/show' state of tracked objects.
//! TODO: std::map<std::uint16_t, bool> enabledStates; ///< Holds the 'enable/disable' state of tracked objects.
//! TODO: std::map<std::uint16_t, bool> selectedStates; ///< Holds the 'selected for input' state of tracked objects.
//! TODO: add current audio signal state
//! TODO: std::uint8_t audioVolumeState; ///< Holds the current audio volume.
//! TODO: std::map<std::uint16_t, std::pair<std::uint16_t, std::uint16_t>> positionStates; ///< Holds the 'position (x,y)' state of tracked objects.
//! TODO: std::map<std::uint16_t, std::pair<std::uint16_t, std::uint16_t>> sizeStates; ///< Holds the 'size (width,height)' state of tracked objects.
//! TODO: std::map<std::uint16_t, std::uint8_t> backgroundColourStates; ///< Holds the 'background colour' state of tracked objects.
std::map<std::uint16_t, std::uint32_t> numericValueStates; ///< Holds the 'numeric value' state of tracked objects.
//! TODO: std::map<std::uint16_t, std::string> stringValueStates; ///< Holds the 'string value' state of tracked objects.
//! TODO: std::map<std::uint16_t, std::uint8_t> endPointStates; ///< Holds the 'end point' state of tracked objects.
//! TODO: add font attribute state
//! TODO: add line attribute state
//! TODO: add fill attribute state
std::uint16_t currentActiveMask; ///< Holds the currently active mask.
//! TODO: std::uint16_t currentWorkingSet; ///< Holds the working set of the current active mask.
//! TODO: std::map<std::uint16_t, std::uint16_t> softKeyMasks; ///< Holds the data/alarms masks with their associated soft keys masks for tracked objects.
//! TODO: std::map<std::uint16_t, std::pair<std::uint8_t, std::uint32_t>> attributeStates; ///< Holds the 'attribute' state of tracked objects.
//! TODO: std::map<std::uint16_t, std::uint8_t> alarmMaskPrioritiesStates; ///< Holds the 'alarm mask priority' state of tracked objects.
//! TODO: std::map<std::uint16_t, std::pair<std::uint8_t, std::uint16_t>> listItemStates; ///< Holds the 'list item' state of tracked objects.
//! TODO: add lock/unlock mask state
//! TODO: add object label state
//! TODO: add polygon point state
//! TODO: add polygon scale state
//! TODO: add graphics context state
//! TODO: std::uint16_t currentColourMap; ///< Holds the current colour map/palette object.

private:
/// @brief Processes a received message.
/// @param[in] message The received message.
/// @param[in] parentPointer The pointer to the parent object, which should be the VirtualTerminalClientStateTracker.
static void process_rx_message(const CANMessage &message, void *parentPointer);

/// @brief Processes a received message.
/// @param[in] message The received message.
void process_rx_message(const CANMessage &message);
};
} // namespace isobus

#endif // ISOBUS_VIRTUAL_TERMINAL_CLIENT_STATE_TRACKER_HPP
Loading
Loading