localization.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 __author__ = 'lsouchet'
3 
4 
5 # Copyright (C) 2014 Aldebaran Robotics
6 #
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
10 #
11 # http://www.apache.org/licenses/LICENSE-2.0
12 #
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
18 #
19 
20 #import ROS dependencies
21 import rospy
22 from geometry_msgs.msg import Point32
23 from visualization_msgs.msg import Marker
24 from geometry_msgs.msg import PoseStamped
25 from nav_msgs.msg import Path
26 
27 #import NAO dependencies
28 from naoqi_driver.naoqi_node import NaoqiNode
29 from geometry_msgs.msg import PoseArray
30 from geometry_msgs.msg import Pose
31 from geometry_msgs.msg import Point
32 from geometry_msgs.msg import Quaternion
33 from tf2_msgs.msg import TFMessage
34 from geometry_msgs.msg import TransformStamped
35 from geometry_msgs.msg import Vector3
36 from sensor_msgs.msg import LaserScan
37 from std_msgs.msg import ColorRGBA
38 from nav_msgs.msg import OccupancyGrid
39 import almath
40 
42 
43  def __init__(self):
44  NaoqiNode.__init__(self, 'naoqi_localization')
45  self.navigation = None
46  self.connectNaoQi()
47  self.publishers = {}
48  self.publishers["uncertainty"] = rospy.Publisher('localization_uncertainty', Marker)
49  self.publishers["map_tf"] = rospy.Publisher('/tf', TFMessage, latch=True)
50  self.publishers["map"] = rospy.Publisher('naoqi_exploration_map', OccupancyGrid , queue_size=None)
51  self.publishers["exploration_path"] = rospy.Publisher('naoqi_exploration_path', Path, queue_size=None)
52  self.frequency = 2
53  self.rate = rospy.Rate(self.frequency)
54 
55  # (re-) connect to NaoQI:
56  def connectNaoQi(self):
57  rospy.loginfo("Exploration Node Connecting to NaoQi at %s:%d", self.pip, self.pport)
58 
59  self.navigation = self.get_proxy("ALNavigation")
60  self.motion = self.get_proxy("ALMotion")
61  if self.navigation is None or self.motion is None:
62  rospy.logerr("Unable to reach ALMotion and ALNavigation.")
63  exit(0)
64  version_array = self.get_proxy("ALSystem").systemVersion().split('.')
65  if len(version_array) < 3:
66  rospy.logerr("Unable to deduce the system version.")
67  exit(0)
68  version_tuple = (int(version_array[0]), int(version_array[1]), int(version_array[2]))
69  min_version = (2, 5, 2)
70  if version_tuple < min_version:
71  rospy.logerr("Naoqi version " + str(min_version) + " required for localization. Yours is " + str(version_tuple))
72  exit(0)
73 
74 
75  def get_ros_quaternion(self, almath_quaternion):
76  output = Quaternion()
77  output.w = almath_quaternion.w
78  output.x = almath_quaternion.x
79  output.y = almath_quaternion.y
80  output.z = almath_quaternion.z
81  return output
82 
83  def get_navigation_tf(self, navigation_pose):
84  navigation_tf = TransformStamped()
85  navigation_tf.header.frame_id = "/map"
86  navigation_tf.header.stamp = rospy.Time.now()
87  navigation_tf.child_frame_id = "/odom"
88  navigation_tf.transform.translation .x = navigation_pose.x
89  navigation_tf.transform.translation .y = navigation_pose.y
90  navigation_tf.transform.rotation = self.get_ros_quaternion(
91  almath.Quaternion_fromAngleAndAxisRotation(navigation_pose.theta, 0, 0, 1))
92  return navigation_tf
93 
94  def build_laser_scan(self, ranges):
95  result = LaserScan()
96  result.header.stamp = rospy.Time.now()
97  result.angle_min = -almath.PI
98  result.angle_max = almath.PI
99  if len(ranges[1]) > 0:
100  result.angle_increment = (result.angle_max - result.angle_min) / len(ranges[1])
101  result.range_min = 0.0
102  result.range_max = ranges[0]
103  for range_it in ranges[1]:
104  result.ranges.append(range_it[1])
105  return result
106 
107  # do it!
108  def run(self):
109  while self.is_looping():
110  navigation_tf_msg = TFMessage()
111  try:
112  motion_to_robot = almath.Pose2D(self.motion.getRobotPosition(True))
113  localization = self.navigation.getRobotPositionInMap()
114  exploration_path = self.navigation.getExplorationPath()
115  except Exception as e:
116  navigation_tf_msg.transforms.append(self.get_navigation_tf(almath.Pose2D()))
117  self.publishers["map_tf"].publish(navigation_tf_msg)
118  self.rate.sleep()
119  continue
120  if len(localization) > 0 and len(localization[0]) == 3:
121  navigation_to_robot = almath.Pose2D(localization[0][0], localization[0][1], localization[0][2])
122  navigation_to_motion = navigation_to_robot * almath.pinv(motion_to_robot)
123  navigation_tf_msg.transforms.append(self.get_navigation_tf(navigation_to_motion))
124  self.publishers["map_tf"].publish(navigation_tf_msg)
125  if len(localization) > 0:
126  if self.publishers["uncertainty"].get_num_connections() > 0:
127  uncertainty = Marker()
128  uncertainty.header.frame_id = "/base_footprint"
129  uncertainty.header.stamp = rospy.Time.now()
130  uncertainty.type = Marker.CYLINDER
131  uncertainty.scale = Vector3(localization[1][0], localization[1][1], 0.2)
132  uncertainty.pose.position = Point(0, 0, 0)
133  uncertainty.pose.orientation = self.get_ros_quaternion(
134  almath.Quaternion_fromAngleAndAxisRotation(0, 0, 0, 1))
135  uncertainty.color = ColorRGBA(1, 0.5, 0.5, 0.5)
136  self.publishers["uncertainty"].publish(uncertainty)
137  if self.publishers["map"].get_num_connections() > 0:
138  aggregated_map = None
139  try:
140  aggregated_map = self.navigation.getMetricalMap()
141  except Exception as e:
142  print("error " + str(e))
143  if aggregated_map is not None:
144  map_marker = OccupancyGrid()
145  map_marker.header.stamp = rospy.Time.now()
146  map_marker.header.frame_id = "/map"
147  map_marker.info.resolution = aggregated_map[0]
148  map_marker.info.width = aggregated_map[1]
149  map_marker.info.height = aggregated_map[2]
150  map_marker.info.origin.orientation = self.get_ros_quaternion(
151  almath.Quaternion_fromAngleAndAxisRotation(-1.57, 0, 0, 1))
152  map_marker.info.origin.position.x = aggregated_map[3][0]
153  map_marker.info.origin.position.y = aggregated_map[3][1]
154  map_marker.data = aggregated_map[4]
155  self.publishers["map"].publish(map_marker)
156  if self.publishers["exploration_path"].get_num_connections() > 0:
157  path = Path()
158  path.header.stamp = rospy.Time.now()
159  path.header.frame_id = "/map"
160  for node in exploration_path:
161  current_node = PoseStamped()
162  current_node.pose.position.x = node[0]
163  current_node.pose.position.y = node[1]
164  path.poses.append(current_node)
165  self.publishers["exploration_path"].publish(path)
166  self.rate.sleep()
167 
168 if __name__ == '__main__':
170  pub.start()
171 
172  rospy.spin()
173  exit(0)
def get_ros_quaternion(self, almath_quaternion)
Definition: localization.py:75
def get_navigation_tf(self, navigation_pose)
Definition: localization.py:83
def build_laser_scan(self, ranges)
Definition: localization.py:94
def get_proxy(self, name, warn=True)


python
Author(s):
autogenerated on Thu Jul 16 2020 03:18:36