state_acquisition.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 '''
4 Copyright (c) 2016, Allgeyer Tobias, Aumann Florian, Borella Jocelyn, Hutmacher Robin, Karrenbauer Oliver, Marek Felix, Meissner Pascal, Trautmann Jeremias, Wittenbeck Valerij
5 
6 All rights reserved.
7 
8 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17 '''
18 
19 import roslib
20 import rospy
21 import smach
22 import smach_ros
23 import numpy
24 from time import time
25 import math
26 
27 from geometry_msgs.msg import (Pose, Point, Quaternion)
28 from asr_next_best_view.msg import RobotStateMessage
29 from asr_robot_model_services.srv import GetPose
30 from sensor_msgs.msg import JointState
31 import tf
32 import tf2_ros
33 
34 """
35 Methods that are required for calculating and comparing the poses and states related to our robot during exploration.
36 """
37 
38 """
39 Accessing tf via c++ since python access is not reliable.
40 """
42  """
43  Returns camera pose
44  """
45  rospy.wait_for_service('/asr_robot_model_services/GetCameraPose', timeout=5)
46  pose = rospy.ServiceProxy('/asr_robot_model_services/GetCameraPose',GetPose)
47  return pose().pose
48 
49 """
50 Old helper for python interface. Might be still used, know wraps c++ interface.
51 """
53  """
54  Returns current camera pose
55  """
56  return get_camera_pose_cpp()
57  # tf2 is used since tf had some strange behaviour.
58  # If there are still errors in this place, look deeper in the ptu driver
59  # since the tf problem is happening there.
60  #tfBuffer = tf2_ros.Buffer()
61  #listener = tf2_ros.TransformListener(tfBuffer)
62 
63  #rospy.sleep(1.0)
64  #try:
65  # trans = tfBuffer.lookup_transform("map", "ptu_mount_link", rospy.Time(0),
66  # rospy.Duration(2))
67  # return Pose(trans.transform.translation,
68  # trans.transform.rotation)
69 
70  #except Exception, e:
71  # rospy.logwarn("Couldn't get Camera pose from tf2")
72  # rospy.logwarn(e)
73 
74 """
75 Accessing tf via c++ since python access is not reliable.
76 """
78  """
79  Returns robot pose
80  """
81  rospy.wait_for_service('/asr_robot_model_services/GetRobotPose', timeout=5)
82  pose = rospy.ServiceProxy('/asr_robot_model_services/GetRobotPose',GetPose)
83  return pose().pose
84 
85 """
86 Old helper for python interface. Might be still used, know wraps c++ interface.
87 """
89  """
90  Returns robot pose
91  """
92  return get_robot_pose_cpp()
93  #listener = tf.TransformListener()
94  #listener.waitForTransform("/map", "/base_link", rospy.Time(0), rospy.Duration(4.0))
95  #try:
96 
105 
107  """
108  Returns the rotation in degrees from pose
109  """
110  pose.position.x = pose.position.x
111  pose.position.y = pose.position.y
112  pose.position.z = 0
113  q = numpy.array([
114  pose.orientation.x,
115  pose.orientation.y,
116  pose.orientation.z,
117  pose.orientation.w])
118  (_, _, yaw) = tf.transformations.euler_from_quaternion(q)
119  return yaw
120 
121 class GetRobotState(smach.State):
122 
123  ptu = None
124 
125  def __init__(self):
126  pass
127 
128  def ptu_callback(self, data):
129  self.ptu = data.position
130 
131  def get_robot_state(self):
132  """
133  Returns the current robot configuration consisting of position and ptu
134  angles
135  """
136 
137  sub_ptu = rospy.Subscriber('/asr_flir_ptu_driver/state', JointState, self.ptu_callback)
138 
139  future = time() + 2
140  while not self.ptu and time() < future:
141  pass
142 
143  rospy.sleep(2)
144  if not self.ptu:
145  self.ptu = [0,0]
146 
147  pose = get_robot_pose_cpp()
148 
149  robot_state = RobotStateMessage()
150  robot_state.pan = self.ptu[0]
151  robot_state.tilt = self.ptu[1]
152  robot_state.x = pose.position.x
153  robot_state.y = pose.position.y
154  robot_state.rotation = get_rotation_from_pose(pose)
155 
156  return robot_state
157 
158 def approx_equal_robot_state(old_robot_pose, old_tilt, new_robot_pose, new_tilt, positionThreshold, orientationThreshold, tiltThreshold):
159  """
160  Checks if two robot states are approximately equal, i.e. disctance of all values are under
161  a threshold.
162  """
163 
164  if not old_robot_pose or not old_tilt or not new_robot_pose or not new_tilt: return False
165 
166  positionDiff = euclidean_distance_3d(old_robot_pose.position, new_robot_pose.position)
167  orientationDiffInDegree = angle_between_quaternions(old_robot_pose.orientation, new_robot_pose.orientation)
168  tiltDiff = abs(old_tilt - new_tilt)
169 
170  if abs(positionDiff) < positionThreshold and abs(orientationDiffInDegree) < orientationThreshold and tiltDiff < tiltThreshold:
171  rospy.loginfo("Two robot states are approx equale.")
172 # rospy.loginfo("old_robot_pose:\n" + str(old_robot_pose))
173 # rospy.loginfo("new_robot_pose:\n" + str(new_robot_pose))
174 # rospy.loginfo("Difference positionDiff: " + str(positionDiff))
175 # rospy.loginfo("Difference orientationDiffInDegree: " + str(orientationDiffInDegree))
176 # rospy.loginfo("Difference tilfDiff: " + str(tiltDiff))
177  return True
178 
179  return False
180 
181 def approx_equal_pose(old_pose, new_pose, threshold):
182  """
183  Checks if two poses are approximately equal, i.e. sum of all values is under
184  a specified threshold.
185  """
186 
187  if not old_pose or not new_pose: return False
188 
189  diff = euclidean_distance_3d(old_pose.position, new_pose.position) + \
190  angle_between_quaternions(old_pose.orientation, new_pose.orientation)
191  rospy.loginfo("Difference poses: " + str(diff))
192  return diff < threshold
193 
194 
195 def euclidean_distance_3d(position1, position2):
196  return math.sqrt(
197  pow(position1.x - position2.x, 2) + \
198  pow(position1.y - position2.y, 2) + \
199  pow(position1.z - position2.z, 2))
200 
201 def angle_between_quaternions(quaternion1, quaternion2):
202  quaternionList1 = quaternion_to_list(quaternion1)
203  quaternionList2 = quaternion_to_list(quaternion2)
204  # convert quaternions to vectors
205  vector1 = get_vector(quaternionList1)
206  vector2 = get_vector(quaternionList2)
207 
208  return angle_between_vectors(vector1, vector2)
209 
210 
211 def angle_between_vectors(vector1, vector2):
212  if numpy.linalg.norm(vector1) * numpy.linalg.norm(vector2) <= 0.00001:
213  return 0.0
214 
215  cosOfAngle = numpy.dot(vector1, vector2) / (numpy.linalg.norm(vector1) * \
216  numpy.linalg.norm(vector2))
217 
218  if cosOfAngle < -1.0: cosOfAngle = -1.0
219  if cosOfAngle > 1.0: cosOfAngle = 1.0
220 
221  rad = math.acos(cosOfAngle)
222 
223  return math.degrees(rad)
224 
225 
226 def get_vector(quaternion):
227  q = [1, 0, 0, 0]
228  return tf.transformations.quaternion_multiply(
229  tf.transformations.quaternion_multiply(quaternion, q),
230  tf.transformations.quaternion_conjugate(quaternion)
231  )[:3]
232 
233 
234 def quaternion_to_list(quaternion):
235  return [quaternion.x, quaternion.y, quaternion.z, quaternion.w]
236 
def approx_equal_robot_state(old_robot_pose, old_tilt, new_robot_pose, new_tilt, positionThreshold, orientationThreshold, tiltThreshold)
def approx_equal_pose(old_pose, new_pose, threshold)
def euclidean_distance_3d(position1, position2)
def angle_between_quaternions(quaternion1, quaternion2)
def angle_between_vectors(vector1, vector2)


asr_state_machine
Author(s): Allgeyer Tobias, Aumann Florian, Borella Jocelyn, Hutmacher Robin, Karrenbauer Oliver, Marek Felix, Meißner Pascal, Trautmann Jeremias, Wittenbeck Valerij
autogenerated on Mon Feb 28 2022 21:53:50