Skip to content

Commit

Permalink
refactor(vt): direct conversion of float to byte representation and v…
Browse files Browse the repository at this point in the history
…ice-versa
  • Loading branch information
GwnDaan committed Jan 8, 2025
1 parent 753e477 commit b6e5bb5
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 99 deletions.
14 changes: 7 additions & 7 deletions examples/seeder_example/vt_application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,13 @@ bool SeederVtApplication::initialize()
VTClientUpdateHelper.add_tracked_numeric_value(currentAlarms2_ObjPtr);

// Track the attribute values we want to update
VTClientUpdateHelper.add_tracked_attribute_float(speed_OutNum, 8, 0.0036f);
VTClientUpdateHelper.add_tracked_attribute(section1Status_OutRect, 5, solidGreen_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section2Status_OutRect, 5, solidYellow_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section3Status_OutRect, 5, solidRed_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section4Status_OutRect, 5, solidRed_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section5Status_OutRect, 5, solidYellow_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section6Status_OutRect, 5, solidGreen_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(speed_OutNum, 8, 0.0036f);
VTClientUpdateHelper.add_tracked_attribute(section1Status_OutRect, 5, (std::uint32_t)solidGreen_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section2Status_OutRect, 5, (std::uint32_t)solidYellow_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section3Status_OutRect, 5, (std::uint32_t)solidRed_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section4Status_OutRect, 5, (std::uint32_t)solidRed_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section5Status_OutRect, 5, (std::uint32_t)solidYellow_FillAttr);
VTClientUpdateHelper.add_tracked_attribute(section6Status_OutRect, 5, (std::uint32_t)solidGreen_FillAttr);

VTClientUpdateHelper.initialize();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ namespace isobus
/// @param[in] objectId The object id of the attribute to track.
/// @param[in] attribute The attribute to track. Make sure it's a float attribute!
/// @param[in] initialValue The initial value of the attribute to track.
void add_tracked_attribute_float(std::uint16_t objectId, std::uint8_t attribute, float initialValue = 0.0f);
void add_tracked_attribute(std::uint16_t objectId, std::uint8_t attribute, float initialValue = 0.0f);

/// @brief Removes an attribute from tracking.
/// @param[in] objectId The object id of the attribute to remove from tracking.
Expand All @@ -116,11 +116,11 @@ namespace isobus
/// @return The value of the attribute of the tracked object.
std::uint32_t get_attribute(std::uint16_t objectId, std::uint8_t attribute) const;

/// @brief Get the value of an attribute of a tracked object, if you tracked it with add_tracked_attribute_float.
/// @brief Get the value of an attribute of a tracked object as a float.
/// @param[in] objectId The object id of the attribute to get.
/// @param[in] attribute The attribute to get.
/// @return The value of the attribute of the tracked object.
float get_attribute_float(std::uint16_t objectId, std::uint8_t attribute) const;
float get_attribute_as_float(std::uint16_t objectId, std::uint8_t attribute) const;

protected:
std::shared_ptr<ControlFunction> client; ///< The control function of the virtual terminal client to track.
Expand All @@ -146,7 +146,6 @@ namespace isobus
std::uint8_t activeWorkingSetAddress = NULL_CAN_ADDRESS; ///< Holds the address of the control function that currently has
std::map<std::uint16_t, std::uint16_t> softKeyMasks; ///< Holds the data/alarms masks with their associated soft keys masks for tracked objects.
std::map<std::uint16_t, std::map<std::uint8_t, std::uint32_t>> attributeStates; ///< Holds the 'attribute' state of tracked objects.
std::map<std::uint16_t, std::map<std::uint8_t, float>> floatAttributeStates; ///< Holds the 'attribute' state of tracked objects, for attributes that use floats (scale, for example).
//! 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
Expand Down
19 changes: 1 addition & 18 deletions isobus/src/isobus_virtual_terminal_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,24 +545,7 @@ namespace isobus

bool VirtualTerminalClient::send_change_attribute(std::uint16_t objectID, std::uint8_t attributeID, float value)
{
static_assert(sizeof(float) == 4, "Float must be 4 bytes");
std::array<std::uint8_t, sizeof(float)> floatBytes = { 0 };
memcpy(floatBytes.data(), &value, sizeof(float));

if (is_big_endian())
{
std::reverse(floatBytes.begin(), floatBytes.end());
}

const std::vector<std::uint8_t> buffer = { static_cast<std::uint8_t>(Function::ChangeAttributeCommand),
static_cast<std::uint8_t>(objectID & 0xFF),
static_cast<std::uint8_t>(objectID >> 8),
attributeID,
floatBytes[0],
floatBytes[1],
floatBytes[2],
floatBytes[3] };
return queue_command(buffer);
return send_change_attribute(objectID, attributeID, float_to_little_endian(value));
}

bool VirtualTerminalClient::send_change_priority(std::uint16_t alarmMaskObjectID, AlarmMaskPriority priority)
Expand Down
48 changes: 5 additions & 43 deletions isobus/src/isobus_virtual_terminal_client_state_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "isobus/isobus/can_network_manager.hpp"
#include "isobus/isobus/can_stack_logger.hpp"
#include "isobus/isobus/isobus_virtual_terminal_client.hpp"
#include "isobus/utility/platform_endianness.hpp"

#include <algorithm>

Expand Down Expand Up @@ -160,22 +161,9 @@ namespace isobus
attributeMap[attribute] = initialValue;
}

void VirtualTerminalClientStateTracker::add_tracked_attribute_float(std::uint16_t objectId, std::uint8_t attribute, float initialValue)
void VirtualTerminalClientStateTracker::add_tracked_attribute(std::uint16_t objectId, std::uint8_t attribute, float initialValue)
{
if (floatAttributeStates.find(objectId) == floatAttributeStates.end())
{
floatAttributeStates[objectId] = {};
}

auto &attributeMap = floatAttributeStates.at(objectId);
if ((attributeMap.find(attribute) != attributeMap.end()) ||
(floatAttributeStates.find(attribute) != floatAttributeStates.end()))
{
LOG_WARNING("[VTStateHelper] add_tracked_attribute: attribute '%lu' of objectId '%lu' already tracked", attribute, objectId);
return;
}

attributeMap[attribute] = initialValue;
return add_tracked_attribute(objectId, attribute, float_to_little_endian(initialValue));
}

void VirtualTerminalClientStateTracker::remove_tracked_attribute(std::uint16_t objectId, std::uint8_t attribute)
Expand Down Expand Up @@ -214,35 +202,9 @@ namespace isobus
return attributeMap.at(attribute);
}

float VirtualTerminalClientStateTracker::get_attribute_float(std::uint16_t objectId, std::uint8_t attribute) const
float VirtualTerminalClientStateTracker::get_attribute_as_float(std::uint16_t objectId, std::uint8_t attribute) const
{
if (attributeStates.find(objectId) == attributeStates.end())
{
if (floatAttributeStates.find(objectId) == floatAttributeStates.end())
{
LOG_WARNING("[VTStateHelper] get_attribute_float: objectId '%lu' has no tracked float attributes", objectId);
return 0.0f;
}

const auto &floatAttributeMap = floatAttributeStates.at(objectId);
if (floatAttributeStates.find(attribute) == floatAttributeStates.end())
{
LOG_WARNING("[VTStateHelper] get_attribute_float: float attribute '%lu' of objectId '%lu' not tracked", attribute, objectId);
return 0;
}
return floatAttributeMap.at(attribute);
}
else
{
const auto &attributeMap = attributeStates.at(objectId);

if (attributeMap.find(attribute) != attributeMap.end())
{
LOG_WARNING("[VTStateHelper] get_attribute_float: attribute '%lu' of objectId '%lu' was tracked as an integer. You are calling the wrong function to get its value!", attribute, objectId);
return static_cast<float>(attributeMap.at(attribute));
}
}
return 0.0f;
return little_endian_to_float(get_attribute(objectId, attribute));
}

void VirtualTerminalClientStateTracker::cache_active_mask(std::uint16_t maskId)
Expand Down
28 changes: 2 additions & 26 deletions isobus/src/isobus_virtual_terminal_client_update_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "isobus/isobus/isobus_virtual_terminal_client_update_helper.hpp"

#include "isobus/isobus/can_stack_logger.hpp"
#include "isobus/utility/platform_endianness.hpp"

namespace isobus
{
Expand Down Expand Up @@ -174,32 +175,7 @@ namespace isobus

bool VirtualTerminalClientUpdateHelper::set_attribute(std::uint16_t objectId, std::uint8_t attribute, float value)
{
if (nullptr == client)
{
LOG_ERROR("[VTStateHelper] set_attribute: client is nullptr");
return false;
}
if (floatAttributeStates.find(objectId) == floatAttributeStates.end())
{
LOG_ERROR("[VTStateHelper] set_attribute: objectId %lu has no float attributes tracked", objectId);
return false;
}
if (floatAttributeStates.at(objectId).find(attribute) == floatAttributeStates.at(objectId).end())
{
LOG_WARNING("[VTStateHelper] set_attribute: float attribute %lu of objectId %lu not tracked", attribute, objectId);
return false;
}
if (floatAttributeStates.at(objectId).at(attribute) == value)
{
return true;
}

bool success = vtClient->send_change_attribute(objectId, attribute, value);
if (success)
{
floatAttributeStates[objectId][attribute] = value;
}
return success;
return set_attribute(objectId, attribute, float_to_little_endian(value));
}

} // namespace isobus
12 changes: 12 additions & 0 deletions utility/include/isobus/utility/platform_endianness.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef PLATFORM_ENDIANNESS_HPP
#define PLATFORM_ENDIANNESS_HPP

#include <cstdint>

namespace isobus
{
/// @brief Returns if the platform is little endian
Expand All @@ -20,6 +22,16 @@ namespace isobus
/// @returns `true` if the platform is big endian, otherwise false
bool is_big_endian();

/// @brief Convert a float attribute to a little endian byte representation
/// @param[in] value The float value to convert
/// @returns The float value as a little endian byte representation
std::uint32_t float_to_little_endian(float value);

/// @brief Convert a little endian byte representation to a float attribute
/// @param[in] byteRepresentation The little endian byte representation to convert
/// @returns The float value
float little_endian_to_float(std::uint32_t byteRepresentation);

} // namespace isobus

#endif //PLATFORM_ENDIANNESS_HPP
36 changes: 35 additions & 1 deletion utility/src/platform_endianness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "isobus/utility/platform_endianness.hpp"

#include <cstdint>
#include <cstring>

namespace isobus
{
Expand All @@ -24,4 +25,37 @@ namespace isobus
{
return (false == is_little_endian());
}
} // namespace isobus

std::uint32_t float_to_little_endian(float value)
{
static_assert(sizeof(float) == 4, "Float must be 4 bytes");
std::uint32_t byteRepresentation;
std::memcpy(&byteRepresentation, &value, sizeof(float));
if (is_big_endian())
{
byteRepresentation =
((byteRepresentation & 0x000000FF) << 24) |
((byteRepresentation & 0x0000FF00) << 8) |
((byteRepresentation & 0x00FF0000) >> 8) |
((byteRepresentation & 0xFF000000) >> 24);
}
return byteRepresentation;
}

float little_endian_to_float(std::uint32_t byteRepresentation)
{
static_assert(sizeof(float) == 4, "Float must be 4 bytes");
if (is_big_endian())
{
byteRepresentation =
((byteRepresentation & 0x000000FF) << 24) |
((byteRepresentation & 0x0000FF00) << 8) |
((byteRepresentation & 0x00FF0000) >> 8) |
((byteRepresentation & 0xFF000000) >> 24);
}
float value;
std::memcpy(&value, &byteRepresentation, sizeof(float));
return value;
}
}
// namespace isobus

0 comments on commit b6e5bb5

Please sign in to comment.