Tutorial: Creating expressions with LEDs#
🏁 Goal of this tutorial
By the end of this tutorial, you will know how to request different type of LEDs effects using the LEDs devices available on PAL’s robots. Additionally, you will see an example of how PAL’s robots’s LEDs can be used for expressiveness purposes.
Pre-requisites#
This tutorial requires you to have
python3
installed.This tutorial requires you to have ROS noetic installed. If you don’t, follow these installation instructions. We suggest to choose the
desktop-full
version, to have access to ROS visualisation tools (e.g., rviz).This tutorial requires you to have the
pal_msgs
package installed. You can download it from this GitHub repository.This tutorial requires you to have a general knowledge of the PAL’s robots’s LEDs API. If you want to know more about the PAL’s robots’s LEDs API, check leds_api.
The code#
This is a possible implementation of a ROS node executing a demo to showcase how we can also use PAL’s robots’s LEDs devices to enhance its expressiveness.
1#!/usr/bin/env python3
2
3# -*- coding: utf-8 -*-
4
5import rospy
6from actionlib import SimpleActionClient
7from pal_device_msgs.msg import DoTimedLedEffectAction,\
8 DoTimedLedEffectGoal, LedEffectParams
9from pal_interaction_msgs.msg import TtsAction, TtsGoal
10from std_msgs.msg import String
11import numpy as np
12
13# led devices ids
14BACK = 0
15LEFT_EAR = 1
16RIGHT_EAR = 2
17RESPEAKER = 4
18
19MAX_PRIORITY = 255 # The maximum value for leds effect priority
20
21def init_clients():
22 """ Initializing the action clients. """
23
24 # Creating a client object to communicate
25 # with the LEDs action server
26 led_client = SimpleActionClient("/pal_led_manager/do_effect",
27 DoTimedLedEffectAction)
28 led_client.wait_for_server()
29
30 # Creating a client object to communicate
31 # with the TTS action server
32 tts_client = SimpleActionClient('/tts',
33 TtsAction)
34 tts_client.wait_for_server()
35
36 return led_client, tts_client
37
38
39def set_color_progress_effect(goal,
40 r1,
41 g1,
42 b1,
43 a1,
44 r2,
45 g2,
46 b2,
47 a2,
48 percentage,
49 offset):
50 """ A function to set a led effect
51 to communicate the progress status
52 regarding a task/action.
53 """
54
55 # first_color --> completion colour
56 goal.params.progress.first_color.r = r1
57 goal.params.progress.first_color.g = g1
58 goal.params.progress.first_color.b = b1
59 goal.params.progress.first_color.a = a1
60
61 # second_color --> non-completed portion colour
62 goal.params.progress.second_color.r = r2
63 goal.params.progress.second_color.g = g2
64 goal.params.progress.second_color.b = b2
65 goal.params.progress.second_color.a = a2
66
67 # percentage --> percentage of LEDs coloured
68 # in first_color
69 goal.params.progress.percentage = percentage
70
71 # led_offset --> the led to start from
72 # in a leds array
73 goal.params.progress.led_offset = offset
74
75 return goal
76
77
78def show_progress(client,
79 devices):
80 """ Displaying a generic task completion
81 progress via leds.
82 This is a demo function to showcase the
83 leds progress effect.
84 """
85
86 goal = DoTimedLedEffectGoal() # The object representing the led effect
87 goal.devices = devices # The devices performing the effect
88 goal.params.effectType = LedEffectParams.PROGRESS # The type of effect
89
90 # Setting values for the two progress
91 # color components
92 # first color --> complete
93 # second color --> uncomplete
94
95 first_color_red = 0.0
96 first_color_green = 0.0
97 first_color_blue = 1.0
98 first_color_alpha = 1.0
99
100 second_color_red = 1.0
101 second_color_green = 0.0
102 second_color_blue = 0.0
103 second_color_alpha = 1.0
104
105 # led offset set to 0. Progression
106 # will be displayed starting from
107 # the top led, counterclockwise
108 offset = 0
109
110 # Incrementing the advancement with a 1% step
111 # every 0.2 seconds.
112 for percentage in np.arange(0, 1.01, 0.01):
113 goal = set_color_progress_effect(goal,
114 first_color_red,
115 first_color_green,
116 first_color_blue,
117 first_color_alpha,
118 second_color_red,
119 second_color_green,
120 second_color_blue,
121 second_color_alpha,
122 percentage,
123 offset)
124
125 # Setting non effect-specific parameters
126 goal.effectDuration.secs = 0
127 goal.effectDuration.nsecs = 200000000
128 goal.priority = MAX_PRIORITY
129
130 client.send_goal(goal)
131
132 # Printing the completion status
133 completion_str = str(percentage*100)+"%"
134 rospy.loginfo("Task completion: "+completion_str)
135
136 # Sleeping slightly less then the effect duration
137 # to always have the next completion goal
138 # queuing when the previous one execution finishes
139 rospy.sleep(0.19)
140
141
142def show_rainbow(client,
143 devices,
144 transition_duration,
145 duration_secs,
146 duration_nsecs = 0):
147 """ Setting up and seding a LedEffectGoal for
148 a rainbow effect (that is, continous transition
149 over the rainbow colours).
150 """
151
152 goal = DoTimedLedEffectGoal()
153 goal.devices = devices
154 goal.params.effectType = LedEffectParams.RAINBOW
155
156 # transition_duration --> the time the effect
157 # will take to complete an iteration over
158 # the rainbow colours
159 goal.params.rainbow.transition_duration.secs = transition_duration
160
161 # Setting non effect-specific parameters: time and priority
162 goal.effectDuration.secs = duration_secs
163 goal.effectDuration.nsecs = duration_nsecs
164 goal.priority = MAX_PRIORITY
165
166 client.send_goal_and_wait(goal)
167
168
169def show_fixed_color(client,
170 devices,
171 r,
172 g,
173 b,
174 a,
175 duration_secs,
176 duration_nsecs = 0):
177 """ Setting up and sending a LedEffectGoal
178 for a fixed color leds effect
179 """
180
181 goal = DoTimedLedEffectGoal()
182 goal.devices = devices
183 goal.params.effectType = LedEffectParams.FIXED_COLOR
184
185 # Setting the colour parameters
186 goal.params.fixed_color.color.r = r
187 goal.params.fixed_color.color.g = g
188 goal.params.fixed_color.color.b = b
189 goal.params.fixed_color.color.a = a
190
191 # Setting non effect-specific parameters
192 goal.effectDuration.secs = duration_secs
193 goal.effectDuration.nsecs = duration_nsecs
194 goal.priority = MAX_PRIORITY
195
196 client.send_goal_and_wait(goal)
197
198
199def show_blinking_color(client,
200 devices,
201 r1,
202 g1,
203 b1,
204 a1,
205 duration_secs1,
206 duration_nsecs1,
207 r2,
208 g2,
209 b2,
210 a2,
211 duration_secs2,
212 duration_nsecs2,
213 duration_secs,
214 duration_nsecs = 0):
215 """ Setting up and sending a LedEffectGoal
216 for a blinking color leds effect.
217 It alternates two colors with custom
218 temporisation.
219 """
220
221 goal = DoTimedLedEffectGoal()
222 goal.devices = devices
223 goal.params.effectType = LedEffectParams.BLINK
224
225 # Setting the first colour parameters
226 goal.params.blink.first_color.r = r1
227 goal.params.blink.first_color.g = g1
228 goal.params.blink.first_color.b = b1
229 goal.params.blink.first_color.a = a1
230
231 # Setting the first colour duration
232 goal.params.blink.first_color_duration.secs = duration_secs1
233 goal.params.blink.first_color_duration.nsecs = duration_nsecs1
234
235 # Setting the second colour parameters
236 goal.params.blink.second_color.r = r2
237 goal.params.blink.second_color.g = g2
238 goal.params.blink.second_color.b = b2
239 goal.params.blink.second_color.a = a1
240
241 # Setting the second colour duration
242 goal.params.blink.second_color_duration.secs = duration_secs2
243 goal.params.blink.second_color_duration.nsecs = duration_nsecs2
244
245 # Setting non effect-specific parameters
246 goal.effectDuration.secs = duration_secs
247 goal.effectDuration.nsecs = duration_nsecs
248 goal.priority = MAX_PRIORITY
249
250 client.send_goal_and_wait(goal)
251
252def send_tts(client,
253 text,
254 language = "en_GB",
255 blocking = False):
256 """ Function sending text to be pronounced
257 to the tts action server.
258 If blocking is True, the function
259 waits for answer from the action,
260 blocking the process.
261 """
262
263 goal = TtsGoal()
264
265 goal.rawtext.text = text
266 goal.rawtext.lang_id = "en_GB"
267
268 if blocking:
269 client.send_goal_and_wait(goal)
270 else:
271 client.send_goal(goal)
272
273
274if __name__ == '__main__':
275 try:
276 rospy.init_node('expressive_leds')
277
278 led_client, tts_client = init_clients()
279
280 # Requesting ARI to introduce people to the tutorial.
281 send_tts(tts_client,
282 "Welcome to the expressive leds tutorial!",
283 blocking = True)
284
285 # ARI is telling people that it will start downloading some
286 # "very important files". During the download process, it will
287 # show the progression status using the leds on its back
288 send_tts(tts_client,
289 "I will now start loading some very important files!\
290 Check my back leds to see what is the progression status.",
291 blocking = True)
292 show_progress(led_client,
293 [BACK])
294
295 # At this point, ARI has completed downloading the "very important
296 # files". To show how happy it is, ARI will emit a rainbow with
297 # all of its (available) leds
298 send_tts(tts_client,
299 "Yes, I made it! Task completed!")
300 rospy.loginfo("yes, I made it! Task completed! :)")
301 show_rainbow(led_client,
302 [BACK, LEFT_EAR, RIGHT_EAR],
303 1,
304 10)
305
306 # Something might be wrong with the files ARI downloaded!
307 # Being in an alert status, it sets all of its leds to red
308 rospy.loginfo("OH NO! Something is going wrong!")
309 send_tts(tts_client,
310 "Oh no! Something might be wrong with these files!")
311 show_fixed_color(led_client,
312 [BACK, LEFT_EAR, RIGHT_EAR, RESPEAKER],
313 r=1,
314 g=0,
315 b=0,
316 a=1,
317 duration_secs=10)
318
319 # ARI is now sure that the downloaded files were not the right
320 # ones, and needs an expert help to revert the situation.
321 # ARI is now emitting blinking yellow light, to attract someone's
322 # attention
323 rospy.loginfo("Please, help me!"+\
324 "These were not the very important files I needed!")
325 send_tts(tts_client,
326 "Please, help me!\
327 These were not the very important files I needed!")
328 show_blinking_color(led_client,
329 [BACK, LEFT_EAR, RIGHT_EAR],
330 r1=1,
331 g1=0,
332 b1=0,
333 a1=1,
334 duration_secs1=1,
335 duration_nsecs1=0,
336 r2=1,
337 g2=1,
338 b2=0,
339 a2=1,
340 duration_secs2=1,
341 duration_nsecs2=0,
342 duration_nsecs=200000000,
343 duration_secs=20
344 )
345 except rospy.ROSInterruptException:
346 print("Abruptly finished!")
The code explained#
First things first, we need to import the required packages.
5import rospy
6from actionlib import SimpleActionClient
7from pal_device_msgs.msg import DoTimedLedEffectAction,\
8 DoTimedLedEffectGoal, LedEffectParams
9from pal_interaction_msgs.msg import TtsAction, TtsGoal
10from std_msgs.msg import String
11import numpy as np
Then, we define some constant values used later in the code. This step increases code readability.
13# led devices ids
14BACK = 0
15LEFT_EAR = 1
16RIGHT_EAR = 2
17RESPEAKER = 4
18
19MAX_PRIORITY = 255 # The maximum value for leds effect priority
Now, we are defining a set of functions that will be used later,
in __main__
. The first function we implement is
init_clients()
, to initialise the client-server
connection required to interact with the ROS action servers involved
in the LEDs and TTS management.
21def init_clients():
22 """ Initializing the action clients. """
23
24 # Creating a client object to communicate
25 # with the LEDs action server
26 led_client = SimpleActionClient("/pal_led_manager/do_effect",
27 DoTimedLedEffectAction)
28 led_client.wait_for_server()
29
30 # Creating a client object to communicate
31 # with the TTS action server
32 tts_client = SimpleActionClient('/tts',
33 TtsAction)
34 tts_client.wait_for_server()
35
36 return led_client, tts_client
We will now go through the definition of a set of functions
to initialise and set the fields of a DoTimedLedEffectAction
object, that is, the object sent by the node to the action server
to request a specific LEDs effect. We invite you to check the
message structure before going through the next functions definition,
to have a better understanding of the fields involved in the LEDs
effects requests.
We will start implementing a function for the progression effect. This is meant to showcase a generic progression state: for instance, the battery level while the robot is docked.
39def set_color_progress_effect(goal,
40 r1,
41 g1,
42 b1,
43 a1,
44 r2,
45 g2,
46 b2,
47 a2,
48 percentage,
49 offset):
Let’s understand the function parameters in detail:
goal
is theDoTimedLedEffectAction
object which parameters will be set through the function.r1, g1, b1, a1
are the red, green, blue and alpha parameters for the completion colour.r2, g2, b2, a2
are the red, green, blue and alpha parameters for the complementary colour. The complementary colour will be used by those LEDs not using the completion colour.percentage
represents the fraction of lights to set with the completion colour. In a process advancement fashion, it represents the process completion status.offset
represents from which light in the LEDs array the progression should start from.
Once inside the function, we assign the colour parameters to the
relative goal
fields.
56goal.params.progress.first_color.r = r1
57goal.params.progress.first_color.g = g1
58goal.params.progress.first_color.b = b1
59goal.params.progress.first_color.a = a1
60
61goal.params.progress.second_color.r = r2
62goal.params.progress.second_color.g = g2
63goal.params.progress.second_color.b = b2
64goal.params.progress.second_color.a = a2
Then we set the percentage:
69goal.params.progress.percentage = percentage
And the light offset.
73goal.params.progress.led_offset = offset
The function ends up returning the goal
object.
75return goal
Another function, show_progress
, uses
set_color_progress_effect
. This is a demo function,
simulating the advancement of the status of a generic process
from 0% to 100%, advancing by a 1% step every 0.2 seconds.
78def show_progress(client,
79 devices)
This function requires two parameters:
client
, the object used to manage the client-server communication with the robot’s LEDs action server.devices
, the list of LEDs devices that will perform the progression effect.
Initially, we create the goal
object, setting two of
its fields that will not change anymore: the type of effect
and the device that will display the effect (in this case,
the back LEDs).
86goal = DoTimedLedEffectGoal()
87goal.devices = devices
88goal.params.effectType = LedEffectParams.PROGRESS
Then, we initialise the first and second colours parameters and the LEDs offset.
95first_color_red = 0.0
96first_color_green = 0.0
97first_color_blue = 1.0
98first_color_alpha = 1.0
99
100second_color_red = 1.0
101second_color_green = 0.0
102second_color_blue = 0.0
103second_color_alpha = 1.0
104
105# led offset set to 0. Progression
106# will be displayed starting from
107# the top led, counterclockwise
108offset = 0
At this point, the progression starts. To simulate a process
status advancement, we iterate over an np.arange
object. At each step, we set the goal
parameters
using the previously defined set_color_progress_effect
.
112for percentage in np.arange(0, 1.01, 0.01):
113 goal = set_color_progress_effect(goal,
114 first_color_red,
115 first_color_green,
116 first_color_blue,
117 first_color_alpha,
118 second_color_red,
119 second_color_green,
120 second_color_blue,
121 second_color_alpha,
122 percentage,
123 offset)
The last step missing before sending goal
to the action server is setting the time duration and
effect priority.
Warning
This being a demo, we will set the priority to the maximum possible value. We invite you to properly set the priority when using LEDs in your custom applications.
126goal.effectDuration.secs = 0
127goal.effectDuration.nsecs = 200000000
128goal.priority = MAX_PRIORITY
At this point, we can send the goal
object
to the action server, using client
.
130client.send_goal(goal)
It’s useful printing the advancement status, for a qualitative evaluation of the effect execution.
133completion_str = str(percentage*100)+"%"
134rospy.loginfo("Task completion: "+completion_str)
As a last step, we add an instruction blocking the process for 0.19 seconds, which is slightly less than the effect duration. This is required as blocking for the entire duration of the effect would introduce a small (but notable) time gap between two consecutive progression goals, where the LEDs would execute another effect from the effects queue (for instance, the battery level), presenting a fragmented behaviour.
Another effect we will be using during the tutorial is the rainbow effect. This makes the LEDs device change its colour continously, ranging over the whole rainbow colour spectrum. Let’s see how to implement a function to generate and request this effect.
142def show_rainbow(client,
143 devices,
144 transition_duration,
145 duration_secs,
146 duration_nsecs = 0):
This function requires 5 parameters:
client
is the object used to manage the client-server communication with the robot’s LEDs action server.devices
is the list of LEDs devices that will perform the effect.transition_duration
is the time the effect will take to complete an iteration over the rainbow colours.duration_secs
andduration_nsecs
define the effect duration.
Firstly, we initialise the object representing the LEDs effect to be sent to the action server for execution.
152goal = DoTimedLedEffectGoal()
Then, we set the devices that will execute the rainbow effect.
153goal.devices = devices
As previously seen, we have to specify through
the goal.params.effectType
parameter
which effect we want to use.
154goal.params.effectType = LedEffectParams.RAINBOW
The rainbow effect has just one effect-specific
parameter, the rainbow transition duration, that we
can set through
goal.params.rainbow.transition_duration.secs = transition_duration
.
159goal.params.rainbow.transition_duration.secs = transition_duration
The last step missing before sending goal
to the action server is setting the time duration and
effect priority.
Warning
This being a demo, we will set the priority to the maximum possible value. We invite you to properly set the priority when using LEDs in your custom applications.
162goal.effectDuration.secs = duration_secs
163goal.effectDuration.nsecs = duration_nsecs
164goal.priority = MAX_PRIORITY
At this point, we can send the goal
object
to the action server, using client
. The LEDs
devices previously specified will execute
the effect immediately if no other LEDs effect
with MAX_PRIORITY
is being performed;
if this is not the case, then the effect
will queue while waiting that all the previous
queued effects with MAX_PRIORITY
will have been performed.
166client.send_goal(goal)
Another effect we will be using during the tutorial is the fixed-colour effect. This will set a static LEDs colour for a certain amount of time. Let’s see how we implemented a function to generate and request this effect.
169def show_fixed_color(client,
170 devices,
171 r,
172 g,
173 b,
174 a,
175 duration_secs,
176 duration_nsecs = 0)
This function requires 8 parameters:
client
is the object used to manage the client-server communication with the robot’s LEDs action serverdevices
is the list of LEDs devices that will perform the effect.r, g, b, a
are respectively the red, green, blue and alpha parameters of the requested fixed colour.duration_secs
andduration_nsecs
define the effect duration.
Firstly, we initialise the object representing the LEDs effect to be sent to the action server for execution.
181goal = DoTimedLedEffectGoal()
Then, we set the devices that will execute the fixed-colour effect.
182goal.devices = devices
As previously seen, we have to specify through
the goal.params.effectType
parameter
which LEDs effect goal
is meant for.
We set the fixed-colour red, green, blue and alpha parameters.
186goal.params.fixed_color.color.r = r
187goal.params.fixed_color.color.g = g
188goal.params.fixed_color.color.b = b
189goal.params.fixed_color.color.a = a
The last step missing before sending goal
to the action server is setting the time duration and
effect priority.
Warning
This being a demo, we will set the priority to the maximum possible value. We invite you to properly set the priority when using LEDs in your custom applications.
192goal.effectDuration.secs = duration_secs
193goal.effectDuration.nsecs = duration_nsecs
194goal.priority = MAX_PRIORITY
At this point, we can send the goal
object
to the action server, using client
. The LEDs
devices previously specified will execute
the effect immediately if no other LEDs effect
with MAX_PRIORITY
is being performed;
if this is not the case, then the effect
will queue while waiting that all the previous
queued effects with MAX_PRIORITY
will have been performed.
196client.send_goal(goal)
The last effect we will show through this tutorial is the blinking effect. This effects requires us to specify two colours and their duration; the LEDs executing this effect will alternate the two colours according to their duration. The effect will be performed for a specific effect duration, which is a parameter we have already seen through this tutorial. Let’s see how we implemented the function setting the parameters and sending the effect to the LEDs action server.
199def show_blinking_color(client,
200 devices,
201 r1,
202 g1,
203 b1,
204 a1,
205 duration_secs1,
206 duration_nsecs1,
207 r2,
208 g2,
209 b2,
210 a2,
211 duration_secs2,
212 duration_nsecs2,
213 duration_secs,
214 duration_nsecs = 0)
This function requires 16 parameters:
client
is the object used to manage the client-server communication with the robot’s LEDs action server.devices
is the list of LEDs devices that will perform the effect.r1, g1, b1, a1
are respectively the red, green, blue and alpha parameters of the first blinking colour.duration_secs1
andduration_nsecs1
define the first colour duration.r2, g2, b2, a2
are respectively the red, green, blue and alpha parameters of the second blinking colour.duration_secs2
andduration_nsecs2
define the second colour duration.duration_secs
andduration_nsecs
define the overall effect duration.
Firstly, we initialise the object representing the LEDs effect to be sent to the action server for execution.
221goal = DoTimedLedEffectGoal()
Then, we set the devices that will execute the blinking effect.
222goal.devices = devices
As previously seen, we have to specify through
the goal.params.effectType
parameter
which LEDs effect goal
is meant for.
223goal.params.effectType = LedEffectParams.BLINK
We can now start setting the effect-specific parameters. We initialise the first blinking colour red, green, blue and alpha values according to the function arguments.
226goal.params.blink.first_color.r = r1
227goal.params.blink.first_color.g = g1
228goal.params.blink.first_color.b = b1
229goal.params.blink.first_color.a = a1
The blinking colours also require a duration.
232goal.params.blink.first_color_duration.secs = duration_secs1
233goal.params.blink.first_color_duration.nsecs = duration_nsecs1
We repeat the same procedure for the second blinking colour.
236goal.params.blink.second_color.r = r2
237goal.params.blink.second_color.g = g2
238goal.params.blink.second_color.b = b2
239goal.params.blink.second_color.a = a1
240
241# Setting the second colour duration
242goal.params.blink.second_color_duration.secs = duration_secs2
243goal.params.blink.second_color_duration.nsecs = duration_nsecs2
The last step missing before sending goal
to the action server is setting the time duration and
effect priority.
Warning
This being a demo, we will set the priority to the maximum possible value. We invite you to properly set the priority when using LEDs in your custom applications.
246goal.effectDuration.secs = duration_secs
247goal.effectDuration.nsecs = duration_nsecs
248goal.priority = MAX_PRIORITY
At this point, we can send the goal
object
to the action server, using client
. The LEDs
devices previously specified will execute
the effect immediately if no other LEDs effect
with MAX_PRIORITY
is being performed;
if this is not the case, then the effect
will queue while waiting that all the previous
queued effects with MAX_PRIORITY
will have been performed.
250client.send_goal(goal)
Before checking the tutorial’s __main__
,
we will illustrate one more support function:
send_tts
. This will manage comunication
with the robot’s TTS action server, sending
it sentences that the robot should pronounce.
252def send_tts(client,
253 text,
254 language = "en_GB",
255 blocking = False)
This function has 4 parameters:
client
is the object used to manage the client-server communication with the robot’s TTS action server.text
is the requested sentence.language
is the language that the robot will use to pronounce the sentence.blocking
specifies whether the function execution should be blocking (that is, waiting for the action execution or failure) or not.
As we have already seen in other functions
involving action servers, the first thing we
do is initialising a goal
. In this
case, it will be a TtsGoal
object.
263goal = TtsGoal()
Then, we set the goal
parameters
related to the text to pronounce and the
language to use.
265goal.rawtext.text = text
266goal.rawtext.lang_id = "en_GB"
Now we are ready to send goal
to the
action server. The different function
used for this depends on whether the blocking
flag is set or not.
268if blocking:
269 client.send_goal_and_wait(goal)
270else:
271 client.send_goal(goal)
At this point, we have defined all the functions
required for this tutorial. In __main__
,
we can find an example of how the functions above
might be used to enhance PAL’s robots’s expressivity.
First things first, we initialise the ROS node and the structures to communicate with the LEDs and TTS action servers:
326if __name__=='__main__'
327 try:
328 # Initialising the ROS node
329 rospy.init_node('expressive_leds')
330
331 # Initialising the two action clients objects
332 # requested during the node execution
333 led_client, tts_client = init_clients()
We ask PAL’s robots to introduce who is watching to
the tutorial. In this case, we are setting the
blocking
flag as we do not want PAL’s robots
to proceed with any other tutorial-related
operation as long as it has not finished the
introduction.
281send_tts(tts_client,
282 "Welcome to the expressive leds tutorial!",
283 blocking = True)
Now, the proper demo can start. The plot is:
PAL’s robots starts downloading some very important files. During the process, PAL’s robots shows the progression status using the progress effect on the back LEDs.
Once PAL’s robots finishes downloading the files, it will show how happy it is about it by executing the rainbow effect with the LEDs on the head and the back.
Suddenly, PAL’s robots notices that something might be wrong with the very important files downloaded. The robot sets its LEDs to red using the fixed colour effect.
It comes out that the very important files downloaded were not the right ones! PAL’s robots LEDs will start blinking using red and yellow, to attract someone’s attention as it needs help.
Let’s go step by step through the functions reproducing
the storyline above. In step 1, we use the
previously defined function show_progress
for the LEDs effect, while using a blocking
send_tts
to introduce the dowloading
operations.
288send_tts(tts_client,
289 "I will now start loading some very important files!\
290 Check my back leds to see what is the progression status.",
291 blocking = True)
292show_progress(led_client,
293 [BACK])
In step 2, we send a non-blocking TTS request PAL’s robots is expressing how happy it is for having completed the previous process. To request the rainbow effect, we use the function specifically defined before.
298send_tts(tts_client,
299 "Yes, I made it! Task completed!")
300rospy.loginfo("yes, I made it! Task completed! :)")
301show_rainbow(led_client,
302 [BACK, LEFT_EAR, RIGHT_EAR],
303 1,
304 10)
In step 3, we send a non-blocking
TTS request and a fixed colour LEDs
effect request to express concern
regarding the downloaded files. The
r, g, b, a
parameters are such
to display the red colour.
308rospy.loginfo("OH NO! Something is going wrong!")
309send_tts(tts_client,
310 "Oh no! Something might be wrong with these files!")
311show_fixed_color(led_client,
312 [BACK, LEFT_EAR, RIGHT_EAR, RESPEAKER],
313 r=1,
314 g=0,
315 b=0,
316 a=1,
317 duration_secs=10)
In step 4, we send a non-blocking TTS request
and we request a red-and-yellow blinking effect
for PAL’s robots leds to attract people’s attention,
as the robot needs help. The
r1, g1, b1, a1
parameters are such
to display the red colour.
The r2, g2, b2, a2
parameters are such
to display the yellow colour.
323 rospy.loginfo("Please, help me!"+\
324 "These were not the very important files I needed!")
325send_tts(tts_client,
326 "Please, help me!\
327 These were not the very important files I needed!")
328show_blinking_color(led_client,
329 [BACK, LEFT_EAR, RIGHT_EAR],
330 r1=1,
331 g1=0,
332 b1=0,
333 a1=1,
334 duration_secs1=1,
335 duration_nsecs1=0,
336 r2=1,
337 g2=1,
338 b2=0,
339 a2=1,
340 duration_secs2=1,
341 duration_nsecs2=0,
342 duration_nsecs=200000000,
343 duration_secs=20
344 )
Next steps#
The node you have developed only includes some of the effects that PAL’s robots’s’ LEDs can perform. We invite you to explore more of these effects, playing with them for a deeper understanding of how LEDs can enhance the robot’s expressiveness.
If you want to know more about expressiveness in PAL’s robots, check Getting started with ARI - Combine voice, gesture and eyes.