YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
controlBoardRemapper_t1_test.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6#include <yarp/os/Time.h>
12
13#include <vector>
14
15#include <catch2/catch_amalgamated.hpp>
16#include <harness.h>
17
18using namespace yarp::os;
19using namespace yarp::dev;
20
21const char *fmcA_file_content = "device fakeMotionControl\n"
22 "[GENERAL]\n"
23 "Joints 2\n"
24 "\n"
25 "AxisName (\"axisA1\" \"axisA2\") \n";
26
27const char *fmcB_file_content = "device fakeMotionControl\n"
28 "[GENERAL]\n"
29 "Joints 3\n"
30 "\n"
31 "AxisName (\"axisB1\" \"axisB2\" \"axisB3\") \n";
32
33const char *fmcC_file_content = "device fakeMotionControl\n"
34 "[GENERAL]\n"
35 "Joints 4\n"
36 "\n"
37 "AxisName (\"axisC1\" \"axisC2\" \"axisC3\" \"axisC4\") \n";
38
39const char *fmcA_file_content_micro = "device fakeMotionControlMicro\n"
40 "[GENERAL]\n"
41 "Joints 2\n"
42 "\n"
43 "AxisName (\"axisA1\" \"axisA2\") \n";
44
45const char *fmcB_file_content_micro = "device fakeMotionControlMicro\n"
46 "[GENERAL]\n"
47 "Joints 3\n"
48 "\n"
49 "AxisName (\"axisB1\" \"axisB2\" \"axisB3\") \n";
50
51const char *fmcC_file_content_micro = "device fakeMotionControlMicro\n"
52 "[GENERAL]\n"
53 "Joints 4\n"
54 "\n"
55 "AxisName (\"axisC1\" \"axisC2\" \"axisC3\" \"axisC4\") \n";
56
57const char *wrapperA_file_content = "device controlBoard_nws_yarp\n"
58 "name /testRemapperRobot/a\n"
59 "period 0.01\n";
60
61const char *wrapperB_file_content = "device controlBoard_nws_yarp\n"
62 "name /testRemapperRobot/b\n"
63 "period 0.01\n";
64
65const char *wrapperC_file_content = "device controlBoard_nws_yarp\n"
66 "name /testRemapperRobot/c\n"
67 "period 0.01\n";
68
69
71{
72 IPositionControl *pos = nullptr;
73 REQUIRE(ddRemapper.view(pos)); // interface position correctly opened
74 REQUIRE(pos);
75
76 int axes = 0;
77 CHECK(pos->getAxes(&axes)); // getAxes returned correctly
78 CHECK((size_t) axes == nrOfRemappedAxes); // remapper seems functional
79
80 IPositionDirect *posdir = nullptr;
81 REQUIRE(ddRemapper.view(posdir)); // direct position interface correctly opened
83
84 IEncoders * encs = nullptr;
85 REQUIRE(ddRemapper.view(encs)); // encoders interface correctly opened
87
88 IControlMode *ctrlmode = nullptr;
89 REQUIRE(ddRemapper.view(ctrlmode)); // control mode interface correctly opened
91
92 // Vector used for setting/getting data from the controlboard
93 std::vector<double> setPosition(nrOfRemappedAxes,-10),
94 setRefSpeeds(nrOfRemappedAxes,-15),
97
98 for(size_t i=0; i < nrOfRemappedAxes; i++)
99 {
100 setPosition[i] = i*100.0+50.0 + rand;
101 setRefSpeeds[i] = i*10.0+5 + rand;
102 readedPosition[i] = -100 + rand;
103 }
104
105 // Set the control mode in position direct
108
109 CHECK(ctrlmode->setControlModes(settedControlMode.data())); // setControlModes correctly called
110
111 // Check that the read control mode is actually position direct
112 // Let's try 10 times because if the remapper is using some remotecontrolboards,
113 // it is possible that this return false if it is called before the first message
114 // has been received from the controlboard_nws_yarp
115 bool getControlModesOk = false;
116 for(int wait=0; wait < 20 && !getControlModesOk; wait++)
117 {
118 getControlModesOk = ctrlmode->getControlModes(readedControlMode.data());
120 }
121 CHECK(getControlModesOk); // getControlModes correctly called
122
123 for(size_t i=0; i < nrOfRemappedAxes; i++)
124 {
125 CHECK(settedControlMode[i] == readedControlMode[i]); // Setted control mode and readed control mode match
126 }
127
128 // Test position direct methods
129
130 // Set position
131 CHECK(posdir->setPositions(setPosition.data())); // setPositions correctly called
132
133 // Set also the speeds in the mean time, so we are sure that we don't get
134 // spurios successful set/get of position because of intermediate buffers
135 CHECK(pos->setRefSpeeds(setRefSpeeds.data())); // setRefSpeeds correctly called
136
137 // Wait some time to make sure that the vector has been correctly propagated
138 // back and forth
140
141 // Read position
142 CHECK(posdir->getRefPositions(readedPosition.data())); // getRefPositions correctly called
143
144 // Check that the two vector match
145 for(size_t i=0; i < nrOfRemappedAxes; i++)
146 {
147 CHECK(setPosition[i] == readedPosition[i]); // Setted position and readed ref position match
148 }
149
150 // Do a similar test for the encoders
151 // in fakeMotionControl their value is the one setted with setPosition
152 CHECK(encs->getEncoders(readedEncoders.data())); // getEncoders correctly called
153
154 // Check that the two vector match
155 for(size_t i=0; i < nrOfRemappedAxes; i++)
156 {
157 CHECK(setPosition[i] == readedEncoders[i]); // Setted position and readed encoders match
158 }
159}
160
161
163{
164 IPositionControl *pos = nullptr;
165 REQUIRE(ddRemapper.view(pos)); // interface position correctly opened
166 REQUIRE(pos);
167
168 int axes = 0;
169 CHECK(pos->getAxes(&axes)); // getAxes returned correctly
170 CHECK((size_t) axes == nrOfRemappedAxes); // remapper seems functional
171
172 IPositionDirect *posdir = nullptr;
173 REQUIRE(ddRemapper.view(posdir)); // direct position interface correctly opened
175
176 IEncoders * encs = nullptr;
177 REQUIRE(ddRemapper.view(encs)); // encoders interface correctly opened
178 REQUIRE(encs);
179
180 IControlMode *ctrlmode = nullptr;
181 REQUIRE(ddRemapper.view(ctrlmode)); // control mode interface correctly opened
183
184 // Vector used for setting/getting data from the controlboard
185 std::vector<double> setPosition(nrOfRemappedAxes,-10),
186 setRefSpeeds(nrOfRemappedAxes,-15),
189
190 for(size_t i=0; i < nrOfRemappedAxes; i++)
191 {
192 setPosition[i] = i*100.0+50.0 + rand;
193 setRefSpeeds[i] = i*10.0+5 + rand;
194 readedPosition[i] = -100 + rand;
195 }
196
197 // Set the control mode in position direct
200
201 CHECK_FALSE(ctrlmode->setControlModes(settedControlMode.data()));
202
203 // Check that the read control mode is actually position direct
204 // Let's try 10 times because if the remapper is using some remotecontrolboards,
205 // it is possible that this return false if it is called before the first message
206 // has been received from the controlboard_nws_yarp
207 bool getControlModesOk = false;
208 for(int wait=0; wait < 20 && !getControlModesOk; wait++)
209 {
210 getControlModesOk = ctrlmode->getControlModes(readedControlMode.data());
212 }
214
215 // Test position direct methods
216
217 // Set also the speeds in the mean time, so we are sure that we don't get
218 // spurios successful set/get of position because of intermediate buffers
219 CHECK_FALSE(pos->setRefSpeeds(setRefSpeeds.data()));
220
221 // Wait some time to make sure that the vector has been correctly propagated
222 // back and forth
224
225 // Read position
226 CHECK_FALSE(posdir->getRefPositions(readedPosition.data()));
227
228 // Do a similar test for the encoders
229 // in fakeMotionControl their value is the one setted with setPosition
230 CHECK(encs->getEncoders(readedEncoders.data())); // getEncoders correctly called
231}
232
233
234TEST_CASE("dev::ControlBoardRemapperTest", "[yarp::dev]")
235{
236 YARP_REQUIRE_PLUGIN("fakeMotionControl", "device");
237 YARP_REQUIRE_PLUGIN("fakeMotionControlMicro", "device");
238 YARP_REQUIRE_PLUGIN("controlboardremapper", "device");
239 YARP_REQUIRE_PLUGIN("controlBoard_nws_yarp", "device");
240 YARP_REQUIRE_PLUGIN("remotecontrolboardremapper", "device");
241
242 Network::setLocalMode(true);
243
244 SECTION("Test the controlboard remapper")
245 {
246 // We first allocate three fakeMotionControl boards
247 // and their wrappers that we will remap using the remapper
248 std::vector<PolyDriver *> fmcbs;
249 std::vector<PolyDriver *> wrappers;
250 fmcbs.resize(3);
251 wrappers.resize(3);
252
253 std::vector<int> fmcbsSizes;
254 fmcbsSizes.push_back(2);
255 fmcbsSizes.push_back(3);
256 fmcbsSizes.push_back(4);
257
258 std::vector<std::string> fmcbsNames;
259 fmcbsNames.push_back("fakeControlBoardA");
260 fmcbsNames.push_back("fakeControlBoardB");
261 fmcbsNames.push_back("fakeControlBoardC");
262
263 std::vector<std::string> wrapperNetworks;
264 wrapperNetworks.push_back("net_a");
265 wrapperNetworks.push_back("net_b");
266 wrapperNetworks.push_back("net_c");
267
268
269 for(int i=0; i < 3; i++)
270 {
271 fmcbs[i] = new PolyDriver();
272
273 Property p;
274
275 if(i==0) { p.fromConfig(fmcA_file_content); }
276 if(i==1) { p.fromConfig(fmcB_file_content); }
277 if(i==2) { p.fromConfig(fmcC_file_content); }
278
279 REQUIRE(fmcbs[i]->open(p)); // fakeMotionControlBoard open reported successful
280
281 IPositionControl *pos = nullptr;
282 REQUIRE(fmcbs[i]->view(pos)); // interface position correctly opened
283 REQUIRE(pos);
284
285 int axes = 0;
286 pos->getAxes(&axes);
287 CHECK(axes == fmcbsSizes[i]); // fakeMotionControlBoard seems functional
288
289 // Open the wrapper
290 wrappers[i] = new PolyDriver();
291
292 if(i==0) { p.fromConfig(wrapperA_file_content); }
293 if(i==1) { p.fromConfig(wrapperB_file_content); }
294 if(i==2) { p.fromConfig(wrapperC_file_content); }
295
296 REQUIRE(wrappers[i]->open(p)); // controlBoard_nws_yarp open reported successful
297
299 REQUIRE(wrappers[i]->view(iwrap)); // interface for multiple wrapper correctly opened for the controlBoard_nws_yarp
300 REQUIRE(iwrap);
301
304
305 REQUIRE(iwrap->attachAll(pdList)); // controlBoard_nws_yarp attached successfully to the device
306 }
307
308 // Create a list containing all the fake controlboards
310
311 for(int i=0; i < 3; i++)
312 {
313 fmcList.push(fmcbs[i],fmcbsNames[i].c_str());
314 }
315
316 // Open a controlboardremapper with the wrong axisName,
317 // and make sure that if fails during attachAll
320 pRemapperWN.put("device","controlboardremapper");
321 pRemapperWN.addGroup("axesNames");
322 Bottle & axesListWN = pRemapperWN.findGroup("axesNames").addList();
323 axesListWN.addString("axisA1");
324 axesListWN.addString("axisB1");
325 axesListWN.addString("axisC1");
326 axesListWN.addString("axisB3");
327 axesListWN.addString("axisC3");
328 axesListWN.addString("axisA2");
329 axesListWN.addString("thisIsAnAxisNameThatDoNotExist");
330
331 REQUIRE(ddRemapperWN.open(pRemapperWN)); // controlboardremapper with wrong names open reported successful
332
334 REQUIRE(ddRemapperWN.view(imultwrapWN)); // interface for multiple wrapper with wrong names correctly opened
336
337 REQUIRE_FALSE(imultwrapWN->attachAll(fmcList)); // attachAll for controlboardremapper with wrong names successful
338
339 // Make sure that a controlboard in which attachAll is not successfull
340 // closes correctly
341 CHECK(ddRemapperWN.close()); // controlboardremapper with wrong names close was successful
342
343 // Open the controlboardremapper
346 pRemapper.put("device","controlboardremapper");
347 pRemapper.addGroup("axesNames");
348 Bottle & axesList = pRemapper.findGroup("axesNames").addList();
349 axesList.addString("axisA1");
350 axesList.addString("axisB1");
351 axesList.addString("axisC1");
352 axesList.addString("axisB3");
353 axesList.addString("axisC3");
354 axesList.addString("axisA2");
355 size_t nrOfRemappedAxes = 6;
356
357 REQUIRE(ddRemapper.open(pRemapper)); // controlboardremapper open reported successful
358
360 REQUIRE(ddRemapper.view(imultwrap)); // interface for multiple wrapper correctly opened
362
363 REQUIRE(imultwrap->attachAll(fmcList)); // attachAll for controlboardremapper successful
364
365
366 // Test the controlboardremapper
368
369 // Open the remotecontrolboardremapper
372 pRemoteRemapper.put("device","remotecontrolboardremapper");
373 pRemoteRemapper.addGroup("axesNames");
374 Bottle & remoteAxesList = pRemoteRemapper.findGroup("axesNames").addList();
375 remoteAxesList.addString("axisA1");
376 remoteAxesList.addString("axisB1");
377 remoteAxesList.addString("axisC1");
378 remoteAxesList.addString("axisB3");
379 remoteAxesList.addString("axisC3");
380 remoteAxesList.addString("axisA2");
381
384 remoteControlBoardsList.addString("/testRemapperRobot/a");
385 remoteControlBoardsList.addString("/testRemapperRobot/b");
386 remoteControlBoardsList.addString("/testRemapperRobot/c");
387 pRemoteRemapper.put("remoteControlBoards",remoteControlBoards.get(0));
388
389 pRemoteRemapper.put("localPortPrefix","/test/remoteControlBoardRemapper");
390
391 Property & opts = pRemoteRemapper.addGroup("REMOTE_CONTROLBOARD_OPTIONS");
392 opts.put("writeStrict","on");
393
394 REQUIRE(ddRemoteRemapper.open(pRemoteRemapper)); // remotecontrolboardremapper open reported successful, testing it
395
396 // Test the remotecontrolboardremapper
398
399 // Close devices
400 imultwrap->detachAll();
403
404 for(int i=0; i < 3; i++)
405 {
406 wrappers[i]->close();
407 delete wrappers[i];
408 wrappers[i] = nullptr;
409 fmcbs[i]->close();
410 delete fmcbs[i];
411 fmcbs[i] = nullptr;
412 }
413 }
414
415 SECTION("Test the controlboard remapper micro")
416 {
417 // We first allocate three fakeMotionControl boards
418 // and their wrappers that we will remap using the remapper
419 std::vector<PolyDriver *> fmcbs;
420 std::vector<PolyDriver *> wrappers;
421 fmcbs.resize(3);
422 wrappers.resize(3);
423
424 std::vector<int> fmcbsSizes;
425 fmcbsSizes.push_back(2);
426 fmcbsSizes.push_back(3);
427 fmcbsSizes.push_back(4);
428
429 std::vector<std::string> fmcbsNames;
430 fmcbsNames.push_back("fakeControlBoardAMicro");
431 fmcbsNames.push_back("fakeControlBoardBMicro");
432 fmcbsNames.push_back("fakeControlBoardCMicro");
433
434 std::vector<std::string> wrapperNetworks;
435 wrapperNetworks.push_back("net_a");
436 wrapperNetworks.push_back("net_b");
437 wrapperNetworks.push_back("net_c");
438
439
440 for(int i=0; i < 3; i++)
441 {
442 fmcbs[i] = new PolyDriver();
443
444 Property p;
445
446 if(i==0) { p.fromConfig(fmcA_file_content_micro); }
447 if(i==1) { p.fromConfig(fmcB_file_content_micro); }
448 if(i==2) { p.fromConfig(fmcC_file_content_micro); }
449
450 REQUIRE(fmcbs[i]->open(p)); // fakeMotionControlBoard open reported successful
451
452 IPositionControl *pos = nullptr;
453 REQUIRE_FALSE(fmcbs[i]->view(pos)); // interface position correctly not opened
454 REQUIRE_FALSE(pos);
455
456 int axes = 0;
457
458 IAxisInfoRaw *axisInfo = nullptr;
459 REQUIRE(fmcbs[i]->view(axisInfo)); // interface axisInfo correctly opened
461 axisInfo->getAxes(&axes);
462 CHECK(axes == fmcbsSizes[i]); // fakeMotionControlBoard seems functional
463
464 // Open the wrapper
465 wrappers[i] = new PolyDriver();
466
467 if(i==0) { p.fromConfig(wrapperA_file_content); }
468 if(i==1) { p.fromConfig(wrapperB_file_content); }
469 if(i==2) { p.fromConfig(wrapperC_file_content); }
470
471 REQUIRE(wrappers[i]->open(p)); // controlBoard_nws_yarp open reported successful
472
474 REQUIRE(wrappers[i]->view(iwrap)); // interface for multiple wrapper correctly opened for the controlBoard_nws_yarp
475 REQUIRE(iwrap);
476
479
480 REQUIRE(iwrap->attachAll(pdList)); // controlBoard_nws_yarp attached successfully to the device
481 }
482
483 // Create a list containing all the fake controlboards
485
486 for(int i=0; i < 3; i++)
487 {
488 fmcList.push(fmcbs[i],fmcbsNames[i].c_str());
489 }
490
491 // Open a controlboardremapper with the wrong axisName,
492 // and make sure that if fails during attachAll
495 pRemapperWN.put("device","controlboardremapper");
496 pRemapperWN.addGroup("axesNames");
497 Bottle & axesListWN = pRemapperWN.findGroup("axesNames").addList();
498 axesListWN.addString("axisA1");
499 axesListWN.addString("axisB1");
500 axesListWN.addString("axisC1");
501 axesListWN.addString("axisB3");
502 axesListWN.addString("axisC3");
503 axesListWN.addString("axisA2");
504 axesListWN.addString("thisIsAnAxisNameThatDoNotExist");
505
506 REQUIRE(ddRemapperWN.open(pRemapperWN)); // controlboardremapper with wrong names open reported successful
507
509 REQUIRE(ddRemapperWN.view(imultwrapWN)); // interface for multiple wrapper with wrong names correctly opened
511
512 REQUIRE_FALSE(imultwrapWN->attachAll(fmcList)); // attachAll for controlboardremapper with wrong names successful
513
514 // Make sure that a controlboard in which attachAll is not successfull
515 // closes correctly
516 CHECK(ddRemapperWN.close()); // controlboardremapper with wrong names close was successful
517
518 // Open the controlboardremapper
521 pRemapper.put("device","controlboardremapper");
522 pRemapper.addGroup("axesNames");
523 Bottle & axesList = pRemapper.findGroup("axesNames").addList();
524 axesList.addString("axisA1");
525 axesList.addString("axisB1");
526 axesList.addString("axisC1");
527 axesList.addString("axisB3");
528 axesList.addString("axisC3");
529 axesList.addString("axisA2");
530 size_t nrOfRemappedAxes = 6;
531
532 REQUIRE(ddRemapper.open(pRemapper)); // controlboardremapper open reported successful
533
535 REQUIRE(ddRemapper.view(imultwrap)); // interface for multiple wrapper correctly opened
537
538 REQUIRE(imultwrap->attachAll(fmcList)); // attachAll for controlboardremapper successful
539
540
541 // Test the controlboardremapper
543
544 // Open the remotecontrolboardremapper
547 pRemoteRemapper.put("device","remotecontrolboardremapper");
548 pRemoteRemapper.addGroup("axesNames");
549 Bottle & remoteAxesList = pRemoteRemapper.findGroup("axesNames").addList();
550 remoteAxesList.addString("axisA1");
551 remoteAxesList.addString("axisB1");
552 remoteAxesList.addString("axisC1");
553 remoteAxesList.addString("axisB3");
554 remoteAxesList.addString("axisC3");
555 remoteAxesList.addString("axisA2");
556
559 remoteControlBoardsList.addString("/testRemapperRobot/a");
560 remoteControlBoardsList.addString("/testRemapperRobot/b");
561 remoteControlBoardsList.addString("/testRemapperRobot/c");
562 pRemoteRemapper.put("remoteControlBoards",remoteControlBoards.get(0));
563
564 pRemoteRemapper.put("localPortPrefix","/test/remoteControlBoardRemapper");
565
566 Property & opts = pRemoteRemapper.addGroup("REMOTE_CONTROLBOARD_OPTIONS");
567 opts.put("writeStrict","on");
568
569 REQUIRE(ddRemoteRemapper.open(pRemoteRemapper)); // remotecontrolboardremapper open reported successful, testing it
570
571 // Test the remotecontrolboardremapper
573
574 // Close devices
575 imultwrap->detachAll();
578
579 for(int i=0; i < 3; i++)
580 {
581 wrappers[i]->close();
582 delete wrappers[i];
583 wrappers[i] = nullptr;
584 fmcbs[i]->close();
585 delete fmcbs[i];
586 fmcbs[i] = nullptr;
587 }
588 }
589
590 Network::setLocalMode(false);
591}
define control board standard interfaces
constexpr yarp::conf::vocab32_t VOCAB_CM_POSITION
constexpr yarp::conf::vocab32_t VOCAB_CM_POSITION_DIRECT
Interface for getting information about specific axes, if available.
Definition IAxisInfo.h:72
Interface for setting control mode in control board.
Control board, encoder interface.
Definition IEncoders.h:116
Interface for an object that can wrap/attach to to another.
Interface for a generic control board device implementing position control.
virtual bool getAxes(int *ax)=0
Get the number of controlled axes.
virtual bool setRefSpeeds(const double *spds)=0
Set reference speed on all joints.
Interface for a generic control board device implementing position control.
A container for a device driver.
Definition PolyDriver.h:23
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
A mini-server for performing network communication in the background.
void close() override
Stop port activity.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
A class for storing options and configuration information.
Definition Property.h:33
const char * wrapperC_file_content
static void checkRemapperMicro(yarp::dev::PolyDriver &ddRemapper, int rand, size_t nrOfRemappedAxes)
TEST_CASE("dev::ControlBoardRemapperTest", "[yarp::dev]")
const char * fmcA_file_content_micro
const char * fmcA_file_content
const char * fmcB_file_content_micro
const char * fmcB_file_content
const char * fmcC_file_content_micro
const char * fmcC_file_content
static void checkRemapper(yarp::dev::PolyDriver &ddRemapper, int rand, size_t nrOfRemappedAxes)
const char * wrapperA_file_content
const char * wrapperB_file_content
For streams capable of holding different kinds of content, check what they actually have.
Definition jointData.cpp:13
void delay(double seconds)
Wait for a certain number of seconds.
Definition Time.cpp:111
An interface to the operating system, including Port based communication.