yarp-devices
Loading...
Searching...
No Matches
exampleOfflineTrajectorySync.cpp

A constant-velocity, single-joint trajectory is generated with configurable final target, motion speed and period between consecutive points. The yarp::dev::IRemoteVariables interface is used to configure and switch to interpolated position (pi) mode on the real robot. Although prepared for remote execution, this application could be rewritten to connect to a local instance of CanBusBroker. The techniques showcased here are best aimed at trajectories fully available offline (e.g. loaded from file) that assume a constant period between points. To fully take advantage of this fact, all points are sent to the robot in a single batch, hence the flow of the program is slightly different from what you'd expect (no delay function within a for-loop).

Usage (showing default option values):

 exampleOfflineTrajectorySync --remote /teo/leftArm --joint 5 --speed 2.0 --target -20.0 --period 50 --ip pt
See also
exampleOfflineTrajectoryAsync.cpp Use this if the period between points is variable.
exampleOfflineTrajectorySync.py
Tutorial: Trajectory Execution (external)
Note
This application is not suitable for simulation.
1// -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2
33#include <cmath>
34
35#include <iostream>
36
37#include <yarp/conf/version.h>
38
39#include <yarp/os/LogStream.h>
40#include <yarp/os/Network.h>
41#include <yarp/os/Property.h>
42#include <yarp/os/ResourceFinder.h>
43#include <yarp/os/SystemClock.h>
44
45#include <yarp/dev/IControlMode.h>
46#include <yarp/dev/IEncoders.h>
47#include <yarp/dev/IPositionControl.h>
48#include <yarp/dev/IPositionDirect.h>
49#include <yarp/dev/IRemoteVariables.h>
50#include <yarp/dev/PolyDriver.h>
51
52constexpr auto DEFAULT_REMOTE = "/teo/leftArm";
53constexpr auto DEFAULT_JOINT = 5;
54constexpr auto DEFAULT_SPEED = 2.0; // deg/s
55constexpr auto DEFAULT_TARGET = (-20.0);
56constexpr auto DEFAULT_PERIOD_MS = 50;
57constexpr auto DEFAULT_IP_MODE = "pt";
58
59int main(int argc, char * argv[])
60{
61 yarp::os::ResourceFinder rf;
62 rf.configure(argc, argv);
63
64 auto remote = rf.check("remote", yarp::os::Value(DEFAULT_REMOTE), "remote port").asString();
65 auto joint = rf.check("joint", yarp::os::Value(DEFAULT_JOINT), "joint id").asInt32();
66 auto speed = rf.check("speed", yarp::os::Value(DEFAULT_SPEED), "trajectory speed (deg/s)").asFloat64();
67 auto target = rf.check("target", yarp::os::Value(DEFAULT_TARGET), "target position (deg)").asFloat64();
68 auto period = rf.check("period", yarp::os::Value(DEFAULT_PERIOD_MS), "command period (ms)").asInt32() * 0.001;
69 auto ip = rf.check("ip", yarp::os::Value(DEFAULT_IP_MODE), "interpolation submode [pt|pvt]").asString();
70
71 if (speed <= 0)
72 {
73 yError() << "Illegal speed (deg/s):" << speed;
74 return 1;
75 }
76
77 if (period <= 0)
78 {
79 yError() << "Illegal period (s):" << period;
80 return 1;
81 }
82
83 if (ip != "pt" && ip != "pvt")
84 {
85 yError() << "Illegal ip mode:" << ip;
86 return 1;
87 }
88
89 yarp::os::Network yarp;
90
91 if (!yarp::os::Network::checkNetwork())
92 {
93 yError() << "Please start a yarp name server first";
94 return 1;
95 }
96
97 yarp::os::Property options {{"device", yarp::os::Value("remote_controlboard")},
98 {"local", yarp::os::Value("/exampleOfflineTrajectorySync")},
99 {"remote", yarp::os::Value(remote)},
100 {"writeStrict", yarp::os::Value("on")}};
101
102 yarp::dev::PolyDriver dd(options);
103
104 if (!dd.isValid())
105 {
106 yError() << "Remote device not available";
107 return 1;
108 }
109
110 yarp::dev::IControlMode * mode;
111 yarp::dev::IEncoders * enc;
112 yarp::dev::IPositionControl * pos;
113 yarp::dev::IPositionDirect * posd;
114 yarp::dev::IRemoteVariables * var;
115
116 if (!dd.view(mode) || !dd.view(enc) || !dd.view(pos) || !dd.view(posd) || !dd.view(var))
117 {
118 yError() << "Unable to acquire robot interfaces";
119 return 1;
120 }
121
122 yarp::os::Bottle b;
123 yarp::os::Bottle & bb = b.addList(); // additional nesting because of controlboardremapper
124
125 bb.addList() = {yarp::os::Value("ipMode"), yarp::os::Value(ip)};
126 bb.addList() = {yarp::os::Value("ipPeriodMs"), yarp::os::Value(period * 1000.0)};
127 bb.addList() = {yarp::os::Value("enableIp"), yarp::os::Value(true)}; // important: place this last
128
129 if (!var->setRemoteVariable("all", b))
130 {
131 yError() << "Unable to set interpolation mode";
132 return 1;
133 }
134
135 if (!mode->setControlMode(joint, VOCAB_CM_POSITION_DIRECT))
136 {
137 yError() << "Unable to set position direct mode";
138 return 1;
139 }
140
141 double initialPos;
142 int retries = 0;
143
144 while (!enc->getEncoder(joint, &initialPos) && retries++ < 10)
145 {
146 yarp::os::SystemClock::delaySystem(0.05);
147 }
148
149 if (retries >= 10)
150 {
151 yError() << "getEncoders() failed";
152 return 1;
153 }
154
155 yInfo() << "Current ENC value:" << initialPos;
156
157 std::cin.get();
158
159 yInfo() << "Moving joint" << joint << "to" << target << "degrees...";
160
161 const double distance = target - initialPos;
162 const double increment = std::copysign(speed * period, distance);
163
164 int count = 1;
165 double newDistance = 0.0;
166
167 do
168 {
169 newDistance = count * increment;
170 auto position = initialPos + newDistance;
171 yInfo("[%d] New target: %f", count++, position);
172 posd->setPosition(joint, position);
173 }
174 while (std::abs(distance) > std::abs(newDistance));
175
176 bool motionDone;
177
178 do
179 {
180 std::cout << "." << std::flush;
181 yarp::os::SystemClock::delaySystem(0.1);
182 }
183#if YARP_VERSION_COMPARE(>=, 4, 0, 0)
184 while (pos->checkMotionDone(motionDone) && !motionDone);
185#else
186 while (pos->checkMotionDone(&motionDone) && !motionDone);
187#endif
188
189 std::cout << " end" << std::endl;
190
191 return 0;
192}