@@ -44,53 +44,135 @@ return_type ChainableControllerInterface::update(
44
44
return ret;
45
45
}
46
46
47
- std::vector<hardware_interface::StateInterface>
47
+ std::vector<hardware_interface::StateInterface::ConstSharedPtr >
48
48
ChainableControllerInterface::export_state_interfaces ()
49
49
{
50
50
auto state_interfaces = on_export_state_interfaces ();
51
+ std::vector<hardware_interface::StateInterface::ConstSharedPtr> state_interfaces_ptrs_vec;
52
+ state_interfaces_ptrs_vec.reserve (state_interfaces.size ());
53
+ ordered_exported_state_interfaces_.reserve (state_interfaces.size ());
54
+ exported_state_interface_names_.reserve (state_interfaces.size ());
51
55
52
56
// check if the names of the controller state interfaces begin with the controller's name
53
57
for (const auto & interface : state_interfaces)
54
58
{
55
59
if (interface.get_prefix_name () != get_node ()->get_name ())
56
60
{
57
- RCLCPP_FATAL (
58
- get_node ()->get_logger (),
59
- " The name of the interface '%s' does not begin with the controller's name. This is "
60
- " mandatory for state interfaces. No state interface will be exported. Please "
61
- " correct and recompile the controller with name '%s' and try again." ,
62
- interface.get_name ().c_str (), get_node ()->get_name ());
63
- state_interfaces.clear ();
64
- break ;
61
+ std::string error_msg =
62
+ " The prefix of the interface '" + interface.get_prefix_name () +
63
+ " ' does not equal the controller's name '" + get_node ()->get_name () +
64
+ " '. This is mandatory for state interfaces. No state interface will be exported. Please "
65
+ " correct and recompile the controller with name '" +
66
+ get_node ()->get_name () + " ' and try again." ;
67
+ throw std::runtime_error (error_msg);
68
+ }
69
+ auto state_interface = std::make_shared<hardware_interface::StateInterface>(interface);
70
+ const auto interface_name = state_interface->get_name ();
71
+ auto [it, succ] = exported_state_interfaces_.insert ({interface_name, state_interface});
72
+ // either we have name duplicate which we want to avoid under all circumstances since interfaces
73
+ // need to be uniquely identify able or something else really went wrong. In any case abort and
74
+ // inform cm by throwing exception
75
+ if (!succ)
76
+ {
77
+ std::string error_msg =
78
+ " Could not insert StateInterface<" + interface_name +
79
+ " > into exported_state_interfaces_ map. Check if you export duplicates. The "
80
+ " map returned iterator with interface_name<" +
81
+ it->second ->get_name () +
82
+ " >. If its a duplicate adjust exportation of InterfacesDescription so that all the "
83
+ " interface names are unique." ;
84
+ exported_state_interfaces_.clear ();
85
+ exported_state_interface_names_.clear ();
86
+ state_interfaces_ptrs_vec.clear ();
87
+ throw std::runtime_error (error_msg);
65
88
}
89
+ ordered_exported_state_interfaces_.push_back (state_interface);
90
+ exported_state_interface_names_.push_back (interface_name);
91
+ state_interfaces_ptrs_vec.push_back (
92
+ std::const_pointer_cast<const hardware_interface::StateInterface>(state_interface));
66
93
}
67
94
68
- return state_interfaces ;
95
+ return state_interfaces_ptrs_vec ;
69
96
}
70
97
71
- std::vector<hardware_interface::CommandInterface>
98
+ std::vector<hardware_interface::CommandInterface::SharedPtr >
72
99
ChainableControllerInterface::export_reference_interfaces ()
73
100
{
74
101
auto reference_interfaces = on_export_reference_interfaces ();
102
+ std::vector<hardware_interface::CommandInterface::SharedPtr> reference_interfaces_ptrs_vec;
103
+ reference_interfaces_ptrs_vec.reserve (reference_interfaces.size ());
104
+ exported_reference_interface_names_.reserve (reference_interfaces.size ());
105
+ ordered_reference_interfaces_.reserve (reference_interfaces.size ());
106
+
107
+ // BEGIN (Handle export change): for backward compatibility
108
+ // check if the "reference_interfaces_" variable is resized to number of interfaces
109
+ if (reference_interfaces_.size () != reference_interfaces.size ())
110
+ {
111
+ std::string error_msg =
112
+ " The internal storage for reference values 'reference_interfaces_' variable has size '" +
113
+ std::to_string (reference_interfaces_.size ()) + " ', but it is expected to have the size '" +
114
+ std::to_string (reference_interfaces.size ()) +
115
+ " ' equal to the number of exported reference interfaces. Please correct and recompile the "
116
+ " controller with name '" +
117
+ get_node ()->get_name () + " ' and try again." ;
118
+ throw std::runtime_error (error_msg);
119
+ }
120
+ // END
75
121
76
122
// check if the names of the reference interfaces begin with the controller's name
77
- for (const auto & interface : reference_interfaces)
123
+ const auto ref_interface_size = reference_interfaces.size ();
124
+ for (auto & interface : reference_interfaces)
78
125
{
79
126
if (interface.get_prefix_name () != get_node ()->get_name ())
80
127
{
81
- RCLCPP_FATAL (
82
- get_node ()->get_logger (),
83
- " The name of the interface '%s' does not begin with the controller's name. This is "
84
- " mandatory "
85
- " for reference interfaces. No reference interface will be exported. Please correct and "
86
- " recompile the controller with name '%s' and try again." ,
87
- interface.get_name ().c_str (), get_node ()->get_name ());
88
- reference_interfaces.clear ();
89
- break ;
128
+ std::string error_msg = " The name of the interface " + interface.get_name () +
129
+ " does not begin with the controller's name. This is mandatory for "
130
+ " reference interfaces. Please "
131
+ " correct and recompile the controller with name " +
132
+ get_node ()->get_name () + " and try again." ;
133
+ throw std::runtime_error (error_msg);
90
134
}
135
+
136
+ hardware_interface::CommandInterface::SharedPtr reference_interface =
137
+ std::make_shared<hardware_interface::CommandInterface>(std::move (interface));
138
+ const auto inteface_name = reference_interface->get_name ();
139
+ // check the exported interface name is unique
140
+ auto [it, succ] = reference_interfaces_ptrs_.insert ({inteface_name, reference_interface});
141
+ // either we have name duplicate which we want to avoid under all circumstances since interfaces
142
+ // need to be uniquely identify able or something else really went wrong. In any case abort and
143
+ // inform cm by throwing exception
144
+ if (!succ)
145
+ {
146
+ std::string error_msg =
147
+ " Could not insert Reference interface<" + inteface_name +
148
+ " > into reference_interfaces_ map. Check if you export duplicates. The "
149
+ " map returned iterator with interface_name<" +
150
+ it->second ->get_name () +
151
+ " >. If its a duplicate adjust exportation of InterfacesDescription so that all the "
152
+ " interface names are unique." ;
153
+ reference_interfaces_.clear ();
154
+ exported_reference_interface_names_.clear ();
155
+ reference_interfaces_ptrs_vec.clear ();
156
+ throw std::runtime_error (error_msg);
157
+ }
158
+ ordered_reference_interfaces_.push_back (reference_interface);
159
+ exported_reference_interface_names_.push_back (inteface_name);
160
+ reference_interfaces_ptrs_vec.push_back (reference_interface);
91
161
}
92
162
93
- return reference_interfaces;
163
+ if (reference_interfaces_ptrs_.size () != ref_interface_size)
164
+ {
165
+ std::string error_msg =
166
+ " The internal storage for reference ptrs 'reference_interfaces_ptrs_' variable has size '" +
167
+ std::to_string (reference_interfaces_ptrs_.size ()) +
168
+ " ', but it is expected to have the size '" + std::to_string (ref_interface_size) +
169
+ " ' equal to the number of exported reference interfaces. Please correct and recompile the "
170
+ " controller with name '" +
171
+ get_node ()->get_name () + " ' and try again." ;
172
+ throw std::runtime_error (error_msg);
173
+ }
174
+
175
+ return reference_interfaces_ptrs_vec;
94
176
}
95
177
96
178
bool ChainableControllerInterface::set_chained_mode (bool chained_mode)
@@ -130,8 +212,8 @@ ChainableControllerInterface::on_export_state_interfaces()
130
212
std::vector<hardware_interface::StateInterface> state_interfaces;
131
213
for (size_t i = 0 ; i < exported_state_interface_names_.size (); ++i)
132
214
{
133
- state_interfaces.emplace_back (hardware_interface::StateInterface (
134
- get_node ()->get_name (), exported_state_interface_names_[i], &state_interfaces_values_[i])) ;
215
+ state_interfaces.emplace_back (
216
+ get_node ()->get_name (), exported_state_interface_names_[i], &state_interfaces_values_[i]);
135
217
}
136
218
return state_interfaces;
137
219
}
0 commit comments