Revision 3877047d client/python/hlrc_client/MiddlewareRSB.py

View differences:

client/python/hlrc_client/MiddlewareRSB.py
38 38
from rst.robot.MouthTarget_pb2  import MouthTarget
39 39

  
40 40
class MiddlewareRSB(Middleware):
41
	#######################################################################
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()
41
    #######################################################################
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 50

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

  
56
	    #######################################################################
57
	    def init_middleware(self):
58 58
		"""initialise middleware
59 59
		"""
60 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:
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 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
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

Also available in: Unified diff