Revision 70c54617

View differences:

client/python/hlrc_client/Middleware.py
35 35
class Middleware:
36 36
    #######################################################################
37 37
    def __init__(self, scope, loglevel=logging.WARNING):
38
	"""initialise
39
	:param scope: base scope we want to listen on
40
	"""
41
	self.base_scope = scope
42

  
43
	self.logger = logging.getLogger(__name__)
44

  
45
	# create nice and actually usable formatter and add it to the handler
46
	self.config_logger(loglevel)
47

  
48
	#initialise defaults
49
	self.default_emotion = RobotEmotion()
50
	self.current_emotion = RobotEmotion()
51
	self.gaze_target = RobotGaze()
52
	self.mouth_target = RobotMouth()
53
	self.robot_animation = RobotAnimation()
54

  
55
	def __del__(self):
56
	    """destructor
57
	    """
58
	    self.logger.debug("destructor of Middleware called")
59

  
60
	    def config_logger(self, level):
61
		formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
62
		ch = logging.StreamHandler()
63
		#ch.setLevel(level)
64
		ch.setFormatter(formatter)
65
		self.logger.setLevel(level)
66
		self.logger.addHandler(ch)
67

  
68
		#######################################################################
69
		#abstract/virtual functions
70
		def die_virtual(self, funcname):
71
		    raise NotImplementedError(funcname + "() is virtual, must be overwritten")
72

  
73
		def init_middleware(self):
74
		    self.die_virtual(sys._getframe().f_code.co_name)
75

  
76
		    def publish_default_emotion(self, emotion, blocking):
77
			self.die_virtual(sys._getframe().f_code.co_name)
78

  
79
			def publish_current_emotion(self, emotion, blocking):
80
			    self.die_virtual(sys._getframe().f_code.co_name)
81

  
82
			    def publish_gaze_target(self, gaze, blocking):
83
				self.die_virtual(sys._getframe().f_code.co_name)
84

  
85
				def publish_mouth_target(self, mouth, blocking):
86
				    self.die_virtual(sys._getframe().f_code.co_name)
87

  
88
				    def publish_head_animation(self, animation, blocking):
89
					self.die_virtual(sys._getframe().f_code.co_name)
90

  
91
					def publish_speech(self, text, blocking):
92
					    self.die_virtual(sys._getframe().f_code.co_name)
93

  
94
					    #######################################################################
95
					    #finally some implemented functions
96
					    def set_default_emotion(self, emotion, blocking):
97
						"""set the default emotion
98
						:param emotion: RobotEmotion to set
99
						:param blocking: True if this call should block until execution finished on robot
100
						"""
101
						self.default_emotion = emotion
102
						self.publish_default_emotion(emotion, blocking)
103

  
104
						def set_current_emotion(self, emotion, blocking):
105
						    """set a temporary emotion (duration: see emotion.time_ms)
106
						    :param emotion: RobotEmotion to set temporarily
107
						    :param blocking: True if this call should block until execution finished on robot
108
						    """
109
						    self.current_emotion = emotion
110
						    self.publish_current_emotion(emotion, blocking)
111

  
112
						    def set_head_animation(self, animation, blocking):
113
							"""trigger a head animation
114
							:param animation: RobotAnimation to set
115
							:param blocking: True if this call should block until execution finished on robot
116
							"""
117
							self.animation = animation
118
							self.publish_head_animation(animation, blocking)
119

  
120
							def set_mouth_target(self, mouth, blocking):
121
							    """set a mouth target
122
							    :param mouth: RobotMouth to set
123
							    :param blocking: True if this call should block until execution finished on robot
124
							    """
125
							    self.mouth_target = mouth
126
							    self.publish_mouth_target(mouth, blocking)
127

  
128
							    def set_speak(self, text, blocking):
129
								"""trigger a tts speech output
130
								:param text: text to synthesize and speak
131
								:param blocking: True if this call should block until execution finished on robot
132
								"""
133
								self.publish_speech(text, blocking)
134

  
135
								def set_gaze_target(self, gaze, blocking):
136
								    """set a new gaze
137
								    :param gaze: RobotGaze to set
138
								    :param blocking: True if this call should block until execution finished on robot
139
								    """
140
								    self.gaze_target = gaze
141
								    self.publish_gaze_target(gaze, blocking)
142

  
143
								    #######################################################################
144
								    #some get methods
145
								    #def get_current_emotion(self):
146
									#	return self.current_emotion
147
									#
148
									#def get_default_emotion(self):
149
									    #	return self.default_emotion
150
									    #
38
        """initialise
39
        :param scope: base scope we want to listen on
40
        """
41
        self.base_scope = scope
42

  
43
        self.logger = logging.getLogger(__name__)
44

  
45
        # create nice and actually usable formatter and add it to the handler
46
        self.config_logger(loglevel)
47

  
48
        #initialise defaults
49
        self.default_emotion = RobotEmotion()
50
        self.current_emotion = RobotEmotion()
51
        self.gaze_target = RobotGaze()
52
        self.mouth_target = RobotMouth()
53
        self.robot_animation = RobotAnimation()
54

  
55
    def __del__(self):
56
        """destructor
57
        """
58
        self.logger.debug("destructor of Middleware called")
59

  
60
    def config_logger(self, level):
61
        formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
62
        ch = logging.StreamHandler()
63
        #ch.setLevel(level)
64
        ch.setFormatter(formatter)
65
        self.logger.setLevel(level)
66
        self.logger.addHandler(ch)
67

  
68
    #######################################################################
69
    #abstract/virtual functions
70
    def die_virtual(self, funcname):
71
        raise NotImplementedError(funcname + "() is virtual, must be overwritten")
72

  
73
    def init_middleware(self):
74
        self.die_virtual(sys._getframe().f_code.co_name)
75

  
76
    def publish_default_emotion(self, emotion, blocking):
77
        self.die_virtual(sys._getframe().f_code.co_name)
78

  
79
    def publish_current_emotion(self, emotion, blocking):
80
        self.die_virtual(sys._getframe().f_code.co_name)
81

  
82
    def publish_gaze_target(self, gaze, blocking):
83
        self.die_virtual(sys._getframe().f_code.co_name)
84

  
85
    def publish_mouth_target(self, mouth, blocking):
86
        self.die_virtual(sys._getframe().f_code.co_name)
87

  
88
    def publish_head_animation(self, animation, blocking):
89
        self.die_virtual(sys._getframe().f_code.co_name)
90

  
91
    def publish_speech(self, text, blocking):
92
        self.die_virtual(sys._getframe().f_code.co_name)
93

  
94
    #######################################################################
95
    #finally some implemented functions
96
    def set_default_emotion(self, emotion, blocking):
97
        """set the default emotion
98
        :param emotion: RobotEmotion to set
99
        :param blocking: True if this call should block until execution finished on robot
100
        """
101
        self.default_emotion = emotion
102
        self.publish_default_emotion(emotion, blocking)
103

  
104
    def set_current_emotion(self, emotion, blocking):
105
        """set a temporary emotion (duration: see emotion.time_ms)
106
        :param emotion: RobotEmotion to set temporarily
107
        :param blocking: True if this call should block until execution finished on robot
108
        """
109
        self.current_emotion = emotion
110
        self.publish_current_emotion(emotion, blocking)
111

  
112
    def set_head_animation(self, animation, blocking):
113
        """trigger a head animation
114
        :param animation: RobotAnimation to set
115
        :param blocking: True if this call should block until execution finished on robot
116
        """
117
        self.animation = animation
118
        self.publish_head_animation(animation, blocking)
119

  
120
    def set_mouth_target(self, mouth, blocking):
121
        """set a mouth target
122
        :param mouth: RobotMouth to set
123
        :param blocking: True if this call should block until execution finished on robot
124
        """
125
        self.mouth_target = mouth
126
        self.publish_mouth_target(mouth, blocking)
127

  
128
    def set_speak(self, text, blocking):
129
        """trigger a tts speech output
130
        :param text: text to synthesize and speak
131
        :param blocking: True if this call should block until execution finished on robot
132
        """
133
        self.publish_speech(text, blocking)
134

  
135
    def set_gaze_target(self, gaze, blocking):
136
        """set a new gaze
137
        :param gaze: RobotGaze to set
138
        :param blocking: True if this call should block until execution finished on robot
139
        """
140
        self.gaze_target = gaze
141
        self.publish_gaze_target(gaze, blocking)
142

  
143
    #######################################################################
144
    #some get methods
145
    #def get_current_emotion(self):
146
    #       return self.current_emotion
147
    #
148
    #def get_default_emotion(self):
149
    #       return self.default_emotion
150
    #
client/python/hlrc_client/MiddlewareROS.py
28 28
from Middleware import *
29 29
import errno
30 30

  
31
import roslib; 
32
import rospy 
31
import roslib;
32
import rospy
33 33
import actionlib
34 34
from hlrc_server.msg import *
35 35

  
......
39 39

  
40 40
    #######################################################################
41 41
    def __init__(self, scope, loglevel=logging.WARNING):
42
	"""initialise
43
	:param scope: base scope we want to listen on
44
	"""
45
	#init base settings
46
	Middleware.__init__(self,scope,loglevel)
47
	#call mw init
48
	self.init_middleware()
49

  
50
	def __del__(self):
51
	    """destructor
52
	    """
53
	    self.logger.debug("destructor of MiddlewareROS called")
54

  
55
	    #######################################################################
56
	    def init_middleware(self):
57
		"""initialise middleware
58
		"""
59
		self.logger.info("initialising ROS middleware connection on scope %s" % (self.base_scope))
60
		
61
		rospy.init_node('hlrc_client', anonymous=True)
62
		
63
		self.logger.info("creating action clients")
64
		
65
		self.logger.debug("creating speech action client")
66
		self.speech_client = actionlib.SimpleActionClient(self.base_scope + "/set/speech", speechAction)
67
		self.speech_client.wait_for_server()
68
		
69
		self.logger.debug("creating default emotion action client")
70
		self.default_emotion_client = actionlib.SimpleActionClient(self.base_scope + "/set/defaultEmotion", emotionstateAction)
71
		self.default_emotion_client.wait_for_server()
72
		
73
		self.logger.debug("creating current emotion action client")
74
		self.current_emotion_client = actionlib.SimpleActionClient(self.base_scope + "/set/currentEmotion", emotionstateAction)
75
		self.current_emotion_client.wait_for_server()
76
		
77
		self.logger.debug("creating animation action client")
78
		self.animation_client = actionlib.SimpleActionClient(self.base_scope + "/set/animation", animationAction)
79
		self.animation_client.wait_for_server()
80
		
81
		self.logger.debug("creating gazetarget action client")
82
		self.gazetarget_client = actionlib.SimpleActionClient(self.base_scope + "/set/gaze", gazetargetAction)
83
		self.gazetarget_client.wait_for_server()
84
		
85
		self.logger.debug("creating mouthtarget action client")
86
		self.mouthtarget_client = actionlib.SimpleActionClient(self.base_scope + "/set/mouth", mouthtargetAction)
87
		self.mouthtarget_client.wait_for_server()
88
		
89
		self.logger.info("MiddlewareROS initialised")
90
		
91

  
92
		#######################################################################
93
		def publish_emotion(self, em_type, emotion, blocking):
94
		    """publish an emotion via mw
95
		    :param em_type: type of emotion (RobotEmotion::TYPE_DEFAULT or RobotEmotion::TYPE_CURRENT)
96
		    :param emotion: emotion to set
97
		    :param blocking: True if this call should block until execution finished on robot
98
		    """
99
		    self.logger.debug("calling the emotion rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
100

  
101
		    #create a goal to send to the action server.
102
		    goal = emotionstateGoal()
103
		    goal.value    = self.convert_emotiontype_to_rosval(emotion.value)
104
		    goal.duration =  int(emotion.time_ms)
105

  
106
		    #which client do we use?
107
		    if (em_type == RobotEmotion.TYPE_DEFAULT):
108
			client = self.default_emotion_client
109
			else:
110
			    client = self.current_emotion_client
111

  
112
			    #send the goal to the server
113
			    client.send_goal(goal)
114

  
115
			    #wait for the server to finish
116
			    if (blocking):
117
				timed_out = client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
118
				if (timed_out):
119
				    self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
120

  
121
				    def publish_default_emotion(self, emotion, blocking):
122
					self.publish_emotion(RobotEmotion.TYPE_DEFAULT, emotion, blocking)
123

  
124
					def publish_current_emotion(self, emotion, blocking):
125
					    self.publish_emotion(RobotEmotion.TYPE_CURRENT, emotion, blocking)
126

  
127
					    def publish_head_animation(self, animation, blocking):
128
						"""publish an head animation via mw
129
						:param animation: animation to set
130
						:param blocking: True if this call should block until execution finished on robot
131
						"""
132
						self.logger.debug("calling the animation rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
133

  
134
						#create a goal to send to the action server.
135
						goal = animationGoal()
136
						goal.target = self.convert_animationtype_to_rosval(animation.value)
137
						goal.repetitions = animation.repetitions
138
						goal.duration_each =  int(animation.time_ms)
139
						goal.scale = animation.scale
140

  
141
						#send the goal to the server
142
						self.animation_client.send_goal(goal)
143

  
144
						#wait for the server to finish
145
						if (blocking):
146
						    timed_out = self.animation_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
147
						    if (timed_out):
148
							self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
149

  
150
							self.logger.debug("animation rpc done")
151

  
152
							def publish_gaze_target(self, gaze, blocking):
153
							    """publish a gaze target via mw
154
							    :param gaze: gaze to set
155
							    :param blocking: True if this call should block until execution finished on robot
156
							    """
157
							    self.logger.debug("calling the gaze rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
158

  
159
							    #create a goal to send to the action server.
160
							    goal = gazetargetGoal()
161
							    goal.pan  = gaze.pan
162
							    goal.tilt = gaze.tilt
163
							    goal.roll = gaze.roll
164
							    goal.vergence = gaze.vergence
165
							    goal.pan_offset  = gaze.pan_offset
166
							    goal.tilt_offset = gaze.tilt_offset
167

  
168
							    #type
169
							    if (gaze.gaze_type == RobotGaze.GAZETARGET_ABSOLUTE):
170
								goal.gaze_type = gazetargetGoal.GAZETARGET_ABSOLUTE
171
								else:
172
								    goal.gaze_type = gazetargetGoal.GAZETARGET_RELATIVE
173

  
174
								    goal.timestamp = rospy.Time.from_sec(gaze.timestamp)
175

  
176
								    #send the goal to the server
177
								    self.gazetarget_client.send_goal(goal)
178

  
179
								    #wait for the server to finish
180
								    if (blocking):
181
									timed_out = self.gazetarget_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
182
									if (timed_out):
183
									    self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
184

  
185

  
186
									    self.logger.debug("gaze rpc done")
187

  
188
									    def publish_mouth_target(self, mouth, blocking):
189
										"""publish a mouth target via mw
190
										:param mouth: mouth value to set
191
										:param blocking: True if this call should block until execution finished on robot
192
										"""
193
										self.logger.debug("calling the mouth rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
194

  
195
										#create a goal to send to the action server.
196
										goal = mouthtargetGoal()
197
										goal.opening_left  = mouth.opening_left
198
										goal.opening_center = mouth.opening_center
199
										goal.opening_right = mouth.opening_right
200
										goal.position_left = mouth.position_left
201
										goal.position_center  = mouth.position_center
202
										goal.position_right = mouth.position_right
203

  
204
										#send the goal to the server
205
										self.mouthtarget_client.send_goal(goal)
206

  
207
										#wait for the server to finish
208
										if (blocking):
209
										    timed_out = self.mouthtarget_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
210
										    if (timed_out):
211
											self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
212

  
213
											self.logger.debug("mouth rpc done")
214

  
215
											def publish_speech(self, text_, blocking):
216
											    """publish a tts request via mw
217
											    :param text_: text to synthesize and speak
218
											    :param blocking: True if this call should block until execution finished on robot
219
											    """
220
											    self.logger.debug("calling the speech rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
221

  
222
											    #create a goal to send to the action server.
223
											    goal = speechGoal(text=text_)
224

  
225
											    #send the goal to the server
226
											    self.speech_client.send_goal(goal)
227

  
228
											    #wait for the server to finish
229
											    if (blocking):
230
												timed_out = self.speech_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
231
												if (timed_out):
232
												    self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
233

  
234
												    self.logger.debug("speech rpc done")
235

  
236
												    #######################################################################
237
												    # some helpers
238
												    def convert_animationtype_to_rosval(self, value):
239
													"""convert RobotAnimation.value to ROS animation value
240
													:param value: RobotAnimation.* id to convert to rsb id
241
													"""
242
													#NOTE: this convertion is important as the actual integer values of
243
													#      thy python api and the protobuf might be different
244
													if (value == RobotAnimation.IDLE):
245
													    return animationGoal.IDLE
246
													elif (value == RobotAnimation.HEAD_NOD):
247
													    return animationGoal.HEAD_NOD
248
													elif (value == RobotAnimation.HEAD_SHAKE):
249
													    return animationGoal.HEAD_SHAKE
250
													elif (value == RobotAnimation.EYEBLINK_L):
251
													    return animationGoal.EYEBLINK_L
252
													elif (value == RobotAnimation.EYEBLINK_R):
253
													    return  animationGoal.EYEBLINK_R
254
													elif (value == RobotAnimation.EYEBLINK_BOTH):
255
													    return  animationGoal.EYEBLINK_BOTH
256
													elif (value == RobotAnimation.EYEBROWS_RAISE):
257
													    return  animationGoal.EYEBROWS_RAISE
258
													elif (value == RobotAnimation.EYEBROWS_LOWER):
259
													    return  animationGoal.EYEBROWS_LOWER
260
													else:
261
													    self.logger.error("invalid animation type %d\n" % (value))
262
													    return  animationGoal.NEUTRAL
263

  
264
													def convert_emotiontype_to_rosval(self, value):
265
													    """convert RobotEmotion.value to ROS animation value
266
													    :param value: RobotEmotion.* id to convert to ros id
267
													    """
268
													    #NOTE: this convertion is important as the actual integer values of
269
													    #      thy python api and the protobuf might be different
270

  
271
													    if (value == RobotEmotion.NEUTRAL):
272
														return emotionstateGoal.NEUTRAL
273
													    elif (value == RobotEmotion.HAPPY):
274
														return emotionstateGoal.HAPPY
275
													    elif (value == RobotEmotion.SAD):
276
														return emotionstateGoal.SAD
277
													    elif (value == RobotEmotion.ANGRY):
278
														return emotionstateGoal.ANGRY
279
													    elif (value == RobotEmotion.SURPRISED):
280
														return  emotionstateGoal.SURPRISED
281
													    elif (value == RobotEmotion.FEAR):
282
														return emotionstateGoal.FEAR
283
													    else:
284
														self.logger.error("invalid emotion type %d\n" % (value))
285
														return  emotionstateGoal.NEUTRAL
42
        """initialise
43
        :param scope: base scope we want to listen on
44
        """
45
        #init base settings
46
        Middleware.__init__(self,scope,loglevel)
47
        #call mw init
48
        self.init_middleware()
49

  
50
    def __del__(self):
51
        """destructor
52
        """
53
        self.logger.debug("destructor of MiddlewareROS called")
54

  
55
    #######################################################################
56
    def init_middleware(self):
57
        """initialise middleware
58
        """
59
        self.logger.info("initialising ROS middleware connection on scope %s" % (self.base_scope))
60

  
61
        rospy.init_node('hlrc_client', anonymous=True)
62

  
63
        self.logger.info("creating action clients")
64

  
65
        self.logger.debug("creating speech action client")
66
        self.speech_client = actionlib.SimpleActionClient(self.base_scope + "/set/speech", speechAction)
67
        self.speech_client.wait_for_server()
68

  
69
        self.logger.debug("creating default emotion action client")
70
        self.default_emotion_client = actionlib.SimpleActionClient(self.base_scope + "/set/defaultEmotion", emotionstateAction)
71
        self.default_emotion_client.wait_for_server()
72

  
73
        self.logger.debug("creating current emotion action client")
74
        self.current_emotion_client = actionlib.SimpleActionClient(self.base_scope + "/set/currentEmotion", emotionstateAction)
75
        self.current_emotion_client.wait_for_server()
76

  
77
        self.logger.debug("creating animation action client")
78
        self.animation_client = actionlib.SimpleActionClient(self.base_scope + "/set/animation", animationAction)
79
        self.animation_client.wait_for_server()
80

  
81
        self.logger.debug("creating gazetarget action client")
82
        self.gazetarget_client = actionlib.SimpleActionClient(self.base_scope + "/set/gaze", gazetargetAction)
83
        self.gazetarget_client.wait_for_server()
84

  
85
        self.logger.debug("creating mouthtarget action client")
86
        self.mouthtarget_client = actionlib.SimpleActionClient(self.base_scope + "/set/mouth", mouthtargetAction)
87
        self.mouthtarget_client.wait_for_server()
88

  
89
        self.logger.info("MiddlewareROS initialised")
90

  
91

  
92
    #######################################################################
93
    def publish_emotion(self, em_type, emotion, blocking):
94
        """publish an emotion via mw
95
        :param em_type: type of emotion (RobotEmotion::TYPE_DEFAULT or RobotEmotion::TYPE_CURRENT)
96
        :param emotion: emotion to set
97
        :param blocking: True if this call should block until execution finished on robot
98
        """
99
        self.logger.debug("calling the emotion rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
100

  
101
        #create a goal to send to the action server.
102
        goal = emotionstateGoal()
103
        goal.value    = self.convert_emotiontype_to_rosval(emotion.value)
104
        goal.duration =  int(emotion.time_ms)
105

  
106
        #which client do we use?
107
        if (em_type == RobotEmotion.TYPE_DEFAULT):
108
            client = self.default_emotion_client
109
        else:
110
            client = self.current_emotion_client
111

  
112
        #send the goal to the server
113
        client.send_goal(goal)
114

  
115
        #wait for the server to finish
116
        if (blocking):
117
            timed_out = client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
118
            if (timed_out):
119
                self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
120

  
121
    def publish_default_emotion(self, emotion, blocking):
122
        self.publish_emotion(RobotEmotion.TYPE_DEFAULT, emotion, blocking)
123

  
124
    def publish_current_emotion(self, emotion, blocking):
125
        self.publish_emotion(RobotEmotion.TYPE_CURRENT, emotion, blocking)
126

  
127
    def publish_head_animation(self, animation, blocking):
128
        """publish an head animation via mw
129
        :param animation: animation to set
130
        :param blocking: True if this call should block until execution finished on robot
131
        """
132
        self.logger.debug("calling the animation rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
133

  
134
        #create a goal to send to the action server.
135
        goal = animationGoal()
136
        goal.target = self.convert_animationtype_to_rosval(animation.value)
137
        goal.repetitions = animation.repetitions
138
        goal.duration_each =  int(animation.time_ms)
139
        goal.scale = animation.scale
140

  
141
        #send the goal to the server
142
        self.animation_client.send_goal(goal)
143

  
144
        #wait for the server to finish
145
        if (blocking):
146
            timed_out = self.animation_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
147
            if (timed_out):
148
                self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
149

  
150
        self.logger.debug("animation rpc done")
151

  
152
    def publish_gaze_target(self, gaze, blocking):
153
        """publish a gaze target via mw
154
        :param gaze: gaze to set
155
        :param blocking: True if this call should block until execution finished on robot
156
        """
157
        self.logger.debug("calling the gaze rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
158

  
159
        #create a goal to send to the action server.
160
        goal = gazetargetGoal()
161
        goal.pan  = gaze.pan
162
        goal.tilt = gaze.tilt
163
        goal.roll = gaze.roll
164
        goal.vergence = gaze.vergence
165
        goal.pan_offset  = gaze.pan_offset
166
        goal.tilt_offset = gaze.tilt_offset
167

  
168
        #type
169
        if (gaze.gaze_type == RobotGaze.GAZETARGET_ABSOLUTE):
170
            goal.gaze_type = gazetargetGoal.GAZETARGET_ABSOLUTE
171
        else:
172
            goal.gaze_type = gazetargetGoal.GAZETARGET_RELATIVE
173

  
174
        goal.timestamp = rospy.Time.from_sec(gaze.timestamp)
175

  
176
        #send the goal to the server
177
        self.gazetarget_client.send_goal(goal)
178

  
179
        #wait for the server to finish
180
        if (blocking):
181
            timed_out = self.gazetarget_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
182
            if (timed_out):
183
                self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
184

  
185

  
186
        self.logger.debug("gaze rpc done")
187

  
188
    def publish_mouth_target(self, mouth, blocking):
189
        """publish a mouth target via mw
190
        :param mouth: mouth value to set
191
        :param blocking: True if this call should block until execution finished on robot
192
        """
193
        self.logger.debug("calling the mouth rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
194

  
195
        #create a goal to send to the action server.
196
        goal = mouthtargetGoal()
197
        goal.opening_left  = mouth.opening_left
198
        goal.opening_center = mouth.opening_center
199
        goal.opening_right = mouth.opening_right
200
        goal.position_left = mouth.position_left
201
        goal.position_center  = mouth.position_center
202
        goal.position_right = mouth.position_right
203

  
204
        #send the goal to the server
205
        self.mouthtarget_client.send_goal(goal)
206

  
207
        #wait for the server to finish
208
        if (blocking):
209
            timed_out = self.mouthtarget_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
210
            if (timed_out):
211
                self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
212

  
213
        self.logger.debug("mouth rpc done")
214

  
215
    def publish_speech(self, text_, blocking):
216
        """publish a tts request via mw
217
        :param text_: text to synthesize and speak
218
        :param blocking: True if this call should block until execution finished on robot
219
        """
220
        self.logger.debug("calling the speech rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
221

  
222
        #create a goal to send to the action server.
223
        goal = speechGoal(text=text_)
224

  
225
        #send the goal to the server
226
        self.speech_client.send_goal(goal)
227

  
228
        #wait for the server to finish
229
        if (blocking):
230
            timed_out = self.speech_client.wait_for_result(rospy.Duration.from_sec(MiddlewareROS.ROS_ACTION_CALL_TIMEOUT))
231
            if (timed_out):
232
                self.logger.error("%s timed out waiting for result" % (sys._getframe().f_code.co_name))
233

  
234
        self.logger.debug("speech rpc done")
235

  
236
    #######################################################################
237
    # some helpers
238
    def convert_animationtype_to_rosval(self, value):
239
        """convert RobotAnimation.value to ROS animation value
240
        :param value: RobotAnimation.* id to convert to rsb id
241
        """
242
        #NOTE: this convertion is important as the actual integer values of
243
        #      thy python api and the protobuf might be different
244
        if (value == RobotAnimation.IDLE):
245
            return animationGoal.IDLE
246
        elif (value == RobotAnimation.HEAD_NOD):
247
            return animationGoal.HEAD_NOD
248
        elif (value == RobotAnimation.HEAD_SHAKE):
249
            return animationGoal.HEAD_SHAKE
250
        elif (value == RobotAnimation.EYEBLINK_L):
251
            return animationGoal.EYEBLINK_L
252
        elif (value == RobotAnimation.EYEBLINK_R):
253
            return  animationGoal.EYEBLINK_R
254
        elif (value == RobotAnimation.EYEBLINK_BOTH):
255
            return  animationGoal.EYEBLINK_BOTH
256
        elif (value == RobotAnimation.EYEBROWS_RAISE):
257
            return  animationGoal.EYEBROWS_RAISE
258
        elif (value == RobotAnimation.EYEBROWS_LOWER):
259
            return  animationGoal.EYEBROWS_LOWER
260
        else:
261
            self.logger.error("invalid animation type %d\n" % (value))
262
            return  animationGoal.NEUTRAL
263

  
264
    def convert_emotiontype_to_rosval(self, value):
265
        """convert RobotEmotion.value to ROS animation value
266
        :param value: RobotEmotion.* id to convert to ros id
267
        """
268
        #NOTE: this convertion is important as the actual integer values of
269
        #      thy python api and the protobuf might be different
270

  
271
        if (value == RobotEmotion.NEUTRAL):
272
            return emotionstateGoal.NEUTRAL
273
        elif (value == RobotEmotion.HAPPY):
274
            return emotionstateGoal.HAPPY
275
        elif (value == RobotEmotion.SAD):
276
            return emotionstateGoal.SAD
277
        elif (value == RobotEmotion.ANGRY):
278
            return emotionstateGoal.ANGRY
279
        elif (value == RobotEmotion.SURPRISED):
280
            return  emotionstateGoal.SURPRISED
281
        elif (value == RobotEmotion.FEAR):
282
            return emotionstateGoal.FEAR
283
        else:
284
            self.logger.error("invalid emotion type %d\n" % (value))
285
            return  emotionstateGoal.NEUTRAL
client/python/hlrc_client/MiddlewareRSB.py
40 40
class MiddlewareRSB(Middleware):
41 41
    #######################################################################
42 42
    def __init__(self, scope, loglevel=logging.WARNING):
43
	"""initialise
44
	:param scope: base scope we want to listen on
45
	"""
46
	#init base settings
47
	Middleware.__init__(self,scope,loglevel)
48
	#call mw init
49
	self.init_middleware()
50

  
51
	def __del__(self):
52
	    """destructor
53
	    """
54
	    self.logger.debug("destructor of MiddlewareROS called")
55

  
56
	    #######################################################################
57
	    def init_middleware(self):
58
		"""initialise middleware
59
		"""
60
		#mute rsb logging:
61
		    logging.getLogger("rsb").setLevel(logging.ERROR)
62

  
63
		    #initialise RSB stuff
64
		    self.logger.info("initialising RSB middleware connection on scope %s, registering rst converters..." % (self.base_scope))
65

  
66
		    self.emotionstate_converter = rsb.converter.ProtocolBufferConverter(messageClass = EmotionState)
67
		    rsb.converter.registerGlobalConverter(self.emotionstate_converter)
68

  
69
		    self.animation_converter = rsb.converter.ProtocolBufferConverter(messageClass = Animation)
70
		    rsb.converter.registerGlobalConverter(self.animation_converter)
71

  
72
		    self.gaze_converter = rsb.converter.ProtocolBufferConverter(messageClass = GazeTarget)
73
		    rsb.converter.registerGlobalConverter(self.gaze_converter)
74

  
75
		    self.mouth_converter = rsb.converter.ProtocolBufferConverter(messageClass = MouthTarget)
76
		    rsb.converter.registerGlobalConverter(self.mouth_converter)
77

  
78
		    try:
79
			self.server = rsb.createRemoteServer(self.base_scope + '/set')
80
			except ValueError:
81
			    self.logger.error("ERROR: invalid scope given. server deactivated")
82
			    self.server.deactivate()
83
			    sys.exit(errno.EINVAL)
84

  
85
			    #######################################################################
86
			    def publish_emotion(self, em_type, emotion, blocking):
87
				"""publish an emotion via mw
88
				:param em_type: type of emotion (RobotEmotion::TYPE_DEFAULT or RobotEmotion::TYPE_CURRENT)
89
				:param emotion: emotion to set
90
				:param blocking: True if this call should block until execution finished on robot
91
				"""
92

  
93
				#create emotion & fill it with values:
94
				    rsb_em = EmotionState()
95

  
96
				    #set value
97
				    rsb_em.value = self.convert_emotiontype_to_rsbval(emotion.value)
98

  
99
				    #set duration
100
				    rsb_em.duration = int(emotion.time_ms)
101

  
102
				    with rsb.createRemoteServer(self.base_scope + '/set') as server:
103
					self.logger.debug("calling the emotion rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
104

  
105
					if (blocking):
106
					    #blocking rpc call:
107
						if (em_type == RobotEmotion.TYPE_DEFAULT):
108
						    result = server.defaultEmotion(rsb_em)
109
						    else:
110
							result = server.currentEmotion(rsb_em)
111

  
112
							self.logger.debug("server reply: '%s'" % result)
113
							else:
114
							    if (em_type == RobotEmotion.TYPE_DEFAULT):
115
								future = server.defaultEmotion.async(rsb_em)
116
								else:
117
								    future = server.currentEmotion.async(rsb_em)
118

  
119
								    #we could block here for a incoming result with a timeout in s
120
								    #print '> server reply: "%s"' % future.get(timeout = 10);
121
								    self.logger.debug("emotion rpc done")
122

  
123
								    def publish_head_animation(self, animation, blocking):
124
									"""publish an head animation via mw
125
									:param animation: animation to set
126
									:param blocking: True if this call should block until execution finished on robot
127
									"""
128

  
129
									self.logger.debug("calling the animation rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
130

  
131
									#create animation & fill it with values:
132
									    rsb_ani = Animation()
133

  
134
									    #select ani
135
									    rsb_ani.target = self.convert_animationtype_to_rsbval(animation.value)
136
									    rsb_ani.repetitions = animation.repetitions
137
									    rsb_ani.duration_each = animation.time_ms
138
									    rsb_ani.scale       = animation.scale
139

  
140
									    if (blocking):
141
										#blocking:
142
										    result = self.server.animation(rsb_ani)
143
										    self.logger.debug("server reply: '%s'" % result)
144
										    else:
145
											future = self.server.animation.async(rsb_ani)
146
											#we can block here for a incoming result with a timeout in s
147
											#print '> server reply: "%s"' % future.get(timeout = 10);
148

  
149
											self.logger.debug("animation rpc done")
150

  
151
											def publish_default_emotion(self, emotion, blocking):
152
											    self.publish_emotion(RobotEmotion.TYPE_DEFAULT, emotion, blocking)
153

  
154
											    def publish_current_emotion(self, emotion, blocking):
155
												self.publish_emotion(RobotEmotion.TYPE_CURRENT, emotion, blocking)
156

  
157
												def publish_gaze_target(self, gaze, blocking):
158
												    """publish a gaze target via mw
159
												    :param gaze: gaze to set
160
												    :param blocking: True if this call should block until execution finished on robot
161
												    """
162
												    self.logger.debug("calling the gaze rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
163

  
164
												    #create gaze target & fill it with values:
165
													rsb_gaze = GazeTarget()
166

  
167
													#fill proto
168
													rsb_gaze.pan  = gaze.pan
169
													rsb_gaze.tilt = gaze.tilt
170
													rsb_gaze.roll = gaze.roll
171
													rsb_gaze.vergence = gaze.vergence
172
													rsb_gaze.pan_offset  = gaze.pan_offset
173
													rsb_gaze.tilt_offset = gaze.tilt_offset
174

  
175
													if (blocking):
176
													    #blocking:
177
														result = self.server.gaze(rsb_gaze)
178
														self.logger.debug("server reply: '%s'" % result)
179
														else:
180
														    future = self.server.gaze.async(rsb_gaze)
181
														    #we can block here for a incoming result with a timeout in s
182
														    #print '> server reply: "%s"' % future.get(timeout = 10);
183

  
184
														    self.logger.debug("gaze rpc done")
185

  
186
														    def publish_mouth_target(self, mouth, blocking):
187
															"""publish a mouth target via mw
188
															:param mouth: mouth value to set
189
															:param blocking: True if this call should block until execution finished on robot
190
															"""
191
															self.logger.debug("calling the mouth rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
192

  
193
															#create mouth state & fill it with values:
194
															    rsb_mouth = MouthTarget()
195

  
196
															    #fill proto
197
															    rsb_mouth.opening_left   = mouth.opening_left
198
															    rsb_mouth.opening_center = mouth.opening_center
199
															    rsb_mouth.opening_right  = mouth.opening_right
200
															    rsb_mouth.position_left  = mouth.position_left
201
															    rsb_mouth.position_center = mouth.position_center
202
															    rsb_mouth.position_right = mouth.position_right
203

  
204
															    if (blocking):
205
																#blocking:
206
																    result = self.server.mouth(rsb_mouth)
207
																    self.logger.debug("server reply: '%s'" % result)
208
																    else:
209
																	future = self.server.mouth.async(rsb_mouth)
210
																	#we can block here for a incoming result with a timeout in s
211
																	#print '> server reply: "%s"' % future.get(timeout = 10);
212

  
213
																	self.logger.debug("mouth rpc done")
214

  
215
																	def publish_speech(self, text, blocking):
216
																	    """publish a tts request via mw
217
																	    :param text: text to synthesize and speak
218
																	    :param blocking: True if this call should block until execution finished on robot
219
																	    """
220
																	    self.logger.debug("calling the speech rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
221

  
222
																	    if (blocking):
223
																		#blocking:
224
																		    result = self.server.speech(text)
225
																		    self.logger.debug("server reply: '%s'" % result)
226
																		    else:
227
																			future = self.server.speech.async(text)
228
																			#we can block here for a incoming result with a timeout in s
229
																			#print '> server reply: "%s"' % future.get(timeout = 10);
230

  
231
																			self.logger.debug("speech rpc done")
232

  
233
																			#######################################################################
234
																			# some helpers
235
																			def convert_animationtype_to_rsbval(self, value):
236
																			    """convert RobotAnimation.value to RSB animation value
237
																			    :param value: RobotAnimation.* id to convert to rsb id
238
																			    """
239
																			    #NOTE: this convertion is important as the actual integer values of
240
																			    #      thy python api and the protobuf might be different
241

  
242
																			    if (value == RobotAnimation.IDLE):
243
																				return Animation().IDLE
244
																			    elif (value == RobotAnimation.HEAD_NOD):
245
																				return Animation().HEAD_NOD
246
																			    elif (value == RobotAnimation.HEAD_SHAKE):
247
																				return Animation().HEAD_SHAKE
248
																			    elif (value == RobotAnimation.EYEBLINK_L):
249
																				return Animation().EYEBLINK_L
250
																			    elif (value == RobotAnimation.EYEBLINK_R):
251
																				return  Animation().EYEBLINK_R
252
																			    elif (value == RobotAnimation.EYEBLINK_BOTH):
253
																				return  Animation().EYEBLINK_BOTH
254
																			    elif (value == RobotAnimation.EYEBROWS_RAISE):
255
																				return  Animation().EYEBROWS_RAISE
256
																			    elif (value == RobotAnimation.EYEBROWS_LOWER):
257
																				return  Animation().EYEBROWS_LOWER
258
																			    else:
259
																				self.logger.error("invalid animation type %d\n" % (value))
260
																				return  Animation().NEUTRAL
261

  
262
																			    def convert_emotiontype_to_rsbval(self, value):
263
																				"""convert RobotEmotion.value to RSB animation value
264
																				:param value: RobotEmotion.* id to convert to rsb id
265
																				"""
266
																				#NOTE: this convertion is important as the actual integer values of
267
																				#      thy python api and the protobuf might be different
268

  
269
																				if (value == RobotEmotion.NEUTRAL):
270
																				    return EmotionState().NEUTRAL
271
																				elif (value == RobotEmotion.HAPPY):
272
																				    return EmotionState().HAPPY
273
																				elif (value == RobotEmotion.SAD):
274
																				    return EmotionState().SAD
275
																				elif (value == RobotEmotion.ANGRY):
276
																				    return EmotionState().ANGRY
277
																				elif (value == RobotEmotion.SURPRISED):
278
																				    return  EmotionState().SURPRISED
279
																				elif (value == RobotEmotion.FEAR):
280
																				    return EmotionState().FEAR
281
																				else:
282
																				    self.logger.error("invalid emotion type %d\n" % (value))
283
																				    return  EmotionState().NEUTRAL
43
        """initialise
44
        :param scope: base scope we want to listen on
45
        """
46
        #init base settings
47
        Middleware.__init__(self,scope,loglevel)
48
        #call mw init
49
        self.init_middleware()
50

  
51
    def __del__(self):
52
        """destructor
53
        """
54
        self.logger.debug("destructor of MiddlewareROS called")
55

  
56
    #######################################################################
57
    def init_middleware(self):
58
        """initialise middleware
59
        """
60
        #mute rsb logging:
61
        logging.getLogger("rsb").setLevel(logging.ERROR)
62

  
63
        #initialise RSB stuff
64
        self.logger.info("initialising RSB middleware connection on scope %s, registering rst converters..." % (self.base_scope))
65

  
66
        self.emotionstate_converter = rsb.converter.ProtocolBufferConverter(messageClass = EmotionState)
67
        rsb.converter.registerGlobalConverter(self.emotionstate_converter)
68

  
69
        self.animation_converter = rsb.converter.ProtocolBufferConverter(messageClass = Animation)
70
        rsb.converter.registerGlobalConverter(self.animation_converter)
71

  
72
        self.gaze_converter = rsb.converter.ProtocolBufferConverter(messageClass = GazeTarget)
73
        rsb.converter.registerGlobalConverter(self.gaze_converter)
74

  
75
        self.mouth_converter = rsb.converter.ProtocolBufferConverter(messageClass = MouthTarget)
76
        rsb.converter.registerGlobalConverter(self.mouth_converter)
77

  
78
        try:
79
            self.server = rsb.createRemoteServer(self.base_scope + '/set')
80
        except ValueError:
81
            self.logger.error("ERROR: invalid scope given. server deactivated")
82
            self.server.deactivate()
83
            sys.exit(errno.EINVAL)
84

  
85
    #######################################################################
86
    def publish_emotion(self, em_type, emotion, blocking):
87
        """publish an emotion via mw
88
        :param em_type: type of emotion (RobotEmotion::TYPE_DEFAULT or RobotEmotion::TYPE_CURRENT)
89
        :param emotion: emotion to set
90
        :param blocking: True if this call should block until execution finished on robot
91
        """
92

  
93
        #create emotion & fill it with values:
94
        rsb_em = EmotionState()
95

  
96
        #set value
97
        rsb_em.value = self.convert_emotiontype_to_rsbval(emotion.value)
98

  
99
        #set duration
100
        rsb_em.duration = int(emotion.time_ms)
101

  
102
        with rsb.createRemoteServer(self.base_scope + '/set') as server:
103
            self.logger.debug("calling the emotion rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
104

  
105
            if (blocking):
106
                #blocking rpc call:
107
                if (em_type == RobotEmotion.TYPE_DEFAULT):
108
                    result = server.defaultEmotion(rsb_em)
109
                else:
110
                    result = server.currentEmotion(rsb_em)
111

  
112
                self.logger.debug("server reply: '%s'" % result)
113
            else:
114
                if (em_type == RobotEmotion.TYPE_DEFAULT):
115
                    future = server.defaultEmotion.async(rsb_em)
116
                else:
117
                    future = server.currentEmotion.async(rsb_em)
118

  
119
                #we could block here for a incoming result with a timeout in s
120
                #print '> server reply: "%s"' % future.get(timeout = 10);
121
            self.logger.debug("emotion rpc done")
122

  
123
    def publish_head_animation(self, animation, blocking):
124
        """publish an head animation via mw
125
        :param animation: animation to set
126
        :param blocking: True if this call should block until execution finished on robot
127
        """
128

  
129
        self.logger.debug("calling the animation rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
130

  
131
        #create animation & fill it with values:
132
        rsb_ani = Animation()
133

  
134
        #select ani
135
        rsb_ani.target = self.convert_animationtype_to_rsbval(animation.value)
136
        rsb_ani.repetitions = animation.repetitions
137
        rsb_ani.duration_each = animation.time_ms
138
        rsb_ani.scale       = animation.scale
139

  
140
        if (blocking):
141
            #blocking:
142
            result = self.server.animation(rsb_ani)
143
            self.logger.debug("server reply: '%s'" % result)
144
        else:
145
            future = self.server.animation.async(rsb_ani)
146
            #we can block here for a incoming result with a timeout in s
147
            #print '> server reply: "%s"' % future.get(timeout = 10);
148

  
149
        self.logger.debug("animation rpc done")
150

  
151
    def publish_default_emotion(self, emotion, blocking):
152
        self.publish_emotion(RobotEmotion.TYPE_DEFAULT, emotion, blocking)
153

  
154
    def publish_current_emotion(self, emotion, blocking):
155
        self.publish_emotion(RobotEmotion.TYPE_CURRENT, emotion, blocking)
156

  
157
    def publish_gaze_target(self, gaze, blocking):
158
        """publish a gaze target via mw
159
        :param gaze: gaze to set
160
        :param blocking: True if this call should block until execution finished on robot
161
        """
162
        self.logger.debug("calling the gaze rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
163

  
164
        #create gaze target & fill it with values:
165
        rsb_gaze = GazeTarget()
166

  
167
        #fill proto
168
        rsb_gaze.pan  = gaze.pan
169
        rsb_gaze.tilt = gaze.tilt
170
        rsb_gaze.roll = gaze.roll
171
        rsb_gaze.vergence = gaze.vergence
172
        rsb_gaze.pan_offset  = gaze.pan_offset
173
        rsb_gaze.tilt_offset = gaze.tilt_offset
174

  
175
        if (blocking):
176
            #blocking:
177
            result = self.server.gaze(rsb_gaze)
178
            self.logger.debug("server reply: '%s'" % result)
179
        else:
180
            future = self.server.gaze.async(rsb_gaze)
181
            #we can block here for a incoming result with a timeout in s
182
            #print '> server reply: "%s"' % future.get(timeout = 10);
183

  
184
        self.logger.debug("gaze rpc done")
185

  
186
    def publish_mouth_target(self, mouth, blocking):
187
        """publish a mouth target via mw
188
        :param mouth: mouth value to set
189
        :param blocking: True if this call should block until execution finished on robot
190
        """
191
        self.logger.debug("calling the mouth rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
192

  
193
        #create mouth state & fill it with values:
194
        rsb_mouth = MouthTarget()
195

  
196
        #fill proto
197
        rsb_mouth.opening_left   = mouth.opening_left
198
        rsb_mouth.opening_center = mouth.opening_center
199
        rsb_mouth.opening_right  = mouth.opening_right
200
        rsb_mouth.position_left  = mouth.position_left
201
        rsb_mouth.position_center = mouth.position_center
202
        rsb_mouth.position_right = mouth.position_right
203

  
204
        if (blocking):
205
            #blocking:
206
            result = self.server.mouth(rsb_mouth)
207
            self.logger.debug("server reply: '%s'" % result)
208
        else:
209
            future = self.server.mouth.async(rsb_mouth)
210
            #we can block here for a incoming result with a timeout in s
211
            #print '> server reply: "%s"' % future.get(timeout = 10);
212

  
213
        self.logger.debug("mouth rpc done")
214

  
215
    def publish_speech(self, text, blocking):
216
        """publish a tts request via mw
217
        :param text: text to synthesize and speak
218
        :param blocking: True if this call should block until execution finished on robot
219
        """
220
        self.logger.debug("calling the speech rpc (%s)..." % ("BLOCKING" if blocking else "NON-BLOCKING"))
221

  
222
        if (blocking):
223
            #blocking:
224
            result = self.server.speech(text)
225
            self.logger.debug("server reply: '%s'" % result)
226
        else:
227
            future = self.server.speech.async(text)
228
            #we can block here for a incoming result with a timeout in s
229
            #print '> server reply: "%s"' % future.get(timeout = 10);
230

  
231
        self.logger.debug("speech rpc done")
232

  
233
    #######################################################################
234
    # some helpers
235
    def convert_animationtype_to_rsbval(self, value):
236
        """convert RobotAnimation.value to RSB animation value
237
        :param value: RobotAnimation.* id to convert to rsb id
238
        """
239
        #NOTE: this convertion is important as the actual integer values of
240
        #      thy python api and the protobuf might be different
241

  
242
        if (value == RobotAnimation.IDLE):
243
            return Animation().IDLE
244
        elif (value == RobotAnimation.HEAD_NOD):
245
            return Animation().HEAD_NOD
246
        elif (value == RobotAnimation.HEAD_SHAKE):
247
            return Animation().HEAD_SHAKE
248
        elif (value == RobotAnimation.EYEBLINK_L):
249
            return Animation().EYEBLINK_L
250
        elif (value == RobotAnimation.EYEBLINK_R):
251
            return  Animation().EYEBLINK_R
252
        elif (value == RobotAnimation.EYEBLINK_BOTH):
253
            return  Animation().EYEBLINK_BOTH
254
        elif (value == RobotAnimation.EYEBROWS_RAISE):
255
            return  Animation().EYEBROWS_RAISE
256
        elif (value == RobotAnimation.EYEBROWS_LOWER):
257
            return  Animation().EYEBROWS_LOWER
258
        else:
259
            self.logger.error("invalid animation type %d\n" % (value))
260
            return  Animation().NEUTRAL
261

  
262
    def convert_emotiontype_to_rsbval(self, value):
263
        """convert RobotEmotion.value to RSB animation value
264
        :param value: RobotEmotion.* id to convert to rsb id
265
        """
266
        #NOTE: this convertion is important as the actual integer values of
267
        #      thy python api and the protobuf might be different
268

  
269
        if (value == RobotEmotion.NEUTRAL):
270
            return EmotionState().NEUTRAL
271
        elif (value == RobotEmotion.HAPPY):
272
            return EmotionState().HAPPY
273
        elif (value == RobotEmotion.SAD):
274
            return EmotionState().SAD
275
        elif (value == RobotEmotion.ANGRY):
276
            return EmotionState().ANGRY
277
        elif (value == RobotEmotion.SURPRISED):
278
            return  EmotionState().SURPRISED
279
        elif (value == RobotEmotion.FEAR):
280
            return EmotionState().FEAR
281
        else:
282
            self.logger.error("invalid emotion type %d\n" % (value))
283
            return  EmotionState().NEUTRAL
client/python/hlrc_client/RobotAnimation.py
36 36
    EYEBROWS_LOWER  = 7
37 37

  
38 38
    def __init__(self, v = IDLE):
39
	self.value = v
40
	self.time_ms = 1000
41
	self.repetitions = 1
42
	self.scale = 1.0
43

  
44
	def value_as_str(self):
45
	    if (self.value == RobotAnimation.IDLE):
46
		return "idle"
47
	    elif (self.value == RobotAnimation.HEAD_NOD):
48
		return "head nod"
49
	    elif (self.value == RobotAnimation.HEAD_SHAKE):
50
		return "head shake"
51
	    elif (self.value == RobotAnimation.EYEBLINK_L):
52
		return "eyeblink l"
53
	    elif (self.value == RobotAnimation.EYEBLINK_R):
54
		return "eyeblink r"
55
	    elif (self.value == RobotAnimation.EYEBROWS_RAISE):
56
		return "eyebrows raise"
57
	    elif (self.value == RobotAnimation.EYEBROWS_LOWER):
58
		return "eyebrows lower"
59
	    else:
60
		return "INVALID ANIMATION TYPE"
61

  
62
	    def __str__(self):
63
		return "RobotAnimation = { value='%s', time_ms=%d repetitions=%d scale=%6.2f }" % \
64
	    (self.value_as_str(), self.time_ms, self.repetitions, self.scale)
39
        self.value = v
40
        self.time_ms = 1000
41
        self.repetitions = 1
42
        self.scale = 1.0
65 43

  
44
    def value_as_str(self):
45
        if (self.value == RobotAnimation.IDLE):
46
            return "idle"
47
        elif (self.value == RobotAnimation.HEAD_NOD):
48
            return "head nod"
49
        elif (self.value == RobotAnimation.HEAD_SHAKE):
50
            return "head shake"
51
        elif (self.value == RobotAnimation.EYEBLINK_L):
52
            return "eyeblink l"
53
        elif (self.value == RobotAnimation.EYEBLINK_R):
54
            return "eyeblink r"
55
        elif (self.value == RobotAnimation.EYEBROWS_RAISE):
56
            return "eyebrows raise"
57
        elif (self.value == RobotAnimation.EYEBROWS_LOWER):
58
            return "eyebrows lower"
59
        else:
60
            return "INVALID ANIMATION TYPE"
66 61

  
62
    def __str__(self):
63
        return "RobotAnimation = { value='%s', time_ms=%d repetitions=%d scale=%6.2f }" % \
64
                (self.value_as_str(), self.time_ms, self.repetitions, self.scale)
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
	"""
39
	self.logger = logging.getLogger(__name__)
40

  
41
	# create nice and actually usable formatter and add it to the handler
42
	self.config_logger(loglevel)
43

  
44
	#store
45
	self.scope = scope
46
	self.mw = mw_name
47
	self.loglevel = loglevel
48

  
49
	self.middleware = None
50

  
51

  
52
	if (self.mw.upper() == "RSB"):
53
	    self.logger.info("creating new middleware connection via RSB")
54
	    try:
55
		from MiddlewareRSB import MiddlewareRSB
56
		except ImportError, e:
57
		    self.logger.error("failed to import RSB or the necessary data types: {}".format(e))
58
		    sys.exit(errno.EINVAL)
59

  
60
		    #import worked, safe to intantiate RSB mw now
61
		    self.middleware = MiddlewareRSB(self.scope, self.loglevel)
62

  
63
		    elif (self.mw.upper() == "ROS"):
64
			self.logger.info("creating new middleware connection via ROS")
65
			try:
66
			    from MiddlewareROS import MiddlewareROS
67
			    except ImportError, e:
68
				self.logger.error("failed to import ROS or the necessary data types: {}".format(e))
69
				sys.exit(errno.EINVAL)
70

  
71
				#import worked, safe to intantiate RSB mw now
72
				self.middleware = MiddlewareROS(self.scope, self.loglevel)
73
				else:
74
				    self.logger.error("invalid middleware requested (%s). supported: {ROS, RSB}\n\n" % (self.mw))
75
				    sys.exit(errno.EINVAL)
76

  
77
				    def __del__(self):
78
					"""destructor
79
					"""
80
					self.logger.debug("destructor of RobotController called")
81

  
82
					def config_logger(self, level):
83
					    """initialise a nice logger formatting
84
					    :param  level: log level
85
					    """
86
					    formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
87
					    ch = logging.StreamHandler()
88
					    #ch.setLevel(level)
89
					    ch.setFormatter(formatter)
90
					    self.logger.setLevel(level)
91
					    self.logger.addHandler(ch)
92

  
93
					    def set_current_emotion(self, robot_emotion, blocking = False):
94
						"""set the current emotion
95
						:param robot_emotion: a RobotEmotion object
96
						:param blocking: should this call block during execution?
97
						"""
98
						self.logger.debug("set_current_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
99
						self.middleware.set_current_emotion(robot_emotion, blocking)
100

  
101
						def set_default_emotion(self, robot_emotion, blocking = False):
102
						    """set the default emotion
103
						    :param robot_emotion: a RobotEmotion object
104
						    :param blocking: should this call block during execution?
105
						    """
106
						    self.logger.debug("set_default_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
107
						    self.middleware.set_default_emotion(robot_emotion, blocking)
108

  
109
						    def set_gaze_target(self, robot_gaze, blocking = False):
110
							"""set a gaze target
111
							:param robot_gaze: a RobotGaze object
112
							:param blocking: should this call block during execution?
113
							"""
114

  
115
							self.logger.debug("set_gaze_target(%s) %s" % (robot_gaze, ("BLOCKING" if blocking else "NON_BLOCKING")))
116
							self.middleware.set_gaze_target(robot_gaze, blocking)
117

  
118
							def set_mouth_target(self, robot_mouth, blocking = False):
119
							    """set a mouth target
120
							    :param robot_mouth: a RobotMouth object
121
							    :param blocking: should this call block during execution?
122
							    """
123
							    self.logger.debug("set_mouth_target(%s) %s" % (robot_mouth, ("BLOCKING" if blocking else "NON_BLOCKING")))
124
							    self.middleware.set_mouth_target(robot_mouth, blocking)
125

  
126
							    def set_head_animation(self, robot_animation, blocking = False):
127
								"""set a head animation
128
								:param robot_animation: a RobotAnimation object
129
								:param blocking: should this call block during execution?
130
								"""
131
								self.logger.debug("set_head_animation(%s) %s" % (robot_animation, ("BLOCKING" if blocking else "NON_BLOCKING")))
132
								self.middleware.set_head_animation(robot_animation, blocking)
133

  
134
								def set_speak(self, text, blocking = False):
135
								    """request the robot to say something using tts
136
								    :param text: text to synthesize
137
								    :param blocking: should this call block during execution?
138
								    """
139
								    self.logger.debug("set_speak(%s) %s" % (text, ("BLOCKING" if blocking else "NON_BLOCKING")))
140
								    self.middleware.set_speak(text, blocking)
141

  
142
								    #def get_gaze_target(self):
143
									#	result = self.middleware.get_gaze_target()
144
									#	self.logger.debug("get_gaze_target() returned %s" % (result))
145
									#	return self.middleware.get_gaze_target()
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
        """
39
        self.logger = logging.getLogger(__name__)
40

  
41
        # create nice and actually usable formatter and add it to the handler
42
        self.config_logger(loglevel)
43

  
44
        #store
45
        self.scope = scope
46
        self.mw = mw_name
47
        self.loglevel = loglevel
48

  
49
        self.middleware = None
50

  
51

  
52
        if (self.mw.upper() == "RSB"):
53
            self.logger.info("creating new middleware connection via RSB")
54
            try:
55
                from MiddlewareRSB import MiddlewareRSB
56
            except ImportError, e:
57
                self.logger.error("failed to import RSB or the necessary data types: {}".format(e))
58
                sys.exit(errno.EINVAL)
59

  
60
            #import worked, safe to intantiate RSB mw now
61
            self.middleware = MiddlewareRSB(self.scope, self.loglevel)
62

  
63
        elif (self.mw.upper() == "ROS"):
64
            self.logger.info("creating new middleware connection via ROS")
65
            try:
66
                from MiddlewareROS import MiddlewareROS
67
            except ImportError, e:
68
                self.logger.error("failed to import ROS or the necessary data types: {}".format(e))
69
                sys.exit(errno.EINVAL)
70

  
71
            #import worked, safe to intantiate RSB mw now
72
            self.middleware = MiddlewareROS(self.scope, self.loglevel)
73
        else:
74
            self.logger.error("invalid middleware requested (%s). supported: {ROS, RSB}\n\n" % (self.mw))
75
            sys.exit(errno.EINVAL)
76

  
77
    def __del__(self):
78
        """destructor
79
        """
80
        self.logger.debug("destructor of RobotController called")
81

  
82
    def config_logger(self, level):
83
        """initialise a nice logger formatting
84
        :param  level: log level
85
        """
86
        formatter = logging.Formatter('%(asctime)s %(name)-30s %(levelname)-8s > %(message)s')
87
        ch = logging.StreamHandler()
88
        #ch.setLevel(level)
89
        ch.setFormatter(formatter)
90
        self.logger.setLevel(level)
91
        self.logger.addHandler(ch)
92

  
93
    def set_current_emotion(self, robot_emotion, blocking = False):
94
        """set the current emotion
95
        :param robot_emotion: a RobotEmotion object
96
        :param blocking: should this call block during execution?
97
        """
98
        self.logger.debug("set_current_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
99
        self.middleware.set_current_emotion(robot_emotion, blocking)
100

  
101
    def set_default_emotion(self, robot_emotion, blocking = False):
102
        """set the default emotion
103
        :param robot_emotion: a RobotEmotion object
104
        :param blocking: should this call block during execution?
105
        """
106
        self.logger.debug("set_default_emotion(%s) %s" % (robot_emotion, ("BLOCKING" if blocking else "NON_BLOCKING")))
107
        self.middleware.set_default_emotion(robot_emotion, blocking)
108

  
109
    def set_gaze_target(self, robot_gaze, blocking = False):
110
        """set a gaze target
111
        :param robot_gaze: a RobotGaze object
112
        :param blocking: should this call block during execution?
113
        """
114

  
115
        self.logger.debug("set_gaze_target(%s) %s" % (robot_gaze, ("BLOCKING" if blocking else "NON_BLOCKING")))
116
        self.middleware.set_gaze_target(robot_gaze, blocking)
117

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff