Revision 0d0f5ca1

View differences:

examples/yarp_icub/CMakeLists.txt
18 18

  
19 19
file(GLOB DUMMY_HEADER_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} include/*.h)
20 20

  
21
ADD_EXECUTABLE(${MAIN} src/main.cpp src/icub_jointinterface.cpp src/icub_data_receiver.cpp ${DUMMY_HEADER_LIST})
21
ADD_EXECUTABLE(${MAIN} src/main.cpp src/icub_jointinterface.cpp src/icub_faceinterface.cpp src/icub_data_receiver.cpp ${DUMMY_HEADER_LIST})
22 22

  
23 23
# we now add the YARP and iCub libraries to our project.
24 24
TARGET_LINK_LIBRARIES(${MAIN} ${Boost_LIBRARIES} ${YARP_LIBRARIES} ${ICUB_LIBRARIES} ${humotion_LIBRARIES})
examples/yarp_icub/include/icub_jointinterface.h
18 18
#include "icub_data_receiver.h"
19 19

  
20 20
class iCubDataReceiver;
21
class iCubFaceInterface;
21 22

  
22 23
class iCubJointInterface : public humotion::server::JointInterface{
23 24
public:
......
69 70
    double target_angle[ICUB_JOINT_ID_ENUM_SIZE];
70 71
    double target_angle_previous[ICUB_JOINT_ID_ENUM_SIZE];
71 72

  
72
    void set_eyelid_angle(double angle);
73
    void set_eyebrow_angle(int id);
74
    void set_mouth();
75

  
76 73
    iCubDataReceiver *icub_data_receiver;
77 74
    void init_joints();
78
    double lid_angle;
79
    int lid_opening_previous;
80
    int previous_mouth_state;
81 75

  
82 76
    std::string scope;
83 77
    yarp::dev::PolyDriver dd;
......
85 79
    yarp::sig::Vector velocities;
86 80
    yarp::sig::Vector commands;
87 81

  
88
    yarp::os::BufferedPort<yarp::os::Bottle> emotion_port[4];
89

  
90 82
    yarp::dev::IVelocityControl *ivel;
91 83
    yarp::dev::IPositionControl *ipos;
92 84
    yarp::dev::IEncodersTimed *iencs;
......
110 102
    int convert_enum_to_motorid(int e);
111 103
    int convert_motorid_to_enum(int id);
112 104

  
105
    iCubFaceInterface *face_interface;
113 106

  
114 107
    typedef boost::bimap<int, int > enum_id_bimap_t;
115 108
    typedef enum_id_bimap_t::value_type enum_id_bimap_entry_t;
examples/yarp_icub/src/icub_data_receiver.cpp
38 38
        icub_jointinterface->fetch_speed(i, velocities[i], timestamps[i]);
39 39
    }
40 40

  
41
    //printf("\n%f %f %f TIME\n", get_timestamp_ms(), timestamps[2], positions[2]);
42
    printf("TIMEDIFF %f\n", get_timestamp_ms() - timestamps[2]);
43

  
41 44
    //tell humotion to update lid angle (hack)
42 45
    icub_jointinterface->fetch_position(100, 0.0, get_timestamp_ms());
43 46
    //fixme: use real id
examples/yarp_icub/src/icub_jointinterface.cpp
1 1
#include "icub_jointinterface.h"
2
#include "icub_faceinterface.h"
3

  
2 4
#include <yarp/os/Property.h>
3 5
using namespace yarp::dev;
4 6
using namespace yarp::sig;
......
22 24
//! constructor
23 25
iCubJointInterface::iCubJointInterface(string _scope) : humotion::server::JointInterface(){
24 26
    scope = _scope;
25

  
27
    face_interface = new iCubFaceInterface(scope);
26 28

  
27 29
    //add mapping from ids to enums:
28 30
    //this might look strange at the first sight but we need to have a generic
......
99 101
        ivel->setRefAccelerations(commands.data());
100 102
    }
101 103

  
102
    //attach to facial expressions:
103
    string emotion_scope = scope + "/face/raw/in";
104
    printf("> opening connection to %s\n", emotion_scope.c_str());
105

  
106
    for(int i=0; i<4; i++){
107
        //strange, if we use one output port only the first command is executed?! flushing issues?
108
        string emotion_port_out = "/emotionwriter" + to_string(i);
109
        if (!emotion_port[i].open(emotion_port_out.c_str())){
110
            printf("> ERROR: failed to open to %s\n",emotion_port_out.c_str());
111
            exit(EXIT_FAILURE);
112
        }
113
        if (!Network::connect(emotion_port_out.c_str(), emotion_scope.c_str())){
114
            printf("> ERROR: failed to connect emotion ports\n");
115
            exit(EXIT_FAILURE);
116
        }
117
    }
118 104
}
119 105

  
120 106
//! destructor
......
148 134
    return it->second;
149 135
}
150 136

  
151
//! special command to set eyelid angle
152
//! \param angle in degrees
153
void iCubJointInterface::set_eyelid_angle(double angle){
154
    if (emotion_port[0].getOutputCount()>0){
155
        //try to set the value based on the upper one
156
        //some guesses from the sim: S30 = 0° / S40 = 10°
157
        int opening = (25.0 + 0.8*angle);
158
        opening = min(48, max(24, opening));
159

  
160
        if (opening == lid_opening_previous){
161
            //no update necessary
162
            return;
163
        }
164

  
165
        lid_angle = angle;
166
        lid_opening_previous = opening;
167

  
168
        char buf[20];
169
        sprintf(buf, "S%2d", opening);
170

  
171
        //printf("> SETTING EYELID '%s' (%f -> %d)\n",buf,angle,opening);
172
        Bottle &cmd = emotion_port[0].prepare();
173
        cmd.clear();
174
        cmd.addString(buf);
175
        emotion_port[0].writeStrict();
176
    }else{
177
        printf("> ERROR: no icub emotion output\n");
178
        exit(EXIT_FAILURE);
179
    }
180
}
181

  
182
//! special command to set the eyebrow angle
183
//! \param id {0=left, 1=right)
184
//! \param angle in degrees
185
void iCubJointInterface::set_eyebrow_angle(int id){
186
    int port_id;
187
    if (id == ICUB_ID_EYES_LEFT_BROW){
188
        port_id = 1;
189
    }else{
190
        port_id = 2;
191
    }
192

  
193
    if (emotion_port[port_id].getOutputCount()>0){
194
        double angle = target_angle[id];
195
        int icub_val = 0;
196

  
197
        //swap rotation direction:
198
        if (id==ICUB_ID_EYES_LEFT_BROW) angle = -angle;
199

  
200
        //convert to icub representation
201
        if (angle < -20){
202
            icub_val = 1;
203
        }else if (angle<10){
204
            icub_val = 2;
205
        }else if (angle<20){
206
            icub_val = 4;
207
        }else{
208
            icub_val = 8;
209
        }
210

  
211
        //make sure to update only on new values:
212
        if (icub_val == target_angle_previous[id]){
213
                //no updata necessary
214
                return;
215
        }
216

  
217
        //store actual value:
218
        target_angle_previous[id] = icub_val;
219

  
220

  
221
        string cmd_s;
222
        if (id==ICUB_ID_EYES_LEFT_BROW){
223
            cmd_s = "L0" + to_string(icub_val);
224
        }else{
225
            cmd_s = "R0" + to_string(icub_val);
226
        }
227

  
228
        printf("> SETTING EYEBROW %d (%f -> %s)\n",id,angle,cmd_s.c_str());
229

  
230
        Bottle &cmd = emotion_port[port_id].prepare();
231
        cmd.clear();
232
        cmd.addString(cmd_s);
233
        emotion_port[port_id].writeStrict();
234
    }else{
235
        printf("> ERROR: no icub emotion output\n");
236
        exit(EXIT_FAILURE);
237
    }
238
}
239 137

  
240 138
void iCubJointInterface::run(){
241
    iCubDataReceiver *data_receiver = new iCubDataReceiver(10/*1000.0 / MAIN_LOOP_FREQUENCY*/, iencs, this);
139
    iCubDataReceiver *data_receiver = new iCubDataReceiver(1000.0 / MAIN_LOOP_FREQUENCY, iencs, this);
242 140
    data_receiver->start();
243 141
}
244 142

  
......
248 146
void iCubJointInterface::publish_target_position(int e){
249 147
    //first: convert humotion enum to our enum:
250 148
    int id = convert_enum_to_motorid(e);
149

  
251 150
    if (id == -1){
252 151
        return; //we are not interested in that data, so we just return here
253 152
    }
......
273 172
//! \param id of joint
274 173
//! \param float value of position
275 174
void iCubJointInterface::store_joint(int id, float value){
276
    //printf("> set joint %d = %f\n",id,value);
175
    printf("> set joint %d = %f\n",id,value);
277 176
    target_angle[id] = value;
278
    //ipos->positionMove(id, value);
279 177
}
280 178

  
281 179
//! execute a move in position mode
......
323 221
    //execute:
324 222
    //ivel->velocityMove(id, speed);
325 223
    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;
224
        //if (id == ICUB_ID_NECK_PAN) speed = -speed;
327 225
        ivel->velocityMove(id, speed);
328 226
        printf("> VEL now=%3.2f target=%3.2f --> dist=%3.2f speed=%3.2f\n",target_angle_previous[id],value,distance,speed);
329 227
    }
......
350 248

  
351 249

  
352 250
    //eyelids: unfortuantely the icub has only 1dof for eyelids, so we use only one dof here:
353
    set_eyelid_angle(target_angle[ICUB_ID_EYES_RIGHT_LID_UPPER]);
251
    face_interface->set_eyelid_angle(target_angle[ICUB_ID_EYES_RIGHT_LID_UPPER]);
354 252

  
355 253
    //eyebrows are set using a special command as well:
356
    set_eyebrow_angle(ICUB_ID_EYES_LEFT_BROW);
357
    set_eyebrow_angle(ICUB_ID_EYES_RIGHT_BROW);
254
    face_interface->set_eyebrow_angle(ICUB_ID_EYES_LEFT_BROW, target_angle);
255
    face_interface->set_eyebrow_angle(ICUB_ID_EYES_RIGHT_BROW, target_angle);
358 256

  
359 257
    //mouth
360
    set_mouth();
361

  
362

  
363
}
364

  
365
void iCubJointInterface::set_mouth(){
366
    //convert from 6DOF mouth displacement to icub leds:
367
    int led_value = 0;
368

  
369
    //fetch center opening:
370
    double center_opening = target_angle[ICUB_ID_LIP_CENTER_LOWER] - target_angle[ICUB_ID_LIP_CENTER_UPPER];
371
    bool mouth_open = (center_opening>15.0)?true:false;
372

  
373
    //side of mouth high or low?
374
    double center_avg = (target_angle[ICUB_ID_LIP_CENTER_LOWER] + target_angle[ICUB_ID_LIP_CENTER_UPPER])/2.0;
375
    double left_avg   = (target_angle[ICUB_ID_LIP_LEFT_LOWER] + target_angle[ICUB_ID_LIP_LEFT_UPPER])/2.0;
376
    double right_avg  = (target_angle[ICUB_ID_LIP_RIGHT_LOWER] + target_angle[ICUB_ID_LIP_RIGHT_UPPER])/2.0;
377

  
378
    //happy, neutral or sad?
379
    double diff_l = center_avg - left_avg;
380
    double diff_r = center_avg - right_avg;
381
    double diff   = (diff_l+diff_r)/2.0;
382

  
383
    if (diff > 2.0){
384
        if (mouth_open){
385
            led_value = 0x14;
386
        }else{
387
            if (diff > 2.6){
388
                led_value = 0x0A;
389
            }else{
390
                led_value = 0x0B;
391
            }
392
        }
393
    }else if (diff < -3.0){
394
        if (mouth_open){
395
            led_value = 0x06;
396
        }else{
397
            led_value = 0x18;
398
        }
399
    }else if (diff < -2.0){
400
        if (mouth_open){
401
            led_value = 0x04; //0x25;
402
        }else{
403
            led_value = 0x08;
404
        }
405
    }else{
406
        if (mouth_open){
407
            led_value = 0x16;
408
        }else{
409
            led_value = 0x08;
410
        }
411
    }
412

  
413

  
414
    if (led_value == previous_mouth_state){
415
        //no update necessary
416
        return;
417
    }
418

  
419
    previous_mouth_state = led_value;
420

  
421
    //convert to string:
422
    char buf[10];
423
    sprintf(buf, "M%02X",led_value);
424

  
425
    /*printf("> sending mouth '%s'\n",buf);
426
    printf("> mouth angles: %3.2f %3.2f %3.2f\n",target_angle[ICUB_ID_LIP_LEFT_UPPER],target_angle[ICUB_ID_LIP_CENTER_UPPER],target_angle[ICUB_ID_LIP_RIGHT_UPPER]);
427
    printf("  mouth         %3.2f %3.2f %3.2f\n",target_angle[ICUB_ID_LIP_LEFT_LOWER],target_angle[ICUB_ID_LIP_CENTER_LOWER],target_angle[ICUB_ID_LIP_RIGHT_LOWER]);
428
    printf("  mouth  open=%3.2f diff=%3.2f\n", center_opening, diff);*/
429

  
430
    //add mouth:
431
    Bottle &cmd = emotion_port[3].prepare();
432
    cmd.clear();
433
    cmd.addString(buf);
434
    emotion_port[3].writeStrict();
258
    face_interface->set_mouth(target_angle);
435 259

  
436 260

  
437 261
    //store joint values which we do not handle on icub here:
......
442 266
    JointInterface::store_incoming_position(ID_LIP_CENTER_LOWER, target_angle[ICUB_ID_LIP_CENTER_LOWER], timestamp);
443 267
    JointInterface::store_incoming_position(ID_LIP_RIGHT_UPPER,  target_angle[ICUB_ID_LIP_RIGHT_UPPER], timestamp);
444 268
    JointInterface::store_incoming_position(ID_LIP_RIGHT_LOWER,  target_angle[ICUB_ID_LIP_RIGHT_LOWER], timestamp);
445

  
446 269
}
447 270

  
448 271
double iCubJointInterface::get_timestamp_ms(){
......
463 286
            return;
464 287

  
465 288
        case(100):
466
            JointInterface::store_incoming_position(ID_EYES_RIGHT_LID_UPPER, lid_angle, timestamp);
289
            //JointInterface::store_incoming_position(ID_EYES_RIGHT_LID_UPPER, lid_angle, timestamp);
467 290
            break;
468 291

  
469 292
        case(ICUB_ID_NECK_PAN):
470 293
            //PAN is inverted!
471
            JointInterface::store_incoming_position(ID_NECK_PAN, -value, timestamp);
294
            JointInterface::store_incoming_position(ID_NECK_PAN, value, timestamp);
472 295
            break;
473 296

  
474 297
        case(ICUB_ID_NECK_TILT):
......
523 346

  
524 347
        case(ICUB_ID_NECK_PAN):
525 348
            //PAN IS INVERTED
526
            JointInterface::store_incoming_speed(ID_NECK_PAN, -value, timestamp);
349
            JointInterface::store_incoming_speed(ID_NECK_PAN, value, timestamp);
527 350
            break;
528 351

  
529 352
        case(ICUB_ID_NECK_TILT):
......
650 473
    //eyelids:
651 474
    joint_min[ID_EYES_RIGHT_LID_UPPER] = -50; //24-30;
652 475
    joint_max[ID_EYES_RIGHT_LID_UPPER] = 50; //48-30;
653
    lid_angle = joint_max[ID_EYES_RIGHT_LID_UPPER];
476
    //lid_angle = joint_max[ID_EYES_RIGHT_LID_UPPER];
654 477

  
655 478
    //eyebrows:
656 479
    joint_min[ID_EYES_LEFT_BROW] = -50;
include/humotion/server/eye_motion_generator.h
43 43

  
44 44
    static const float SACCADE_SPEED_THRESHOLD;
45 45
private:
46
    void setup_eyemotion(int dof, float target, float now);
46
    void setup_eyemotion(int dof, float target, float current_position, float current_speed);
47 47

  
48 48
    TimestampedList tsl_gaze_target_pan;
49 49
    TimestampedList tsl_gaze_target_tilt;
include/humotion/server/motion_generator.h
46 46

  
47 47
protected:
48 48
    float get_current_position(int joint_id);
49
    float get_current_speed(int joint_id);
49 50
    float limit_target(int joint_id, float val);
50 51

  
51 52
    JointInterface *joint_interface;
include/humotion/server/neck_motion_generator.h
37 37
    ~NeckMotionGenerator();
38 38
    void calculate_targets();
39 39
    void publish_targets();
40
    void setup_neckmotion(int dof, float target, float now);
40
    void setup_neckmotion(int dof, float target, float current_position, float current_speed);
41 41

  
42 42
private:
43 43
    float get_breath_offset();
include/humotion/server/reflexxes_motion_generator.h
41 41
    ~ReflexxesMotionGenerator();
42 42

  
43 43
protected:
44
    void reflexxes_set_input(int dof, float target, float position, float max_speed, float max_accel);
44
    void reflexxes_set_input(int dof, float target, float current_position, float current_speed, float max_speed, float max_accel);
45 45
    void reflexxes_calculate_profile();
46 46

  
47 47
    //*****************************************
src/server/controller.cpp
98 98

  
99 99
    //check if this timestamp allows a valid conversion:
100 100
    Timestamp history_begin = joint_interface->get_ts_position(JointInterface::ID_NECK_PAN).get_first_timestamp();
101
    Timestamp history_end   = joint_interface->get_ts_position(JointInterface::ID_NECK_PAN).get_last_timestamp();
101
    // Timestamp history_end   = joint_interface->get_ts_position(JointInterface::ID_NECK_PAN).get_last_timestamp();
102 102

  
103 103
    //printf("> incoming: %f, history is %f to %f\n",relative_target_timestamp.to_seconds(), history_begin.to_seconds(), history_end.to_seconds());
104 104

  
src/server/eye_motion_generator.cpp
49 49
//! \param dof id of joint
50 50
//! \param target angle
51 51
//! \param current angle
52
void EyeMotionGenerator::setup_eyemotion(int dof, float target, float now){
52
void EyeMotionGenerator::setup_eyemotion(int dof, float target, float current_position, float current_speed){
53 53
    //get distance to target:
54
    float distance_abs = fabs(target - now);
54
    float distance_abs = fabs(target - current_position);
55 55
    //get max speed: factor can be found in encyc britannica: "linear.... being 300° per second for 10° and 500° per second for 30°" (max=700)
56 56
    float max_speed = fmin(700.0, 10.0*distance_abs + 200.0);
57 57
    //max accel: use data from ""Speed and Accuracy of Saccadic Eye Movements: Characteristics of Impulse Variability in the Oculomotor System"
......
60 60
    float max_accel = fmin(80000.0, 1526.53*distance_abs + 10245.4);
61 61

  
62 62
    //feed reflexxes api with data
63
    reflexxes_set_input(dof, target, now, max_speed, max_accel);
63
    reflexxes_set_input(dof, target, current_position, current_speed, max_speed, max_accel);
64 64
}
65 65

  
66 66
//! calculate joint targets
......
95 95
    float eye_pan_l_now = get_current_position(JointInterface::ID_EYES_LEFT_LR);
96 96
    float eye_pan_r_now = get_current_position(JointInterface::ID_EYES_RIGHT_LR);
97 97
    float eye_tilt_now  = get_current_position(JointInterface::ID_EYES_BOTH_UD);
98
    //fetch current velocities
99
    float eye_pan_l_speed = get_current_speed(JointInterface::ID_EYES_LEFT_LR);
100
    float eye_pan_r_speed = get_current_speed(JointInterface::ID_EYES_RIGHT_LR);
101
    float eye_tilt_speed  = get_current_speed(JointInterface::ID_EYES_BOTH_UD);
98 102

  
99 103
    //pass paramaters to reflexxes api:
100
    setup_eyemotion(0, eye_pan_l_target, eye_pan_l_now);
101
    setup_eyemotion(1, eye_pan_r_target, eye_pan_r_now);
102
    setup_eyemotion(2, eye_tilt_target, eye_tilt_now);
103
    cout << "EYE MOTION 2 " << eye_tilt_target << " now=" << eye_tilt_now << "\n";
104
    setup_eyemotion(0, eye_pan_l_target, eye_pan_l_now, eye_pan_l_speed);
105
    setup_eyemotion(1, eye_pan_r_target, eye_pan_r_now, eye_pan_r_speed);
106
    setup_eyemotion(2, eye_tilt_target, eye_tilt_now, eye_tilt_speed);
107

  
108
    // cout << "EYE MOTION 2 " << eye_tilt_target << " now=" << eye_tilt_now << "\n";
104 109

  
105 110
    //call reflexxes to handle profile calculation:
106 111
    reflexxes_calculate_profile();
src/server/motion_generator.cpp
45 45
MotionGenerator::~MotionGenerator(){
46 46
}
47 47

  
48
//! fetch thr latest (=current) position of a joint
48
//! fetch the latest (=current) speed of a joint
49
//! \param joint_id
50
//! \return float value of joint speed
51
float MotionGenerator::get_current_speed(int joint_id){
52
    return joint_interface->get_ts_speed(joint_id).get_newest_value();
53
}
54

  
55
//! fetch the latest (=current) position of a joint
49 56
//! \param joint_id
50 57
//! \return float value of joint position
51 58
float MotionGenerator::get_current_position(int joint_id){
src/server/neck_motion_generator.cpp
95 95
    float neck_pan_now  = get_current_position(JointInterface::ID_NECK_PAN);
96 96
    float neck_tilt_now = get_current_position(JointInterface::ID_NECK_TILT);
97 97
    float neck_roll_now = get_current_position(JointInterface::ID_NECK_ROLL);
98
    // fetch current velocities
99
    float neck_pan_speed  = get_current_speed(JointInterface::ID_NECK_PAN);
100
    float neck_tilt_speed = get_current_speed(JointInterface::ID_NECK_TILT);
101
    float neck_roll_speed = get_current_speed(JointInterface::ID_NECK_ROLL);
98 102

  
99 103
    //reached target?
100 104
    float goal_diff   = fabs(get_current_gaze().distance_pt_abs(requested_gaze_state));
......
143 147
    neck_tilt_target += get_breath_offset();
144 148

  
145 149
    //pass parameters to reflexxes api:
146
    setup_neckmotion(0, neck_pan_target,  neck_pan_now);
147
    setup_neckmotion(1, neck_tilt_target, neck_tilt_now);
148
    setup_neckmotion(2, neck_roll_target, neck_roll_now);
150
    setup_neckmotion(0, neck_pan_target,  neck_pan_now, neck_pan_speed);
151
    setup_neckmotion(1, neck_tilt_target, neck_tilt_now, neck_tilt_speed);
152
    setup_neckmotion(2, neck_roll_target, neck_roll_now, neck_roll_speed);
149 153

  
150 154
    //call reflexxes to handle profile calculation:
151 155
    reflexxes_calculate_profile();
......
158 162
    joint_interface->set_target_position(JointInterface::ID_NECK_TILT,
159 163
                                         reflexxes_position_output->NewPositionVector->VecData[1],
160 164
                                         reflexxes_position_output->NewVelocityVector->VecData[1]);
165

  
161 166
    joint_interface->set_target_position(JointInterface::ID_NECK_ROLL,
162 167
                                         reflexxes_position_output->NewPositionVector->VecData[2],
163 168
                                         reflexxes_position_output->NewVelocityVector->VecData[2]);
169

  
170
    printf("\n%f %f %f %f %f %f DBG\n",
171
            neck_pan_now, neck_pan_target,
172
            reflexxes_position_output->NewPositionVector->VecData[0],
173
            joint_interface->get_ts_speed(JointInterface::ID_NECK_PAN).get_newest_value(),
174
            reflexxes_position_output->NewVelocityVector->VecData[0]
175
            );
164 176
}
165 177

  
166 178
//! publish targets to motor boards:
......
179 191
//! \param dof id of joint
180 192
//! \param target angle
181 193
//! \param current angle
182
void NeckMotionGenerator::setup_neckmotion(int dof, float target, float now){
194
void NeckMotionGenerator::setup_neckmotion(int dof, float target, float current_position, float current_speed){
183 195
    //get distance to target:
184
    float distance_abs = fabs(target - now);
196
    float distance_abs = fabs(target - current_position);
185 197

  
186 198
    //get max speed: according to [guitton87] there is a relation between distance_abs and v_max_head:
187 199
    //v_max = 4.39 * d_total + 106.0 (in degrees)
......
216 228
    ///printf("MAX SPEED %4.2f / max accel %4.2f\n",max_speed, max_accel);
217 229

  
218 230
    //feed reflexxes api with data
219
    reflexxes_set_input(dof, target, now, max_speed, max_accel);
231
    reflexxes_set_input(dof, target, current_position, current_speed, max_speed, max_accel);
220 232
}
src/server/reflexxes_motion_generator.cpp
54 54
//! \param target angle
55 55
//! \param max_speed max reachable speed during accel
56 56
//! \param max_accel max allowable acceleration
57
void ReflexxesMotionGenerator::reflexxes_set_input(int dof, float target, float position, float max_speed, float max_accel){
57
void ReflexxesMotionGenerator::reflexxes_set_input(int dof, float target, float current_position, float current_speed, float max_speed, float max_accel){
58 58
    assert(dof < dof_count);
59 59

  
60 60
    //set up reflexxes:
......
63 63
    reflexxes_position_input->MaxVelocityVector->VecData[dof]     = max_speed;
64 64
    reflexxes_position_input->MaxAccelerationVector->VecData[dof] = max_accel;
65 65
    reflexxes_position_input->TargetVelocityVector->VecData[dof]  = 0.0; //target speed is zero (really?)
66
    reflexxes_position_input->CurrentPositionVector->VecData[dof]  = position;
66
    // feed back current pos & velocity
67
    reflexxes_position_input->CurrentPositionVector->VecData[dof]  = current_position;
68
    reflexxes_position_input->CurrentVelocityVector->VecData[dof]  = current_speed;
67 69

  
68 70
    // safety: libreflexxes does not like zero accellerations...
69 71
    if (reflexxes_position_input->MaxAccelerationVector->VecData[dof] == 0.0){
70 72
            reflexxes_position_input->MaxAccelerationVector->VecData[dof] = 0.0001;
71 73
    }
72

  
73 74
}
74 75

  
76

  
75 77
//! calculate motion profile
76 78

  
77 79
void ReflexxesMotionGenerator::reflexxes_calculate_profile(){
......
88 90
    //feed back values:
89 91
    for(int i=0; i<dof_count; i++){
90 92
        //reflexxes_position_input->CurrentPositionVector->VecData[i]     = reflexxes_position_output->NewPositionVector->VecData[i];
91
        reflexxes_position_input->CurrentVelocityVector->VecData[i]     = reflexxes_position_output->NewVelocityVector->VecData[i];
92
        reflexxes_position_input->CurrentAccelerationVector->VecData[i] = reflexxes_position_output->NewAccelerationVector->VecData[i];
93
        //reflexxes_position_input->CurrentVelocityVector->VecData[i]     = reflexxes_position_output->NewVelocityVector->VecData[i];
94
        //reflexxes_position_input->CurrentAccelerationVector->VecData[i] = reflexxes_position_output->NewAccelerationVector->VecData[i];
93 95
    }
94 96
}

Also available in: Unified diff