Purpose
- Provides high-level C++ wrappers for nodes that communicate with
vt_client_node. - Hides raw ROS topic publish/subscribe details behind typed classes and methods.
Header
include/ros2_isobus/vt_client_interface.hpp
Classes
ros2_isobus::VTContainer- Container visibility control only.
- Topics:
ISOBUS/vt/container/<name_token>/visible/(set|value|result). - Methods:
set_visible(bool),visible(),visible_result().
ros2_isobus::VTNumber- Number value set/get via
ISOBUS/vt/number/<name_token>/(set|value).
- Number value set/get via
ros2_isobus::VTInputNumber- Input-number value set/get via
ISOBUS/vt/input_number/<name_token>/(set|value). - Enable control:
ISOBUS/vt/input_number/<name_token>/enabled/(set|value|result). - Methods:
set(double),value(),on_change(...),set_enabled(bool),enabled(),enabled_result().
- Input-number value set/get via
ros2_isobus::VTString- String value set/get via
ISOBUS/vt/string/<name_token>/(set|value).
- String value set/get via
ros2_isobus::VTInputString- Input-string value set/get via
ISOBUS/vt/input_string/<name_token>/(set|value). - Enable control:
ISOBUS/vt/input_string/<name_token>/enabled/(set|value|result). - Methods:
set(string),value(),on_change(...),set_enabled(bool),enabled(),enabled_result().
- Input-string value set/get via
ros2_isobus::VTInputBoolean- Input-boolean value set/get via
ISOBUS/vt/input_bool/<name_token>/(set|value). - Enable control:
ISOBUS/vt/input_bool/<name_token>/enabled/(set|value|result). - Methods:
set(bool),value(),on_change(...),set_enabled(bool),enabled(),enabled_result().
- Input-boolean value set/get via
ros2_isobus::VTList- List index set/get via
ISOBUS/vt/list/<name_token>/(set|value).
- List index set/get via
ros2_isobus::VTButton- Event input via
ISOBUS/vt/event/button/<name_token>. - Enable control:
ISOBUS/vt/button/<name_token>/enabled/(set|value|result). - Callback registration:
on_event(std::function<void(bool)>)for press/release.on_pressed(std::function<void()>)for press only (code=0x01).on_released(std::function<void()>)for release only (code=0x00).
- Event input via
ros2_isobus::VTSoftkey- Event input via
ISOBUS/vt/event/softkey/<name_token>. - Same callback API as
VTButton.
- Event input via
ros2_isobus::VTAuxFunction<TValue>- AUX-N function input and assignment streams under
ISOBUS/vt/aux/<name_token>. input/valueis converted from normalizedFloat64tobool, an integer type or a floating-point type selected byTValue.- Accessors:
input_value(),input_value_raw(),input_raw(),assignment(),assignment_result(). - Callbacks:
on_input(...),on_input_raw(...),on_assignment(...),on_assignment_result(...).
- AUX-N function input and assignment streams under
ros2_isobus::VTWorkingSet- Working-set level communication:
- active/softkey mask set/value/result
- status, session state
- pointing/navigation events
- diagnostics
- AUX status (
aux_status(),on_aux_status(...)) - runtime pool updates (
send_pool_update_xml(...)) - runtime pool update result callback (
on_updated(...))
- Supports both:
- named trigger topics (
trigger_active_mask("mask_name"))
- named trigger topics (
- Working-set level communication:
Pool Creation And XML Usage
- Create/edit the VT object pool with PoolEdit.
- Export XML from PoolEdit (
Export XML). - Configure that XML path as
vt_client_nodeparameterxml_file. - Use XML
namevalues as wrappername_tokenconstructor arguments.
Modeling Recommendation
- Prefer
numbervariable/stringvariableobjects for general data flow:- Input object references variable.
- Output object references the same variable.
- You can also use input objects directly without variables via:
VTInputNumberVTInputStringVTInputBoolean
- Direct input wrappers are especially useful when you need runtime
enabledcontrol.
Usage Example
#include "ros2_isobus/vt_client_interface.hpp"
class MyNode : public rclcpp::Node {
public:
MyNode() : Node("my_node"),
label_(*this, "label0"),
panel_(*this, "main_panel"),
ok_button_(*this, "ok_button"),
ws_(*this) {
ok_button_.on_pressed([this]() {
label_.set("OK");
panel_.set_visible(true);
});
ws_.trigger_active_mask("main_mask");
ws_.on_updated([this](const ros2_isobus::msg::VTUpdateResult & r) {
RCLCPP_INFO(
get_logger(),
"update: success=%s detail=%s pending=%u in_progress=%u",
r.success ? "true" : "false",
r.detail.c_str(),
static_cast<unsigned>(r.pending_updates),
static_cast<unsigned>(r.in_progress_updates));
});
}
private:
ros2_isobus::VTString label_;
ros2_isobus::VTContainer panel_;
ros2_isobus::VTButton ok_button_;
ros2_isobus::VTWorkingSet ws_;
};Input Wrapper Example
#include "ros2_isobus/vt_client_interface.hpp"
class VtInputDemo : public rclcpp::Node {
public:
VtInputDemo() : Node("vt_input_demo"),
in_num_(*this, "counter_input"),
in_str_(*this, "text_input"),
in_bool_(*this, "bool_input") {
in_num_.on_change([this](double v) {
RCLCPP_INFO(get_logger(), "counter_input=%.0f", v);
});
in_str_.on_change([this](const std::string & s) {
RCLCPP_INFO(get_logger(), "text_input=%s", s.c_str());
});
in_bool_.on_change([this](bool b) {
RCLCPP_INFO(get_logger(), "bool_input=%s", b ? "true" : "false");
});
// Example: disable all input fields
in_num_.set_enabled(false);
in_str_.set_enabled(false);
in_bool_.set_enabled(false);
}
private:
ros2_isobus::VTInputNumber in_num_;
ros2_isobus::VTInputString in_str_;
ros2_isobus::VTInputBoolean in_bool_;
};AUX-N Wrapper Example
#include "ros2_isobus/vt_client_interface.hpp"
class VtAuxDemo : public rclcpp::Node {
public:
VtAuxDemo() : Node("vt_aux_demo"), aux_(*this, "aux_function") {
aux_.on_input([this](double value) {
RCLCPP_INFO(get_logger(), "AUX input=%.3f", value);
});
aux_.on_assignment([this](const ros2_isobus::msg::VTAuxAssignment & assignment) {
RCLCPP_INFO(get_logger(), "AUX assigned=%s", assignment.assigned ? "true" : "false");
});
}
private:
ros2_isobus::VTAuxFunction<double> aux_;
};The VT node must run with vt_aux_n_support:=true, and aux_function must match an
auxiliaryfunction object's XML name.
Pool Update Example (send_pool_update_xml)
#include "ros2_isobus/vt_client_interface.hpp"
class VtPoolUpdateDemo : public rclcpp::Node {
public:
VtPoolUpdateDemo() : Node("vt_pool_update_demo"), ws_(*this) {
ws_.on_updated([this](const ros2_isobus::msg::VTUpdateResult & r) {
RCLCPP_INFO(
get_logger(),
"pool update: success=%s detail=%s pending=%u in_progress=%u",
r.success ? "true" : "false",
r.detail.c_str(),
static_cast<unsigned>(r.pending_updates),
static_cast<unsigned>(r.in_progress_updates));
});
// Update one object (single XML element).
ws_.send_pool_update_xml(
"<polygon height=\"200\" id=\"290\" name=\"link3\" polygon_type=\"convex\" use=\"mask\" width=\"200\">"
"<fillattributes fill_colour=\"yellow\" fill_type=\"fillcolour\" id=\"291\" name=\"yellow\" role=\"fill_attributes\" use=\"mask\"/>"
"<lineattributes id=\"292\" line_art=\"1111111111111111\" line_colour=\"black\" line_width=\"1\" name=\"black1\" role=\"line_attributes\" use=\"mask\"/>"
"<point pos_x=\"90\" pos_y=\"87\"/>"
"<point pos_x=\"140\" pos_y=\"72\"/>"
"<point pos_x=\"148\" pos_y=\"97\"/>"
"<point pos_x=\"97\" pos_y=\"112\"/>"
"</polygon>");
// Recommended: group related updates into one payload.
ws_.send_pool_update_xml(
"<objectpool>"
"<polygon height=\"200\" id=\"287\" name=\"link2\" polygon_type=\"convex\" use=\"mask\" width=\"200\">"
"<fillattributes fill_colour=\"yellow\" fill_type=\"fillcolour\" id=\"288\" name=\"yello\" role=\"fill_attributes\" use=\"mask\"/>"
"<lineattributes id=\"289\" line_art=\"1111111111111111\" line_colour=\"black\" line_width=\"1\" name=\"black1\" role=\"line_attributes\" use=\"mask\"/>"
"<point pos_x=\"30\" pos_y=\"68\"/>"
"<point pos_x=\"36\" pos_y=\"53\"/>"
"<point pos_x=\"94\" pos_y=\"80\"/>"
"<point pos_x=\"88\" pos_y=\"95\"/>"
"</polygon>"
"<polygon height=\"200\" id=\"290\" name=\"link3\" polygon_type=\"convex\" use=\"mask\" width=\"200\">"
"<fillattributes fill_colour=\"yellow\" fill_type=\"fillcolour\" id=\"291\" name=\"yellow\" role=\"fill_attributes\" use=\"mask\"/>"
"<lineattributes id=\"292\" line_art=\"1111111111111111\" line_colour=\"black\" line_width=\"1\" name=\"black1\" role=\"line_attributes\" use=\"mask\"/>"
"<point pos_x=\"90\" pos_y=\"87\"/>"
"<point pos_x=\"140\" pos_y=\"72\"/>"
"<point pos_x=\"148\" pos_y=\"97\"/>"
"<point pos_x=\"97\" pos_y=\"112\"/>"
"</polygon>"
"</objectpool>");
}
private:
ros2_isobus::VTWorkingSet ws_;
};Notes
- Each object class instance is bound to one XML
name_token. - Values/results are cached internally and protected with mutexes.
- This helper assumes
vt_client_nodeis running and has created matching topics from loaded XML. VTWorkingSet::send_pool_update_xml(...)can update one or many objects in one XML payload.- You can call
send_pool_update_xml(...)multiple times; updates are serialized internally byvt_client_node. - Recommended: put all related object changes into one XML payload when possible.