22 #include <robottestingframework/TestAssert.h>
23 #include <robottestingframework/dll/Plugin.h>
24 #include <yarp/os/Time.h>
25 #include <yarp/os/Property.h>
30 #include "TorqueControlAccuracy.h"
32 using namespace robottestingframework;
33 using namespace yarp::os;
34 using namespace yarp::dev;
39 TorqueControlAccuracy::TorqueControlAccuracy() : yarp::robottestingframework::TestCase(
"TorqueControlAccuracy") {
52 TorqueControlAccuracy::~TorqueControlAccuracy() { }
54 bool TorqueControlAccuracy::setup(yarp::os::Property& property) {
57 if(property.check(
"name"))
58 setName(property.find(
"name").asString());
61 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check(
"robot"),
"The robot name must be given as the test parameter!");
62 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check(
"part"),
"The part name must be given as the test parameter!");
63 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check(
"joints"),
"The joints list must be given as the test parameter!");
64 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check(
"zeros"),
"The zero position list must be given as the test parameter!");
65 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check(
"cycles"),
"The number of cycles of the control signal must be given as the test parameter!");
66 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check(
"step"),
"The amplitude of the step reference signal expressed in Nm!");
67 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(property.check(
"sampleTime"),
"The sampleTime of the control signal must be given as the test parameter!");
69 m_robotName =
property.find(
"robot").asString();
70 m_partName =
property.find(
"part").asString();
72 Bottle* jointsBottle =
property.find(
"joints").asList();
73 Bottle* zerosBottle =
property.find(
"zeros").asList();
75 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(jointsBottle!=0,
"unable to parse joints parameter");
76 m_n_cmd_joints = jointsBottle->size();
77 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(m_n_cmd_joints>0,
"invalid number of joints, it must be >0");
79 m_step =
property.find(
"step").asFloat64();
81 m_cycles =
property.find(
"cycles").asInt32();
82 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(m_cycles>0,
"invalid cycles");
84 m_sampleTime =
property.find(
"sampleTime").asFloat64();
85 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(m_sampleTime>0,
"invalid sampleTime");
88 options.put(
"device",
"remote_controlboard");
89 options.put(
"remote",
"/" + m_robotName +
"/" + m_partName);
90 options.put(
"local",
"/TorqueControlAccuracyTest/" + m_robotName +
"/" + m_partName);
92 dd =
new PolyDriver(options);
93 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(dd->isValid(),
"Unable to open device driver");
94 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(dd->view(itrq),
"Unable to open torque control interface");
95 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(dd->view(ienc),
"Unable to open encoders interface");
96 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(dd->view(ipos),
"Unable to open position interface");
97 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(dd->view(icmd),
"Unable to open control mode interface");
98 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF(dd->view(iimd),
"Unable to open interaction mode interface");
100 if (!ienc->getAxes(&m_n_part_joints))
102 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"unable to get the number of joints of the part");
105 m_zeros =
new double[m_n_part_joints];
106 m_encoders =
new double[m_n_part_joints];
107 m_jointsList =
new int[m_n_cmd_joints];
108 m_torques =
new double[m_n_part_joints];
109 for (
int i = 0; i <m_n_cmd_joints; i++) m_jointsList[i] = jointsBottle->get(i).asInt32();
110 for (
int i = 0; i <m_n_cmd_joints; i++) m_zeros[i] = zerosBottle->get(i).asFloat64();
115 void TorqueControlAccuracy::tearDown()
117 if (m_jointsList) {
delete [] m_jointsList; m_jointsList = 0; }
118 if (m_zeros) {
delete [] m_zeros; m_zeros = 0; }
119 if (m_torques) {
delete [] m_torques; m_torques = 0; }
120 if (m_encoders) {
delete [] m_encoders; m_encoders = 0; }
121 if (dd) {
delete dd; dd =0;}
124 void TorqueControlAccuracy::setMode(
int desired_mode)
126 for (
int i = 0; i<m_n_cmd_joints; i++)
128 icmd->setControlMode(m_jointsList[i], desired_mode);
129 iimd->setInteractionMode(m_jointsList[i], VOCAB_IM_STIFF);
130 yarp::os::Time::delay(0.010);
134 yarp::dev::InteractionModeEnum imode;
140 for (
int i = 0; i<m_n_cmd_joints; i++)
142 icmd->getControlMode(m_jointsList[i], &cmode);
143 iimd->getInteractionMode(m_jointsList[i], &imode);
144 if (cmode==desired_mode && imode==VOCAB_IM_STIFF) ok++;
146 if (ok == m_n_cmd_joints)
break;
149 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"Unable to set control mode/interaction mode");
151 yarp::os::Time::delay(0.2);
156 bool TorqueControlAccuracy::goHome()
158 for (
int i = 0; i<m_n_cmd_joints; i++)
160 ipos->setRefSpeed(m_jointsList[i], 20.0);
161 ipos->positionMove(m_jointsList[i], m_zeros[i]);
168 for (
int i = 0; i<m_n_cmd_joints; i++)
170 ienc->getEncoder(m_jointsList[i], &m_encoders[m_jointsList[i]]);
171 if (fabs(m_encoders[m_jointsList[i]] - m_zeros[i])<0.5) in_position++;
173 if (in_position == m_n_cmd_joints)
break;
176 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR(
"Timeout while reaching zero position");
179 yarp::os::Time::delay(0.2);
183 yarp::os::Time::delay(0.5);
187 void TorqueControlAccuracy::run()
189 for (
int i = 0; i < m_n_cmd_joints; i++)
191 for (
int cycle = 0; cycle < m_cycles; cycle++)
193 setMode(VOCAB_CM_POSITION);
194 if (goHome() ==
false)
196 ROBOTTESTINGFRAMEWORK_ASSERT_FAIL(
"Test stopped");
198 setMode(VOCAB_CM_TORQUE);
199 double start_time = yarp::os::Time::now();
201 std::string buff =
"Testing Joint: " + std::to_string(i) +
" cycle: " + std::to_string(cycle);
202 ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
204 double time_zero = 0;
205 yarp::os::Bottle dataToPlotRaw;
206 yarp::os::Bottle dataToPlotSync;
210 double curr_time = yarp::os::Time::now();
211 double elapsed = curr_time - start_time;
217 else if (elapsed > 1.0 && elapsed <= 4.0)
219 m_cmd_single = m_zeros[i] + m_step;
220 if (time_zero == 0) time_zero = elapsed;
227 ienc->getEncoders(m_encoders);
228 itrq->getTorques(m_torques);
229 itrq->setRefTorque(m_jointsList[i], m_cmd_single);
231 Bottle& b1 = dataToPlotRaw.addList();
233 b1.addFloat64(elapsed);
234 b1.addFloat64(m_torques[m_jointsList[i]]);
235 b1.addFloat64(m_cmd_single);
236 yarp::os::Time::delay(m_sampleTime);
240 for (
int t = 0; t < dataToPlotRaw.size(); t++)
242 int cycle = dataToPlotRaw.get(t).asList()->get(0).asInt32();
243 double time = dataToPlotRaw.get(t).asList()->get(1).asFloat64();
244 double val = dataToPlotRaw.get(t).asList()->get(2).asFloat64();
245 double cmd = dataToPlotRaw.get(t).asList()->get(3).asFloat64();
246 Bottle& b1 = dataToPlotSync.addList();
248 b1.addFloat64(time - time_zero);
253 m_dataToSave.append(dataToPlotSync);
257 std::string filename =
"torqueControlAccuracy_plot_";
258 filename += m_partName;
259 filename += std::to_string(i);
261 saveToFile(filename, m_dataToSave);
265 setMode(VOCAB_CM_POSITION);
267 ROBOTTESTINGFRAMEWORK_TEST_REPORT(
"Data acquisition complete");
282 void TorqueControlAccuracy::saveToFile(std::string filename, yarp::os::Bottle &b)
285 fs.open(filename.c_str(), std::fstream::out);
287 for (
int i = 0; i<b.size(); i++)
289 std::string s = b.get(i).toString();
290 std::replace(s.begin(), s.end(),
'(',
' ');
291 std::replace(s.begin(), s.end(),
')',
' ');
292 fs << s << std::endl;
This tests checks the a torque PID response, sending a step reference signal with a setRefTorque comm...