Revision 35b3ca25

View differences:

examples/yarp_icub/include/icub_data_receiver.h
20 20

  
21 21
class iCubDataReceiver : public yarp::os::RateThread{
22 22
public:
23
    iCubDataReceiver(int period, yarp::dev::IEncodersTimed *_iencs, iCubJointInterface *_icub_jointinterface);
23
    iCubDataReceiver(int period, iCubJointInterface *icub_jointinterface);
24 24
    bool threadInit();
25 25
    void threadRelease();
26 26
    void run();
27 27
private:
28
    double get_timestamp_ms();
28
    void store_incoming_position(int icub_id, double value, double timestamp);
29 29

  
30
    yarp::sig::Vector positions;
31
    yarp::sig::Vector velocities;
32
    yarp::sig::Vector commands;
33
    yarp::sig::Vector timestamps;
30
    float target_eye_pan_;
31
    float target_eye_vergence_;
34 32

  
35
    yarp::dev::IEncodersTimed *iencs;
36
    iCubJointInterface *icub_jointinterface;
33
    yarp::sig::Vector yarp_positions_;
34
    yarp::sig::Vector yarp_commands_;
35
    yarp::sig::Vector yarp_timestamps_;
36

  
37
    iCubJointInterface *icub_jointinterface_;
38
    yarp::dev::IEncodersTimed *yarp_iencs_;
37 39
};
38 40

  
examples/yarp_icub/include/icub_faceinterface.h
19 19
    ~iCubFaceInterface();
20 20

  
21 21

  
22
    void set_eyelid_angle(double angle);
23
    void set_eyebrow_angle(int id, double *target_angle);
24
    void set_mouth(double *target_angle);
22
    void set_eyelid_angle(float angle);
23
    void set_eyebrow_angle(int id, float *target_angle);
24
    void set_mouth(float *target_angle);
25 25

  
26 26
private:
27 27
    double lid_angle;
examples/yarp_icub/include/icub_jointinterface.h
25 25
    iCubJointInterface(std::string scope);
26 26
    ~iCubJointInterface();
27 27

  
28
    //void fetch_position(Device *dev, double timestamp);
29
    //void fetch_speed(Device *dev, double timestamp);
30
    void fetch_position(int id, double value, double timestamp);
31
    void fetch_speed(int id, double value, double timestamp);
28
    void store_incoming_position(int id, double value, double timestamp);
32 29
    void run();
33 30

  
31
    int convert_icub_jointid_to_humotion(int id);
32
    int convert_humotion_jointid_to_icub(int id);
33

  
34 34
    enum JOINT_ID_ENUM{
35 35
        ICUB_ID_NECK_TILT = 0,
36 36
        ICUB_ID_NECK_ROLL = 1,
......
38 38
        ICUB_ID_EYES_BOTH_UD = 3,
39 39
        ICUB_ID_EYES_PAN = 4,
40 40
        ICUB_ID_EYES_VERGENCE = 5,
41
        //the following ids are used for remapping:
42
        //ICUB_ID_EYES_LEFT_LR,
43
        //ICUB_ID_EYES_RIGHT_LR,
44 41
        ICUB_ID_EYES_LEFT_LID_LOWER,
45 42
        ICUB_ID_EYES_LEFT_LID_UPPER,
46 43
        ICUB_ID_EYES_RIGHT_LID_LOWER,
......
56 53
        ICUB_JOINT_ID_ENUM_SIZE
57 54
    };
58 55

  
56
    yarp::dev::PolyDriver *get_yarp_polydriver() { return &yarp_polydriver_; }
57

  
59 58
    static const int MAIN_LOOP_FREQUENCY = 50;
60 59

  
61 60
protected:
62 61
    void disable_joint(int e);
63
    void publish_target_position(int e);
62
    void publish_target(int e, float position, float velocity);
64 63
    void enable_joint(int e);
65 64
    void execute_motion();
66 65

  
67 66
private:
67
    yarp::dev::PolyDriver yarp_polydriver_;
68

  
69
    std::vector<double> pv_mix_last_error_;
70
    std::vector<double> pv_mix_pid_p_;
71
    std::vector<double> pv_mix_pid_d_;
72

  
73
    // yarp views
74
    yarp::dev::IVelocityControl *yarp_ivel_;
75
    yarp::dev::IPositionControl *yarp_ipos_;
76
    //yarp::dev::IEncodersTimed *yarp_iencs_;
77
    yarp::dev::IControlLimits *yarp_ilimits_;
78
    yarp::dev::IAmplifierControl *yarp_amp_;
79
    yarp::dev::IPidControl *yarp_pid_;
80
    yarp::dev::IControlMode *yarp_icontrol_;
81

  
82
    yarp::sig::Vector yarp_commands_;
83

  
84
    float target_angle_[ICUB_JOINT_ID_ENUM_SIZE];
85
    float target_velocity_[ICUB_JOINT_ID_ENUM_SIZE];
86

  
87

  
88
    void init_controller();
89
    void init_id_map();
90
    void init_pv_mix_pid();
91
    void insert_icupid_to_humotionid_mapping(int icubid, int humotionid);
92

  
93

  
94
    void store_icub_joint_target(int icub_id, float position, float velocity);
95

  
96
    //*******************************************
97

  
98

  
68 99
    void set_joint_enable_state(int e, bool enabled);
69
    double get_timestamp_ms();
70
    double target_angle[ICUB_JOINT_ID_ENUM_SIZE];
71
    double target_angle_previous[ICUB_JOINT_ID_ENUM_SIZE];
100
    //double target_angle[ICUB_JOINT_ID_ENUM_SIZE];
101
    //double target_angle_previous[ICUB_JOINT_ID_ENUM_SIZE];
72 102

  
73 103
    iCubDataReceiver *icub_data_receiver;
74 104
    void init_joints();
75 105

  
76 106
    std::string scope;
77
    yarp::dev::PolyDriver dd;
78 107
    yarp::sig::Vector positions;
79 108
    yarp::sig::Vector velocities;
80
    yarp::sig::Vector commands;
81

  
82
    yarp::dev::IVelocityControl *ivel;
83
    yarp::dev::IPositionControl *ipos;
84
    yarp::dev::IEncodersTimed *iencs;
85
    yarp::dev::IControlLimits *ilimits;
86
    yarp::dev::IAmplifierControl *amp;
87
    yarp::dev::IPidControl *pid;
88
    yarp::dev::IControlMode *icontrol;
89
    std::vector<double> last_position_error;
90
    std::vector<double> PID_P;
91
    std::vector<double> PID_D;
109

  
92 110

  
93 111
    void store_min_max(yarp::dev::IControlLimits *ilimits, int id, int e);
94 112

  
......
105 123
    int convert_enum_to_motorid(int e);
106 124
    int convert_motorid_to_enum(int id);
107 125

  
108
    iCubFaceInterface *face_interface;
126
    iCubFaceInterface *face_interface_;
109 127

  
110 128
    typedef boost::bimap<int, int > enum_id_bimap_t;
111 129
    typedef enum_id_bimap_t::value_type enum_id_bimap_entry_t;
examples/yarp_icub/src/icub_data_receiver.cpp
1 1
#include "icub_data_receiver.h"
2
#include <humotion/server/joint_interface.h>
2 3
#include <yarp/os/Property.h>
3
using namespace yarp::dev;
4
using namespace yarp::sig;
5
using namespace yarp::os;
6
using namespace std;
7

  
8
iCubDataReceiver::iCubDataReceiver(int period, IEncodersTimed *_iencs, iCubJointInterface *_icub_jointinterface):RateThread(period){
9
    iencs = _iencs;
10
    icub_jointinterface = _icub_jointinterface;
4
//using namespace yarp::dev;
5
//using namespace yarp::sig;
6
//using namespace yarp::os;
7
using std::cout;
8
using std::string;
9

  
10
using humotion::server::JointInterface;
11
using yarp::dev::IEncodersTimed;
12
using yarp::sig::Vector;
13

  
14
iCubDataReceiver::iCubDataReceiver(int period, iCubJointInterface *icub_jointinterface)
15
    : yarp::os::RateThread(period) {
16

  
17
    // store pointer to icub jointinterface
18
    icub_jointinterface_ = icub_jointinterface;
19

  
20
    //fetch yarp iencs view:
21
    yarp::dev::PolyDriver *poly_driver = icub_jointinterface->get_yarp_polydriver();
22
    bool success = poly_driver->view(yarp_iencs_);
23
    if (!success) {
24
        cout << "ERROR: polydriver failed to init iencs view\n";
25
        exit(EXIT_FAILURE);
26
    }
27

  
28
    // resize data storage vectors to match the number of axes:
11 29
    int joints;
12
    iencs->getAxes(&joints);
13
    positions.resize(joints);
14
    velocities.resize(joints);
15
    timestamps.resize(joints);
30
    yarp_iencs_->getAxes(&joints);
31
    yarp_positions_.resize(joints);
32
    yarp_timestamps_.resize(joints);
16 33
}
17 34

  
18
bool iCubDataReceiver::threadInit(){ return true; }
19
void iCubDataReceiver::threadRelease(){ }
20

  
21
double iCubDataReceiver::get_timestamp_ms(){
22
    struct timespec spec;
23
    clock_gettime(CLOCK_REALTIME, &spec);
24
    return spec.tv_sec+spec.tv_nsec/1000000000.0;
35
bool iCubDataReceiver::threadInit() {
36
    return true;
25 37
}
26 38

  
27
void iCubDataReceiver::run(){
39
void iCubDataReceiver::threadRelease() {
40
}
28 41

  
42
void iCubDataReceiver::run() {
29 43
    //grab pos+vel data:
30
    iencs->getEncodersTimed(positions.data(), timestamps.data());
31
    iencs->getEncoderSpeeds(velocities.data());
32

  
33
    //double timestamp = get_timestamp_ms();
44
    yarp_iencs_->getEncodersTimed(yarp_positions_.data(), yarp_timestamps_.data());
45
    //iencs->getEncoderSpeeds(velocities.data());
34 46

  
35 47
    //publish data to humotion
36
    for(int i=0; i<positions.size(); i++){
37
        icub_jointinterface->fetch_position(i, positions[i], timestamps[i]);
38
        icub_jointinterface->fetch_speed(i, velocities[i], timestamps[i]);
39
        if (i==iCubJointInterface::ICUB_ID_NECK_PAN){
40
            printf("\nMMM p=%f v=%f\n",positions[i],velocities[i]);
41
        }
48
    for(int i=0; i<yarp_positions_.size(); i++){
49
        store_incoming_position(i, yarp_positions_[i], yarp_timestamps_[i]);
42 50
    }
43 51

  
44
    //printf("\n%f %f %f TIME\n", get_timestamp_ms(), timestamps[2], positions[2]);
45
    //printf("TIMEDIFF %f\n", get_timestamp_ms() - timestamps[2]);
46

  
47
    //tell humotion to update lid angle (hack)
48
    icub_jointinterface->fetch_position(100, 0.0, get_timestamp_ms());
52
    //small hack to tell humotion to update the lid angle
49 53
    //fixme: use real id
54
    store_incoming_position(100, 0.0, yarp_timestamps_[0]);
55
}
56

  
57
void iCubDataReceiver::store_incoming_position(int icub_id, double value, double timestamp) {
58
    // store joint position in humotion backend
59
    if ((icub_id == iCubJointInterface::ICUB_ID_EYES_PAN) ||
60
            (icub_id == iCubJointInterface::ICUB_ID_EYES_VERGENCE)) {
61
        // the icub handles eyes differently
62
        // instead of using seperate left/right pan the icub uses
63
        // a combined pan angle and vergence. therfore we have to convert this here:
64
        if (icub_id == iCubJointInterface::ICUB_ID_EYES_PAN) {
65
            target_eye_pan_ = value;
66
        } else {
67
            target_eye_vergence_ = value;
68
        }
69

  
70
        float left  = target_eye_pan_ + target_eye_vergence_/2.0;
71
        float right = target_eye_pan_ - target_eye_vergence_/2.0;
72

  
73
        icub_jointinterface_->store_incoming_position(JointInterface::ID_EYES_LEFT_LR,
74
                                                     left, timestamp);
75
        icub_jointinterface_->store_incoming_position(JointInterface::ID_EYES_RIGHT_LR,
76
                                                     right, timestamp);
77
    } else if (icub_id == 100) {
78
        //HACK
79
        //icub_jointinterface->store_incoming_position(ID_EYES_RIGHT_LID_UPPER,
80
        //                                             lid_angle, timestamp);
81
    } else {
82
        // known configured mapping between joint ids
83
        int humotion_id = icub_jointinterface_->convert_icub_jointid_to_humotion(icub_id);
84
        icub_jointinterface_->store_incoming_position(humotion_id, value, timestamp);
85
    }
50 86
}
examples/yarp_icub/src/icub_faceinterface.cpp
108 108

  
109 109
//! special command to set eyelid angle
110 110
//! \param angle in degrees
111
void iCubFaceInterface::set_eyelid_angle(double angle){
111
void iCubFaceInterface::set_eyelid_angle(float angle){
112 112
    if (emotion_port[0].getOutputCount()>0){
113 113
        //try to set the value based on the upper one
114 114
        //some guesses from the sim: S30 = 0° / S40 = 10°
......
140 140
//! special command to set the eyebrow angle
141 141
//! \param id {0=left, 1=right)
142 142
//! \param angle in degrees
143
void iCubFaceInterface::set_eyebrow_angle(int id, double *target_angle){
143
void iCubFaceInterface::set_eyebrow_angle(int id, float *target_angle){
144 144
    int port_id;
145 145
    if (id == iCubJointInterface::ICUB_ID_EYES_LEFT_BROW){
146 146
        port_id = 1;
......
195 195
    }
196 196
}
197 197

  
198
void iCubFaceInterface::set_mouth(double *target_angle){
198
void iCubFaceInterface::set_mouth(float *target_angle){
199 199
    //convert from 6DOF mouth displacement to icub leds:
200 200
    int led_value = 0;
201 201

  
examples/yarp_icub/src/icub_jointinterface.cpp
17 17
http://wiki.icub.org/wiki/Motor_control
18 18
*/
19 19

  
20
//WARNING: DO NOT CHANGE THIS; VELOCITYMODE IS NOT YET IMPLEMENTED
21 20
#define POSITION_CONTROL 0
22

  
21
using std::cout;
23 22

  
24 23
//! constructor
25 24
iCubJointInterface::iCubJointInterface(string _scope) : humotion::server::JointInterface(){
26 25
    scope = _scope;
27
    face_interface = new iCubFaceInterface(scope);
28

  
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
    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
    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
    //init pd control variables
64
    enum_id_bimap_t::const_iterator it;
65
    last_position_error.resize(ICUB_JOINT_ID_ENUM_SIZE);
66
    PID_P.resize(ICUB_JOINT_ID_ENUM_SIZE);
67
    PID_D.resize(ICUB_JOINT_ID_ENUM_SIZE);
68 26

  
69
    for(it = enum_id_bimap.begin(); it != enum_id_bimap.end(); ++it) {
70
        int id = it->left;
71
        last_position_error[id] = 0.0;
72
        PID_P[id] = 4.5;
73
        PID_D[id] = 0.3;
74
    }
27
    // add mappings from icub ids to humotion ids
28
    init_id_map();
29

  
30
    // initialise the pd controller for the velocity and position mixer
31
    init_pv_mix_pid();
75 32

  
33
    // intantiate the face interface
34
    face_interface_ = new iCubFaceInterface(scope);
76 35

  
36
    // intantiate the polydriver
77 37
    Property options;
78 38
    options.put("device", "remote_controlboard");
79 39
    options.put("local", "/local/head");
80
    options.put("remote", scope+"/head");
81
    dd.open(options);
82

  
83
    //fetch views:
84
    dd.view(iencs);
85
    dd.view(ipos);
86
    dd.view(ivel);
87
    dd.view(ilimits);
88
    dd.view(pid);
89
    dd.view(amp);
90

  
91

  
92
    if ( (!iencs) || (!ipos) || (!ilimits) || (!ivel) || (!amp) || (!pid)){
93
        printf("> ERROR: failed to open icub views\n");
40
    options.put("remote", scope + "/head");
41
    yarp_polydriver_.open(options);
42

  
43
    // fetch yarp views:
44
    bool success = true;
45
    //success &= yarp_polydriver_.view(yarp_iencs_);
46
    success &= yarp_polydriver_.view(yarp_ipos_);
47
    success &= yarp_polydriver_.view(yarp_ivel_);
48
    success &= yarp_polydriver_.view(yarp_ilimits_);
49
    success &= yarp_polydriver_.view(yarp_pid_);
50
    success &= yarp_polydriver_.view(yarp_amp_);
51

  
52
    if (!success) {
53
        cout << "ERROR: failed to fetch one or more yarp views... exiting\n";
94 54
        exit(EXIT_FAILURE);
95 55
    }
96 56

  
97
    int joints;
98 57

  
99 58
    //tell humotion about min/max joint values:
100 59
    init_joints();
101 60

  
102
    iencs->getAxes(&joints);
103
    positions.resize(joints);
104
    velocities.resize(joints);
105
    commands.resize(joints);
61
    //initialise joint controller
62
    init_controller();
63
}
64

  
65
//! destructor
66
iCubJointInterface::~iCubJointInterface(){
67
}
68

  
69
//! init the controller that allows to write target angles or velocities
70
void iCubJointInterface::init_controller() {
71
    int number_of_joints;
106 72

  
107 73
    //set position mode:
108 74
    if (POSITION_CONTROL){
109
        commands=200000.0;
110
        ipos->setRefAccelerations(commands.data());
111
        ipos->setPositionMode();
75
        // use position controller, first fetch no of axes:
76
        yarp_ipos_->getAxes(&number_of_joints);
77

  
78
        // set ref acceleration to a value for all axes:
79
        yarp_commands_.resize(number_of_joints);
80
        yarp_commands_ = 200000.0;
81
        yarp_ipos_->setRefAccelerations(yarp_commands_.data());
82
        yarp_ipos_->setPositionMode();
112 83
    }else{
113
        ivel->setVelocityMode();
114
        commands=300.0;
115
        ivel->setRefAccelerations(commands.data());
84
        // use position controller, first fetch no of axes:
85
        yarp_ivel_->getAxes(&number_of_joints);
86

  
87
        // set ref acceleration to a value for all axes:
88
        yarp_commands_.resize(number_of_joints);
89
        yarp_commands_=300.0;
90
        yarp_ivel_->setRefAccelerations(yarp_commands_.data());
91
        yarp_ivel_->setVelocityMode();
116 92
    }
117 93

  
118
}
119 94

  
120
//! destructor
121
iCubJointInterface::~iCubJointInterface(){
122 95
}
123 96

  
97
//! initialise icub joint id to humotion joint id mappings
98
void iCubJointInterface::init_id_map() {
99
        insert_icupid_to_humotionid_mapping(ICUB_ID_LIP_LEFT_UPPER,   ID_LIP_LEFT_UPPER);
100
        insert_icupid_to_humotionid_mapping(ICUB_ID_LIP_LEFT_LOWER,   ID_LIP_LEFT_LOWER);
101
        insert_icupid_to_humotionid_mapping(ICUB_ID_LIP_CENTER_UPPER, ID_LIP_CENTER_UPPER);
102
        insert_icupid_to_humotionid_mapping(ICUB_ID_LIP_CENTER_LOWER, ID_LIP_CENTER_LOWER);
103
        insert_icupid_to_humotionid_mapping(ICUB_ID_LIP_RIGHT_UPPER,  ID_LIP_RIGHT_UPPER);
104
        insert_icupid_to_humotionid_mapping(ICUB_ID_LIP_RIGHT_LOWER,  ID_LIP_RIGHT_LOWER);
105
        insert_icupid_to_humotionid_mapping(ICUB_ID_NECK_PAN,    ID_NECK_PAN);
106
        insert_icupid_to_humotionid_mapping(ICUB_ID_NECK_TILT,   ID_NECK_TILT);
107
        insert_icupid_to_humotionid_mapping(ICUB_ID_NECK_ROLL,   ID_NECK_ROLL);
108
        // FIXME: remove this hack tha repurposes LEFT/RIGHT eye pan from humotion as vergence/pan
109
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_PAN,   ID_EYES_LEFT_LR);
110
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_VERGENCE,   ID_EYES_RIGHT_LR);
111
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_BOTH_UD,   ID_EYES_BOTH_UD);
112
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_LEFT_LID_LOWER, ID_EYES_LEFT_LID_LOWER);
113
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_LEFT_LID_UPPER, ID_EYES_LEFT_LID_UPPER);
114
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_LEFT_BROW, ID_EYES_LEFT_BROW);
115
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_RIGHT_LID_LOWER, ID_EYES_RIGHT_LID_LOWER);
116
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_RIGHT_LID_UPPER,ID_EYES_RIGHT_LID_UPPER);
117
        insert_icupid_to_humotionid_mapping(ICUB_ID_EYES_RIGHT_BROW, ID_EYES_RIGHT_BROW);
118
}
124 119

  
120
//! initialize the position and velocity mixer PD controller
121
void iCubJointInterface::init_pv_mix_pid() {
122
    // init control variables and last error variable for the internal
123
    // position and velocity mixer PD controller:
124
    pv_mix_pid_p_.resize(ICUB_JOINT_ID_ENUM_SIZE);
125
    pv_mix_pid_d_.resize(ICUB_JOINT_ID_ENUM_SIZE);
126
    pv_mix_last_error_.resize(ICUB_JOINT_ID_ENUM_SIZE);
125 127

  
126
//! conversion table for humotion motor ids to our ids:
127
//! \param enum from JointInterface::JOINT_ID_ENUM
128
//! \return int value of motor id
129
int iCubJointInterface::convert_enum_to_motorid(int e){
130
    enum_id_bimap_t::right_const_iterator it = enum_id_bimap.right.find(e);
131
    if(it == enum_id_bimap.right.end()) {
132
        //key does not exists, we are not interested in that dataset, return -1
133
        return -1;
128
    enum_id_bimap_t::const_iterator it;
129
    for(it = enum_id_bimap.begin(); it != enum_id_bimap.end(); ++it) {
130
        int id = it->left;
131
        pv_mix_pid_p_[id] = 4.5;
132
        pv_mix_pid_d_[id] = 0.3;
133
        pv_mix_last_error_[id] = 0.0;
134 134
    }
135
    return it->second;
136
}
137 135

  
136
}
138 137

  
139
//! conversion table for our ids to humotion motor ids:
140
//! \param  int value of motor id
141
//! \return enum from JointInterface::JOINT_ID_ENUM
142
int iCubJointInterface::convert_motorid_to_enum(int id){
143
    enum_id_bimap_t::left_const_iterator it = enum_id_bimap.left.find(id);
144
    if(it == enum_id_bimap.left.end()) {
145
        //key does not exists, we are not interested in that dataset, return -1
146
        return -1;
147
    }
148
    return it->second;
138
//! add mapping from icub joint ids to humotion ids
139
//! this might look strange at the first sight but we need to have a generic
140
//! way to acces joints from libhumotion. therefore the lib uses its enum with ID_* enum ids
141
//! to access the joints. now we need to define a mapping to map those to the icub motor ids.
142
void iCubJointInterface::insert_icupid_to_humotionid_mapping(int icubid, int humotionid) {
143
    enum_id_bimap.insert(enum_id_bimap_entry_t(icubid, humotionid));
149 144
}
150 145

  
151 146

  
147

  
148

  
152 149
void iCubJointInterface::run(){
153
    iCubDataReceiver *data_receiver = new iCubDataReceiver(0.5 * 1000.0 / MAIN_LOOP_FREQUENCY, iencs, this);
150
    float loop_duration_ms = 1000.0 / MAIN_LOOP_FREQUENCY;
151
    iCubDataReceiver *data_receiver = new iCubDataReceiver(loop_duration_ms, this);
154 152
    data_receiver->start();
155 153
}
156 154

  
157
//! set the target position of a joint
155
//! stores the target position & velocity of a given joint
158 156
//! \param enum id of joint
159 157
//! \param float value
160
void iCubJointInterface::publish_target_position(int e){
161
    //first: convert humotion enum to our enum:
162
    int id = convert_enum_to_motorid(e);
163

  
164
    if (id == -1){
165
        return; //we are not interested in that data, so we just return here
166
    }
167

  
168
    if (id == ICUB_ID_NECK_PAN){
169
        //PAN seems to be swapped
170
        store_joint(ICUB_ID_NECK_PAN, -joint_target[e]);
171
    }else if ((id == ICUB_ID_EYES_PAN) || ( id == ICUB_ID_EYES_VERGENCE)){
172
        //icub handles eyes differently, we have to set pan angle + vergence
173
        float pan      = (joint_target[ID_EYES_LEFT_LR] + joint_target[ID_EYES_RIGHT_LR]) / 2;
174
        float vergence = (joint_target[ID_EYES_LEFT_LR]  - joint_target[ID_EYES_RIGHT_LR]);
175
        //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);
176

  
177
        store_joint(ICUB_ID_EYES_PAN, pan);
178
        store_joint(ICUB_ID_EYES_VERGENCE, vergence);
158
void iCubJointInterface::publish_target(int humotion_id, float position, float velocity){
159
    // special handler for eye joints
160
    if ((humotion_id == JointInterface::ID_EYES_LEFT_LR) ||
161
        (humotion_id == JointInterface::ID_EYES_RIGHT_LR)){
162
        // the icub has a combined pan angle for both eyes, so seperate this:
163
        float target_position_left  = get_target_position(JointInterface::ID_EYES_LEFT_LR);
164
        float target_position_right = get_target_position(JointInterface::ID_EYES_RIGHT_LR);
165
        float target_velocity_left  = get_target_velocity(JointInterface::ID_EYES_LEFT_LR);
166
        float target_velocity_right = get_target_velocity(JointInterface::ID_EYES_RIGHT_LR);
167

  
168
        // calculate target angles
169
        float target_position_pan      = (target_position_left + target_position_right) / 2;
170
        float target_position_vergence = (target_position_left - target_position_right);
171

  
172
        // calculate target velocities
173
        // for now just use the same velocity for pan and vergence
174
        float target_velocity_pan = (target_velocity_left + target_velocity_right) / 2.0;
175
        float target_velocity_tilt = target_velocity_pan;
176

  
177
        store_icub_joint_target(ICUB_ID_EYES_PAN,
178
                                target_position_pan, target_velocity_pan);
179
        store_icub_joint_target(ICUB_ID_EYES_VERGENCE,
180
                                target_position_vergence, target_velocity_tilt);
179 181
    }else{
180
        store_joint(id, joint_target[e]);
182
        // convert to icub joint id
183
        int icub_id = convert_humotion_jointid_to_icub(humotion_id);
184
        // store target data
185
        store_icub_joint_target(icub_id, position, velocity);
181 186
    }
182 187
}
183 188

  
184 189

  
185
//! set the target position of a joint
190
//! set the target data for a given icub joint
186 191
//! \param id of joint
187 192
//! \param float value of position
188
void iCubJointInterface::store_joint(int id, float value){
189
    printf("> set joint %d = %f\n",id,value);
190
    target_angle[id] = value;
193
void iCubJointInterface::store_icub_joint_target(int icub_id, float position, float velocity) {
194
    printf("> set icub joint %d -> p = %f, v = %f\n",icub_id,position,velocity);
195
    target_angle_[icub_id] = position;
196
    target_velocity_[icub_id] = velocity;
191 197
}
192 198

  
193 199
//! execute a move in position mode
194 200
//! \param id of joint
195 201
//! \param angle
196
void iCubJointInterface::set_target_in_positionmode(int id){
197
    double target = target_angle[id];
202
void iCubJointInterface::set_target_in_positionmode(int id) {
203
    assert(POSITION_CONTROL);
204
    assert(id<=ICUB_ID_EYES_VERGENCE);
198 205

  
199
    if (id>ICUB_ID_EYES_VERGENCE){
200
        printf("> ERROR: set_target_positionmode(id=%d, %3.2f) not supported for this id\n",id,target);
201
        return;
202
    }
206
    // fetch the current target position
207
    float target = target_angle_[id];
203 208

  
204 209
    // execute motion as position control cmd
205
    ipos->positionMove(id, target);
206

  
210
    yarp_ipos_->positionMove(id, target);
207 211
}
208 212

  
209 213
//! execute a move in velocity mode
210 214
//! \param id of joint
211 215
//! \param angle
212
void iCubJointInterface::set_target_in_velocitymode(int id){
213
    // set speed cacluated as in velocity + set position -> replicates smoothmotion from flobi?!
214
    //first: calculate necessary speed to reach the given target within the next clock tick:
215
    double distance = target_angle[id] - target_angle_previous[id];
216

  
217
    //make the motion smooth: we want to reach 85% of the target in the next iteration:
218
    distance = 0.85 * distance;
219

  
220
    //distance = -5.0 / 50.0;
221

  
222
    //calculate speed
223
    //double speed = distance * ((double)MAIN_LOOP_FREQUENCY);
216
void iCubJointInterface::set_target_in_velocitymode(int icub_id) {
217
    assert(!POSITION_CONTROL);
224 218

  
219
    // fetch humotion id from icub joint id
220
    int humotion_id = convert_humotion_jointid_to_icub(icub_id);
225 221

  
222
    // fetch the target velocity
223
    float target_velocity = target_velocity_[icub_id];
226 224

  
227
    int e = convert_motorid_to_enum(id);
228
    double speed = joint_target_speed[e];
229

  
230
    double max = 150.0;
231
    if (speed > max) speed = max;
232
    if (speed < -max) speed = -max;
233

  
234
    //speed = -speed;
235

  
236

  
237
    // find out the latency between incoming data and now:
238
    float latency = get_ts_speed(e).get_last_timestamp().to_seconds() - humotion::Timestamp::now().to_seconds();
239
    printf("TS DIFF %fms\n",latency*1000.0);
225
    float vmax = 150.0;
226
    if (target_velocity > vmax)  target_velocity = vmax;
227
    if (target_velocity < -vmax) target_velocity = -vmax;
240 228

  
241 229
    //execute:
242 230
    //ivel->velocityMove(id, speed);
243
    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) ){
244
        //do a pd control for velocity moves that incorporates position errors:
245
        humotion::Timestamp data_ts = get_ts_position(e).get_last_timestamp();
246
        //TODO: add interpolation into future!
247
        //humotion::Timestamp data_ts = humotion::Timestamp::now(); and extend get_interpol value with get_future_value
248
        double position_error = target_angle[id] - get_ts_position(e).get_interpolated_value(data_ts);
249
        double error_d = (position_error - last_position_error[id]) / (framerate*1000.0);
250
        last_position_error[id] = position_error;
251
        //finally do a PD loop to get the target velocity
252
        double target_velocity = 0.1*(PID_P[id] * position_error + PID_D[id]*error_d) - speed;
253

  
254
        printf("%f %f %f %f %f %f PID%d\n",
255
               get_ts_position(e).get_interpolated_value(data_ts),
256
               target_angle[id],
257
               get_ts_speed(e).get_interpolated_value(data_ts),
258
               target_velocity,
259
               speed,
260
               position_error,
261
               id
262
               );
263

  
264

  
265
        //if (id == ICUB_ID_NECK_PAN) speed = -speed;
266
        ivel->velocityMove(id, target_velocity);
267
        printf("> VEL now=%3.2f target=%3.2f --> dist=%3.2f speed=%3.2f\n",target_angle_previous[id],target_angle[id],distance,speed);
231
    if ((icub_id != ICUB_ID_NECK_PAN)  &&
232
        (icub_id != ICUB_ID_EYES_BOTH_UD) &&
233
        (icub_id != ICUB_ID_NECK_TILT) &&
234
        (icub_id != ICUB_ID_EYES_BOTH_UD) &&
235
        (icub_id != ICUB_ID_NECK_TILT)) {
236
        // limit to some joints for debugging...
237
        return;
268 238
    }
269 239

  
270
    target_angle_previous[id] = get_ts_position(convert_motorid_to_enum(id)).get_newest_value();
240
    // we now add a pd control loop for velocity moves in order to handle position errors
241
    // TODO: add position interpolation into future. this requires to enable the velocity
242
    //       broadcast in the torso and head ini file and fetch that velocity in the
243
    //       icub_data_receiver as well. TODO: check if the can bus has enough bandwidth for that...
244

  
245
    // first: fetch the timstamp of the last known position
246
    humotion::Timestamp data_ts = get_ts_position(humotion_id).get_last_timestamp();
247

  
248
    // calculate position error:
249
    float position_error = target_angle_[icub_id] - get_ts_position(humotion_id).get_interpolated_value(data_ts);
250

  
251
    // calculate d term
252
    float error_d = (position_error - pv_mix_last_error_[icub_id]) / (framerate*1000.0);
253
    pv_mix_last_error_[icub_id] = position_error;
254

  
255
    // finally do a PD loop to get the target velocity
256
    float pv_mix_velocity = pv_mix_pid_p_[icub_id] * position_error
257
                            + pv_mix_pid_p_[icub_id]*error_d
258
                            + target_velocity;
259

  
260
    printf("%f %f %f %f %f %f PID%d\n",
261
           get_ts_position(humotion_id).get_interpolated_value(data_ts),
262
           target_angle_[icub_id],
263
           123.4, //NOT USED ANYMORE//get_ts_speed(humotion_id).get_interpolated_value(data_ts),
264
           pv_mix_velocity,
265
           target_velocity,
266
           position_error,
267
           icub_id
268
           );
269

  
270
    // execute velocity move
271
    yarp_ivel_->velocityMove(icub_id, pv_mix_velocity);
271 272
}
272 273

  
273 274
//! actually execute the scheduled motion commands
......
289 290

  
290 291

  
291 292
    //eyelids: unfortuantely the icub has only 1dof for eyelids, so we use only one dof here:
292
    face_interface->set_eyelid_angle(target_angle[ICUB_ID_EYES_RIGHT_LID_UPPER]);
293
    face_interface_->set_eyelid_angle(target_angle_[ICUB_ID_EYES_RIGHT_LID_UPPER]);
293 294

  
294 295
    //eyebrows are set using a special command as well:
295
    face_interface->set_eyebrow_angle(ICUB_ID_EYES_LEFT_BROW, target_angle);
296
    face_interface->set_eyebrow_angle(ICUB_ID_EYES_RIGHT_BROW, target_angle);
296
    face_interface_->set_eyebrow_angle(ICUB_ID_EYES_LEFT_BROW, target_angle_);
297
    face_interface_->set_eyebrow_angle(ICUB_ID_EYES_RIGHT_BROW, target_angle_);
297 298

  
298 299
    //mouth
299
    face_interface->set_mouth(target_angle);
300
    face_interface_->set_mouth(target_angle_);
300 301

  
301 302

  
302 303
    //store joint values which we do not handle on icub here:
303
    double timestamp = get_timestamp_ms();
304
    JointInterface::store_incoming_position(ID_LIP_LEFT_UPPER,   target_angle[ICUB_ID_LIP_LEFT_UPPER], timestamp);
305
    JointInterface::store_incoming_position(ID_LIP_LEFT_LOWER,   target_angle[ICUB_ID_LIP_LEFT_LOWER], timestamp);
306
    JointInterface::store_incoming_position(ID_LIP_CENTER_UPPER, target_angle[ICUB_ID_LIP_CENTER_UPPER], timestamp);
307
    JointInterface::store_incoming_position(ID_LIP_CENTER_LOWER, target_angle[ICUB_ID_LIP_CENTER_LOWER], timestamp);
308
    JointInterface::store_incoming_position(ID_LIP_RIGHT_UPPER,  target_angle[ICUB_ID_LIP_RIGHT_UPPER], timestamp);
309
    JointInterface::store_incoming_position(ID_LIP_RIGHT_LOWER,  target_angle[ICUB_ID_LIP_RIGHT_LOWER], timestamp);
304
    double timestamp = humotion::Timestamp::now().to_seconds();
305
    JointInterface::store_incoming_position(ID_LIP_LEFT_UPPER,   target_angle_[ICUB_ID_LIP_LEFT_UPPER], timestamp);
306
    JointInterface::store_incoming_position(ID_LIP_LEFT_LOWER,   target_angle_[ICUB_ID_LIP_LEFT_LOWER], timestamp);
307
    JointInterface::store_incoming_position(ID_LIP_CENTER_UPPER, target_angle_[ICUB_ID_LIP_CENTER_UPPER], timestamp);
308
    JointInterface::store_incoming_position(ID_LIP_CENTER_LOWER, target_angle_[ICUB_ID_LIP_CENTER_LOWER], timestamp);
309
    JointInterface::store_incoming_position(ID_LIP_RIGHT_UPPER,  target_angle_[ICUB_ID_LIP_RIGHT_UPPER], timestamp);
310
    JointInterface::store_incoming_position(ID_LIP_RIGHT_LOWER,  target_angle_[ICUB_ID_LIP_RIGHT_LOWER], timestamp);
310 311
}
311 312

  
312
double iCubJointInterface::get_timestamp_ms(){
313
    struct timespec spec;
314
    clock_gettime(CLOCK_REALTIME, &spec);
315
    return spec.tv_sec*1000 + spec.tv_nsec / 1.0e6;
316
}
317 313

  
318 314
//! set the current position of a joint
319 315
//! \param id of joint
320 316
//! \param float value of position
321 317
//! \param double timestamp
322
void iCubJointInterface::fetch_position(int id, double value, double timestamp){
318
void iCubJointInterface::store_incoming_position(int id, double value, double timestamp){
323 319
    //store joint based on id:
324 320
    switch(id){
325 321
        default:
......
374 370

  
375 371
}
376 372

  
377
//! set the current speed of a joint
378
//! \param enum id of joint
379
//! \param float value of speed
380
//! \param double timestamp
381
void iCubJointInterface::fetch_speed(int id, double value, double timestamp){
382

  
383
    switch(id){
384
        default:
385
            printf("> ERROR: unhandled joint id %d\n",id);
386
            return;
387

  
388
        case(ICUB_ID_NECK_PAN):
389
            //PAN IS INVERTED
390
            JointInterface::store_incoming_speed(ID_NECK_PAN, value, timestamp);
391
            break;
392

  
393
        case(ICUB_ID_NECK_TILT):
394
            JointInterface::store_incoming_speed(ID_NECK_TILT, value, timestamp);
395
            break;
396

  
397
        case(ICUB_ID_NECK_ROLL):
398
            JointInterface::store_incoming_speed(ID_NECK_ROLL, value, timestamp);
399
            break;
400

  
401
        case(ICUB_ID_EYES_BOTH_UD):
402
            JointInterface::store_incoming_speed(ID_EYES_BOTH_UD, value, timestamp);
403
            break;
404

  
405
        //icub handles eyes differently, we have to set pan angle + vergence
406
        case(ICUB_ID_EYES_PAN): {//pan
407
            last_vel_eye_pan = value;
408
            float left  = last_vel_eye_pan + last_vel_eye_vergence/2.0;
409
            float right = last_vel_eye_pan - last_vel_eye_vergence/2.0;
410

  
411
            //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);
412
            JointInterface::store_incoming_speed(ID_EYES_LEFT_LR, left, timestamp);
413
            JointInterface::store_incoming_speed(ID_EYES_RIGHT_LR, right, timestamp);
414
            break;
415
        }
416

  
417
        case(ICUB_ID_EYES_VERGENCE): { //vergence
418
            last_vel_eye_pan = value;
419
            float left  = last_vel_eye_pan + last_vel_eye_vergence/2.0;
420
            float right = last_vel_eye_pan - last_vel_eye_vergence/2.0;
421

  
422
            //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);
423
            JointInterface::store_incoming_speed(ID_EYES_LEFT_LR, left, timestamp);
424
            JointInterface::store_incoming_speed(ID_EYES_RIGHT_LR, right, timestamp);
425
            break;
426
        }
427
    }
428
}
429

  
430 373
void iCubJointInterface::set_joint_enable_state(int e, bool enable) {
431 374
    int icub_jointid = -1;
432 375

  
......
463 406

  
464 407
    if (icub_jointid != -1) {
465 408
        if (enable) {
466
            amp->enableAmp(icub_jointid);
467
            pid->enablePid(icub_jointid);
409
            yarp_amp_->enableAmp(icub_jointid);
410
            yarp_pid_->enablePid(icub_jointid);
468 411
        } else {
469
            pid->disablePid(icub_jointid);
470
            amp->disableAmp(icub_jointid);
412
            yarp_pid_->disablePid(icub_jointid);
413
            yarp_amp_->disableAmp(icub_jointid);
471 414
        }
472 415
    }
473 416
}
......
495 438
//! initialise a joint (set up controller mode etc)
496 439
//! \param joint enum
497 440
void iCubJointInterface::init_joints(){
498
    store_min_max(ilimits, ICUB_ID_NECK_TILT, ID_NECK_TILT);
499
    store_min_max(ilimits, ICUB_ID_NECK_ROLL, ID_NECK_ROLL);
500
    store_min_max(ilimits, ICUB_ID_NECK_PAN, ID_NECK_PAN);
501
    store_min_max(ilimits, ICUB_ID_EYES_BOTH_UD, ID_EYES_BOTH_UD);
441
    store_min_max(yarp_ilimits_, ICUB_ID_NECK_TILT, ID_NECK_TILT);
442
    store_min_max(yarp_ilimits_, ICUB_ID_NECK_ROLL, ID_NECK_ROLL);
443
    store_min_max(yarp_ilimits_, ICUB_ID_NECK_PAN, ID_NECK_PAN);
444
    store_min_max(yarp_ilimits_, ICUB_ID_EYES_BOTH_UD, ID_EYES_BOTH_UD);
502 445

  
503 446
    //icub handles eyes differently, we have to set pan angle + vergence
504 447
    double pan_min, pan_max, vergence_min, vergence_max;
505
    ilimits->getLimits(ICUB_ID_EYES_PAN, &pan_min, &pan_max);
506
    ilimits->getLimits(ICUB_ID_EYES_VERGENCE, &vergence_min, &vergence_max);
448
    yarp_ilimits_->getLimits(ICUB_ID_EYES_PAN, &pan_min, &pan_max);
449
    yarp_ilimits_->getLimits(ICUB_ID_EYES_VERGENCE, &vergence_min, &vergence_max);
507 450

  
508 451
    //this is not 100% correct, should be fixed:
509 452
    joint_min[ID_EYES_LEFT_LR] = pan_min; // - vergence_max/2;
......
535 478
    joint_max[ID_LIP_RIGHT_UPPER] = 50;
536 479
    joint_min[ID_LIP_RIGHT_LOWER] = 5;
537 480
    joint_max[ID_LIP_RIGHT_LOWER] = 50;
481
}
482

  
483
//! conversion table for humotion joint id to icub joint id
484
//! \param int value for humotion joint id from JointInterface::JOINT_ID_ENUM
485
//! \return int value of icub joint id
486
int iCubJointInterface::convert_humotion_jointid_to_icub(int humotion_id){
487
    enum_id_bimap_t::right_const_iterator it = enum_id_bimap.right.find(humotion_id);
488
    if(it == enum_id_bimap.right.end()) {
489
        //key does not exist
490
        cout << "ERROR: invalid humotion joint id given. can not convert this. exiting\n";
491
        exit(EXIT_FAILURE);
492
    }
493
    return it->second;
494
}
538 495

  
539 496

  
497
//! conversion table for icub joint id to humotion joint id
498
//! \param  int value of icub joint id
499
//! \return int value of humotion joint id from JointInterface::JOINT_ID_ENUM
500
int iCubJointInterface::convert_icub_jointid_to_humotion(int icub_id){
501
    enum_id_bimap_t::left_const_iterator it = enum_id_bimap.left.find(icub_id);
502
    if(it == enum_id_bimap.left.end()) {
503
        //key does not exist
504
        cout << "ERROR: invalid icub joint id given. can not convert this. exiting\n";
505
        exit(EXIT_FAILURE);
506
    }
507
    return it->second;
540 508
}
509

  
include/humotion/server/joint_interface.h
50 50
    JointInterface();
51 51
    ~JointInterface();
52 52

  
53
    void set_target_position(int joint_id, float position, float speed);
53
    void set_target(int joint_id, float position, float velocity);
54 54
    float get_target_position(int joint_id);
55
    virtual void publish_target_position(int joint_id) = 0;
55
    float get_target_velocity(int joint_id);
56

  
57
    void publish_target(int joint_id);
58
    virtual void publish_target(int joint_id, float position, float velocity) = 0;
56 59
    virtual void execute_motion() = 0;
57 60

  
58 61
    typedef std::map<int, TimestampedList> joint_tsl_map_t;
......
113 116

  
114 117
    float joint_min[JOINT_ID_ENUM_SIZE];
115 118
    float joint_max[JOINT_ID_ENUM_SIZE];
116
    float joint_target[JOINT_ID_ENUM_SIZE];
117
    float joint_target_speed[JOINT_ID_ENUM_SIZE];
118 119

  
119 120

  
120 121

  
121 122
private:
123
    float joint_target_position_[JOINT_ID_ENUM_SIZE];
124
    float joint_target_velocity_[JOINT_ID_ENUM_SIZE];
125

  
122 126
    boost::mutex joint_ts_position_map_access_mutex;
123 127
    boost::mutex joint_ts_speed_map_access_mutex;
124 128
    joint_tsl_map_t joint_ts_position_map;
src/server/eye_motion_generator.cpp
124 124
    reflexxes_calculate_profile();
125 125

  
126 126
    //tell the joint about the new values:
127
    joint_interface->set_target_position(JointInterface::ID_EYES_LEFT_LR,
128
                                         reflexxes_position_output->NewPositionVector->VecData[0],
129
                                         reflexxes_position_output->NewVelocityVector->VecData[0]);
130
    joint_interface->set_target_position(JointInterface::ID_EYES_RIGHT_LR,
131
                                         reflexxes_position_output->NewPositionVector->VecData[1],
132
                                         reflexxes_position_output->NewVelocityVector->VecData[1]);
133
    joint_interface->set_target_position(JointInterface::ID_EYES_BOTH_UD,
134
                                         reflexxes_position_output->NewPositionVector->VecData[2],
135
                                         reflexxes_position_output->NewVelocityVector->VecData[2]);
127
    joint_interface->set_target(JointInterface::ID_EYES_LEFT_LR,
128
                                reflexxes_position_output->NewPositionVector->VecData[0],
129
                                reflexxes_position_output->NewVelocityVector->VecData[0]);
130
    joint_interface->set_target(JointInterface::ID_EYES_RIGHT_LR,
131
                                reflexxes_position_output->NewPositionVector->VecData[1],
132
                                reflexxes_position_output->NewVelocityVector->VecData[1]);
133
    joint_interface->set_target(JointInterface::ID_EYES_BOTH_UD,
134
                                reflexxes_position_output->NewPositionVector->VecData[2],
135
                                reflexxes_position_output->NewVelocityVector->VecData[2]);
136 136

  
137 137
    cout << reflexxes_position_output->NewPositionVector->VecData[2] << " " << reflexxes_position_output->NewVelocityVector->VecData[2] ;
138 138
}
......
142 142
void EyeMotionGenerator::publish_targets(){
143 143
    //publish values if there is an active gaze input within the last timerange
144 144
    if (gaze_target_input_active()){
145
        joint_interface->publish_target_position(JointInterface::ID_EYES_LEFT_LR);
146
        joint_interface->publish_target_position(JointInterface::ID_EYES_RIGHT_LR);
147
        joint_interface->publish_target_position(JointInterface::ID_EYES_BOTH_UD);
145
        joint_interface->publish_target(JointInterface::ID_EYES_LEFT_LR);
146
        joint_interface->publish_target(JointInterface::ID_EYES_RIGHT_LR);
147
        joint_interface->publish_target(JointInterface::ID_EYES_BOTH_UD);
148 148
    }
149 149
}
src/server/eyebrow_motion_generator.cpp
22 22
    float eyebrow_right_target = requested_gaze_state.eyebrow_right;
23 23

  
24 24
    //store targets:
25
    joint_interface->set_target_position(JointInterface::ID_EYES_LEFT_BROW, eyebrow_left_target, 0.0);
26
    joint_interface->set_target_position(JointInterface::ID_EYES_RIGHT_BROW, eyebrow_right_target, 0.0);
25
    joint_interface->set_target(JointInterface::ID_EYES_LEFT_BROW, eyebrow_left_target, 0.0);
26
    joint_interface->set_target(JointInterface::ID_EYES_RIGHT_BROW, eyebrow_right_target, 0.0);
27 27
}
28 28

  
29 29
//! publish targets to motor boards:
30 30
void EyebrowMotionGenerator::publish_targets(){
31 31
    //publish values if there is an active gaze input within the last timerange
32 32
    if (gaze_target_input_active()){
33
        joint_interface->publish_target_position(JointInterface::ID_EYES_LEFT_BROW);
34
        joint_interface->publish_target_position(JointInterface::ID_EYES_RIGHT_BROW);
33
        joint_interface->publish_target(JointInterface::ID_EYES_LEFT_BROW);
34
        joint_interface->publish_target(JointInterface::ID_EYES_RIGHT_BROW);
35 35
    }
36 36
}
src/server/eyelid_motion_generator.cpp
77 77
    //limit target angles:
78 78
    eyelid_upper_left_target  = limit_target(JointInterface::ID_EYES_LEFT_LID_UPPER,  eyelid_upper_left_target);
79 79
    eyelid_lower_left_target  = limit_target(JointInterface::ID_EYES_LEFT_LID_LOWER,  eyelid_lower_left_target);
80
    eyelid_upper_right_target = limit_target(JointInterface::ID_EYES_RIGHT_LID_UPPER,  eyelid_upper_right_target);
81
    eyelid_lower_right_target = limit_target(JointInterface::ID_EYES_RIGHT_LID_LOWER,  eyelid_lower_right_target);
80
    eyelid_upper_right_target = limit_target(JointInterface::ID_EYES_RIGHT_LID_UPPER, eyelid_upper_right_target);
81
    eyelid_lower_right_target = limit_target(JointInterface::ID_EYES_RIGHT_LID_LOWER, eyelid_lower_right_target);
82 82

  
83 83
    //(temporarily) store the target
84
    joint_interface->set_target_position(JointInterface::ID_EYES_LEFT_LID_UPPER,  eyelid_upper_left_target, 0.0);
85
    joint_interface->set_target_position(JointInterface::ID_EYES_LEFT_LID_LOWER,  eyelid_lower_left_target, 0.0);
86
    joint_interface->set_target_position(JointInterface::ID_EYES_RIGHT_LID_UPPER,  eyelid_upper_right_target, 0.0);
87
    joint_interface->set_target_position(JointInterface::ID_EYES_RIGHT_LID_LOWER,  eyelid_lower_right_target, 0.0);
84
    joint_interface->set_target(JointInterface::ID_EYES_LEFT_LID_UPPER,  eyelid_upper_left_target, 0.0);
85
    joint_interface->set_target(JointInterface::ID_EYES_LEFT_LID_LOWER,  eyelid_lower_left_target, 0.0);
86
    joint_interface->set_target(JointInterface::ID_EYES_RIGHT_LID_UPPER, eyelid_upper_right_target, 0.0);
87
    joint_interface->set_target(JointInterface::ID_EYES_RIGHT_LID_LOWER, eyelid_lower_right_target, 0.0);
88 88

  
89 89
    //check for saccade
90 90
    check_for_saccade();
......
221 221
        //use the upper value + 10 deg as close state:
222 222
        value = joint_interface->get_joint_min(JointInterface::ID_EYES_LEFT_LID_UPPER) + 10.0;
223 223
        //overwrite last target_
224
        joint_interface->set_target_position(joint_id, value, 0.0);
224
        joint_interface->set_target(joint_id, value, 0.0);
225 225
        break;
226 226

  
227 227
    case(JointInterface::ID_EYES_RIGHT_LID_UPPER):
......
229 229
        //use the upper value + 10 deg as close state:
230 230
        value = joint_interface->get_joint_min(JointInterface::ID_EYES_RIGHT_LID_UPPER) + 10.0;
231 231
        //overwrite last target_
232
        joint_interface->set_target_position(joint_id, value, 0.0);
232
        joint_interface->set_target(joint_id, value, 0.0);
233 233
        break;
234 234
    }
235 235
}
......
268 268
void EyelidMotionGenerator::publish_targets(){
269 269
    //publish values if there is an active gaze input within the last timerange
270 270
    if (gaze_target_input_active()){
271
        joint_interface->publish_target_position(JointInterface::ID_EYES_LEFT_LID_UPPER);
272
        joint_interface->publish_target_position(JointInterface::ID_EYES_LEFT_LID_LOWER);
273
        joint_interface->publish_target_position(JointInterface::ID_EYES_RIGHT_LID_UPPER);
274
        joint_interface->publish_target_position(JointInterface::ID_EYES_RIGHT_LID_LOWER);
271
        joint_interface->publish_target(JointInterface::ID_EYES_LEFT_LID_UPPER);
272
        joint_interface->publish_target(JointInterface::ID_EYES_LEFT_LID_LOWER);
273
        joint_interface->publish_target(JointInterface::ID_EYES_RIGHT_LID_UPPER);
274
        joint_interface->publish_target(JointInterface::ID_EYES_RIGHT_LID_LOWER);
275 275
    }
276 276
}
src/server/joint_interface.cpp
48 48
//! set joint target position
49 49
//! \param joint_id of joint
50 50
//! \param float position
51
void JointInterface::set_target_position(int joint_id, float position, float speed){
51
void JointInterface::set_target(int joint_id, float position, float velocity){
52 52
    assert(joint_id < JOINT_ID_ENUM_SIZE);
53 53

  
54 54
    //update current value
55
    joint_target[joint_id] = position;
56
    joint_target_speed[joint_id] = speed;
55
    joint_target_position_[joint_id] = position;
56
    joint_target_velocity_[joint_id] = velocity;
57 57
}
58 58

  
59 59
//! fetch target position
60 60
//! \param joint_id of joint
61 61
float JointInterface::get_target_position(int joint_id){
62 62
    assert(joint_id < JOINT_ID_ENUM_SIZE);
63
    return joint_target[joint_id];
63
    return joint_target_position_[joint_id];
64
}
65

  
66
//! fetch target velocity
67
//! \param joint_id of joint
68
float JointInterface::get_target_velocity(int joint_id){
69
    assert(joint_id < JOINT_ID_ENUM_SIZE);
70
    return joint_target_velocity_[joint_id];
64 71
}
65 72

  
66 73
//! incoming position data
......
234 241
    gaze_enabled = false;
235 242
}
236 243

  
237
//! fetch maximum allowable joint position
244
//! fetch maximum allowed joint position
238 245
//! \return max position
239 246
float JointInterface::get_joint_max(int joint_id){
240 247
    assert((joint_id > 0) && (joint_id < JOINT_ID_ENUM_SIZE));
241 248
    return joint_max[joint_id];
242 249
}
243 250

  
244
//! fetch minimum allowable joint position
251
//! fetch minimum allowed joint position
245 252
//! \return min position
246 253
float JointInterface::get_joint_min(int joint_id){
247 254
    assert((joint_id > 0) && (joint_id < JOINT_ID_ENUM_SIZE));
......
253 260
bool JointInterface::get_joint_position_map_empty(){
254 261
    return (joint_ts_position_map.empty());
255 262
}
263

  
264
//! call the virtual store function with given position and velocities
265
void JointInterface::publish_target(int joint_id) {
266
    publish_target(joint_id, joint_target_position_[joint_id], joint_target_velocity_[joint_id]);
267
}
src/server/mouth_motion_generator.cpp
91 91
        unsafe_target_upper = unsafe_target_lower - opening;
92 92
    }
93 93

  
94
    //tell the joint about the new values:
95
    joint_interface->set_target_position(upper_id, unsafe_target_upper, 0.0);
96
    joint_interface->set_target_position(lower_id, unsafe_target_lower, 0.0);
97

  
98
    //printf("> update_mouth_target(u=%d, l=%d) -> upper = %4.2f, lower = %4.2f\n",upper_id, lower_id,unsafe_target_upper,unsafe_target_lower);
94
    // tell the joint about the new values:
95
    joint_interface->set_target(upper_id, unsafe_target_upper, 0.0);
96
    joint_interface->set_target(lower_id, unsafe_target_lower, 0.0);
99 97
}
100 98

  
101 99

  
......
139 137
void MouthMotionGenerator::publish_targets(){
140 138
    //publish values if there is an active gaze input within the last timerange
141 139
    if (mouth_target_input_active()){
142
        joint_interface->publish_target_position(JointInterface::ID_LIP_LEFT_UPPER);
143
        joint_interface->publish_target_position(JointInterface::ID_LIP_LEFT_LOWER);
144
        joint_interface->publish_target_position(JointInterface::ID_LIP_CENTER_UPPER);
145
        joint_interface->publish_target_position(JointInterface::ID_LIP_CENTER_LOWER);
146
        joint_interface->publish_target_position(JointInterface::ID_LIP_RIGHT_UPPER);
147
        joint_interface->publish_target_position(JointInterface::ID_LIP_RIGHT_LOWER);
140
        joint_interface->publish_target(JointInterface::ID_LIP_LEFT_UPPER);
141
        joint_interface->publish_target(JointInterface::ID_LIP_LEFT_LOWER);
142
        joint_interface->publish_target(JointInterface::ID_LIP_CENTER_UPPER);
143
        joint_interface->publish_target(JointInterface::ID_LIP_CENTER_LOWER);
144
        joint_interface->publish_target(JointInterface::ID_LIP_RIGHT_UPPER);
145
        joint_interface->publish_target(JointInterface::ID_LIP_RIGHT_LOWER);
148 146
    }
149 147
}
150 148

  
src/server/neck_motion_generator.cpp
162 162
    reflexxes_calculate_profile();
163 163

  
164 164
    //tell the joint if about the new values:
165
    joint_interface->set_target_position(JointInterface::ID_NECK_PAN,
166
                                         reflexxes_position_output->NewPositionVector->VecData[0],
167
                                         reflexxes_position_output->NewVelocityVector->VecData[0]);
165
    joint_interface->set_target(JointInterface::ID_NECK_PAN,
166
                                reflexxes_position_output->NewPositionVector->VecData[0],
167
                                reflexxes_position_output->NewVelocityVector->VecData[0]);
168 168

  
169
    joint_interface->set_target_position(JointInterface::ID_NECK_TILT,
170
                                         reflexxes_position_output->NewPositionVector->VecData[1],
171
                                         reflexxes_position_output->NewVelocityVector->VecData[1]);
169
    joint_interface->set_target(JointInterface::ID_NECK_TILT,
170
                                reflexxes_position_output->NewPositionVector->VecData[1],
171
                                reflexxes_position_output->NewVelocityVector->VecData[1]);
172 172

  
173
    joint_interface->set_target_position(JointInterface::ID_NECK_ROLL,
174
                                         reflexxes_position_output->NewPositionVector->VecData[2],
175
                                         reflexxes_position_output->NewVelocityVector->VecData[2]);
173
    joint_interface->set_target(JointInterface::ID_NECK_ROLL,
174
                                reflexxes_position_output->NewPositionVector->VecData[2],
175
                                reflexxes_position_output->NewVelocityVector->VecData[2]);
176 176

  
177 177
    printf("\n%f %f %f %f %f DBG\n",
178 178
            neck_pan_now, neck_pan_target,
......
186 186
void NeckMotionGenerator::publish_targets(){
187 187
    //publish values if there is an active gaze input within the last timerange
188 188
    if (gaze_target_input_active()){
189
        joint_interface->publish_target_position(JointInterface::ID_NECK_PAN);
190
        joint_interface->publish_target_position(JointInterface::ID_NECK_TILT);
191
        joint_interface->publish_target_position(JointInterface::ID_NECK_ROLL);
189
        joint_interface->publish_target(JointInterface::ID_NECK_PAN);
190
        joint_interface->publish_target(JointInterface::ID_NECK_TILT);
191
        joint_interface->publish_target(JointInterface::ID_NECK_ROLL);
192 192
    }
193 193
}
194 194

  

Also available in: Unified diff