Statistics
| Branch: | Tag: | Revision:

humotion / examples / yarp_icub / src / icub_jointinterface.cpp @ cc3bdc80

History | View | Annotate | Download (18.949 KB)

1 8c6c1163 Simon Schulz
#include "icub_jointinterface.h"
2 0d0f5ca1 Simon Schulz
#include "icub_faceinterface.h"
3
4 8c6c1163 Simon Schulz
#include <yarp/os/Property.h>
5
using namespace yarp::dev;
6
using namespace yarp::sig;
7
using namespace yarp::os;
8
using namespace std;
9
/*running:
10
/media/local_data/sschulz/iros15/icub-nightly/share/iCub/contexts/simConfig:> iCub_SIM
11
/media/local_data/sschulz/iros15/icub-nightly/share/iCub/contexts/simFaceExpressions:> ../../../../bin/simFaceExpressions
12
yarp connect /face/eyelids /icubSim/face/eyelids
13
yarp connect /face/image/out /icubSim/texture/face
14

15
TEST: yarp write /writer /icubSim/face/raw/in
16

17
http://wiki.icub.org/wiki/Motor_control
18
*/
19
20
//WARNING: DO NOT CHANGE THIS; VELOCITYMODE IS NOT YET IMPLEMENTED
21 7adf90be Simon Schulz
#define POSITION_CONTROL 0
22 8c6c1163 Simon Schulz
23
24
//! constructor
25
iCubJointInterface::iCubJointInterface(string _scope) : humotion::server::JointInterface(){
26
    scope = _scope;
27 0d0f5ca1 Simon Schulz
    face_interface = new iCubFaceInterface(scope);
28 8c6c1163 Simon Schulz
29
    //add mapping from ids to enums:
30
    //this might look strange at the first sight but we need to have a generic
31
    //way to acces joints from libhumotion. therefore the lib uses its enum with ID_* enum ids
32
    //to access the joints. now we need to define a mapping to map those to our motor ids.
33
    //this is what we use the enum bimap for (convertion fro/to motorid is handled
34
    //by \sa convert_enum_to_motorid() and \sa convert_motorid_to_enum() lateron
35
36
    //MOUTH
37
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_LIP_LEFT_UPPER,   ID_LIP_LEFT_UPPER));
38
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_LIP_LEFT_LOWER,   ID_LIP_LEFT_LOWER));
39
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_LIP_CENTER_UPPER, ID_LIP_CENTER_UPPER));
40
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_LIP_CENTER_LOWER, ID_LIP_CENTER_LOWER));
41
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_LIP_RIGHT_UPPER,  ID_LIP_RIGHT_UPPER));
42
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_LIP_RIGHT_LOWER,  ID_LIP_RIGHT_LOWER));
43
44
    //NECK
45
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_NECK_PAN,    ID_NECK_PAN));
46
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_NECK_TILT,   ID_NECK_TILT));
47
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_NECK_ROLL,   ID_NECK_ROLL));
48
49
    //EYES
50 7adf90be Simon Schulz
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_PAN,   ID_EYES_LEFT_LR));
51
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_VERGENCE,   ID_EYES_RIGHT_LR));
52 8c6c1163 Simon Schulz
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_BOTH_UD,   ID_EYES_BOTH_UD));
53
54
    //EYELIDS
55
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_LEFT_LID_LOWER, ID_EYES_LEFT_LID_LOWER));
56
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_LEFT_LID_UPPER, ID_EYES_LEFT_LID_UPPER));
57
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_LEFT_BROW, ID_EYES_LEFT_BROW));
58
59
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_RIGHT_LID_LOWER, ID_EYES_RIGHT_LID_LOWER));
60
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_RIGHT_LID_UPPER,ID_EYES_RIGHT_LID_UPPER));
61
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_RIGHT_BROW, ID_EYES_RIGHT_BROW));
62
63 87b50988 Simon Schulz
    //init pd control variables
64 cc3bdc80 Simon Schulz
    enum_id_bimap_t::const_iterator it;
65
    for(it = enum_id_bimap.begin(); it != enum_id_bimap.end(); ++it) {
66
        int id = it->left;
67
        last_position_error[id] = 0.0;
68 87b50988 Simon Schulz
        PID_P[id] = 0.5;
69
        PID_D[id] = 0.1;
70
    }
71
72
73 8c6c1163 Simon Schulz
    Property options;
74
    options.put("device", "remote_controlboard");
75
    options.put("local", "/local/head");
76
    options.put("remote", scope+"/head");
77
    dd.open(options);
78
79
    //fetch views:
80
    dd.view(iencs);
81
    dd.view(ipos);
82
    dd.view(ivel);
83
    dd.view(ilimits);
84 7adf90be Simon Schulz
    dd.view(pid);
85
    dd.view(amp);
86 8c6c1163 Simon Schulz
87 7adf90be Simon Schulz
88
    if ( (!iencs) || (!ipos) || (!ilimits) || (!ivel) || (!amp) || (!pid)){
89 8c6c1163 Simon Schulz
        printf("> ERROR: failed to open icub views\n");
90
        exit(EXIT_FAILURE);
91
    }
92
93
    int joints;
94
95
    //tell humotion about min/max joint values:
96
    init_joints();
97
98
    iencs->getAxes(&joints);
99
    positions.resize(joints);
100
    velocities.resize(joints);
101
    commands.resize(joints);
102
103
    //set position mode:
104
    if (POSITION_CONTROL){
105
        commands=200000.0;
106
        ipos->setRefAccelerations(commands.data());
107
        ipos->setPositionMode();
108
    }else{
109
        ivel->setVelocityMode();
110 7adf90be Simon Schulz
        commands=100.0;
111 8c6c1163 Simon Schulz
        ivel->setRefAccelerations(commands.data());
112
    }
113
114
}
115
116
//! destructor
117
iCubJointInterface::~iCubJointInterface(){
118
}
119
120
121
122
//! conversion table for humotion motor ids to our ids:
123
//! \param enum from JointInterface::JOINT_ID_ENUM
124
//! \return int value of motor id
125
int iCubJointInterface::convert_enum_to_motorid(int e){
126
    enum_id_bimap_t::right_const_iterator it = enum_id_bimap.right.find(e);
127
    if(it == enum_id_bimap.right.end()) {
128
        //key does not exists, we are not interested in that dataset, return -1
129
        return -1;
130
    }
131
    return it->second;
132
}
133
134
135
//! conversion table for our ids to humotion motor ids:
136
//! \param  int value of motor id
137
//! \return enum from JointInterface::JOINT_ID_ENUM
138
int iCubJointInterface::convert_motorid_to_enum(int id){
139
    enum_id_bimap_t::left_const_iterator it = enum_id_bimap.left.find(id);
140
    if(it == enum_id_bimap.left.end()) {
141
        //key does not exists, we are not interested in that dataset, return -1
142
        return -1;
143
    }
144
    return it->second;
145
}
146
147
148
void iCubJointInterface::run(){
149 1efa78e9 sschulz
    iCubDataReceiver *data_receiver = new iCubDataReceiver(0.5 * 1000.0 / MAIN_LOOP_FREQUENCY, iencs, this);
150 8c6c1163 Simon Schulz
    data_receiver->start();
151
}
152
153
//! set the target position of a joint
154
//! \param enum id of joint
155
//! \param float value
156
void iCubJointInterface::publish_target_position(int e){
157
    //first: convert humotion enum to our enum:
158
    int id = convert_enum_to_motorid(e);
159 0d0f5ca1 Simon Schulz
160 8c6c1163 Simon Schulz
    if (id == -1){
161
        return; //we are not interested in that data, so we just return here
162
    }
163
164
    if (id == ICUB_ID_NECK_PAN){
165
        //PAN seems to be swapped
166
        store_joint(ICUB_ID_NECK_PAN, -joint_target[e]);
167 7adf90be Simon Schulz
    }else if ((id == ICUB_ID_EYES_PAN) || ( id == ICUB_ID_EYES_VERGENCE)){
168 8c6c1163 Simon Schulz
        //icub handles eyes differently, we have to set pan angle + vergence
169
        float pan      = (joint_target[ID_EYES_LEFT_LR] + joint_target[ID_EYES_RIGHT_LR]) / 2;
170
        float vergence = (joint_target[ID_EYES_LEFT_LR]  - joint_target[ID_EYES_RIGHT_LR]);
171
        //printf("EYEDBG %3.2f %3.2f --_> pan %3.2f verg=%3.2f\n",joint_target[ID_EYES_LEFT_LR], joint_target[ID_EYES_RIGHT_LR],pan,vergence);
172
173
        store_joint(ICUB_ID_EYES_PAN, pan);
174
        store_joint(ICUB_ID_EYES_VERGENCE, vergence);
175
    }else{
176
        store_joint(id, joint_target[e]);
177
    }
178
}
179
180
181
//! set the target position of a joint
182
//! \param id of joint
183
//! \param float value of position
184
void iCubJointInterface::store_joint(int id, float value){
185 0d0f5ca1 Simon Schulz
    printf("> set joint %d = %f\n",id,value);
186 8c6c1163 Simon Schulz
    target_angle[id] = value;
187
}
188
189
//! execute a move in position mode
190
//! \param id of joint
191
//! \param angle
192 87b50988 Simon Schulz
void iCubJointInterface::set_target_in_positionmode(int id){
193
    double target = target_angle[id];
194
195 8c6c1163 Simon Schulz
    if (id>ICUB_ID_EYES_VERGENCE){
196 87b50988 Simon Schulz
        printf("> ERROR: set_target_positionmode(id=%d, %3.2f) not supported for this id\n",id,target);
197 8c6c1163 Simon Schulz
        return;
198
    }
199
200 7adf90be Simon Schulz
    // execute motion as position control cmd
201 87b50988 Simon Schulz
    ipos->positionMove(id, target);
202 7adf90be Simon Schulz
203 8c6c1163 Simon Schulz
}
204
205
//! execute a move in velocity mode
206
//! \param id of joint
207
//! \param angle
208 87b50988 Simon Schulz
void iCubJointInterface::set_target_in_velocitymode(int id){
209 7adf90be Simon Schulz
    // set speed cacluated as in velocity + set position -> replicates smoothmotion from flobi?!
210 8c6c1163 Simon Schulz
    //first: calculate necessary speed to reach the given target within the next clock tick:
211 cc3bdc80 Simon Schulz
    double distance = target_angle[id] - target_angle_previous[id];
212 7adf90be Simon Schulz
213 8c6c1163 Simon Schulz
    //make the motion smooth: we want to reach 85% of the target in the next iteration:
214
    distance = 0.85 * distance;
215 7adf90be Simon Schulz
216
    //distance = -5.0 / 50.0;
217
218 8c6c1163 Simon Schulz
    //calculate speed
219 7adf90be Simon Schulz
    //double speed = distance * ((double)MAIN_LOOP_FREQUENCY);
220
221
222
223
    int e = convert_motorid_to_enum(id);
224
    double speed = joint_target_speed[e];
225
226
    double max = 150.0;
227
    if (speed > max) speed = max;
228
    if (speed < -max) speed = -max;
229
230
    //speed = -speed;
231
232
233 497d9d24 Simon Schulz
    // find out the latency between incoming data and now:
234
    float latency = get_ts_speed(e).get_last_timestamp().to_seconds() - humotion::Timestamp::now().to_seconds();
235
    printf("TS DIFF %fms\n",latency*1000.0);
236
237 8c6c1163 Simon Schulz
    //execute:
238 7adf90be Simon Schulz
    //ivel->velocityMove(id, speed);
239
    if ((id == ICUB_ID_NECK_PAN)  || (id == ICUB_ID_EYES_BOTH_UD) || (id == ICUB_ID_NECK_TILT) || (id == ICUB_ID_EYES_BOTH_UD) ||  (id == ICUB_ID_NECK_TILT) ){
240 87b50988 Simon Schulz
        //do a pd control for velocity moves that incorporates position errors:
241
        humotion::Timestamp data_ts = get_ts_position(id).get_last_timestamp();
242
        //TODO: add interpolation into future!
243
        //humotion::Timestamp data_ts = humotion::Timestamp::now(); and extend get_interpol value with get_future_value
244
        double position_error = target_angle[id] - get_ts_position(id).get_interpolated_value(data_ts);
245 cc3bdc80 Simon Schulz
        double error_d = (position_error - last_position_error[id]) / (framerate*1000.0);
246 87b50988 Simon Schulz
        last_position_error[id] = position_error;
247
        //finally do a PD loop to get the target velocity
248
        double target_velocity = PID_P[id] * position_error + PID_D[id]*error_d + speed;
249
250 0d0f5ca1 Simon Schulz
        //if (id == ICUB_ID_NECK_PAN) speed = -speed;
251 87b50988 Simon Schulz
        ivel->velocityMove(id, target_velocity);
252 cc3bdc80 Simon Schulz
        printf("> VEL now=%3.2f target=%3.2f --> dist=%3.2f speed=%3.2f\n",target_angle_previous[id],target_angle[id],distance,speed);
253 7adf90be Simon Schulz
    }
254 8c6c1163 Simon Schulz
255
    target_angle_previous[id] = get_ts_position(convert_motorid_to_enum(id)).get_newest_value();
256
}
257
258
//! actually execute the scheduled motion commands
259
void iCubJointInterface::execute_motion(){
260
261
    // set up neck and eye motion commands:
262
    if (POSITION_CONTROL){
263
        //position control
264
        for(int i=ICUB_ID_NECK_TILT; i<=ICUB_ID_EYES_VERGENCE; i++){
265 cc3bdc80 Simon Schulz
            set_target_in_positionmode(i);
266 8c6c1163 Simon Schulz
        }
267
    }else{
268
        //velocity control
269
        for(int i=ICUB_ID_NECK_TILT; i<=ICUB_ID_EYES_VERGENCE; i++){
270 cc3bdc80 Simon Schulz
            set_target_in_velocitymode(i);
271 8c6c1163 Simon Schulz
        }
272
    }
273
    //printf("> TARGET PAN = %3.2f\n",target_angle[ICUB_ID_NECK_PAN]);
274
275
276
    //eyelids: unfortuantely the icub has only 1dof for eyelids, so we use only one dof here:
277 0d0f5ca1 Simon Schulz
    face_interface->set_eyelid_angle(target_angle[ICUB_ID_EYES_RIGHT_LID_UPPER]);
278 8c6c1163 Simon Schulz
279
    //eyebrows are set using a special command as well:
280 0d0f5ca1 Simon Schulz
    face_interface->set_eyebrow_angle(ICUB_ID_EYES_LEFT_BROW, target_angle);
281
    face_interface->set_eyebrow_angle(ICUB_ID_EYES_RIGHT_BROW, target_angle);
282 8c6c1163 Simon Schulz
283
    //mouth
284 0d0f5ca1 Simon Schulz
    face_interface->set_mouth(target_angle);
285 8c6c1163 Simon Schulz
286
287
    //store joint values which we do not handle on icub here:
288
    double timestamp = get_timestamp_ms();
289
    JointInterface::store_incoming_position(ID_LIP_LEFT_UPPER,   target_angle[ICUB_ID_LIP_LEFT_UPPER], timestamp);
290
    JointInterface::store_incoming_position(ID_LIP_LEFT_LOWER,   target_angle[ICUB_ID_LIP_LEFT_LOWER], timestamp);
291
    JointInterface::store_incoming_position(ID_LIP_CENTER_UPPER, target_angle[ICUB_ID_LIP_CENTER_UPPER], timestamp);
292
    JointInterface::store_incoming_position(ID_LIP_CENTER_LOWER, target_angle[ICUB_ID_LIP_CENTER_LOWER], timestamp);
293
    JointInterface::store_incoming_position(ID_LIP_RIGHT_UPPER,  target_angle[ICUB_ID_LIP_RIGHT_UPPER], timestamp);
294
    JointInterface::store_incoming_position(ID_LIP_RIGHT_LOWER,  target_angle[ICUB_ID_LIP_RIGHT_LOWER], timestamp);
295
}
296
297
double iCubJointInterface::get_timestamp_ms(){
298
    struct timespec spec;
299
    clock_gettime(CLOCK_REALTIME, &spec);
300
    return spec.tv_sec*1000 + spec.tv_nsec / 1.0e6;
301
}
302
303
//! set the current position of a joint
304
//! \param id of joint
305
//! \param float value of position
306
//! \param double timestamp
307
void iCubJointInterface::fetch_position(int id, double value, double timestamp){
308
    //store joint based on id:
309
    switch(id){
310
        default:
311
            printf("> ERROR: unhandled joint id %d\n",id);
312
            return;
313
314
        case(100):
315 0d0f5ca1 Simon Schulz
            //JointInterface::store_incoming_position(ID_EYES_RIGHT_LID_UPPER, lid_angle, timestamp);
316 8c6c1163 Simon Schulz
            break;
317
318 7adf90be Simon Schulz
        case(ICUB_ID_NECK_PAN):
319 8c6c1163 Simon Schulz
            //PAN is inverted!
320 0d0f5ca1 Simon Schulz
            JointInterface::store_incoming_position(ID_NECK_PAN, value, timestamp);
321 8c6c1163 Simon Schulz
            break;
322
323 7adf90be Simon Schulz
        case(ICUB_ID_NECK_TILT):
324 8c6c1163 Simon Schulz
            JointInterface::store_incoming_position(ID_NECK_TILT, value, timestamp);
325
            break;
326
327 7adf90be Simon Schulz
        case(ICUB_ID_NECK_ROLL):
328 8c6c1163 Simon Schulz
            JointInterface::store_incoming_position(ID_NECK_ROLL, value, timestamp);
329
            break;
330
331 7adf90be Simon Schulz
        case(ICUB_ID_EYES_BOTH_UD):
332 8c6c1163 Simon Schulz
            JointInterface::store_incoming_position(ID_EYES_BOTH_UD, value, timestamp);
333
            break;
334
335
        //icub handles eyes differently, we have to set pan angle + vergence
336 7adf90be Simon Schulz
        case(ICUB_ID_EYES_PAN): {//pan
337 8c6c1163 Simon Schulz
            last_pos_eye_pan = value;
338
            float left  = last_pos_eye_pan + last_pos_eye_vergence/2.0;
339
            float right = last_pos_eye_pan - last_pos_eye_vergence/2.0;
340
341
            //printf("> eye: pan=%3.2f vergence=%3.2f --> L=%3.2f R=%3.2f\n", last_pos_eye_pan, last_pos_eye_vergence, left, right);
342
            JointInterface::store_incoming_position(ID_EYES_LEFT_LR, left, timestamp);
343
            JointInterface::store_incoming_position(ID_EYES_RIGHT_LR, right, timestamp);
344
            break;
345
        }
346
347 7adf90be Simon Schulz
        case(ICUB_ID_EYES_VERGENCE): { //vergence
348 8c6c1163 Simon Schulz
            last_pos_eye_vergence = value;
349
            float left  = last_pos_eye_pan + last_pos_eye_vergence/2.0;
350
            float right = last_pos_eye_pan - last_pos_eye_vergence/2.0;
351
352
            //printf("> eye: pan=%3.2f vergence=%3.2f --> L=%3.2f R=%3.2f\n", last_pos_eye_pan, last_pos_eye_vergence, left, right);
353
            JointInterface::store_incoming_position(ID_EYES_LEFT_LR, left, timestamp);
354
            JointInterface::store_incoming_position(ID_EYES_RIGHT_LR, right, timestamp);
355
            break;
356
        }
357
    }
358
359
360
}
361
362
//! set the current speed of a joint
363
//! \param enum id of joint
364
//! \param float value of speed
365
//! \param double timestamp
366
void iCubJointInterface::fetch_speed(int id, double value, double timestamp){
367
368
    switch(id){
369
        default:
370
            printf("> ERROR: unhandled joint id %d\n",id);
371
            return;
372
373 7adf90be Simon Schulz
        case(ICUB_ID_NECK_PAN):
374
            //PAN IS INVERTED
375 0d0f5ca1 Simon Schulz
            JointInterface::store_incoming_speed(ID_NECK_PAN, value, timestamp);
376 8c6c1163 Simon Schulz
            break;
377
378 7adf90be Simon Schulz
        case(ICUB_ID_NECK_TILT):
379 8c6c1163 Simon Schulz
            JointInterface::store_incoming_speed(ID_NECK_TILT, value, timestamp);
380
            break;
381
382 7adf90be Simon Schulz
        case(ICUB_ID_NECK_ROLL):
383 8c6c1163 Simon Schulz
            JointInterface::store_incoming_speed(ID_NECK_ROLL, value, timestamp);
384
            break;
385
386 7adf90be Simon Schulz
        case(ICUB_ID_EYES_BOTH_UD):
387 8c6c1163 Simon Schulz
            JointInterface::store_incoming_speed(ID_EYES_BOTH_UD, value, timestamp);
388
            break;
389
390
        //icub handles eyes differently, we have to set pan angle + vergence
391 7adf90be Simon Schulz
        case(ICUB_ID_EYES_PAN): {//pan
392 8c6c1163 Simon Schulz
            last_vel_eye_pan = value;
393
            float left  = last_vel_eye_pan + last_vel_eye_vergence/2.0;
394
            float right = last_vel_eye_pan - last_vel_eye_vergence/2.0;
395
396
            //printf("> eye: velocity pan=%3.2f vergence=%3.2f --> L=%3.2f R=%3.2f\n", last_vel_eye_pan, last_vel_eye_vergence, left, right);
397
            JointInterface::store_incoming_speed(ID_EYES_LEFT_LR, left, timestamp);
398
            JointInterface::store_incoming_speed(ID_EYES_RIGHT_LR, right, timestamp);
399
            break;
400
        }
401
402 7adf90be Simon Schulz
        case(ICUB_ID_EYES_VERGENCE): { //vergence
403 8c6c1163 Simon Schulz
            last_vel_eye_pan = value;
404
            float left  = last_vel_eye_pan + last_vel_eye_vergence/2.0;
405
            float right = last_vel_eye_pan - last_vel_eye_vergence/2.0;
406
407
            //printf("> eye: velocity pan=%3.2f vergence=%3.2f --> L=%3.2f R=%3.2f\n", last_vel_eye_pan, last_vel_eye_vergence, left, right);
408
            JointInterface::store_incoming_speed(ID_EYES_LEFT_LR, left, timestamp);
409
            JointInterface::store_incoming_speed(ID_EYES_RIGHT_LR, right, timestamp);
410
            break;
411
        }
412
    }
413 7adf90be Simon Schulz
}
414 8c6c1163 Simon Schulz
415 7adf90be Simon Schulz
void iCubJointInterface::set_joint_enable_state(int e, bool enable) {
416
    int icub_jointid = -1;
417 8c6c1163 Simon Schulz
418 7adf90be Simon Schulz
    switch(e){
419
        default:
420
            break;
421 8c6c1163 Simon Schulz
422 7adf90be Simon Schulz
    case(ID_NECK_PAN):
423
        icub_jointid = ICUB_ID_NECK_PAN;
424
        break;
425 8c6c1163 Simon Schulz
426 7adf90be Simon Schulz
    case(ID_NECK_TILT):
427
        icub_jointid = ICUB_ID_NECK_TILT;
428
        break;
429 8c6c1163 Simon Schulz
430 7adf90be Simon Schulz
    case(ID_NECK_ROLL):
431
        icub_jointid = ICUB_ID_NECK_ROLL;
432
        break;
433
434
    case(ID_EYES_BOTH_UD):
435
        icub_jointid = ICUB_ID_EYES_BOTH_UD;
436
        break;
437
438
    // icub handles eyes as pan angle + vergence...
439
    // -> hack: left eye enables pan and right eye enables vergence
440
    case(ID_EYES_LEFT_LR):
441
        icub_jointid = ICUB_ID_EYES_PAN;
442
        break;
443
444
    case(ID_EYES_RIGHT_LR):
445
        icub_jointid = ICUB_ID_EYES_VERGENCE;
446
        break;
447 8c6c1163 Simon Schulz
    }
448
449 7adf90be Simon Schulz
    if (icub_jointid != -1) {
450
        if (enable) {
451
            amp->enableAmp(icub_jointid);
452
            pid->enablePid(icub_jointid);
453
        } else {
454
            pid->disablePid(icub_jointid);
455
            amp->disableAmp(icub_jointid);
456
        }
457
    }
458 8c6c1163 Simon Schulz
}
459
460
//! prepare and enable a joint
461
//! NOTE: this should also prefill the min/max positions for this joint
462
//! \param the enum id of a joint
463
void iCubJointInterface::enable_joint(int e){
464 7adf90be Simon Schulz
    set_joint_enable_state(e, true);
465
}
466 8c6c1163 Simon Schulz
467 7adf90be Simon Schulz
//! shutdown and disable a joint
468
//! \param the enum id of a joint
469
void iCubJointInterface::disable_joint(int e){
470
    set_joint_enable_state(e, false);
471 8c6c1163 Simon Schulz
}
472
473
void iCubJointInterface::store_min_max(IControlLimits *ilimits, int id, int e){
474
    double min, max;
475
    ilimits->getLimits(id, &min, &max);
476
    joint_min[e] = min;
477
    joint_max[e] = max;
478
}
479
480
//! initialise a joint (set up controller mode etc)
481
//! \param joint enum
482
void iCubJointInterface::init_joints(){
483 7adf90be Simon Schulz
    store_min_max(ilimits, ICUB_ID_NECK_TILT, ID_NECK_TILT);
484
    store_min_max(ilimits, ICUB_ID_NECK_ROLL, ID_NECK_ROLL);
485
    store_min_max(ilimits, ICUB_ID_NECK_PAN, ID_NECK_PAN);
486
    store_min_max(ilimits, ICUB_ID_EYES_BOTH_UD, ID_EYES_BOTH_UD);
487 8c6c1163 Simon Schulz
488
    //icub handles eyes differently, we have to set pan angle + vergence
489
    double pan_min, pan_max, vergence_min, vergence_max;
490 7adf90be Simon Schulz
    ilimits->getLimits(ICUB_ID_EYES_PAN, &pan_min, &pan_max);
491
    ilimits->getLimits(ICUB_ID_EYES_VERGENCE, &vergence_min, &vergence_max);
492 8c6c1163 Simon Schulz
493
    //this is not 100% correct, should be fixed:
494
    joint_min[ID_EYES_LEFT_LR] = pan_min; // - vergence_max/2;
495
    joint_max[ID_EYES_LEFT_LR] = pan_max; // - vergence_max/2;
496
    joint_min[ID_EYES_RIGHT_LR] = joint_min[ID_EYES_LEFT_LR];
497
    joint_max[ID_EYES_RIGHT_LR] = joint_max[ID_EYES_LEFT_LR];
498
499
    //eyelids:
500
    joint_min[ID_EYES_RIGHT_LID_UPPER] = -50; //24-30;
501
    joint_max[ID_EYES_RIGHT_LID_UPPER] = 50; //48-30;
502 0d0f5ca1 Simon Schulz
    //lid_angle = joint_max[ID_EYES_RIGHT_LID_UPPER];
503 8c6c1163 Simon Schulz
504
    //eyebrows:
505
    joint_min[ID_EYES_LEFT_BROW] = -50;
506
    joint_max[ID_EYES_LEFT_BROW] = 50;
507
    joint_min[ID_EYES_RIGHT_BROW] = joint_min[ID_EYES_LEFT_BROW];
508
    joint_max[ID_EYES_RIGHT_BROW] = joint_max[ID_EYES_LEFT_BROW];
509
510
    //mouth:
511
    joint_min[ID_LIP_CENTER_UPPER] = 5;
512
    joint_max[ID_LIP_CENTER_UPPER] = 50;
513
    joint_min[ID_LIP_CENTER_LOWER] = 5;
514
    joint_max[ID_LIP_CENTER_LOWER] = 50;
515
    joint_min[ID_LIP_LEFT_UPPER] = 5;
516
    joint_max[ID_LIP_LEFT_UPPER] = 50;
517
    joint_min[ID_LIP_LEFT_LOWER] = 5;
518
    joint_max[ID_LIP_LEFT_LOWER] = 50;
519
    joint_min[ID_LIP_RIGHT_UPPER] = 5;
520
    joint_max[ID_LIP_RIGHT_UPPER] = 50;
521
    joint_min[ID_LIP_RIGHT_LOWER] = 5;
522
    joint_max[ID_LIP_RIGHT_LOWER] = 50;
523
524
525
}