icub-test
Loading...
Searching...
No Matches
motorEncodersSignCheck.cpp
1/*
2 * iCub Robot Unit Tests (Robot Testing Framework)
3 *
4 * Copyright (C) 2015-2019 Istituto Italiano di Tecnologia (IIT)
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21
22#include <robottestingframework/TestAssert.h>
23#include <robottestingframework/dll/Plugin.h>
24#include <yarp/os/Time.h>
25#include <yarp/os/Property.h>
26#include <algorithm>
27#include "motorEncodersSignCheck.h"
28#include "iostream"
29
30
31using namespace robottestingframework;
32
33using namespace yarp::os;
34using namespace yarp::dev;
35
36// prepare the plugin
37ROBOTTESTINGFRAMEWORK_PREPARE_PLUGIN(MotorEncodersSignCheck)
38
39MotorEncodersSignCheck::MotorEncodersSignCheck() : yarp::robottestingframework::TestCase("MotorEncodersSignCheck") {
40 jointsList=0;
41 dd=0;
42 icmd=0;
43 iimd=0;
44 ienc=0;
45 imenc=0;
46 jPosMotion=0;
47}
48
49MotorEncodersSignCheck::~MotorEncodersSignCheck() { }
50
51bool MotorEncodersSignCheck::setup(yarp::os::Property& property) {
52
53 if(property.check("name"))
54 setName(property.find("name").asString());
55
56 // updating parameters
57 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("robot"), "The robot name must be given as the test parameter!");
58 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("part"), "The part name must be given as the test parameter!");
59 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("joints"), "The joints list must be given as the test parameter!");
60 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("home"), "The home position must be given as the test parameter!");
61
62 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("pwmStep"), "The output_step must be given as the test parameter!");
63 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(property.check("pwmMax"), "The output_max must be given as the test parameter!");
64
65 robotName = property.find("robot").asString();
66 partName = property.find("part").asString();
67
68 Bottle* homeBottle = property.find("home").asList();
69 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(homeBottle!=0,"unable to parse zero parameter");
70
71 Bottle* jointsBottle = property.find("joints").asList();
72 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(jointsBottle!=0,"unable to parse joints parameter");
73
74 Bottle* pwm_step_Bottle = property.find("pwmStep").asList();
75 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(pwm_step_Bottle!=0,"unable to parse pwmStep parameter");
76
77 Bottle* command_delay_Bottle = property.find("commandDelay").asList();
78 if(command_delay_Bottle==0)
79 ROBOTTESTINGFRAMEWORK_TEST_REPORT("Command delay not configured. default value (0.1 sec) will be used ");
80
81
82 Bottle* pwm_max_Bottle = property.find("pwmMax").asList();
83 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(pwm_max_Bottle!=0,"unable to parse joints parameter");
84
85 Bottle* threshold_Bottle = property.find("PosThreshold").asList();
86 if(threshold_Bottle==0)
87 ROBOTTESTINGFRAMEWORK_TEST_REPORT("Position threshold not configured. default value (5 deg) will be used ");
88
89 Bottle* pwm_start_Bottle = property.find("pwmStart").asList();
90 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(pwm_start_Bottle!=0,"unable to parse pwmStart parameter");
91
92
93 Property options;
94 options.put("device", "remote_controlboard");
95 options.put("remote", "/"+robotName+"/"+partName);
96 options.put("local", "/mEncSignCheckTest/"+robotName+"/"+partName);
97
98 dd = new PolyDriver(options);
99 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->isValid(),"Unable to open device driver");
100 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipwm),"Unable to open pwm interface");
101 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ienc),"Unable to open encoders interface");
102 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(icmd),"Unable to open control mode interface");
103 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(iimd),"Unable to open interaction mode interface");
104 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(imenc),"Unable to open interaction mode interface");
105 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(dd->view(ipid),"Unable to open ipidcontrol interface");
106
107 if (!ienc->getAxes(&n_part_joints))
108 {
109 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR("unable to get the number of joints of the part");
110 }
111
112 int n_cmd_joints = jointsBottle->size();
113 ROBOTTESTINGFRAMEWORK_ASSERT_ERROR_IF_FALSE(n_cmd_joints>0 && n_cmd_joints<=n_part_joints,"invalid number of joints, it must be >0 & <= number of part joints");
114 jointsList.clear();
115 for (int i=0; i <n_cmd_joints; i++) jointsList.push_back(jointsBottle->get(i).asInt32());
116
117 home.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) home[i]=homeBottle->get(i).asFloat64();
118 opl_step.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) opl_step[i]=pwm_step_Bottle->get(i).asFloat64();
119 opl_max.resize (n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) opl_max[i]=pwm_max_Bottle->get(i).asFloat64();
120 opl_start.resize(n_cmd_joints); for (int i=0; i< n_cmd_joints; i++) opl_start[i]=pwm_start_Bottle->get(i).asFloat64();
121 pos_threshold.resize (n_cmd_joints);
122 if(threshold_Bottle!=0)
123 {
124 for (int i=0; i< n_cmd_joints; i++)
125 pos_threshold[i]=threshold_Bottle->get(i).asFloat64();
126 }
127 else
128 {
129 for (int i=0; i< n_cmd_joints; i++)
130 pos_threshold[i]=5;
131 }
132
133 opl_delay.resize (n_cmd_joints);
134 if(command_delay_Bottle!=0)
135 {
136 for (int i=0; i< n_cmd_joints; i++)
137 opl_delay[i]=command_delay_Bottle->get(i).asFloat64();
138 }
139 else
140 {
141 for (int i=0; i< n_cmd_joints; i++)
142 opl_delay[i]=0.1;
143 }
144
145 jPosMotion = new yarp::robottestingframework::jointsPosMotion(dd, jointsList);
146 jPosMotion->setTolerance(2.0);
147 jPosMotion->setTimeout(10); //10 sec
148
149
150 return true;
151}
152
153void MotorEncodersSignCheck::tearDown()
154{
155 char buff[500];
156 sprintf(buff,"Closing test module");ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
157 if(jPosMotion)
158 {
159 jPosMotion->setAndCheckPosControlMode();
160 jPosMotion->goTo(home);
161 }
162 delete jPosMotion;
163
164 if (dd) {delete dd; dd =0;}
165}
166
167
168void MotorEncodersSignCheck::setModeSingle(int i, int desired_control_mode, yarp::dev::InteractionModeEnum desired_interaction_mode)
169{
170 icmd->setControlMode((int)jointsList[i],desired_control_mode);
171 iimd->setInteractionMode((int)jointsList[i],desired_interaction_mode);
172 yarp::os::Time::delay(0.010);
173}
174
175void MotorEncodersSignCheck::OplExecute(int i)
176{
177 char buff[500];
178 double time = yarp::os::Time::now();
179 double time_old = yarp::os::Time::now();
180 double enc=0;
181 double start_enc=0;
182 double const delta = 10;
183 bool not_moving = true;
184 double opl=opl_start[i];
185
186 ipwm->setRefDutyCycle((int)jointsList[i], opl);
187 double last_opl_cmd=yarp::os::Time::now();
188 yarp::os::Time::delay(3.0); //i need to wait a while because when i set ref output zero, joint may move (due to stiction or gravity) and I should save the position when pwm=0
189
190 imenc->getMotorEncoder((int)jointsList[i],&start_enc);
191
192
193 while (not_moving)
194 {
195
196 ipwm->setRefDutyCycle(jointsList[i], opl);
197 imenc->getMotorEncoder((int)jointsList[i],&enc);
198
199 if(enc > start_enc+pos_threshold[i])
200 {
201 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
202 not_moving=false;
203 sprintf(buff,"TEST SUCCESS (pwm=%f) enc=%f start_enc=%f",opl, enc, start_enc);
204 ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
205 }
206 else if(enc < start_enc-pos_threshold[i])
207 {
208 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
209 not_moving=false;
210 ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF_FALSE(0, robottestingframework::Asserter::format("because enc readings drecrease enc=%f start_enc=%f (output=%f)", enc, start_enc, opl));
211 }
212 else if (jPosMotion->checkJointLimitsReached((int)jointsList[i]))
213 {
214 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
215 not_moving=false;
216 ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF_FALSE(0,robottestingframework::Asserter::format("Test failed because hw limit was touched (enc=%f)",enc));
217 }
218
219 if (yarp::os::Time::now()-last_opl_cmd>opl_delay[i])
220 {
221 opl+=opl_step[i];
222 last_opl_cmd=yarp::os::Time::now();
223 }
224 if (opl>=opl_max[i])
225 {
226 ipwm->setRefDutyCycle((int)jointsList[i], 0.0);
227 not_moving=false;
228 ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF_FALSE(0,robottestingframework::Asserter::format("Test failed failed because max output was reached(output=%f)",opl));
229 }
230
231 yarp::os::Time::delay(0.010);
232
233 if (time-time_old>5.0 && not_moving==true)
234 {
235 sprintf(buff,"test in progress on joint %d, current output value = %f",(int)jointsList[i],opl);ROBOTTESTINGFRAMEWORK_TEST_REPORT(buff);
236 time_old=time;
237 }
238 }
239}
240
241void MotorEncodersSignCheck::run()
242{
243
244 char buff[500];
245 jPosMotion->setAndCheckPosControlMode();
246 jPosMotion->goTo(home);
247
248
249 for (unsigned int i=0 ; i<jointsList.size(); i++)
250 {
251 double posout=0;
252 ROBOTTESTINGFRAMEWORK_TEST_FAIL_IF_FALSE((ipid->getPidOutput(yarp::dev::PidControlTypeEnum::VOCAB_PIDTYPE_POSITION, (int)jointsList[i], &posout)),
253 robottestingframework::Asserter::format(" getOutput j %d return false",(int)jointsList[i]));
254
255 setModeSingle(i,VOCAB_CM_PWM,VOCAB_IM_STIFF);
256 ipwm->setRefDutyCycle((int)jointsList[i],0.0);
257
258 ROBOTTESTINGFRAMEWORK_TEST_REPORT(robottestingframework::Asserter::format("Testing joint %d with starting pwm = %.2f. In position j had pwm = %.2f",(int)jointsList[i], opl_start[i], posout));
259 OplExecute(i);
260
261 jPosMotion->setAndCheckPosControlMode();
262 jPosMotion->goTo(home);
263
264 }
265
266 }
This tests checks if the motor encoder readings increase when positive pwm is applayed to motor.