Revision f8fa1217

View differences:

client/python/hlrc_client.egg-info/SOURCES.txt
12 12
hlrc_client/RobotGaze.py
13 13
hlrc_client/RobotMouth.py
14 14
hlrc_client/__init__.py
15
hlrc_client/hlrc_play_animation.py
16
hlrc_client/hlrc_set_emotion.py
17
hlrc_client/hlrc_speak_utterance.py
18 15
hlrc_client/hlrc_test_gui.py
19 16
hlrc_client/textgrid_hlrc.py
20 17
hlrc_client.egg-info/PKG-INFO
client/python/hlrc_client.egg-info/entry_points.txt
1 1
[console_scripts]
2

  
2
hlrc_test_gui = hlrc_client.hlrc_test_gui:main
3 3

  
client/python/hlrc_client/Middleware.py
51 51
		self.gaze_target = RobotGaze()
52 52
		self.mouth_target = RobotMouth()
53 53
		self.robot_animation = RobotAnimation()
54
		
54
			
55
	def __del__(self):
56
		"""destructor
57
		"""
58
		self.logger.debug("destructor of Middleware called")
55 59
	
56 60
	def config_logger(self, level):
57 61
		formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
client/python/hlrc_client/MiddlewareROS.py
52 52
		Middleware.__init__(self,scope,loglevel)
53 53
		#call mw init
54 54
		self.init_middleware()
55
			
56
	def __del__(self):
57
		"""destructor
58
		"""
59
		self.logger.debug("destructor of MiddlewareROS called")
55 60
		
56 61
	#######################################################################
57 62
        def init_middleware(self):
client/python/hlrc_client/MiddlewareRSB.py
52 52
		Middleware.__init__(self,scope,loglevel)
53 53
		#call mw init
54 54
		self.init_middleware()
55
		
55

  
56
	def __del__(self):
57
		"""destructor
58
		"""
59
		self.logger.debug("destructor of MiddlewareROS called")
60
	
56 61
	#######################################################################
57 62
        def init_middleware(self):
58 63
		"""initialise middleware
client/python/hlrc_client/RobotController.py
31 31

  
32 32
class RobotController:
33 33
	def __init__(self, mw_name, scope, loglevel=logging.WARNING):
34
		"""initialise
35
		:param mw_name: which mw to use, currentyl ROS and RSB are supported
36
		:param scope: base scope we want to listen on 
37
		:param  loglevel: optional log level
38
		"""
34 39
		self.logger = logging.getLogger(__name__)
35 40
		
36 41
		# create nice and actually usable formatter and add it to the handler
37 42
		self.config_logger(loglevel)
38 43
		
39
		#store scope
44
		#store 
40 45
		self.scope = scope
46
		self.mw = mw_name
47
		self.loglevel = loglevel
41 48
		
42
		if (mw_name.upper() == "RSB"):
49
		self.middleware = None
50
		
51
				
52
		if (self.mw.upper() == "RSB"):
43 53
			self.logger.info("creating new middleware connection via RSB")
44
			self.middleware = MiddlewareRSB(self.scope, loglevel)
45
		elif (mw_name.upper() == "ROS"):
54
			self.middleware = MiddlewareRSB(self.scope, self.loglevel)
55
		elif (self.mw.upper() == "ROS"):
46 56
			self.logger.info("creating new middleware connection via ROS")
47
			self.middleware = MiddlewareROS(self.scope, loglevel)
57
			self.middleware = MiddlewareROS(self.scope, self.loglevel)
48 58
		else:
49
			self.logger.error("invalid middleware requested (%s). supported: {ROS, RSB}\n\n" % (mw_name))
59
			self.logger.error("invalid middleware requested (%s). supported: {ROS, RSB}\n\n" % (self.mw))
50 60
			sys.exit(errno.EINVAL)
51 61
	
62
	def __del__(self):
63
		"""destructor
64
		"""
65
		self.logger.debug("destructor of RobotController called")
66
	
52 67
	def config_logger(self, level):
68
		"""initialise a nice logger formatting
69
		:param  level: log level
70
		"""
53 71
		formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
54 72
		ch = logging.StreamHandler()
55 73
		#ch.setLevel(level)
......
58 76
		self.logger.addHandler(ch)
59 77

  
60 78
	def set_current_emotion(self, robot_emotion, blocking = False):
79
		"""set the current emotion
80
		:param robot_emotion: a RobotEmotion object
81
		:param blocking: should this call block during execution?
82
		"""
61 83
		self.logger.debug("set_current_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
62 84
		self.middleware.set_current_emotion(robot_emotion, blocking)
63 85
		
64 86
	def set_default_emotion(self, robot_emotion, blocking = False):
87
		"""set the default emotion
88
		:param robot_emotion: a RobotEmotion object
89
		:param blocking: should this call block during execution?
90
		"""
65 91
		self.logger.debug("set_default_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
66 92
		self.middleware.set_default_emotion(robot_emotion, blocking)
67 93
	
68 94
	def set_gaze_target(self, robot_gaze, blocking = False):
95
		"""set a gaze target
96
		:param robot_gaze: a RobotGaze object
97
		:param blocking: should this call block during execution?
98
		"""
99
		
69 100
		self.logger.debug("set_gaze_target(%s) %s" % (robot_gaze, ("BLOCKING" if blocking else "NON_BLOCKING")))
70 101
		self.middleware.set_gaze_target(robot_gaze, blocking)
71 102
	
72 103
	def set_mouth_target(self, robot_mouth, blocking = False):
104
		"""set a mouth target
105
		:param robot_mouth: a RobotMouth object
106
		:param blocking: should this call block during execution?
107
		"""		
73 108
		self.logger.debug("set_mouth_target(%s) %s" % (robot_mouth, ("BLOCKING" if blocking else "NON_BLOCKING")))
74 109
		self.middleware.set_mouth_target(robot_mouth, blocking)
75 110
	
76 111
	def set_head_animation(self, robot_animation, blocking = False):
112
		"""set a head animation
113
		:param robot_animation: a RobotAnimation object
114
		:param blocking: should this call block during execution?
115
		"""		
77 116
		self.logger.debug("set_head_animation(%s) %s" % (robot_animation, ("BLOCKING" if blocking else "NON_BLOCKING")))
78 117
		self.middleware.set_head_animation(robot_animation, blocking)
79 118
	
80 119
	def set_speak(self, text, blocking = False):
120
		"""request the robot to say something using tts
121
		:param text: text to synthesize
122
		:param blocking: should this call block during execution?
123
		"""
81 124
		self.logger.debug("set_speak(%s) %s" % (text, ("BLOCKING" if blocking else "NON_BLOCKING")))
82 125
		self.middleware.set_speak(text, blocking)
83 126

  
84
	def get_gaze_target(self):
85
		result = self.middleware.get_gaze_target()
86
		self.logger.debug("get_gaze_target() returned %s" % (result))
87
		return self.middleware.get_gaze_target()
127
	#def get_gaze_target(self):
128
	#	result = self.middleware.get_gaze_target()
129
	#	self.logger.debug("get_gaze_target() returned %s" % (result))
130
	#	return self.middleware.get_gaze_target()
client/python/hlrc_client/hlrc_play_animation.py
1
#!/usr/bin/python
2
#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
3
import sys
4
import logging
5
import errno
6

  
7
try:
8
    import rsb
9
    import rsb.converter
10
    import rst
11
    import rstsandbox
12
    from rst.robot.Animation_pb2 import Animation
13
except ImportError as exception:
14
    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
15
    sys.exit(errno.ENOPKG)
16

  
17
class hlrc_animation():
18
    def __init__(self, _base_scope):
19
        #print "> registering rst converter"
20
        converter = rsb.converter.ProtocolBufferConverter(messageClass = Animation)
21
        rsb.converter.registerGlobalConverter(converter)
22
        self.server = None	
23
        self.set_scope(_base_scope);
24

  
25
    def __del__(self):
26
        if (not self.server is None):
27
            self.server.deactivate()
28

  
29
    def set_scope(self, scope):
30
        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
31
        print "> setting scope to '%s'" % self.base_scope
32
	if (not self.server is None):
33
            self.server.deactivate()
34
	try:
35
            self.server = rsb.createRemoteServer(self.base_scope + '/set')
36
        except ValueError:
37
            print "> invalid scope given. server deactivated"
38
            self.server.deactivate()
39

  
40
    def trigger_animation(self, ani_id, repetitions, duration_each, scale, blocking):
41
        if (self.server is None):
42
            print("> invalid server")
43
            return
44
        #create animation & fill it with values:
45
        ani = Animation()
46

  
47
        #select ani
48
        ani.target = ani_id
49
        ani.repetitions = repetitions
50
        ani.duration_each = duration_each
51
        ani.scale       = scale
52

  
53
        if (blocking):
54
            #blocking:
55
            print "> calling the animation rpc (blocking until we finished talking)..."
56
            print '> server reply: "%s"' % self.server.animation(ani)
57
        else:
58
            print "> calling the animation rpc (NON-BLOCKING)..."
59
            return self.server.animation.async(ani)
60
            #we can block here for a incoming result with a timeout in s
61
            #print '> server reply: "%s"' % future.get(timeout = 10);
62

  
63
        print "> blocking call done"
64
    
65
def main():
66
    if (len(sys.argv) != 5):
67
        print "> usage: %s <base scope> <animation id> <dur each> <repetitions>\n>     example: %s /flobi1 1 1000 1" % (sys.argv[0] , sys.argv[0])
68
        sys.exit(0)
69

  
70
    # Pacify logger.
71
    #logging.basicConfig()
72
    scope  = sys.argv[1]
73
    ani_id = int(sys.argv[2])
74
    dur    = int(sys.argv[3])
75
    rep    = int(sys.argv[4])
76
    scale  = 1.0
77

  
78
    hani = hlrc_animation(scope)
79
    hani.trigger_animation(ani_id, rep, dur, scale, 1)
80

  
81
if __name__ == '__main__':
82
    main()
83

  
84

  
client/python/hlrc_client/hlrc_set_emotion.py
1
#!/usr/bin/python
2
#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
3
import sys
4
import logging
5
import errno
6

  
7
try:
8
    import rsb
9
    import rsb.converter
10
    import rst
11
    import rstsandbox
12
    from rst.robot.EmotionState_pb2 import EmotionState
13
except ImportError as exception:
14
    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
15
    sys.exit(errno.ENOPKG)
16

  
17
class hlrc_emotion():
18
    def __init__(self, _base_scope):
19
        #print "> registering rst converter"
20
        converter = rsb.converter.ProtocolBufferConverter(messageClass = EmotionState)
21
        rsb.converter.registerGlobalConverter(converter)
22
	self.set_scope( _base_scope);
23

  
24
    def set_scope(self, scope):
25
        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
26
        print "> setting scope to '%s'" % self.base_scope
27
        try:
28
            self.server = rsb.createRemoteServer(self.base_scope + '/set')
29
        except ValueError:
30
            print "> invalid scope given. server deactivated"
31
            self.server.deactivate()
32

  
33
    def set_emotion(self, emotion_id, duration_each, blocking):
34
        if (self.server is None):
35
            print("> invalid server")
36
            return
37

  
38
        #create emotion & fill it with values:
39
        em = EmotionState()
40

  
41
        #select ani
42
        em.value    = emotion_id
43
        em.duration = duration_each
44

  
45
        with rsb.createRemoteServer(self.base_scope + '/set') as server:
46
            if (blocking):
47
                #blocking:
48
                print "> calling the emotion rpc (blocking until we finished talking)..."
49
                print '> server reply: "%s"' % server.currentEmotion(em)
50
            else:
51
               print "> calling the animation rpc (NON-BLOCKING)..."
52
               future = server.currentEmotion.async(em)
53
               #we can block here for a incoming result with a timeout in s
54
               #print '> server reply: "%s"' % future.get(timeout = 10);
55

  
56
        print "> done"
57
    
58
def main():
59
    if (len(sys.argv) != 4):
60
        print "> usage: %s <base scope> <emotion id> <duration>\n>     example: %s /flobi1 1 1000" % (sys.argv[0] , sys.argv[0])
61
        sys.exit(0)
62

  
63
    # Pacify logger.
64
    #logging.basicConfig()
65
    em_id = int(sys.argv[2])
66
    dur    = int(sys.argv[3])
67
    base   = sys.argv[1]
68

  
69
    hlrc_emotion(base).set_emotion(em_id, dur, 1)
70

  
71
if __name__ == '__main__':
72
    main()
73

  
74

  
client/python/hlrc_client/hlrc_speak_utterance.py
1
#!/usr/bin/python
2
#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
3
import sys
4
import wave
5

  
6
from textgrid_hlc import *
7
import logging
8
import errno
9
import os.path
10

  
11
try:
12
    import rsb
13
    import rsb.converter
14
    import rst
15
    import rstsandbox
16
    from rst.audition.Utterance_pb2 import Utterance
17
    from rst.audition.SoundChunk_pb2 import SoundChunk
18
except ImportError as exception:
19
    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
20
    sys.exit(errno.ENOPKG)
21

  
22
class hlrc_utterance():
23
    def __init__(self, _base_scope):
24
        #print "> registering rst converter"
25
        converter = rsb.converter.ProtocolBufferConverter(messageClass = Utterance)
26
        rsb.converter.registerGlobalConverter(converter)
27
	self.set_scope(_base_scope)
28

  
29
    def set_scope(self, scope):
30
        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
31
        print "> setting scope to '%s'" % self.base_scope
32
        try:
33
            self.server = rsb.createRemoteServer(self.base_scope + '/set')
34
        except ValueError:
35
            print "> invalid scope given. server deactivated"
36
            self.server.deactivate()
37

  
38
    def trigger_utterance(self, filename_praat, filename_wav, blocking):
39
        if (self.server is None):
40
            print("> invalid server")
41
            return
42

  
43
        if (not os.path.isfile(filename_praat)):
44
            print "can not open file '%s'" % (filename_praat)
45
            return 0
46

  
47
        if (not os.path.isfile(filename_wav)):
48
            print "can not open file '%s'" % (filename_wav)
49
            return 0
50

  
51
        print "> reading wave file '%s'" % (filename_wav)
52
        wav = wave.open(filename_wav, "r")
53

  
54
    
55
        print "> parsing praat file '%s'" % (filename_praat)
56
        tgrid = TextGrid.load(filename_praat)
57
    
58
    
59
        #create utterance & fill it with values:
60
        ut = Utterance()
61
    
62
        #textual description of audio file
63
        ut.text = filename_praat
64
        
65
        ut.audio.data = wav.readframes(-1)
66
        ut.audio.sample_count = wav.getnframes()
67
        ut.audio.channels = wav.getnchannels()
68
        ut.audio.rate = wav.getframerate()
69
    
70
        if (wav.getsampwidth() == 1):
71
            ut.audio.sample_type = SoundChunk.SAMPLE_U8
72
        elif (wav.getsampwidth() == 2):
73
            ut.audio.sample_type = SoundChunk.SAMPLE_S16
74
        else:
75
            print "> invalid sample type. py doc says wave files are either u8 or s16"
76
            exit(0)
77
    
78
        #wave spec says always little endian
79
        ut.audio.endianness = SoundChunk.ENDIAN_LITTLE
80
    
81
        print "> filling phones with data from praat"
82
        for tier in tgrid.tiers:
83
            idx = (tgrid.tiers.index(tier)) + 1
84
            transcript = tier.simple_transcript
85
            for (xmin, xmax, utt) in transcript:
86
                phoneme = ut.phonemes.add()
87
                phoneme.symbol = utt
88
                phoneme.duration = int(1000.0*(float(xmax)-float(xmin)))
89
    
90
        with rsb.createRemoteServer(self.base_scope + '/set') as server:
91
            
92
            if (blocking):
93
                #blocking:
94
                print "> calling the utterance rpc (blocking until we finished talking)..."
95
                print '> server reply: "%s"' % server.utterance(ut)
96
            else:
97
               print "> calling the utterance rpc (NON-BLOCKING)..."
98
               future = server.utterance.async(ut)
99
               #we can block here for a incoming result with a timeout in seconds
100
               #print '> server reply: "%s"' % future.get(timeout = 10);
101
    
102
        print "> done"
103
        return 1
104

  
105
def main():
106
    # Pacify logger.
107
    #logging.basicConfig()
108
    if (len(sys.argv) != 4):
109
        print "> usage: %s <base_scope> file.praat file.wav\n>     example: %s /flobi1 hello.praat hello.wav" % (sys.argv[0] , sys.argv[0])
110
        sys.exit(0)
111

  
112
    filename_praat = sys.argv[2]
113
    filename_wav = sys.argv[3]
114
    base = sys.argv[1]
115

  
116
    hlc = hlrc_utterance(base)
117
    hlc.trigger_utterance(filename_praat, filename_wav, 1)
118

  
119
if __name__ == '__main__':
120
    main()
client/python/hlrc_client/hlrc_test_gui.py
1 1
#!/usr/bin/python
2

  
3
"""
4
This file is part of hlrc
5

  
6
Copyright(c) sschulz <AT> techfak.uni-bielefeld.de
7
http://opensource.cit-ec.de/projects/hlrc
8

  
9
This file may be licensed under the terms of the
10
GNU General Public License Version 3 (the ``GPL''),
11
or (at your option) any later version.
12

  
13
Software distributed under the License is distributed
14
on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
15
express or implied. See the GPL for the specific language
16
governing rights and limitations.
17

  
18
You should have received a copy of the GPL along with this
19
program. If not, go to http://www.gnu.org/licenses/gpl.html
20
or write to the Free Software Foundation, Inc.,
21
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22

  
23
The development of this software was supported by the
24
Excellence Cluster EXC 277 Cognitive Interaction Technology.
25
The Excellence Cluster EXC 277 is a grant of the Deutsche
26
Forschungsgemeinschaft (DFG) in the context of the German
27
Excellence Initiative.
28
"""
29

  
30

  
31
import logging
32
from hlrc_client import *
33
import time
34
import errno
2 35
import sys
3 36
import os.path
37

  
4 38
from PyQt4 import QtGui, QtCore
5 39
from PyQt4.QtCore import SIGNAL
6
from hlrc_speak_utterance import hlrc_utterance
7
from hlrc_play_animation import hlrc_animation
8
from hlrc_set_emotion import hlrc_emotion
9 40

  
10
class Example(QtGui.QWidget):
41
#from hlrc_speak_utterance import hlrc_utterance
42
#from hlrc_play_animation import hlrc_animation
43
#from hlrc_set_emotion import hlrc_emotion
44

  
45
class HLRCExample(QtGui.QWidget):
11 46
    
12
    def __init__(self, _scope):
13
        super(Example, self).__init__()
14
        self.scope = _scope
15
        self.initUI()
16
	scope = self.scope_lineedit.text()
17
        self.hlrc_utterance = hlrc_utterance(scope)
18
        self.hlrc_animation = hlrc_animation(scope)
19
        self.hlrc_emotion   = hlrc_emotion(scope)
20

  
21
    def scopeChanged(self):
22
	self.scope = self.scope_lineedit.text()
23
        print "> changed scope to %s" % self.scope
24
        self.hlrc_utterance.set_scope(self.scope)
25
        self.hlrc_animation.set_scope(self.scope)
26
        self.hlrc_emotion.set_scope(self.scope)
27

  
28
    def initUtteranceUI(self):
29
        groupBox = QtGui.QGroupBox("utterances")
30

  
31
        hello = QtGui.QPushButton("hello...")
32
        hello.clicked.connect(self.utterance_button_clicked)
33

  
34
        count = QtGui.QPushButton("12345...")
35
        count.clicked.connect(self.utterance_button_clicked)
36

  
37

  
38
        vbox = QtGui.QVBoxLayout()
39
        vbox.addWidget(hello)
40
        vbox.addWidget(count)
41
        vbox.addStretch(1)
42
        groupBox.setLayout(vbox)
43

  
44
        return groupBox
45

  
46
    def initSpinbox(self, _min, _max, _init, double):
47
        if (double): 
48
            s = QtGui.QDoubleSpinBox()
49
        else:
50
            s = QtGui.QSpinBox()
51

  
52
        s.setMinimum(_min)
53
        s.setMaximum(_max)
54
        s.setValue(_init)
55
        return s
56

  
57
    def initEmotionUI(self):
58
        groupBox = QtGui.QGroupBox("emotion")
59
        neutral   = QtGui.QPushButton("neutral")
60
        neutral.clicked.connect(self.emotion_button_clicked)
61
        surprised = QtGui.QPushButton("surprise")
62
        surprised.clicked.connect(self.emotion_button_clicked)
63
        angry     = QtGui.QPushButton("angry")
64
        angry.clicked.connect(self.emotion_button_clicked)
65
        happy     = QtGui.QPushButton("happy")
66
        happy.clicked.connect(self.emotion_button_clicked)
67
        sad     = QtGui.QPushButton("sad")
68
        sad.clicked.connect(self.emotion_button_clicked)
69
        fear      = QtGui.QPushButton("fear")
70
        fear.clicked.connect(self.emotion_button_clicked)
71

  
72
        self.duration_spinbox = self.initSpinbox(100, 10000, 1000, 0)
73

  
74
        vbox = QtGui.QVBoxLayout()
75
        vbox.addWidget(self.duration_spinbox)
76
        vbox.addWidget(neutral)
77
        vbox.addWidget(surprised)
78
        vbox.addWidget(angry)
79
        vbox.addWidget(happy)
80
        vbox.addWidget(sad)
81
        vbox.addWidget(fear)
82
        vbox.addStretch(1)
83
        groupBox.setLayout(vbox)
84
        return groupBox
85

  
86

  
87
    def initAnimationButton(self, name):
88
        b = QtGui.QPushButton(name)
89
        b.clicked.connect(self.animation_button_clicked)
90
        return b
91

  
92
    def initAnimUI(self):
93
        groupBox = QtGui.QGroupBox("animations")
94
  
95
        #options
96
        options = QtGui.QHBoxLayout()
97
        vbox_r = QtGui.QVBoxLayout()
98
        vbox_r.addWidget(QtGui.QLabel("repetitions"))
99
        self.repetitions_spinbox = self.initSpinbox(1,10,1,0)
100
        vbox_r.addWidget(self.repetitions_spinbox)
101

  
102
        vbox_d = QtGui.QVBoxLayout()
103
        vbox_d.addWidget(QtGui.QLabel("duration/ms (each)"))
104
        self.duration_each_spinbox = self.initSpinbox(100,10000,1000,0)
105
        vbox_d.addWidget(self.duration_each_spinbox)
106

  
107
        vbox_s = QtGui.QVBoxLayout()
108
        vbox_s.addWidget(QtGui.QLabel("scale"))
109
        self.scale_spinbox = self.initSpinbox(0.1, 5.0, 1.0, 1)
110
        vbox_s.addWidget(self.scale_spinbox)
111

  
112

  
113
        options.addLayout(vbox_r)
114
        options.addLayout(vbox_d)        
115
        options.addLayout(vbox_s)
116

  
117
        #buttons
118
        vbox = QtGui.QVBoxLayout()
119
        vbox.addLayout(options)
120
        vbox.addWidget(self.initAnimationButton("head shake"))
121
        vbox.addWidget(self.initAnimationButton("head nod"))
122
        vbox.addWidget(self.initAnimationButton("eyeblink left"))
123
        vbox.addWidget(self.initAnimationButton("eyeblink right"))
124
        vbox.addWidget(self.initAnimationButton("eyeblink both"))
125
	vbox.addWidget(self.initAnimationButton("eyebrows raise"))
126
	vbox.addWidget(self.initAnimationButton("eyebrows lower"))
127
        vbox.addStretch(1)
128
        groupBox.setLayout(vbox)
129

  
130
        return groupBox
131

  
132
    def initUI(self):        
133

  
134
        self.scope_lineedit = QtGui.QLineEdit(self.scope);
135
        self.connect(self.scope_lineedit, SIGNAL("editingFinished()"),self.scopeChanged)
136

  
137
	vbox = QtGui.QVBoxLayout();
47
	def __init__(self, scope, mw):
48
		super(HLRCExample, self).__init__()
138 49
	
139
	hboxl = QtGui.QHBoxLayout();
140
	hboxl.addWidget(QtGui.QLabel("base scope: "));
141
	hboxl.addWidget(self.scope_lineedit);
142
	vbox.addLayout(hboxl);
143

  
144
        hbox = QtGui.QHBoxLayout()
145
	vbox.addLayout(hbox);
50
		self.scope = scope
51
		self.mw = mw
52
		self.initUI()
53
		self.robot_controller = RobotController(self.mw, self.scope, logging.DEBUG)
54

  
55
	def initUtteranceUI(self):
56
		groupBox = QtGui.QGroupBox("utterances")
57

  
58
		hello = QtGui.QPushButton("hello...")
59
		hello.clicked.connect(self.utterance_button_clicked)
60

  
61
		count = QtGui.QPushButton("12345...")
62
		count.clicked.connect(self.utterance_button_clicked)
63

  
64

  
65
		vbox = QtGui.QVBoxLayout()
66
		vbox.addWidget(hello)
67
		vbox.addWidget(count)
68
		vbox.addStretch(1)
69
		groupBox.setLayout(vbox)
70

  
71
		return groupBox
72

  
73
	def initSpinbox(self, _min, _max, _init, double):
74
		if (double): 
75
			s = QtGui.QDoubleSpinBox()
76
		else:
77
			s = QtGui.QSpinBox()
78

  
79
		s.setMinimum(_min)
80
		s.setMaximum(_max)
81
		s.setValue(_init)
82
		return s
83

  
84
	def initPushButton(self, base_layout, text, action):
85
		button = QtGui.QPushButton(text)
86
		button.clicked.connect(action)
87
		base_layout.addWidget(button)
88
		
89
	def initEmotionUI(self):
90
		vbox = QtGui.QVBoxLayout()
91
		self.duration_spinbox = self.initSpinbox(100, 10000, 1000, 0)
92
		vbox.addWidget(self.duration_spinbox)
93
		
94
		self.duration_spinbox = self.initSpinbox(100, 10000, 1000, 0)
95
		self.initPushButton(vbox, "neutral",  self.emotion_button_clicked)
96
		self.initPushButton(vbox, "surprise", self.emotion_button_clicked)
97
		self.initPushButton(vbox, "angry",    self.emotion_button_clicked)
98
		self.initPushButton(vbox, "happy",    self.emotion_button_clicked)
99
		self.initPushButton(vbox, "sad",      self.emotion_button_clicked)
100
		self.initPushButton(vbox, "fear",     self.emotion_button_clicked)
101
		vbox.addStretch(1)
102
		
103
		groupBox = QtGui.QGroupBox("emotion")
104
		groupBox.setLayout(vbox)
105
		return groupBox
106

  
107
	def initAnimationButton(self, base_layout, name):
108
		b = QtGui.QPushButton(name)
109
		b.clicked.connect(self.animation_button_clicked)
110
		base_layout.addWidget(b)
111

  
112
	def initAnimUI(self):
113
		groupBox = QtGui.QGroupBox("animations")
146 114
	
147
        #emotion
148
        hbox.addWidget(self.initEmotionUI())
149

  
150
        #utterance:
151
        hbox.addWidget(self.initUtteranceUI())
152

  
153
        #animations:
154
        hbox.addWidget(self.initAnimUI())
155

  
156
        self.setLayout(vbox)
157
        #sld.valueChanged.connect(lcd.display)
158
        
159
        self.setGeometry(400, 100, 250, 150)
160
        self.setWindowTitle("HLC Server test GUI")
161
        self.show()
162

  
163
    def utterance_button_clicked(self):
164
        button = self.sender().text()
165
        
166
        fn_praat = "b.praat"
167
        fn_wav   = "b.wav"
168

  
169
        if (button == "12345..."):
170
            print("123")
171
            fn_praat = "1234.praat"
172
            fn_wav   = "1234.wav"
173

  
174
        elif (button == "hello..."):
175
            print "hello"
176
            fn_praat = "hello_my_name.praat"
177
            fn_wav   = "hello_my_name.wav"
178

  
179
        else:
180
            print "invalid button '%s'" % (button)
181
            return
182

  
183
        #try to find the wav/praat files:
184
        path = os.path.dirname(os.path.realpath(__file__)) + "/../share/hlrc_server/examples/"
185
        if (not os.path.isfile(path + fn_wav)):
186
            #try fallback solution for running from current folder:
187
            path = "examples/"
188

  
189
        self.hlrc_utterance.trigger_utterance(path + fn_praat, path + fn_wav, 0)
190

  
191
    def emotion_button_clicked(self):
192
        button = self.sender().text()
193
        duration = self.duration_spinbox.value()
194

  
195

  
196
        if (button == "angry"):
197
            self.hlrc_emotion.set_emotion(3, duration, 0)
198
        elif (button == "neutral"):
199
            self.hlrc_emotion.set_emotion(0, duration, 0)
200
        elif (button == "happy"):
201
            self.hlrc_emotion.set_emotion(1, duration, 0)
202
        elif (button == "sad"):
203
            self.hlrc_emotion.set_emotion(2, duration, 0)
204
        elif (button == "surprise"):
205
            self.hlrc_emotion.set_emotion(4, duration, 0)
206
        elif (button == "fear"):
207
            self.hlrc_emotion.set_emotion(5, duration, 0)
208
        else:
209
            print "invalid emotion id '%s'" % (button)
210
            return
211

  
212
    def animation_button_clicked(self):
213
        button = self.sender().text()
214

  
215
        repetitions = self.repetitions_spinbox.value()
216
        duration_each = self.duration_each_spinbox.value()
217
        scale = self.scale_spinbox.value()
218

  
219
        if (button == "head nod"):
220
            self.hlrc_animation.trigger_animation(1, repetitions, duration_each, scale, 0)
221
        elif (button == "head shake"):
222
            self.hlrc_animation.trigger_animation(2, repetitions, duration_each, scale, 0)
223
        elif (button == "eyeblink left"):
224
            self.hlrc_animation.trigger_animation(3, repetitions, duration_each, scale, 0)
225
        elif (button == "eyeblink right"):
226
            self.hlrc_animation.trigger_animation(4, repetitions, duration_each, scale, 0)
227
        elif (button == "eyeblink both"):
228
            self.hlrc_animation.trigger_animation(5, repetitions, duration_each, scale, 0)
229
        elif (button == "eyebrows raise"):
230
            self.hlrc_animation.trigger_animation(6, repetitions, duration_each, scale, 0)
231
        elif (button == "eyebrows lower"):
232
            self.hlrc_animation.trigger_animation(7, repetitions, duration_each, scale, 0)
233
        else:
234
            print "invalid button '%s'" % (button)
235
            return
115
		#options
116
		options = QtGui.QHBoxLayout()
117
		vbox_r = QtGui.QVBoxLayout()
118
		vbox_r.addWidget(QtGui.QLabel("repetitions"))
119
		self.repetitions_spinbox = self.initSpinbox(1,10,1,0)
120
		vbox_r.addWidget(self.repetitions_spinbox)
121

  
122
		vbox_d = QtGui.QVBoxLayout()
123
		vbox_d.addWidget(QtGui.QLabel("duration/ms (each)"))
124
		self.duration_each_spinbox = self.initSpinbox(100,10000,1000,0)
125
		vbox_d.addWidget(self.duration_each_spinbox)
126

  
127
		vbox_s = QtGui.QVBoxLayout()
128
		vbox_s.addWidget(QtGui.QLabel("scale"))
129
		self.scale_spinbox = self.initSpinbox(0.1, 5.0, 1.0, 1)
130
		vbox_s.addWidget(self.scale_spinbox)
131

  
132

  
133
		options.addLayout(vbox_r)
134
		options.addLayout(vbox_d)        
135
		options.addLayout(vbox_s)
136

  
137
		#buttons
138
		vbox = QtGui.QVBoxLayout()
139
		vbox.addLayout(options)
140
		self.initAnimationButton(vbox, "head shake")
141
		self.initAnimationButton(vbox, "head nod")
142
		self.initAnimationButton(vbox, "eyeblink left")
143
		self.initAnimationButton(vbox, "eyeblink right")
144
		self.initAnimationButton(vbox, "eyeblink both")
145
		self.initAnimationButton(vbox, "eyebrows raise")
146
		self.initAnimationButton(vbox, "eyebrows lower")
147
		vbox.addStretch(1)
148
		groupBox.setLayout(vbox)
149

  
150
		return groupBox
151

  
152
	def initUI(self):
153
		vbox = QtGui.QVBoxLayout()
154
		
155
		hboxl = QtGui.QHBoxLayout()
156
		hboxl.addWidget(QtGui.QLabel("base scope: "))
157
		hboxl.addWidget(QtGui.QLabel(self.scope))
158
		vbox.addLayout(hboxl)
159

  
160
		hbox = QtGui.QHBoxLayout()
161
		vbox.addLayout(hbox)
162
		
163
		#emotion
164
		hbox.addWidget(self.initEmotionUI())
165

  
166
		#utterance:
167
		hbox.addWidget(self.initUtteranceUI())
168

  
169
		#animations:
170
		hbox.addWidget(self.initAnimUI())
171

  
172
		self.setLayout(vbox)
173
		#sld.valueChanged.connect(lcd.display)
174
		
175
		self.setGeometry(400, 100, 250, 150)
176
		self.setWindowTitle("HLRC Server test GUI - %s" % self.scope)
177
		self.show()
178

  
179
	def utterance_button_clicked(self):
180
		button = self.sender().text()
181
		
182
		
183
		if (button == "12345..."):
184
			self.robot_controller.set_speak("1 2 3 4 5 6 7 8 9 10", False)
185
		elif (button == "hello..."):
186
			self.robot_controller.set_speak("Hello my name is flobi. How can i help you?", False)
187
		else:
188
			self.robot_controller.set_speak("invalid button name", False)
189
			print "invalid button '%s'" % (button)
190

  
191
	def emotion_button_clicked(self):
192
		button = self.sender().text()
193
		
194
		re = RobotEmotion()
195
		re.time_ms = self.duration_spinbox.value()
196
		
197
		if (button == "angry"):
198
			re.value = RobotEmotion.ANGRY
199
		elif (button == "neutral"):
200
			re.value = RobotEmotion.NEUTRAL
201
		elif (button == "happy"):
202
			re.value = RobotEmotion.HAPPY
203
		elif (button == "sad"):
204
			re.value = RobotEmotion.SAD
205
		elif (button == "surprise"):
206
			re.value = RobotEmotion.SURPRISED
207
		elif (button == "fear"):
208
			re.value = RobotEmotion.FEAR
209
		else:
210
			print "invalid emotion id '%s'" % (button)
211
			return 
212
		
213
		self.robot_controller.set_current_emotion(re, False)
214
		
215
	def animation_button_clicked(self):
216
		button = self.sender().text()
217
		
218
		ra = RobotAnimation()
219
		ra.time_ms =  self.duration_each_spinbox.value()
220
		ra.repetitions = self.repetitions_spinbox.value()
221
		ra.scale = self.scale_spinbox.value()
222

  
223
		if (button == "head nod"):
224
			ra.value = RobotAnimation.HEAD_NOD
225
		elif (button == "head shake"):
226
			ra.value = RobotAnimation.HEAD_SHAKE
227
		elif (button == "eyeblink left"):
228
			ra.value = RobotAnimation.EYEBLINK_L
229
		elif (button == "eyeblink right"):
230
			ra.value = RobotAnimation.EYEBLINK_R
231
		elif (button == "eyeblink both"):
232
			ra.value = RobotAnimation.EYEBLINK_BOTH
233
		elif (button == "eyebrows raise"):
234
			ra.value = RobotAnimation.EYEBROWS_RAISE
235
		elif (button == "eyebrows lower"):
236
			ra.value = RobotAnimation.EYEBROWS_LOWER
237
		else:
238
			print "invalid button '%s'" % (button)
239
			return
240
		
241
		self.robot_controller.set_head_animation(ra, False)
236 242

  
237 243
def main():
238
    scope = "/home/wardrobe/flobi"
239
    if (len(sys.argv) == 2):
244
	if (len(sys.argv) != 3):
245
		print("usage:   hlrc_test_gui.py <middleware> <scope>\n\n")
246
		print("example: hlrc_test_gui.py ROS /flobi\n\n")
247
		sys.exit(errno.EINVAL)
248
		
240 249
	scope = sys.argv[1]
250
	mw    = sys.argv[2]
241 251

  
242
    app = QtGui.QApplication(sys.argv)
243
    ex = Example(scope)
244
    sys.exit(app.exec_())
252
	app = QtGui.QApplication(sys.argv)
253
	ex = HLRCExample(mw, scope)
254
	sys.exit(app.exec_())
245 255

  
246 256

  
247 257
if __name__ == '__main__':
248
    main()
258
	main()
client/python/hlrc_set_emotion.py
1
#!/usr/bin/python
2
#PYTHONPATH="/opt/ros/groovy/lib/python2.7/dist-packages:/vol/csra/releases/nightly/lib/python2.7/:/vol/csra/releases/nightly/lib/python2.7/site-packages/
3
import sys
4
import logging
5
import errno
6

  
7
try:
8
    import rsb
9
    import rsb.converter
10
    import rst
11
    import rstsandbox
12
    from rst.robot.EmotionState_pb2 import EmotionState
13
except ImportError as exception:
14
    sys.stderr.write("ImportError: {}\n> HINT: try to export PYTHONPATH=$PYTHONPATH:$YOUR_PREFIX/lib/python2.7/site-packages/\n\n".format(exception))
15
    sys.exit(errno.ENOPKG)
16

  
17
class hlrc_emotion():
18
    def __init__(self, _base_scope):
19
        #print "> registering rst converter"
20
        converter = rsb.converter.ProtocolBufferConverter(messageClass = EmotionState)
21
        rsb.converter.registerGlobalConverter(converter)
22
	self.set_scope( _base_scope);
23

  
24
    def set_scope(self, scope):
25
        self.base_scope = str(scope) #NOTE: str() is important here, scope is a qstring (?) and gets deleted during call
26
        print "> setting scope to '%s'" % self.base_scope
27
        try:
28
            self.server = rsb.createRemoteServer(self.base_scope + '/set')
29
        except ValueError:
30
            print "> invalid scope given. server deactivated"
31
            self.server.deactivate()
32

  
33
    def set_emotion(self, emotion_id, duration_each, blocking):
34
        if (self.server is None):
35
            print("> invalid server")
36
            return
37

  
38
        #create emotion & fill it with values:
39
        em = EmotionState()
40

  
41
        #select ani
42
        em.value    = emotion_id
43
        em.duration = duration_each
44

  
45
        with rsb.createRemoteServer(self.base_scope + '/set') as server:
46
            if (blocking):
47
                #blocking:
48
                print "> calling the emotion rpc (blocking until we finished talking)..."
49
                print '> server reply: "%s"' % server.currentEmotion(em)
50
            else:
51
               print "> calling the animation rpc (NON-BLOCKING)..."
52
               future = server.currentEmotion.async(em)
53
               #we can block here for a incoming result with a timeout in s
54
               #print '> server reply: "%s"' % future.get(timeout = 10);
55

  
56
        print "> done"
57
    
58
def main():
59
    if (len(sys.argv) != 4):
60
        print "> usage: %s <base scope> <emotion id> <duration>\n>     example: %s /flobi1 1 1000" % (sys.argv[0] , sys.argv[0])
61
        sys.exit(0)
62

  
63
    # Pacify logger.
64
    #logging.basicConfig()
65
    em_id = int(sys.argv[2])
66
    dur    = int(sys.argv[3])
67
    base   = sys.argv[1]
68

  
69
    hlrc_emotion(base).set_emotion(em_id, dur, 1)
70

  
71
if __name__ == '__main__':
72
    main()
73

  
74

  
client/python/setup.py
99 99
    # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
100 100
    data_files=[], #('my_data', ['data/data_file'])],
101 101

  
102
    #scripts=['bin/hlrc_test_gui.py'],
103
    
104

  
102 105
    # To provide executable scripts, use entry points in preference to the
103 106
    # "scripts" keyword. Entry points provide cross-platform support and allow
104 107
    # pip to create the appropriate form of executable for the target platform.
105 108
    entry_points={
106 109
        'console_scripts': [
107
            #'sample=sample:main',
110
            'hlrc_test_gui=hlrc_client.hlrc_test_gui:main',
108 111
        ],
109 112
    },
110 113
)
client/python/test.py
1
#!/usr/bin/python
1 2
"""
2 3
This file is part of hlrc
3 4

  
server/CMakeLists.txt
154 154
#    )
155 155

  
156 156
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
157
install(PROGRAMS tools/hlrc_test_gui.py DESTINATION bin)
158
install(FILES tools/hlrc_play_animation.py  DESTINATION lib/python2.7/site-packages)
159
install(FILES tools/hlrc_speak_utterance.py DESTINATION lib/python2.7/site-packages)
160 157

  
161
#workaround to keep functionallity of old py scripts:
162
install(PROGRAMS tools/hlrc_speak_utterance.py DESTINATION bin)
163
install(PROGRAMS tools/hlrc_play_animation.py DESTINATION bin)
164
install(PROGRAMS tools/hlrc_set_emotion.py DESTINATION bin)
165

  
166
install(FILES tools/textgrid_hlrc.py DESTINATION lib/python2.7/site-packages)
167

  
168
FILE(GLOB example_files_wav   "${CMAKE_CURRENT_SOURCE_DIR}/tools/examples/*.wav")
169
FILE(GLOB example_files_praat "${CMAKE_CURRENT_SOURCE_DIR}/tools/examples/*.praat")
170
LIST(APPEND example_files ${example_files_wav} ${example_files_praat})
171
install(FILES ${example_files} DESTINATION share/hlrc_server/examples)
172 158

  
server/tools/hlrc_test_gui.py
1
#!/usr/bin/python
2
import sys
3
import os.path
4
from PyQt4 import QtGui, QtCore
5
from PyQt4.QtCore import SIGNAL
6
from hlrc_speak_utterance import hlrc_utterance
7
from hlrc_play_animation import hlrc_animation
8
from hlrc_set_emotion import hlrc_emotion
9

  
10
class Example(QtGui.QWidget):
11
    
12
    def __init__(self, _scope):
13
        super(Example, self).__init__()
14
        self.scope = _scope
15
        self.initUI()
16
	scope = self.scope_lineedit.text()
17
        self.hlrc_utterance = hlrc_utterance(scope)
18
        self.hlrc_animation = hlrc_animation(scope)
19
        self.hlrc_emotion   = hlrc_emotion(scope)
20

  
21
    def scopeChanged(self):
22
	self.scope = self.scope_lineedit.text()
23
        print "> changed scope to %s" % self.scope
24
        self.hlrc_utterance.set_scope(self.scope)
25
        self.hlrc_animation.set_scope(self.scope)
26
        self.hlrc_emotion.set_scope(self.scope)
27

  
28
    def initUtteranceUI(self):
29
        groupBox = QtGui.QGroupBox("utterances")
30

  
31
        hello = QtGui.QPushButton("hello...")
32
        hello.clicked.connect(self.utterance_button_clicked)
33

  
34
        count = QtGui.QPushButton("12345...")
35
        count.clicked.connect(self.utterance_button_clicked)
36

  
37

  
38
        vbox = QtGui.QVBoxLayout()
39
        vbox.addWidget(hello)
40
        vbox.addWidget(count)
41
        vbox.addStretch(1)
42
        groupBox.setLayout(vbox)
43

  
44
        return groupBox
45

  
46
    def initSpinbox(self, _min, _max, _init, double):
47
        if (double): 
48
            s = QtGui.QDoubleSpinBox()
49
        else:
50
            s = QtGui.QSpinBox()
51

  
52
        s.setMinimum(_min)
53
        s.setMaximum(_max)
54
        s.setValue(_init)
55
        return s
56

  
57
    def initEmotionUI(self):
58
        groupBox = QtGui.QGroupBox("emotion")
59
        neutral   = QtGui.QPushButton("neutral")
60
        neutral.clicked.connect(self.emotion_button_clicked)
61
        surprised = QtGui.QPushButton("surprise")
62
        surprised.clicked.connect(self.emotion_button_clicked)
63
        angry     = QtGui.QPushButton("angry")
64
        angry.clicked.connect(self.emotion_button_clicked)
65
        happy     = QtGui.QPushButton("happy")
66
        happy.clicked.connect(self.emotion_button_clicked)
67
        sad     = QtGui.QPushButton("sad")
68
        sad.clicked.connect(self.emotion_button_clicked)
69
        fear      = QtGui.QPushButton("fear")
70
        fear.clicked.connect(self.emotion_button_clicked)
71

  
72
        self.duration_spinbox = self.initSpinbox(100, 10000, 1000, 0)
73

  
74
        vbox = QtGui.QVBoxLayout()
75
        vbox.addWidget(self.duration_spinbox)
76
        vbox.addWidget(neutral)
77
        vbox.addWidget(surprised)
78
        vbox.addWidget(angry)
79
        vbox.addWidget(happy)
80
        vbox.addWidget(sad)
81
        vbox.addWidget(fear)
82
        vbox.addStretch(1)
83
        groupBox.setLayout(vbox)
84
        return groupBox
85

  
86

  
87
    def initAnimationButton(self, name):
88
        b = QtGui.QPushButton(name)
89
        b.clicked.connect(self.animation_button_clicked)
90
        return b
91

  
92
    def initAnimUI(self):
93
        groupBox = QtGui.QGroupBox("animations")
94
  
95
        #options
96
        options = QtGui.QHBoxLayout()
97
        vbox_r = QtGui.QVBoxLayout()
98
        vbox_r.addWidget(QtGui.QLabel("repetitions"))
99
        self.repetitions_spinbox = self.initSpinbox(1,10,1,0)
100
        vbox_r.addWidget(self.repetitions_spinbox)
101

  
102
        vbox_d = QtGui.QVBoxLayout()
103
        vbox_d.addWidget(QtGui.QLabel("duration/ms (each)"))
104
        self.duration_each_spinbox = self.initSpinbox(100,10000,1000,0)
105
        vbox_d.addWidget(self.duration_each_spinbox)
106

  
107
        vbox_s = QtGui.QVBoxLayout()
108
        vbox_s.addWidget(QtGui.QLabel("scale"))
109
        self.scale_spinbox = self.initSpinbox(0.1, 5.0, 1.0, 1)
110
        vbox_s.addWidget(self.scale_spinbox)
111

  
112

  
113
        options.addLayout(vbox_r)
114
        options.addLayout(vbox_d)        
115
        options.addLayout(vbox_s)
116

  
117
        #buttons
118
        vbox = QtGui.QVBoxLayout()
119
        vbox.addLayout(options)
120
        vbox.addWidget(self.initAnimationButton("head shake"))
121
        vbox.addWidget(self.initAnimationButton("head nod"))
122
        vbox.addWidget(self.initAnimationButton("eyeblink left"))
123
        vbox.addWidget(self.initAnimationButton("eyeblink right"))
124
        vbox.addWidget(self.initAnimationButton("eyeblink both"))
125
	vbox.addWidget(self.initAnimationButton("eyebrows raise"))
126
	vbox.addWidget(self.initAnimationButton("eyebrows lower"))
127
        vbox.addStretch(1)
128
        groupBox.setLayout(vbox)
129

  
130
        return groupBox
131

  
132
    def initUI(self):        
133

  
134
        self.scope_lineedit = QtGui.QLineEdit(self.scope);
135
        self.connect(self.scope_lineedit, SIGNAL("editingFinished()"),self.scopeChanged)
136

  
137
	vbox = QtGui.QVBoxLayout();
138
	
139
	hboxl = QtGui.QHBoxLayout();
140
	hboxl.addWidget(QtGui.QLabel("base scope: "));
141
	hboxl.addWidget(self.scope_lineedit);
142
	vbox.addLayout(hboxl);
143

  
144
        hbox = QtGui.QHBoxLayout()
145
	vbox.addLayout(hbox);
146
	
147
        #emotion
148
        hbox.addWidget(self.initEmotionUI())
149

  
150
        #utterance:
151
        hbox.addWidget(self.initUtteranceUI())
152

  
153
        #animations:
154
        hbox.addWidget(self.initAnimUI())
155

  
156
        self.setLayout(vbox)
157
        #sld.valueChanged.connect(lcd.display)
158
        
159
        self.setGeometry(400, 100, 250, 150)
160
        self.setWindowTitle("HLC Server test GUI")
161
        self.show()
162

  
163
    def utterance_button_clicked(self):
164
        button = self.sender().text()
165
        
166
        fn_praat = "b.praat"
167
        fn_wav   = "b.wav"
168

  
169
        if (button == "12345..."):
170
            print("123")
171
            fn_praat = "1234.praat"
172
            fn_wav   = "1234.wav"
173

  
174
        elif (button == "hello..."):
175
            print "hello"
176
            fn_praat = "hello_my_name.praat"
177
            fn_wav   = "hello_my_name.wav"
178

  
179
        else:
180
            print "invalid button '%s'" % (button)
181
            return
182

  
183
        #try to find the wav/praat files:
184
        path = os.path.dirname(os.path.realpath(__file__)) + "/../share/hlrc_server/examples/"
185
        if (not os.path.isfile(path + fn_wav)):
186
            #try fallback solution for running from current folder:
187
            path = "examples/"
188

  
189
        self.hlrc_utterance.trigger_utterance(path + fn_praat, path + fn_wav, 0)
190

  
191
    def emotion_button_clicked(self):
192
        button = self.sender().text()
193
        duration = self.duration_spinbox.value()
194

  
195

  
196
        if (button == "angry"):
197
            self.hlrc_emotion.set_emotion(3, duration, 0)
198
        elif (button == "neutral"):
199
            self.hlrc_emotion.set_emotion(0, duration, 0)
200
        elif (button == "happy"):
201
            self.hlrc_emotion.set_emotion(1, duration, 0)
202
        elif (button == "sad"):
203
            self.hlrc_emotion.set_emotion(2, duration, 0)
204
        elif (button == "surprise"):
205
            self.hlrc_emotion.set_emotion(4, duration, 0)
206
        elif (button == "fear"):
207
            self.hlrc_emotion.set_emotion(5, duration, 0)
208
        else:
209
            print "invalid emotion id '%s'" % (button)
210
            return
211

  
212
    def animation_button_clicked(self):
213
        button = self.sender().text()
214

  
215
        repetitions = self.repetitions_spinbox.value()
216
        duration_each = self.duration_each_spinbox.value()
217
        scale = self.scale_spinbox.value()
218

  
219
        if (button == "head nod"):
220
            self.hlrc_animation.trigger_animation(1, repetitions, duration_each, scale, 0)
221
        elif (button == "head shake"):
222
            self.hlrc_animation.trigger_animation(2, repetitions, duration_each, scale, 0)
223
        elif (button == "eyeblink left"):
224
            self.hlrc_animation.trigger_animation(3, repetitions, duration_each, scale, 0)
225
        elif (button == "eyeblink right"):
226
            self.hlrc_animation.trigger_animation(4, repetitions, duration_each, scale, 0)
227
        elif (button == "eyeblink both"):
228
            self.hlrc_animation.trigger_animation(5, repetitions, duration_each, scale, 0)
229
        elif (button == "eyebrows raise"):
230
            self.hlrc_animation.trigger_animation(6, repetitions, duration_each, scale, 0)
231
        elif (button == "eyebrows lower"):
232
            self.hlrc_animation.trigger_animation(7, repetitions, duration_each, scale, 0)
233
        else:
234
            print "invalid button '%s'" % (button)
235
            return
236

  
237
def main():
238
    scope = "/home/wardrobe/flobi"
239
    if (len(sys.argv) == 2):
240
	scope = sys.argv[1]
241

  
242
    app = QtGui.QApplication(sys.argv)
243
    ex = Example(scope)
244
    sys.exit(app.exec_())
245

  
246

  
247
if __name__ == '__main__':
248
    main()

Also available in: Unified diff