Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#ifndef ISOBUS_TASK_CONTROLLER_CLIENT_OBJECTS_HPP
#define ISOBUS_TASK_CONTROLLER_CLIENT_OBJECTS_HPP

#include "isobus/utility/data_span.hpp"

#include <array>
#include <cstdint>
#include <string>
Expand All @@ -22,11 +24,11 @@ namespace isobus
/// @brief Enumerates the different kinds of DDOP objects
enum class ObjectTypes
{
Device, ///< The root object. Each device shall have one single Device
DeviceElement, ///< Subcomponent of a device. Has multiple sub-types
DeviceProcessData, ///< Contains a single process data variable definition
DeviceProperty, ///< A device property element
DeviceValuePresentation ///< Contains the presentation information to display the value of a DeviceProcessData or DeviceProperty object
Device, ///< The root object. Each device shall have one single Device (DVC)
DeviceElement, ///< Subcomponent of a device. Has multiple sub-types (DET)
DeviceProcessData, ///< Contains a single process data variable definition (DPD)
DeviceProperty, ///< A device property element (DPT)
DeviceValuePresentation ///< Contains the presentation information to display the value of a DeviceProcessData or DeviceProperty object (DVP)
};

/// @brief A base class for a Task Controller Object
Expand Down Expand Up @@ -272,6 +274,10 @@ namespace isobus
/// @returns true if the child object ID was found and removed, otherwise false
bool remove_reference_to_child_object(std::uint16_t childID);

/// @brief Returns a span of the child objects added with `add_reference_to_child_object`.
/// @returns A span of the child object IDs
DataSpan<const std::uint16_t> get_child_object_ids() const;

/// @brief Returns the number of child objects added with `add_reference_to_child_object`.
/// @note The maximum number of child objects is technically 65535 because the serialized
/// form of the value uses a 16-bit integer to store the count.
Expand Down Expand Up @@ -368,6 +374,11 @@ namespace isobus
/// @param[in] properties The new properties bitfield to set
void set_properties_bitfield(std::uint8_t properties);

/// @brief Tests whether a property is set in the properties bitfield
/// @param property The property to test for
/// @returns `true` if the property is set, otherwise `false`
bool has_property(DeviceProcessDataObject::PropertiesBit property);

/// @brief Returns the object's available trigger methods
/// @returns The available trigger methods bitfield for this object
std::uint8_t get_trigger_methods_bitfield() const;
Expand All @@ -376,6 +387,11 @@ namespace isobus
/// @param[in] methods The new trigger methods bitfield to set
void set_trigger_methods_bitfield(std::uint8_t methods);

/// @brief Tests whether a trigger method is set in the trigger methods bitfield
/// @param method The trigger method to test for
/// @returns `true` if the trigger method is set, otherwise `false`
bool has_trigger_method(DeviceProcessDataObject::AvailableTriggerMethods method);

private:
static const std::string tableID; ///< XML element namespace for DeviceProcessData.
std::uint16_t ddi; ///< Identifier of process data variable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,22 +260,22 @@ namespace isobus
/// @brief Sends a time interval measurement command.
/// The process data value for this command is the time interval for sending the data element
/// specified by the data dictionary identifier.The client has to send the value of this data
/// element to the TC or DL cyclic with this time interval.
/// element to the TC or DL cyclic with this time interval in milliseconds.
/// @param[in] clientControlFunction The control function to send the message to
/// @param[in] dataDescriptionIndex The data description index of the data element to send the command for
/// @param[in] elementNumber The element number of the data element to send the command for
/// @param[in] timeInterval The time interval for sending the data element specified by the data dictionary identifier.
/// @param[in] timeInterval The time interval in milliseconds for sending the data element specified by the data dictionary identifier.
/// @returns true if the message was sent, otherwise false
bool send_time_interval_measurement_command(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t timeInterval) const;

/// @brief Sends a distance interval measurement command.
/// The process data value for this command is the distance interval for sending the data element
/// specified by the data dictionary identifier.The client has to send the value of this data
/// element to the TC or DL cyclic with this distance interval.
/// element to the TC or DL cyclic with this distance interval in millimeters.
/// @param[in] clientControlFunction The control function to send the message to
/// @param[in] dataDescriptionIndex The data description index of the data element to send the command for
/// @param[in] elementNumber The element number of the data element to send the command for
/// @param[in] distanceInterval The distance interval for sending the data element specified by the data dictionary identifier.
/// @param[in] distanceInterval The distance interval in millimeters for sending the data element specified by the data dictionary identifier.
/// @returns true if the message was sent, otherwise false
bool send_distance_interval_measurement_command(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t distanceInterval) const;

Expand Down
8 changes: 8 additions & 0 deletions isobus/src/isobus_device_descriptor_object_pool_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,14 @@ namespace isobus
set_value_from_property(retVal.yOffset_mm, property, DataDescriptionIndex::DeviceElementOffsetY);
set_value_from_property(retVal.zOffset_mm, property, DataDescriptionIndex::DeviceElementOffsetZ);
set_value_from_property(retVal.width_mm, property, DataDescriptionIndex::ActualWorkingWidth);
if (!retVal.width_mm.isValuePresent)
{
set_value_from_property(retVal.width_mm, property, DataDescriptionIndex::MaximumWorkingWidth);
}
if (!retVal.width_mm.isValuePresent)
{
set_value_from_property(retVal.width_mm, property, DataDescriptionIndex::DefaultWorkingWidth);
}
Comment on lines +239 to +246
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with this implementation is that it's dependent on the order. Example: when the DefaultWorkingWidth comes first in the iteration, that value is chosen

My suggestion: we save all 3 properties in the section variable, and then we have a member function of the Section class that chooses the correct one based on the priority given by the standard

}
else if (task_controller_object::ObjectTypes::DeviceProcessData == sectionChildObject->get_object_type())
{
Expand Down
15 changes: 15 additions & 0 deletions isobus/src/isobus_task_controller_client_objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,11 @@ namespace isobus
return retVal;
}

DataSpan<const std::uint16_t> DeviceElementObject::get_child_object_ids() const
{
return DataSpan<const std::uint16_t>(referenceList.data(), referenceList.size());
}

std::uint16_t DeviceElementObject::get_number_child_objects() const
{
return static_cast<std::uint16_t>(referenceList.size());
Expand Down Expand Up @@ -416,6 +421,11 @@ namespace isobus
propertiesBitfield = properties;
}

bool DeviceProcessDataObject::has_property(DeviceProcessDataObject::PropertiesBit property)
{
return (0 != (propertiesBitfield & static_cast<std::uint8_t>(property)));
}

std::uint8_t DeviceProcessDataObject::get_trigger_methods_bitfield() const
{
return triggerMethodsBitfield;
Expand All @@ -426,6 +436,11 @@ namespace isobus
triggerMethodsBitfield = methods;
}

bool DeviceProcessDataObject::has_trigger_method(DeviceProcessDataObject::AvailableTriggerMethods method)
{
return (0 != (triggerMethodsBitfield & static_cast<std::uint8_t>(method)));
}

const std::string DevicePropertyObject::tableID = "DPT";

DevicePropertyObject::DevicePropertyObject(std::string propertyDesignator,
Expand Down
7 changes: 7 additions & 0 deletions isobus/src/isobus_task_controller_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,36 +61,43 @@ namespace isobus

bool TaskControllerServer::send_time_interval_measurement_command(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t timeInterval) const
{
LOG_DEBUG("[TC Server]: Requesting time interval measurement from client %hhu for DDI %s element %hu with time interval %u ms", clientControlFunction->get_address(), DataDictionary::ddi_to_string(dataDescriptionIndex).c_str(), elementNumber, timeInterval);
return send_measurement_command(clientControlFunction, static_cast<std::uint8_t>(ProcessDataCommands::MeasurementTimeInterval), dataDescriptionIndex, elementNumber, timeInterval);
}

bool TaskControllerServer::send_distance_interval_measurement_command(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t distanceInterval) const
{
LOG_DEBUG("[TC Server]: Requesting distance interval measurement from client %hhu for DDI %s element %hu with distance interval %u mm", clientControlFunction->get_address(), DataDictionary::ddi_to_string(dataDescriptionIndex).c_str(), elementNumber, distanceInterval);
return send_measurement_command(clientControlFunction, static_cast<std::uint8_t>(ProcessDataCommands::MeasurementDistanceInterval), dataDescriptionIndex, elementNumber, distanceInterval);
}

bool TaskControllerServer::send_minimum_threshold_measurement_command(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t minimum) const
{
LOG_DEBUG("[TC Server]: Requesting minimum threshold measurement from client %hhu for DDI %s element %hu with minimum threshold %u", clientControlFunction->get_address(), DataDictionary::ddi_to_string(dataDescriptionIndex).c_str(), elementNumber, minimum);
return send_measurement_command(clientControlFunction, static_cast<std::uint8_t>(ProcessDataCommands::MeasurementMinimumWithinThreshold), dataDescriptionIndex, elementNumber, minimum);
}

bool TaskControllerServer::send_maximum_threshold_measurement_command(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t maximum) const
{
LOG_DEBUG("[TC Server]: Requesting maximum threshold measurement from client %hhu for DDI %s element %hu with maximum threshold %u", clientControlFunction->get_address(), DataDictionary::ddi_to_string(dataDescriptionIndex).c_str(), elementNumber, maximum);
return send_measurement_command(clientControlFunction, static_cast<std::uint8_t>(ProcessDataCommands::MeasurementMaximumWithinThreshold), dataDescriptionIndex, elementNumber, maximum);
}

bool TaskControllerServer::send_change_threshold_measurement_command(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t threshold) const
{
LOG_DEBUG("[TC Server]: Requesting change threshold measurement from client %hhu for DDI %s element %hu with threshold %u", clientControlFunction->get_address(), DataDictionary::ddi_to_string(dataDescriptionIndex).c_str(), elementNumber, threshold);
return send_measurement_command(clientControlFunction, static_cast<std::uint8_t>(ProcessDataCommands::MeasurementChangeThreshold), dataDescriptionIndex, elementNumber, threshold);
}

bool TaskControllerServer::send_set_value_and_acknowledge(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t processDataValue) const
{
LOG_DEBUG("[TC Server]: Sending set value and acknowledge to client %hhu for DDI %s element %hu with value %s", clientControlFunction->get_address(), DataDictionary::ddi_to_string(dataDescriptionIndex).c_str(), elementNumber, DataDictionary::format_value_with_ddi(dataDescriptionIndex, processDataValue).c_str());
return send_measurement_command(clientControlFunction, static_cast<std::uint8_t>(ProcessDataCommands::SetValueAndAcknowledge), dataDescriptionIndex, elementNumber, processDataValue);
}

bool TaskControllerServer::send_set_value(std::shared_ptr<ControlFunction> clientControlFunction, std::uint16_t dataDescriptionIndex, std::uint16_t elementNumber, std::uint32_t processDataValue) const
{
LOG_DEBUG("[TC Server]: Sending set value to client %hhu for DDI %s element %hu with value %s", clientControlFunction->get_address(), DataDictionary::ddi_to_string(dataDescriptionIndex).c_str(), elementNumber, DataDictionary::format_value_with_ddi(dataDescriptionIndex, processDataValue).c_str());
return send_measurement_command(clientControlFunction, static_cast<std::uint8_t>(ProcessDataCommands::Value), dataDescriptionIndex, elementNumber, processDataValue);
}

Expand Down
Loading