nao_leds.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #
4 # ROS node to control NAO's LEDs using NaoQI
5 # Tested with NaoQI: 1.12
6 #
7 # Copyright (c) 2012, 2013 Miguel Sarabia
8 # Imperial College London
9 #
10 # Redistribution and use in source and binary forms, with or without
11 # modification, are permitted provided that the following conditions are met:
12 #
13 # # Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 # # Redistributions in binary form must reproduce the above copyright
16 # notice, this list of conditions and the following disclaimer in the
17 # documentation and/or other materials provided with the distribution.
18 # # Neither the name of the Imperial College London nor the names of its
19 # contributors may be used to endorse or promote products derived from
20 # this software without specific prior written permission.
21 #
22 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 #
34 
35 
36 import rospy
37 import actionlib
38 import random
39 import copy
40 
41 from naoqi_driver.naoqi_node import NaoqiNode
42 
43 from naoqi_bridge_msgs.msg import(
44  BlinkAction,
45  BlinkResult,
46  BlinkFeedback,
47  FadeRGB
48  )
49 
51  #This should be treated as a constant
52  NODE_NAME = "nao_leds"
53 
54  def __init__( self ):
55 
56  #Initialisation
57  NaoqiNode.__init__( self, self.NODE_NAME )
58 
59  #Proxy to interface with LEDs
60  self.proxy = self.get_proxy( "ALLeds" )
61 
62  #Seed python's random number generator
63  random.seed( rospy.Time.now().to_nsec() )
64 
65  #Create a subscriber for the fade_rgb topic
66  self.subscriber = rospy.Subscriber(
67  "fade_rgb",
68  FadeRGB,
69  self.fade_rgb)
70 
71  #Prepare and start actionlib server
73  "blink",
74  BlinkAction,
75  self.run_blink,
76  False
77  )
78  self.actionlib.start()
79 
80  def fade_rgb(self, request) :
81  hexColor = int(
82  int(request.color.r*255) << 16 |
83  int(request.color.g*255) << 8 |
84  int(request.color.b*255)
85  )
86 
87  self.proxy.fadeRGB(
88  request.led_name,
89  hexColor,
90  request.fade_duration.to_sec()
91  )
92 
93  def run_blink( self, request ):
94  #Note that this function is executed on a different thread
95 
96  third_of_duration = request.blink_duration / 3.0
97 
98  #Prepare background message
99  bg_msg = FadeRGB();
100  bg_msg.led_name = "FaceLeds"
101  bg_msg.color = request.bg_color
102  bg_msg.fade_duration = third_of_duration
103 
104  #Prepare a copy for blink_msg
105  blink_msg = copy.deepcopy( bg_msg )
106 
107  #Construct result and feedback
108  feedback = BlinkFeedback()
109  result = BlinkResult()
110  result.still_blinking = False
111 
112  #Check valid parameters
113  bad_request = False
114  reason = ""
115  if not request.colors:
116  bad_request = True
117  reason = "No colors to blink were specified"
118  elif request.blink_duration.to_sec() <= 0.0:
119  bad_request = True
120  reason = "Blink duration cannot be 0"
121  elif request.blink_rate_mean <= 0.0 or request.blink_rate_sd <= 0.0:
122  bad_request = True
123  reason = "Invalid parameter for blink rate"
124 
125  if bad_request:
126  rospy.logwarn("Bad Blink request: {}".format(reason))
127  self.actionlib.set_aborted(result, reason)
128  return
129 
130  #Sleep time is drawn from a gaussian dist with these parameters
131  sleep_mean = request.blink_rate_mean
132  sleep_sd = request.blink_rate_sd
133  max_sleep_time = sleep_mean + 3* sleep_sd #This is highly unlikely
134 
135  #Main blinking loop
136  while ( not self.actionlib.is_preempt_requested() and
137  not rospy.is_shutdown() ) :
138 
139  #Chose a blinking color at random
140  blink_msg.color = random.choice( request.colors )
141 
142  #Send command (takes 1/3 duration to fade)
143  self.fade_rgb( blink_msg )
144  #Sleep (takes 1/3 duration)
145  rospy.sleep( third_of_duration )
146  #Fade to background (takes another 1/3 duration)
147  self.fade_rgb( bg_msg )
148 
149  #Publish feedback
150  feedback.last_color = blink_msg.color
151  self.actionlib.publish_feedback( feedback )
152 
153  #Sleep for a random amount of time
154  sleep_time = random.gauss( sleep_mean, sleep_sd )
155 
156  if sleep_time < 0:
157  sleep_time = 0
158  elif sleep_time > max_sleep_time :
159  sleep_time = max_sleep_time
160 
161  rospy.sleep( sleep_time )
162 
163  #If we were pre-empted by other request, make sure result shows this
164  if self.actionlib.is_new_goal_available() :
165  result.still_blinking = True
166 
167  # Task never completes so if we reach here, blink has been pre-empted
168  self.actionlib.set_preempted( result )
169 
170 if __name__ == '__main__':
171  node = NaoLeds()
172  rospy.loginfo( node.NODE_NAME + " running..." )
173  rospy.spin()
174  rospy.loginfo( node.NODE_NAME + " stopped." )
175  exit(0)
string NODE_NAME
Definition: nao_leds.py:52
def fade_rgb(self, request)
Definition: nao_leds.py:80
def run_blink(self, request)
Definition: nao_leds.py:93
def __init__(self)
Definition: nao_leds.py:54
def get_proxy(self, name, warn=True)


nao_apps
Author(s):
autogenerated on Mon Jun 10 2019 14:04:55