22 #include <robottestingframework/TestAssert.h>
23 #include <robottestingframework/dll/Plugin.h>
24 #include <yarp/os/LogStream.h>
25 #include <yarp/os/Time.h>
26 #include <yarp/os/Property.h>
32 #include "PositionControlAccuracy.h"
34 using namespace robottestingframework;
35 using namespace yarp::os;
36 using namespace yarp::dev;
41 PositionControlAccuracy::PositionControlAccuracy() : yarp::robottestingframework::TestCase(
"PositionControlAccuracy") {
55 PositionControlAccuracy::~PositionControlAccuracy() { }
57 bool PositionControlAccuracy::setup(yarp::os::Property& property) {
60 if(property.check(
"name"))
61 setName(property.find(
"name").asString());
64 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"robot"),
"The robot name must be given as the test parameter!");
65 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"part"),
"The part name must be given as the test parameter!");
66 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"joints"),
"The joints list must be given as the test parameter!");
67 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"zeros"),
"The zero position list must be given as the test parameter!");
68 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"cycles"),
"The number of cycles of the control signal must be given as the test parameter!");
69 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"step"),
"The amplitude of the step reference signal expressed in degrees!");
70 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check(
"sampleTime"),
"The sampleTime of the control signal must be given as the test parameter!");
71 if(property.check(
"filename"))
72 {m_requested_filename =
property.find(
"filename").asString();}
73 if(property.check(
"home_tolerance"))
74 {m_home_tolerance =
property.find(
"home_tolerance").asFloat64();}
75 if(property.check(
"step_duration"))
76 {m_step_duration =
property.find(
"step_duration").asFloat64();}
78 m_robotName =
property.find(
"robot").asString();
79 m_partName =
property.find(
"part").asString();
81 Bottle* jointsBottle =
property.find(
"joints").asList();
82 Bottle* zerosBottle =
property.find(
"zeros").asList();
84 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(jointsBottle!=0,
"unable to parse joints parameter");
85 m_n_cmd_joints = jointsBottle->size();
86 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(m_n_cmd_joints>0,
"invalid number of joints, it must be >0");
88 m_step =
property.find(
"step").asFloat64();
90 m_cycles =
property.find(
"cycles").asInt32();
91 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(m_cycles>0,
"invalid cycles");
93 m_sampleTime =
property.find(
"sampleTime").asFloat64();
94 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(m_sampleTime>0,
"invalid sampleTime");
97 options.put(
"device",
"remote_controlboard");
98 options.put(
"remote",
"/" + m_robotName +
"/" + m_partName);
99 options.put(
"local",
"/positionControlAccuracyTest/" + m_robotName +
"/" + m_partName);
101 dd =
new PolyDriver(options);
102 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->isValid(),
"Unable to open device driver");
103 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(idir),
"Unable to open position direct interface");
104 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ienc),
"Unable to open encoders interface");
105 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipos),
"Unable to open position interface");
106 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(icmd),
"Unable to open control mode interface");
107 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iimd),
"Unable to open interaction mode interface");
108 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipid),
"Unable to open pid interface");
110 if (!ienc->getAxes(&m_n_part_joints))
112 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"unable to get the number of joints of the part");
115 m_zeros =
new double[m_n_part_joints];
116 m_encoders =
new double[m_n_part_joints];
117 m_jointsList =
new int[m_n_cmd_joints];
118 for (
int i = 0; i <m_n_cmd_joints; i++) m_jointsList[i] = jointsBottle->get(i).asInt32();
119 for (
int i = 0; i <m_n_cmd_joints; i++) m_zeros[i] = zerosBottle->get(i).asFloat64();
121 double p_Kp=std::nanf(
"");
122 double p_Ki=std::nanf(
"");
123 double p_Kd=std::nanf(
"");
124 double p_Max=std::nanf(
"");
126 int cj=m_jointsList[0];
127 ipid->getPid(VOCAB_PIDTYPE_POSITION,cj,&m_orig_pid);
128 m_new_pid=m_orig_pid;
130 if(property.check(
"Kp"))
131 {p_Kp =
property.find(
"Kp").asFloat64();}
132 if(property.check(
"Ki"))
133 {p_Ki =
property.find(
"Ki").asFloat64();}
134 if(property.check(
"Kd"))
135 {p_Kd =
property.find(
"Kd").asFloat64();}
138 if (std::isnan(p_Kp)==
false) {m_new_pid.kp=p_Kp;}
139 if (std::isnan(p_Kd)==
false) {m_new_pid.kd=p_Kd;}
140 if (std::isnan(p_Ki)==
false) {m_new_pid.ki=p_Ki;}
152 void PositionControlAccuracy::tearDown()
154 if (m_jointsList) {
delete [] m_jointsList; m_jointsList = 0; }
155 if (m_zeros) {
delete [] m_zeros; m_zeros = 0; }
156 if (m_encoders) {
delete [] m_encoders; m_encoders = 0; }
157 if (dd) {
delete dd; dd =0;}
160 void PositionControlAccuracy::setMode(
int desired_mode)
162 for (
int i = 0; i<m_n_cmd_joints; i++)
164 icmd->setControlMode(m_jointsList[i], desired_mode);
165 iimd->setInteractionMode(m_jointsList[i], VOCAB_IM_STIFF);
166 yarp::os::Time::delay(0.010);
170 yarp::dev::InteractionModeEnum imode;
176 for (
int i = 0; i<m_n_cmd_joints; i++)
178 icmd->getControlMode(m_jointsList[i], &cmode);
179 iimd->getInteractionMode(m_jointsList[i], &imode);
180 if (cmode==desired_mode && imode==VOCAB_IM_STIFF) ok++;
182 if (ok == m_n_cmd_joints)
break;
185 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"Unable to set control mode/interaction mode");
187 yarp::os::Time::delay(0.2);
192 bool PositionControlAccuracy::goHome()
194 for (
int i = 0; i<m_n_cmd_joints; i++)
196 ipos->setRefSpeed(m_jointsList[i], 20.0);
197 ipos->positionMove(m_jointsList[i], m_zeros[i]);
204 for (
int i = 0; i<m_n_cmd_joints; i++)
206 ienc->getEncoder(m_jointsList[i], &m_encoders[m_jointsList[i]]);
207 if (fabs(m_encoders[m_jointsList[i]] - m_zeros[i])<m_home_tolerance) in_position++;
209 if (in_position == m_n_cmd_joints)
break;
212 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"Timeout while reaching zero position");
215 yarp::os::Time::delay(0.2);
219 yarp::os::Time::delay(0.5);
223 void PositionControlAccuracy::run()
225 for (
int i = 0; i < m_n_cmd_joints; i++)
227 for (
int cycle = 0; cycle < m_cycles; cycle++)
229 ipid->setPid(VOCAB_PIDTYPE_POSITION,m_jointsList[i],m_orig_pid);
230 setMode(VOCAB_CM_POSITION);
231 if (goHome() ==
false)
233 ROBOTTESTINGFRAMEWORK_ASSERT_FAIL(
"Test stopped");
236 ipid->setPid(VOCAB_PIDTYPE_POSITION,m_jointsList[i],m_new_pid);
237 setMode(VOCAB_CM_POSITION_DIRECT);
238 double start_time = yarp::os::Time::now();
241 sprintf(cbuff,
"Testing Joint: %d cycle: %d", i, cycle);
243 std::string buff(cbuff);
244 ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
246 double time_zero = 0;
247 yarp::os::Bottle dataToPlotRaw;
248 yarp::os::Bottle dataToPlotSync;
252 double curr_time = yarp::os::Time::now();
253 double elapsed = curr_time - start_time;
257 m_cmd_single = m_zeros[i];
259 else if (elapsed > 1.0 && elapsed <= m_step_duration)
261 m_cmd_single = m_zeros[i] + m_step;
262 if (time_zero == 0) time_zero = elapsed;
269 ienc->getEncoders(m_encoders);
270 idir->setPosition(m_jointsList[i], m_cmd_single);
272 Bottle& b1 = dataToPlotRaw.addList();
274 b1.addFloat64(elapsed);
275 b1.addFloat64(m_encoders[m_jointsList[i]]);
276 b1.addFloat64(m_cmd_single);
277 yarp::os::Time::delay(m_sampleTime);
281 for (
int t = 0; t < dataToPlotRaw.size(); t++)
283 int cycle = dataToPlotRaw.get(t).asList()->get(0).asInt32();
284 double time = dataToPlotRaw.get(t).asList()->get(1).asFloat64();
285 double val = dataToPlotRaw.get(t).asList()->get(2).asFloat64();
286 double cmd = dataToPlotRaw.get(t).asList()->get(3).asFloat64();
287 Bottle& b1 = dataToPlotSync.addList();
289 b1.addFloat64(time - time_zero);
294 m_dataToSave.append(dataToPlotSync);
298 std::string filename;
299 if (m_requested_filename==
"")
302 sprintf(cfilename,
"positionControlAccuracy_plot_%s%d.txt", m_partName.c_str(), i);
303 filename = cfilename;
310 filename=m_requested_filename;
312 yInfo() <<
"Saving file to: "<< filename;
313 saveToFile(filename, m_dataToSave);
314 ipid->setPid(VOCAB_PIDTYPE_POSITION,m_jointsList[i],m_orig_pid);
318 setMode(VOCAB_CM_POSITION);
320 ROBOTTESTINGFRAMEWORK_TEST_REPORT(
"Data acquisition complete");
335 void PositionControlAccuracy::saveToFile(std::string filename, yarp::os::Bottle &b)
338 fs.open(filename.c_str(), std::fstream::out);
340 for (
int i = 0; i<b.size(); i++)
342 std::string s = b.get(i).toString();
343 std::replace(s.begin(), s.end(),
'(',
' ');
344 std::replace(s.begin(), s.end(),
')',
' ');
345 fs << s << std::endl;
This tests checks the a position PID response, sending a step reference signal with a positionDirect ...