Revision 7adf90be examples/yarp_icub/src/icub_jointinterface.cpp

View differences:

examples/yarp_icub/src/icub_jointinterface.cpp
16 16
*/
17 17

  
18 18
//WARNING: DO NOT CHANGE THIS; VELOCITYMODE IS NOT YET IMPLEMENTED
19
#define POSITION_CONTROL 1
19
#define POSITION_CONTROL 0
20 20

  
21 21

  
22 22
//! constructor
......
45 45
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_NECK_ROLL,   ID_NECK_ROLL));
46 46

  
47 47
    //EYES
48
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_LEFT_LR,   ID_EYES_LEFT_LR));
49
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_RIGHT_LR,   ID_EYES_RIGHT_LR));
48
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_PAN,   ID_EYES_LEFT_LR));
49
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_VERGENCE,   ID_EYES_RIGHT_LR));
50 50
    enum_id_bimap.insert(enum_id_bimap_entry_t(ICUB_ID_EYES_BOTH_UD,   ID_EYES_BOTH_UD));
51 51

  
52 52
    //EYELIDS
......
69 69
    dd.view(ipos);
70 70
    dd.view(ivel);
71 71
    dd.view(ilimits);
72
    dd.view(pid);
73
    dd.view(amp);
72 74

  
73
    if ( (!iencs) || (!ipos) || (!ilimits) || (!ivel)){
75

  
76
    if ( (!iencs) || (!ipos) || (!ilimits) || (!ivel) || (!amp) || (!pid)){
74 77
        printf("> ERROR: failed to open icub views\n");
75 78
        exit(EXIT_FAILURE);
76 79
    }
......
92 95
        ipos->setPositionMode();
93 96
    }else{
94 97
        ivel->setVelocityMode();
95
        commands=1000000;
98
        commands=100.0;
96 99
        ivel->setRefAccelerations(commands.data());
97 100
    }
98 101

  
......
169 172
        Bottle &cmd = emotion_port[0].prepare();
170 173
        cmd.clear();
171 174
        cmd.addString(buf);
172
        emotion_port[0].write();
175
        emotion_port[0].writeStrict();
173 176
    }else{
174 177
        printf("> ERROR: no icub emotion output\n");
175 178
        exit(EXIT_FAILURE);
......
227 230
        Bottle &cmd = emotion_port[port_id].prepare();
228 231
        cmd.clear();
229 232
        cmd.addString(cmd_s);
230
        emotion_port[port_id].write();
233
        emotion_port[port_id].writeStrict();
231 234
    }else{
232 235
        printf("> ERROR: no icub emotion output\n");
233 236
        exit(EXIT_FAILURE);
......
252 255
    if (id == ICUB_ID_NECK_PAN){
253 256
        //PAN seems to be swapped
254 257
        store_joint(ICUB_ID_NECK_PAN, -joint_target[e]);
255
    }else if ((id == ICUB_ID_EYES_LEFT_LR) || ( id == ICUB_ID_EYES_RIGHT_LR)){
258
    }else if ((id == ICUB_ID_EYES_PAN) || ( id == ICUB_ID_EYES_VERGENCE)){
256 259
        //icub handles eyes differently, we have to set pan angle + vergence
257 260
        float pan      = (joint_target[ID_EYES_LEFT_LR] + joint_target[ID_EYES_RIGHT_LR]) / 2;
258 261
        float vergence = (joint_target[ID_EYES_LEFT_LR]  - joint_target[ID_EYES_RIGHT_LR]);
......
283 286
        printf("> ERROR: set_target_positionmode(id=%d, %3.2f) not supported for this id\n",id,value);
284 287
        return;
285 288
    }
286
#if 0
287
    //set speed cacluated as in velocity + set position -> replicates smoothmotion from flobi?!
288

  
289
    //first: calculate necessary speed to reach the given target within the next clock tick:
290
    double distance = value - target_angle_previous[id];
291
    //make the motion smooth: we want to reach 85% of the target in the next iteration:
292
    //calculate speed for that:
293
    double speed = 0.85 * distance * ((double)MAIN_LOOP_FREQUENCY);
294 289

  
295
    //set up speed for controller:
296
    ipos->setRefSpeed(id, speed);
297
#endif
298
    //execute motion
290
    // execute motion as position control cmd
299 291
    ipos->positionMove(id, value);
292

  
300 293
}
301 294

  
302 295
//! execute a move in velocity mode
303 296
//! \param id of joint
304 297
//! \param angle
305 298
void iCubJointInterface::set_target_in_velocitymode(int id, double value){
299
    // set speed cacluated as in velocity + set position -> replicates smoothmotion from flobi?!
306 300
    //first: calculate necessary speed to reach the given target within the next clock tick:
307 301
    double distance = value - target_angle_previous[id];
302

  
308 303
    //make the motion smooth: we want to reach 85% of the target in the next iteration:
309 304
    distance = 0.85 * distance;
305

  
306
    //distance = -5.0 / 50.0;
307

  
310 308
    //calculate speed
311
    double speed = distance * ((double)MAIN_LOOP_FREQUENCY);
309
    //double speed = distance * ((double)MAIN_LOOP_FREQUENCY);
310

  
311

  
312

  
313
    int e = convert_motorid_to_enum(id);
314
    double speed = joint_target_speed[e];
315

  
316
    double max = 150.0;
317
    if (speed > max) speed = max;
318
    if (speed < -max) speed = -max;
319

  
320
    //speed = -speed;
321

  
322

  
312 323
    //execute:
313
    ivel->velocityMove(id, speed);
314
    //if (id == ICUB_ID_NECK_PAN) printf("> VEL now=%3.2f target=%3.2f --> dist=%3.2f speed=%3.2f\n",target_angle_previous[id],value,distance,speed);
324
    //ivel->velocityMove(id, speed);
325
    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) ){
326
        if (id == ICUB_ID_NECK_PAN) speed = -speed;
327
        ivel->velocityMove(id, speed);
328
        printf("> VEL now=%3.2f target=%3.2f --> dist=%3.2f speed=%3.2f\n",target_angle_previous[id],value,distance,speed);
329
    }
315 330

  
316 331
    target_angle_previous[id] = get_ts_position(convert_motorid_to_enum(id)).get_newest_value();
317 332
}
......
416 431
    Bottle &cmd = emotion_port[3].prepare();
417 432
    cmd.clear();
418 433
    cmd.addString(buf);
419
    emotion_port[3].write();
434
    emotion_port[3].writeStrict();
420 435

  
421 436

  
422 437
    //store joint values which we do not handle on icub here:
......
451 466
            JointInterface::store_incoming_position(ID_EYES_RIGHT_LID_UPPER, lid_angle, timestamp);
452 467
            break;
453 468

  
454
        case(2):
469
        case(ICUB_ID_NECK_PAN):
455 470
            //PAN is inverted!
456 471
            JointInterface::store_incoming_position(ID_NECK_PAN, -value, timestamp);
457 472
            break;
458 473

  
459
        case(0):
474
        case(ICUB_ID_NECK_TILT):
460 475
            JointInterface::store_incoming_position(ID_NECK_TILT, value, timestamp);
461 476
            break;
462 477

  
463
        case(1):
478
        case(ICUB_ID_NECK_ROLL):
464 479
            JointInterface::store_incoming_position(ID_NECK_ROLL, value, timestamp);
465 480
            break;
466 481

  
467
        case(3):
482
        case(ICUB_ID_EYES_BOTH_UD):
468 483
            JointInterface::store_incoming_position(ID_EYES_BOTH_UD, value, timestamp);
469 484
            break;
470 485

  
471 486
        //icub handles eyes differently, we have to set pan angle + vergence
472
        case(4): {//pan
487
        case(ICUB_ID_EYES_PAN): {//pan
473 488
            last_pos_eye_pan = value;
474 489
            float left  = last_pos_eye_pan + last_pos_eye_vergence/2.0;
475 490
            float right = last_pos_eye_pan - last_pos_eye_vergence/2.0;
......
480 495
            break;
481 496
        }
482 497

  
483
        case(5): { //vergence
498
        case(ICUB_ID_EYES_VERGENCE): { //vergence
484 499
            last_pos_eye_vergence = value;
485 500
            float left  = last_pos_eye_pan + last_pos_eye_vergence/2.0;
486 501
            float right = last_pos_eye_pan - last_pos_eye_vergence/2.0;
......
506 521
            printf("> ERROR: unhandled joint id %d\n",id);
507 522
            return;
508 523

  
509
        case(2):
510
            JointInterface::store_incoming_speed(ID_NECK_PAN, value, timestamp);
524
        case(ICUB_ID_NECK_PAN):
525
            //PAN IS INVERTED
526
            JointInterface::store_incoming_speed(ID_NECK_PAN, -value, timestamp);
511 527
            break;
512 528

  
513
        case(0):
529
        case(ICUB_ID_NECK_TILT):
514 530
            JointInterface::store_incoming_speed(ID_NECK_TILT, value, timestamp);
515 531
            break;
516 532

  
517
        case(1):
533
        case(ICUB_ID_NECK_ROLL):
518 534
            JointInterface::store_incoming_speed(ID_NECK_ROLL, value, timestamp);
519 535
            break;
520 536

  
521
        case(3):
537
        case(ICUB_ID_EYES_BOTH_UD):
522 538
            JointInterface::store_incoming_speed(ID_EYES_BOTH_UD, value, timestamp);
523 539
            break;
524 540

  
525 541
        //icub handles eyes differently, we have to set pan angle + vergence
526
        case(4): {//pan
542
        case(ICUB_ID_EYES_PAN): {//pan
527 543
            last_vel_eye_pan = value;
528 544
            float left  = last_vel_eye_pan + last_vel_eye_vergence/2.0;
529 545
            float right = last_vel_eye_pan - last_vel_eye_vergence/2.0;
......
534 550
            break;
535 551
        }
536 552

  
537
        case(5): { //vergence
553
        case(ICUB_ID_EYES_VERGENCE): { //vergence
538 554
            last_vel_eye_pan = value;
539 555
            float left  = last_vel_eye_pan + last_vel_eye_vergence/2.0;
540 556
            float right = last_vel_eye_pan - last_vel_eye_vergence/2.0;
......
545 561
            break;
546 562
        }
547 563
    }
548
/*
549
    JointInterface::store_incoming_speed(ID_LIP_LEFT_UPPER, 0.0, timestamp);
550
    JointInterface::store_incoming_speed(ID_LIP_LEFT_LOWER, 0.0, timestamp);
551
    JointInterface::store_incoming_speed(ID_LIP_CENTER_UPPER, 0.0, timestamp);
552
    JointInterface::store_incoming_speed(ID_LIP_CENTER_LOWER, 0.0, timestamp);
553
    JointInterface::store_incoming_speed(ID_LIP_RIGHT_UPPER, 0.0, timestamp);
554
    JointInterface::store_incoming_speed(ID_LIP_RIGHT_LOWER, 0.0, timestamp);
555

  
556
    JointInterface::store_incoming_speed(ID_EYES_LEFT_LID_LOWER, 0.0, timestamp);
557
    JointInterface::store_incoming_speed(ID_EYES_LEFT_LID_UPPER, 0.0, timestamp);
558
    JointInterface::store_incoming_speed(ID_EYES_LEFT_BROW, 0.0, timestamp);
559

  
560
    JointInterface::store_incoming_speed(ID_EYES_RIGHT_LID_LOWER, 0.0, timestamp);
561
    JointInterface::store_incoming_speed(ID_EYES_RIGHT_LID_UPPER,0.0, timestamp);
562
    JointInterface::store_incoming_speed(ID_EYES_RIGHT_BROW, 0.0, timestamp);*/
563
    /*
564
    //fetch enum id:
565
    int e = convert_motorid_to_enum(device->get_device_id());
566
    if (e == -1){
567
        return; //we are not interested in that data, so we just return here
568
    }
564
}
569 565

  
570
    JointInterface::store_incoming_speed(e, device->get_register(XSC3_REGISTER_MOTORSPEED), timestamp);*/
566
void iCubJointInterface::set_joint_enable_state(int e, bool enable) {
567
    int icub_jointid = -1;
571 568

  
572
}
573
/*
574
//! conversion table for humotion motor ids to our ids:
575
//! \param enum from JointInterface::JOINT_ID_ENUM
576
//! \return int value of motor id
577
int HumotionJointInterface::convert_enum_to_motorid(int e){
578
    enum_id_bimap_t::right_const_iterator it = enum_id_bimap.right.find(e);
579
    if(it == enum_id_bimap.right.end()) {
580
        //key does not exists, we are not interested in that dataset, return -1
581
        return -1;
582
    }
569
    switch(e){
570
        default:
571
            break;
583 572

  
584
    return it->second;
585
}
573
    case(ID_NECK_PAN):
574
        icub_jointid = ICUB_ID_NECK_PAN;
575
        break;
586 576

  
577
    case(ID_NECK_TILT):
578
        icub_jointid = ICUB_ID_NECK_TILT;
579
        break;
587 580

  
588
//! conversion table for our ids to humotion motor ids:
589
//! \param  int value of motor id
590
//! \return enum from JointInterface::JOINT_ID_ENUM
591
int HumotionJointInterface::convert_motorid_to_enum(int id){
592
    enum_id_bimap_t::left_const_iterator it = enum_id_bimap.left.find(id);
593
    if(it == enum_id_bimap.left.end()) {
594
        //key does not exists, we are not interested in that dataset, return -1
595
        return -1;
581
    case(ID_NECK_ROLL):
582
        icub_jointid = ICUB_ID_NECK_ROLL;
583
        break;
584

  
585
    case(ID_EYES_BOTH_UD):
586
        icub_jointid = ICUB_ID_EYES_BOTH_UD;
587
        break;
588

  
589
    // icub handles eyes as pan angle + vergence...
590
    // -> hack: left eye enables pan and right eye enables vergence
591
    case(ID_EYES_LEFT_LR):
592
        icub_jointid = ICUB_ID_EYES_PAN;
593
        break;
594

  
595
    case(ID_EYES_RIGHT_LR):
596
        icub_jointid = ICUB_ID_EYES_VERGENCE;
597
        break;
596 598
    }
597 599

  
598
    return it->second;
600
    if (icub_jointid != -1) {
601
        if (enable) {
602
            amp->enableAmp(icub_jointid);
603
            pid->enablePid(icub_jointid);
604
        } else {
605
            pid->disablePid(icub_jointid);
606
            amp->disableAmp(icub_jointid);
607
        }
608
    }
599 609
}
600
*/
601 610

  
602 611
//! prepare and enable a joint
603 612
//! NOTE: this should also prefill the min/max positions for this joint
604 613
//! \param the enum id of a joint
605 614
void iCubJointInterface::enable_joint(int e){
606
    //FIXME ADD THIS:
607
    // enable the amplifier and the pid controller on each joint
608
    /*for (i = 0; i < nj; i++) {
609
       amp->enableAmp(i);
610
       pid->enablePid(i);
611
    }*/
612

  
613

  
614
    //set up smooth motion controller
615
    //step1: set up framerate
616
    //dev->set_register_blocking(XSC3_REGISTER_PID_RAMP, framerate, true);
617

  
618
    //step2: set controllertype:
619
    //printf("> activating smooth motion control for joint id 0x%02X (%s)\n", motor_id, joint_name.c_str());
620
    //dev->set_register_blocking(XSC3_REGISTER_PID_CONTROLLER, XSC3_PROTOCOL_PID_CONTROLLERTYPE_SMOOTH_PLAYBACK, true);
621

  
622
    //step3: set pid controller:
623
    /*if ((e == ID_LIP_LEFT_UPPER) || (e == ID_LIP_LEFT_LOWER) || (e == ID_LIP_CENTER_UPPER) || (e == ID_LIP_CENTER_LOWER) || (e == ID_LIP_RIGHT_UPPER) || (e == ID_LIP_RIGHT_LOWER)){
624
        printf("> fixing PID i controller value for smooth motion (FIXME: restore old value!!)\n");
625
        dev->set_register_blocking(XSC3_REGISTER_CONST_I, 10, true);
626
    }*/
627

  
628
    //uint16_t result = dev->get_register_blocking_raw(XSC3_REGISTER_PID_CONTROLLER);
629

  
630
    //check if setting pid controllertype was successfull:
631
    /*if (result != XSC3_PROTOCOL_PID_CONTROLLERTYPE_SMOOTH_PLAYBACK){
632
        printf("> failed to set smooth motion controller for joint %s (res=0x%04X)\n",joint_name.c_str(),result);
633
        exit(1);
634
    }*/
635

  
636
    //fetch min/max:
637
   // init_joint(e);
638

  
639
    //ok fine, now enable motor:
640
    //printf("> enabling motor %s\n", joint_name.c_str());
641
    //dev->set_register_blocking(XSC3_REGISTER_STATUS, XSC3_PROTOCOL_STATUS_BITMASK_MOTOR_ENABLE, true);
615
    set_joint_enable_state(e, true);
616
}
642 617

  
618
//! shutdown and disable a joint
619
//! \param the enum id of a joint
620
void iCubJointInterface::disable_joint(int e){
621
    set_joint_enable_state(e, false);
643 622
}
644 623

  
645 624
void iCubJointInterface::store_min_max(IControlLimits *ilimits, int id, int e){
......
652 631
//! initialise a joint (set up controller mode etc)
653 632
//! \param joint enum
654 633
void iCubJointInterface::init_joints(){
655
    store_min_max(ilimits, 0, ID_NECK_TILT);
656
    store_min_max(ilimits, 1, ID_NECK_ROLL);
657
    store_min_max(ilimits, 2, ID_NECK_PAN);
658
    store_min_max(ilimits, 3, ID_EYES_BOTH_UD);
634
    store_min_max(ilimits, ICUB_ID_NECK_TILT, ID_NECK_TILT);
635
    store_min_max(ilimits, ICUB_ID_NECK_ROLL, ID_NECK_ROLL);
636
    store_min_max(ilimits, ICUB_ID_NECK_PAN, ID_NECK_PAN);
637
    store_min_max(ilimits, ICUB_ID_EYES_BOTH_UD, ID_EYES_BOTH_UD);
659 638

  
660 639
    //icub handles eyes differently, we have to set pan angle + vergence
661 640
    double pan_min, pan_max, vergence_min, vergence_max;
662
    ilimits->getLimits(4, &pan_min, &pan_max);
663
    ilimits->getLimits(5, &vergence_min, &vergence_max);
641
    ilimits->getLimits(ICUB_ID_EYES_PAN, &pan_min, &pan_max);
642
    ilimits->getLimits(ICUB_ID_EYES_VERGENCE, &vergence_min, &vergence_max);
664 643

  
665 644
    //this is not 100% correct, should be fixed:
666 645
    joint_min[ID_EYES_LEFT_LR] = pan_min; // - vergence_max/2;
......
695 674

  
696 675

  
697 676
}
698

  
699
//! shutdown and disable a joint
700
//! \param the enum id of a joint
701
void iCubJointInterface::disable_joint(int e){
702
    /*
703
        //first: convert humotion enum to our enum:
704
        int motor_id = convert_enum_to_motorid(e);
705
        if (motor_id == -1){
706
            return; //we are not interested in that data, so we just return here
707
        }
708

  
709
        //fetch device:
710
        Device *dev = get_device(motor_id);
711
        printf("> FIXME: ADD DISABLE CODE\n");
712
        printf("> FIXME: ADD DISABLE CODE\n");
713
        printf("> FIXME: ADD DISABLE CODE\n");
714
        printf("> FIXME: ADD DISABLE CODE\n");
715
        printf("> FIXME: ADD DISABLE CODE\n");
716
        printf("> FIXME: ADD DISABLE CODE\n");
717
        printf("> FIXME: ADD DISABLE CODE\n");
718
        printf("> FIXME: ADD DISABLE CODE\n");
719
        printf("> FIXME: ADD DISABLE CODE\n");
720
        */
721
}

Also available in: Unified diff