Revision efbcb710

View differences:

server/include/Arbiter.h
65 65
    void override_by_utterance();
66 66
    void override_by_mouth();
67 67

  
68
    humotion::GazeState soft_overblend_gaze(humotion::GazeState gaze_now,
69
                                            humotion::GazeState gaze_target,
70
                                            unsigned int overblend_time);
71

  
68 72
    EmotionConfig emotion_config_current;
69 73
    EmotionConfig emotion_config_default;
70 74

  
71 75
    humotion::MouthState mouth_state;
72 76
    humotion::GazeState gaze_state;
73 77

  
78

  
79
    boost::posix_time::ptime gaze_state_end_time;
80
    humotion::GazeState gaze_state_old;
81
    bool gaze_state_animation_restart;
82

  
83
    EmotionConfig *emotion_target;
84

  
74 85
    MouthConfig mouth_config;
75 86

  
76 87
    boost::shared_ptr<Utterance> utterance;
server/include/EmotionConfig.h
34 34

  
35 35

  
36 36
class EmotionConfig{
37
public: 
37
public:
38 38

  
39 39
    typedef enum{
40 40
        NEUTRAL  = 0,
......
48 48

  
49 49
    EmotionConfig();
50 50
    EmotionConfig(EmotionType e);
51
	~EmotionConfig();
51
    ~EmotionConfig();
52 52

  
53 53
    void set_duration(unsigned long ms);
54 54

  
......
64 64
    bool is_active();
65 65

  
66 66

  
67
	//override/influence the gaze state
68
	// -> override neck angles (will be added to neck ptr)
69
	// -> set eyelid opening (rel to moving eyeball)
70
	// -> force eyebrows
71
	humotion::GazeState gaze_override;
67
    //override/influence the gaze state
68
    // -> override neck angles (will be added to neck ptr)
69
    // -> set eyelid opening (rel to moving eyeball)
70
    // -> force eyebrows
71
    humotion::GazeState gaze_override;
72 72

  
73
	//override mouth
74
	humotion::MouthState mouth_override;
73
    //override mouth
74
    humotion::MouthState mouth_override;
75

  
76
    //overblend time
77
    unsigned int overblend_time_ms;
75 78
private:
76
     boost::system_time end_time;
79
    boost::system_time end_time;
77 80
};
78 81

  
server/include/EmotionState.h
37 37

  
38 38
    EmotionConfig::EmotionType value;
39 39
    unsigned int duration;
40

  
40
    unsigned int overblend_time_ms;
41 41
};
42 42

  
43 43

  
server/src/Arbiter.cpp
34 34
using namespace boost;
35 35
using namespace std;
36 36

  
37

  
38 37
Arbiter::Arbiter(std::string audio_output){
39 38
    //initialize audio player:
40 39
    if (iequals(audio_output, "none")){
......
56 55
    emotion_config_current.set_duration(2000);
57 56
    emotion_config_default.init_neutral();
58 57

  
58
    gaze_state_animation_restart = true;
59
    emotion_target = &emotion_config_default;
60

  
59 61
    utterance = boost::shared_ptr<Utterance>(new Utterance());
60 62
}
61 63

  
......
68 70

  
69 71
    //update our config, ignore duration as this is the default emotion
70 72
    emotion_config_default.select_config(e.value);
73
    emotion_target = &emotion_config_default;
74

  
75
    gaze_state_animation_restart = true;
71 76

  
72 77
    printf("> stored default emotion\n");
73 78
}
......
81 86
    emotion_config_current.select_config(e.value);
82 87
    emotion_config_current.set_duration(e.duration);
83 88

  
89
    emotion_target = &emotion_config_current;
90
    gaze_state_animation_restart = true;
91

  
84 92
    printf("> stored current emotion (val=%d, duration = %dms)\n",e.value, e.duration);
85 93
}
86 94

  
......
257 265
}
258 266

  
259 267
void Arbiter::override_by_emotion(){
268
    if (emotion_target == NULL) {
269
        return;
270
    }
271

  
260 272
    //lock access
261 273
    mutex::scoped_lock scoped_lock1(emotion_config_default_mutex);
262
    mutex::scoped_lock scoped_lock2(emotion_config_current_mutex);
263 274

  
264
    EmotionConfig *emotion_target = &emotion_config_default;
265 275

  
266
    //which emotion is active?
267
    if (emotion_config_current.is_active()){
268
        //current emotion is not timed out, override default
269
        emotion_target = &emotion_config_current;
276
    // did the current emotion time out?
277
    if (!emotion_target->is_active()){
278
        // revert to default:
279
        emotion_target = &emotion_config_default;
280
        // trigger soft fade
281
        gaze_state_animation_restart = true;
270 282
    }
271 283

  
272 284
    //emotions will set the mouth state here (will be overwritten by speak)
273 285
    mouth_state = emotion_target->mouth_override;
286
    //mouth_state = ...
274 287

  
275 288
    //emotions will add an offset to the gaze state:
276 289
    //pan,tilt,roll will be overwritten by override_by_gaze() we only keep the offset values from this!
277 290
    //FIXME: change to eyelid opening  upper/lower once humotion supports it
278 291
    //eyebrow angles come from this
279
    gaze_state = emotion_target->gaze_override;
292
    humotion::GazeState gaze_state_target = emotion_target->gaze_override;
293
    // apply a soft overblending to the new gaze target
294
    gaze_state = soft_overblend_gaze(gaze_state, gaze_state_target, emotion_target->overblend_time_ms);
295

  
280 296
    //gaze_state.dump();
281 297

  
282 298
    //IMPORTANT: clear request from emotion target:
283 299
    emotion_target->gaze_override.eyeblink_request_left = 0;
284 300
    emotion_target->gaze_override.eyeblink_request_right = 0;
301
}
302

  
303
humotion::GazeState Arbiter::soft_overblend_gaze(humotion::GazeState gaze_now,
304
                                                 humotion::GazeState gaze_target,
305
                                                 unsigned int overblend_time) {
306
    humotion::GazeState result = gaze_now;
307

  
308
    result.eyeblink_request_left = 0;
309
    result.eyeblink_request_right = 0;
310

  
311
    if (gaze_state_animation_restart) {
312
        // new incoming target, set up soft fade:
313
        gaze_state_old = gaze_state;
314
        gaze_state_end_time = get_system_time() + boost::posix_time::milliseconds(overblend_time);
315
        gaze_state_animation_restart = false;
316
    }
317
    // do smooth overblend, all targets should be reached at gaze_state_end_time
318
    boost::posix_time::time_duration tdiff = gaze_state_end_time - get_system_time();
319
    if (tdiff.is_negative()) {
320
        // animation is done, exit now
321
        return result;
322
    } else {
323
        // do smooth animation
324
        double diff_ms = tdiff.total_milliseconds();
325
        double tp = 1.0 - diff_ms / static_cast<double>(overblend_time);
326

  
327
        result.pan_offset = gaze_state_old.pan_offset + tp * (gaze_target.pan_offset - gaze_state_old.pan_offset);
328
        result.tilt_offset = gaze_state_old.tilt_offset + tp * (gaze_target.tilt_offset - gaze_state_old.tilt_offset);
329
        result.roll_offset = gaze_state_old.roll_offset + tp * (gaze_target.roll_offset - gaze_state_old.roll_offset);
330

  
331
        result.eyelid_opening_lower = gaze_state_old.eyelid_opening_lower + tp * (gaze_target.eyelid_opening_lower - gaze_state_old.eyelid_opening_lower);
332
        result.eyelid_opening_upper = gaze_state_old.eyelid_opening_upper + tp * (gaze_target.eyelid_opening_upper - gaze_state_old.eyelid_opening_upper);
333

  
334
        result.eyebrow_left = gaze_state_old.eyebrow_left + tp * (gaze_target.eyebrow_left - gaze_state_old.eyebrow_left);
335
        result.eyebrow_right = gaze_state_old.eyebrow_right + tp * (gaze_target.eyebrow_right - gaze_state_old.eyebrow_right);
336

  
337
    }
285 338

  
339
    return result;
286 340
}
287 341

  
288 342

  
server/src/EmotionConfig.cpp
55 55
}
56 56

  
57 57
void EmotionConfig::select_config(EmotionType e){
58
    // default overblend time
59
    overblend_time_ms = 500;
60

  
58 61
    switch((int) e){
59 62
        default:
60 63
        case(NEUTRAL): init_neutral(); break;
......
130 133

  
131 134
void EmotionConfig::init_sad(){
132 135
    gaze_override.pan_offset = 0.0;
133
    gaze_override.tilt_offset = -3.0;
136
    gaze_override.tilt_offset = -13.0;
134 137
    gaze_override.roll_offset = -3.0;
135 138
    gaze_override.gaze_type = humotion::GazeState::GAZETYPE_ABSOLUTE; //GAZETYPE_OVERRIDE;
136 139

  
server/src/EmotionState.cpp
32 32

  
33 33
EmotionState::EmotionState(){
34 34
    value = EmotionConfig::NEUTRAL;
35
	duration = 0;
35
    duration = 0;
36 36
}
37 37

  
38 38
EmotionState::~EmotionState(){

Also available in: Unified diff