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).
37 #include <yarp/os/LogStream.h>
38 #include <yarp/os/Network.h>
39 #include <yarp/os/Property.h>
40 #include <yarp/os/ResourceFinder.h>
41 #include <yarp/os/SystemClock.h>
43 #include <yarp/dev/IControlMode.h>
44 #include <yarp/dev/IEncoders.h>
45 #include <yarp/dev/IPositionControl.h>
46 #include <yarp/dev/IPositionDirect.h>
47 #include <yarp/dev/IRemoteVariables.h>
48 #include <yarp/dev/PolyDriver.h>
50 constexpr
auto DEFAULT_REMOTE =
"/teo/leftArm";
51 constexpr
auto DEFAULT_JOINT = 5;
52 constexpr
auto DEFAULT_SPEED = 2.0;
53 constexpr
auto DEFAULT_TARGET = (-20.0);
54 constexpr
auto DEFAULT_PERIOD_MS = 50;
55 constexpr
auto DEFAULT_IP_MODE =
"pt";
57 int main(
int argc,
char * argv[])
59 yarp::os::ResourceFinder rf;
60 rf.configure(argc, argv);
62 auto remote = rf.check(
"remote", yarp::os::Value(DEFAULT_REMOTE),
"remote port").asString();
63 auto joint = rf.check(
"joint", yarp::os::Value(DEFAULT_JOINT),
"joint id").asInt32();
64 auto speed = rf.check(
"speed", yarp::os::Value(DEFAULT_SPEED),
"trajectory speed (deg/s)").asFloat64();
65 auto target = rf.check(
"target", yarp::os::Value(DEFAULT_TARGET),
"target position (deg)").asFloat64();
66 auto period = rf.check(
"period", yarp::os::Value(DEFAULT_PERIOD_MS),
"command period (ms)").asInt32() * 0.001;
67 auto ip = rf.check(
"ip", yarp::os::Value(DEFAULT_IP_MODE),
"interpolation submode [pt|pvt]").asString();
71 yError() <<
"Illegal speed (deg/s):" << speed;
77 yError() <<
"Illegal period (s):" << period;
81 if (ip !=
"pt" && ip !=
"pvt")
83 yError() <<
"Illegal ip mode:" << ip;
87 yarp::os::Network yarp;
89 if (!yarp::os::Network::checkNetwork())
91 yError() <<
"Please start a yarp name server first";
95 yarp::os::Property options {{
"device", yarp::os::Value(
"remote_controlboard")},
96 {
"local", yarp::os::Value(
"/exampleOfflineTrajectorySync")},
97 {
"remote", yarp::os::Value(remote)},
98 {
"writeStrict", yarp::os::Value(
"on")}};
100 yarp::dev::PolyDriver dd(options);
104 yError() <<
"Remote device not available";
108 yarp::dev::IControlMode * mode;
109 yarp::dev::IEncoders * enc;
110 yarp::dev::IPositionControl * pos;
111 yarp::dev::IPositionDirect * posd;
112 yarp::dev::IRemoteVariables * var;
114 if (!dd.view(mode) || !dd.view(enc) || !dd.view(pos) || !dd.view(posd) || !dd.view(var))
116 yError() <<
"Unable to acquire robot interfaces";
121 yarp::os::Bottle & bb = b.addList();
123 bb.addList() = {yarp::os::Value(
"ipMode"), yarp::os::Value(ip)};
124 bb.addList() = {yarp::os::Value(
"ipPeriodMs"), yarp::os::Value(period * 1000.0)};
125 bb.addList() = {yarp::os::Value(
"enableIp"), yarp::os::Value(
true)};
127 if (!var->setRemoteVariable(
"all", b))
129 yError() <<
"Unable to set interpolation mode";
133 if (!mode->setControlMode(joint, VOCAB_CM_POSITION_DIRECT))
135 yError() <<
"Unable to set position direct mode";
142 while (!enc->getEncoder(joint, &initialPos) && retries++ < 10)
144 yarp::os::SystemClock::delaySystem(0.05);
149 yError() <<
"getEncoders() failed";
153 yInfo() <<
"Current ENC value:" << initialPos;
157 yInfo() <<
"Moving joint" << joint <<
"to" << target <<
"degrees...";
159 const double distance = target - initialPos;
160 const double increment = std::copysign(speed * period, distance);
163 double newDistance = 0.0;
167 newDistance = count * increment;
168 auto position = initialPos + newDistance;
169 yInfo(
"[%d] New target: %f", count++, position);
170 posd->setPosition(joint, position);
172 while (std::abs(distance) > std::abs(newDistance));
178 std::cout <<
"." << std::flush;
179 yarp::os::SystemClock::delaySystem(0.1);
181 while (pos->checkMotionDone(&motionDone) && !motionDone);
183 std::cout <<
" end" << std::endl;