YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include <yarp/os/Network.h>
7#include <yarp/os/RFModule.h>
8#include <yarp/os/Time.h>
9#include <yarp/os/Log.h>
10#include <yarp/os/LogStream.h>
12#include <yarp/sig/Vector.h>
14
15#include <fstream>
16#include <iostream>
17#include <iomanip>
18#include <string>
19#include <vector>
20#include <deque>
21#include <cmath>
22#include <map>
23#include <mutex>
24
25#include "robotDriver.h"
26#include "robotAction.h"
27#include "broadcastingThread.h"
28#include "controlThread.h"
29
30// ******************** THE MODULE
32{
33protected:
35 std::string m_name;
37 std::map<std::string,robotDriver*> m_robotControllers;
38 std::map<std::string,action_class> m_actions;
41
43
44 public: //yarpActionsPlayer_IDL methods
45 bool start() override;
46 bool stop() override;
47 bool reset() override;
48 bool forever() override;
49 bool print_frames() override;
50 bool speed_factor(const double value) override;
51 bool resample(const double value) override;
52 bool choose_action(const std::string& action_name) override;
53 bool play_action(const std::string& action_name) override;
54 bool show_actions() override;
55 bool set_thread_period(const double value) override;
56
57 public:
59 {
60 m_verbose=true;
61 }
62
64 {
65 for (auto it = m_robotControllers.begin(); it != m_robotControllers.end(); it++)
66 {
67 if (it->second)
68 {
69 delete it->second;
70 it->second = nullptr;
71 }
72 }
73 yInfo() << "cleanup complete";
74
75 if (m_wthread)
76 {
77 delete m_wthread;
78 m_wthread=nullptr;
79 }
80
81 if (m_bthread)
82 {
83 delete m_bthread;
84 m_bthread=nullptr;
85 }
86 }
87
88 bool chooseActionByName(std::string id)
89 {
90 if (m_actions.find(id) == m_actions.end())
91 {
92 yError() << "action id not found";
93 return false;
94 }
96
97 action_class *action = &m_actions[id];
98 std::string controller_name = action->controller_name;
99 robotDriver *driver = m_robotControllers[controller_name];
100
101 if (!driver || !action)
102 {
103 yError() << "invalid driver/action pointer";
104 return false;
105 }
106 yInfo() << "action selected:" << id;
107 yDebug() << "action controller:" << controller_name;
108 yDebug() << "number of action frames:" << action->action_frames_vector.size();
109 return m_wthread->action_change(action, driver);
110 }
111
113 {
114 std::string ss = "actions:\n";
115 size_t i = 0;
116 for (auto it=m_actions.begin(); it!=m_actions.end();it++)
117 {
118 ss = ss + "(" + std::to_string(i++) + ") " + it->second.action_name + "\n";
119 }
120 return ss;
121 }
122
123 bool loadConfiguration(std::string filename, double resample_period)
124 {
126 if (!p.fromConfigFile(filename))
127 {
128 yError() << "Unable to read configuration file!";
129 return false;
130 }
131
132 yarp::os::Bottle& bot_cont = p.findGroup("CONTROLLERS");
133 if (bot_cont.size() == 0)
134 {
135 yError() << "Unable to read CONTROLLERS section";
136 return false;
137 }
138 size_t num_of_controllers = bot_cont.size();
139 for (size_t i = 1; i < num_of_controllers; i++)
140 {
141 yDebug() << bot_cont.get(i).toString();
142 yarp::os::Bottle* bot_cont_elem = bot_cont.get(i).asList();
143 size_t num_of_celems = bot_cont_elem->size();
144 if (bot_cont_elem && num_of_celems == 3)
145 {
146 //parse a line of the controllers section
147 std::string controller_name = bot_cont_elem->get(0).toString();
148 std::string remoteControlBoards = bot_cont_elem->get(1).toString();
149 std::string axesNames = bot_cont_elem->get(2).toString();
150 robotDriver* rob = new robotDriver;
151 yarp::os::Property rmoptions;
152 rmoptions.put("remoteControlBoards", bot_cont_elem->get(1));
153 rmoptions.put("axesNames", bot_cont_elem->get(2));
154 rmoptions.put("localPortPrefix", m_name + "/controller/" + controller_name);
155
156 //configure the controller
157 bool rob_ok = true;
158 rob_ok &= rob->configure(rmoptions);
159 rob_ok &= rob->init();
160 if (!rob_ok)
161 {
162 yError() << "Unable to initialize controller" << controller_name;
163 return false;
164 }
165 //put the controller in the list
166 m_robotControllers[controller_name] = rob;
167 }
168 else
169 {
170 yError() << "Invalid entry in CONTROLLERS section";
171 return false;
172 }
173 }
174
175 yarp::os::Bottle& bot_action = p.findGroup("ACTIONS");
176 if (bot_action.size() == 0)
177 {
178 yError() << "Unable to read ACTIONS section";
179 return false;
180 }
181 for (size_t i = 1; i < bot_action.size(); i++)
182 {
183 std::string str = bot_action.toString();
184 yDebug() << bot_action.get(i).toString();
185 yarp::os::Bottle* bot_act_elem = bot_action.get(i).asList();
186 size_t num_of_aelems = bot_act_elem->size();
187 if (bot_act_elem && num_of_aelems==3)
188 {
189 //parse a line of the ACTIONS section
190 std::string action_name = bot_act_elem->get(0).toString();
191 std::string controller_name = bot_act_elem->get(1).toString();
192 std::string action_file_name = bot_act_elem->get(2).toString();
193
194 //check if the controller name exists
195 if (m_robotControllers.find(controller_name) == m_robotControllers.end())
196 {
197 yError() << controller_name << "in action" << action_name << "does not exists";
198 return false;
199 }
200
201 //load the action file
202 action_class tmpAction;
203 tmpAction.action_name = action_name;
204 tmpAction.controller_name = controller_name;
205 size_t njoints = m_robotControllers[controller_name]->getNJoints();
206
207 if (!tmpAction.openFile(action_file_name, njoints, 0.010))
208 {
209 yError() << "Unable to parse file";
210 return false;
211 }
212 if (resample_period!=0.0)
213 {
214 tmpAction.interpolate_action_frames(resample_period);
215 }
216
217 //put the action in the list
218 m_actions[action_name] = tmpAction;
219 }
220 else
221 {
222 yError() << "Invalid entry in ACTIONS section";
223 return false;
224 }
225 }
226
227 yInfo() << "configuration file successfully loaded";
228 return true;
229 }
230
232 {
233 yInfo();
234 yInfo() << "Command line:";
235 yInfo() << "yarpActionsPlayer --filename `name` [--name `module_name`] [--execute] [--period period_s] [--resample resample_period_s] [--pos_tolerance pos] [--pos_timeout pos] [--pos_strict_check enable] ";
236 yInfo();
237 yInfo() << "`name` : file containing the actions";
238 yInfo() << "`module_name` : prefix of the ports opened by the module (default: /yarpActionsPlayer)";
239 yInfo() << "`execute` : if enabled, the yarpActionsPlayer will send commands to the robot. Otherwise, only it will operate in simulation mode only";
240 yInfo() << "`pos_tolerance` : the tolerance (in degrees) that will be checked by the initial movement in position mode, before switching to positionDirect mode. Default: 2degrees";
241 yInfo() << "`pos_timeout` : the amount of time (in seconds) the robot will attempt to reach the target position within the specified position tolerance. Default: 2s";
242 yInfo() << "`pos_strict_check` : if set to true, the system will halt if home position is halted, otherwise it will continue after the timeout expires. Default: false";
243 yInfo() << "`period` : the period (in s) of the thread processing the commands. Default 0.010s";
244 yInfo() << "`resample`: all the loaded trajectory files are internally resampled at the specified period. Default: not enabled";
245 yInfo();
246 }
247
249 {
250 std::string test_string = rf.toString();
251
252 // generic configuration
253 if (rf.check("name"))
254 m_name = std::string("/") + rf.find("name").asString().c_str();
255 else
256 m_name = "/yarpActionsPlayer";
257
258 // rpc port
259 m_rpcPort.open((m_name + "/rpc").c_str());
260 this->yarp().attachAsServer(m_rpcPort);
261
262 // get the configuration for parameter period
263 double period = 0.005;
264 if (rf.check("period") == true)
265 {
266 period = rf.find("period").asFloat64();
267 }
268
269 // Instantiate the thread
270 m_wthread = new ControlThread(m_name,period);
271
272 //set the configuration for parameter execute
273 if (rf.check("execute")==true)
274 {
275 yInfo() << "Enabling iPid->setReference() controller";
277 }
278 else
279 {
280 yInfo() << "Not using iPid->setReference() controller";
282 }
283
284 //set the position tolerance
285 if (rf.check("help") == true)
286 {
287 print_help();
288 return false;
289 }
290
291 //set the position tolerance
292 if (rf.check("pos_tolerance") == true)
293 {
294 double tol = rf.find("tolerance").asFloat64();
295 yInfo() << "Position tolerance set to " << tol << "degrees";
297 }
298
299 //set the position timeout
300 if (rf.check("pos_timeout") == true)
301 {
302 double timeout = rf.find("pos_timeout").asFloat64();
303 yInfo() << "Position timeout set to " << timeout << "seconds";
305 }
306
307 //set the position timeout
308 if (rf.check("pos_strict_check") == true)
309 {
310 bool enable = rf.find("pos_strict_check").asBool();
312 }
313
314 double resample_period = 0;
315 if (rf.check("resample") == true)
316 {
317 resample_period = rf.find("resample_period").asFloat64();
318 yInfo() << "Set resample period equal to:" << resample_period << "s";
319 }
320
321 //open the configuration file
322 if (rf.check("filename")==true)
323 {
324 if (rf.find("filename").isString())
325 {
326 std::string filename = rf.find("filename").asString();
327 bool b = loadConfiguration(filename, resample_period);
328 if (!b)
329 {
330 yError() << "Configuration error!";
331 return false;
332 }
333 }
334 else
335 {
336 yError() << "`filename` option syntax error.";
337 print_help();
338 return false;
339 }
340 }
341 else
342 {
343 yWarning() << "`filename` option not found. No sequence files loaded.";
344 }
345
346 //check if actions are valid
347 if (m_actions.empty())
348 {
349 yInfo() << "There are no actions!";
350 return false;
351 }
352
353 //select the first action
354 yInfo() << "automatically selecting the first action";
355 std::string first_action_name;
356 first_action_name = this->m_actions.begin()->first;
357 this->chooseActionByName(first_action_name);
358
359 //start the thread
360 if (!m_wthread->start())
361 {
362 yError() << "Working thread did not start, queue will not work";
363 }
364 else
365 {
366 yInfo() << "Working thread started";
367 }
368
369 yInfo() << "module successfully configured. ready.";
370 return true;
371 }
372
373 virtual bool close()
374 {
376
377 return true;
378 }
379
380 virtual double getPeriod() { return 1.0; }
381 virtual bool updateModule() { return true; }
382};
383
384//--------------------------------------------------------------------------
385int main(int argc, char *argv[])
386{
388 rf.setDefaultContext("yarpActionsPlayer");
389 rf.configure(argc,argv);
390
392
393 if (!yarp.checkNetwork())
394 {
395 yError() << "yarp.checkNetwork() failed.";
396 return -1;
397 }
398
399 scriptModule mod;
400
401 return mod.runModule(rf);
402}
403
405{
406 return this->m_wthread->action_start();
407}
408
410{
411 return this->m_wthread->action_stop();
412}
413
415{
416 return this->m_wthread->action_reset();
417}
418
420{
421 return this->m_wthread->action_forever();
422}
423
425{
426 return this->m_wthread->action_print();
427}
428
429bool scriptModule::speed_factor(const double value)
430{
431 return this->m_wthread->action_setSpeedFactor(value);
432}
433
434bool scriptModule::resample(const double value)
435{
436 return this->m_wthread->action_resample(value);
437}
438
439bool scriptModule::choose_action(const std::string& action_name)
440{
441 return this->chooseActionByName(action_name);
442}
443
444bool scriptModule::play_action(const std::string& action_name)
445{
446 bool b = this->chooseActionByName(action_name);
447 if (b)
448 {
449 bool b1 = this->m_wthread->action_start();
450 }
451 do { yarp::os::Time::delay(0.010); }
453 return true;
454}
455
457{
458 std::string actions_str = this->string_list_actions();
459 std::string current_action_name;
460 bool b = m_wthread->action_getname(current_action_name);
461 yInfo() << "current_action: " <<current_action_name;
462 yInfo() << actions_str;
463 return true;
464}
465
466bool scriptModule::set_thread_period(const double value)
467{
468 if (value > 0)
469 {
470 m_wthread->setPeriod(value);
471 yError("invalid period value");
472 }
473 else
474 {
475 yInfo("Period set to %f", value);
476 }
477 return true;
478}
#define yInfo(...)
Definition Log.h:319
#define yError(...)
Definition Log.h:361
#define yDebug(...)
Definition Log.h:275
#define yWarning(...)
Definition Log.h:340
contains the definition of a Vector type
bool action_getname(std::string &name)
void setPositionStrictCheck(bool enable)
bool m_enable_execute_joint_command
action_status_enum getStatus()
bool action_resample(double value)
bool action_setSpeedFactor(double factor=1)
void setPositionTolerance(double tolerance)
bool action_change(action_class *action, robotDriver *driver)
void setPositionTimeout(double timeloops)
void interpolate_action_frames(double timestep)
std::string action_name
Definition robotAction.h:48
bool openFile(std::string filename, size_t njoints, double timestep=-1)
std::string controller_name
Definition robotAction.h:49
std::deque< action_frame > action_frames_vector
Definition robotAction.h:53
bool configure(const yarp::os::Property &copt)
bool reset() override
Rewinds the currently selected action.
Definition main.cpp:414
bool speed_factor(const double value) override
Sets the playback speed factor for the currently selected action (default value: 1....
Definition main.cpp:429
bool show_actions() override
Prints all the loaded actions.
Definition main.cpp:456
std::string string_list_actions()
Definition main.cpp:112
bool loadConfiguration(std::string filename, double resample_period)
Definition main.cpp:123
void print_help()
Definition main.cpp:231
std::map< std::string, action_class > m_actions
Definition main.cpp:38
virtual bool updateModule()
Override this to do whatever your module needs to do.
Definition main.cpp:381
BroadcastingThread * m_bthread
Definition main.cpp:40
bool resample(const double value) override
Resamples the currently selected action (in seconds, recommended value 0.010s).
Definition main.cpp:434
std::string m_name
Definition main.cpp:35
bool start() override
Start (or resumes, if stopped) the currently selected action.
Definition main.cpp:404
bool m_verbose
Definition main.cpp:36
bool choose_action(const std::string &action_name) override
Choose the current action and wait for further commands.
Definition main.cpp:439
bool forever() override
Similar to play, but it will automatically restart the playback when the last frame is reached.
Definition main.cpp:419
bool set_thread_period(const double value) override
Sets the period of the sampling thread (for advanced use only, default value: 0.010s).
Definition main.cpp:466
bool print_frames() override
Prints all the frames of the currently selected action.
Definition main.cpp:424
std::string m_current_action_id
Definition main.cpp:42
~scriptModule()
Definition main.cpp:63
virtual double getPeriod()
You can override this to control the approximate periodicity at which updateModule() is called by run...
Definition main.cpp:380
yarp::os::Port m_rpcPort
Definition main.cpp:34
virtual bool configure(yarp::os::ResourceFinder &rf)
Configure the module, pass a ResourceFinder object to the module.
Definition main.cpp:248
bool stop() override
Stops the currently selected (running) action.
Definition main.cpp:409
bool play_action(const std::string &action_name) override
Play an action one single time.
Definition main.cpp:444
bool chooseActionByName(std::string id)
Definition main.cpp:88
virtual bool close()
Close function.
Definition main.cpp:373
scriptModule()
Definition main.cpp:58
ControlThread * m_wthread
Definition main.cpp:39
std::map< std::string, robotDriver * > m_robotControllers
Definition main.cpp:37
yarpActionsPlayer_IDL Interface.
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
size_type size() const
Gets the number of elements in the bottle.
Definition Bottle.cpp:251
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition Bottle.cpp:246
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition Bottle.cpp:211
Utilities for manipulating the YARP network, including initialization and shutdown.
Definition Network.h:706
bool setPeriod(double period)
Set the (new) period of the thread.
bool start()
Call this to start the thread.
A mini-server for network communication.
Definition Port.h:46
void close() override
Stop port activity.
Definition Port.cpp:363
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition Port.cpp:79
A class for storing options and configuration information.
Definition Property.h:33
bool fromConfigFile(const std::string &fname, bool wipe=true)
Interprets a file as a list of properties.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition Property.cpp:987
Bottle & findGroup(const std::string &key) const override
Gets a list corresponding to a given keyword.
A base-class for standard YARP modules that supports ResourceFinder.
Definition RFModule.h:20
virtual int runModule()
Calls updateModule() until that returns false.
Definition RFModule.cpp:323
Helper class for finding config files and other external resources.
bool check(const std::string &key) const override
Check if there exists a property of the given name.
bool setDefaultContext(const std::string &contextName)
Sets the context for the current ResourceFinder object.
bool configure(int argc, char *argv[], bool skipFirstArgument=true)
Sets up the ResourceFinder.
std::string toString() const override
Return a standard text representation of the content of the object.
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
virtual yarp::conf::float64_t asFloat64() const
Get 64-bit floating point value.
Definition Value.cpp:222
virtual bool isString() const
Checks if value is a string.
Definition Value.cpp:156
virtual bool asBool() const
Get boolean value.
Definition Value.cpp:186
virtual Bottle * asList() const
Get list value.
Definition Value.cpp:240
std::string toString() const override
Return a standard text representation of the content of the object.
Definition Value.cpp:356
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
yarp::os::WireLink & yarp()
Get YARP state associated with this object.
Definition Wire.h:28
int main(int argc, char *argv[])
Definition main.cpp:385
void delay(double seconds)
Wait for a certain number of seconds.
Definition Time.cpp:111
The main, catch-all namespace for YARP.
Definition dirs.h:16
@ ACTION_IDLE
Definition robotAction.h:19