normalsTool.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, Braun Kai, Heizmann Heinrich, Heller Florian, Mehlhaus Jonas, Meissner Pascal, Schleicher Ralf, Stoeckle Patrick, Walter Milena
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 '''
20 
21 import sys
22 import math
23 import rospy
24 from visualization_msgs.msg import MarkerArray
25 from visualization_msgs.msg import Marker
26 from geometry_msgs.msg import Point
27 from rosparam import upload_params
28 from yaml import load
29 import rospkg
30 import colorsys
31 
32 def multiply_matrix(matrix_1,matrix_2):
33 
34  result_matrix = []
35  if len(matrix_1[0]) != len(matrix_2):
36  print "Invalid Matrix"
37  return False
38  for i in range(len(matrix_1)):
39  line = []
40  for j in range(len(matrix_2[0])):
41  element = 0
42  for k in range(len(matrix_1[0])):
43  element = element + matrix_1[i][k] * matrix_2[k][j]
44  line.append(element)
45  result_matrix.append(line)
46  return result_matrix
47 
48 def matrix_vector_mult(matrix,vector):
49  result_vect = []
50  for mat in matrix:
51  result_vect.append(mat[0]*vector[0]+mat[1]*vector[1]+mat[2]*vector[2])
52  return result_vect
53 
54 
55 def get_rotation_matrix(angle_x, angle_y, angle_z):
56  rotation_matrix_x = []
57  rotation_matrix_x.append([1,0,0])
58  rotation_matrix_x.append([0,math.cos(angle_x),-math.sin(angle_x)])
59  rotation_matrix_x.append([0,math.sin(angle_x),math.cos(angle_x)])
60 
61  rotation_matrix_y = []
62  rotation_matrix_y.append([math.cos(angle_y),0,math.sin(angle_y)])
63  rotation_matrix_y.append([0,1,0])
64  rotation_matrix_y.append([-math.sin(angle_y),0,math.cos(angle_y)])
65 
66  rotation_matrix_z = []
67  rotation_matrix_z.append([math.cos(angle_z),-math.sin(angle_z),0])
68  rotation_matrix_z.append([math.sin(angle_z),math.cos(angle_z),0])
69  rotation_matrix_z.append([0,0,1])
70 
71  return multiply_matrix(rotation_matrix_z,multiply_matrix(rotation_matrix_y,rotation_matrix_x))
72 
73 def xyz_to_sph(x, y, z):
74  r = math.sqrt(x**2 + y**2 + z**2)
75  elev = math.acos(z / r)
76  az = math.atan2(y,x)
77  return r, elev, az
78 
79 def sph_to_xyz(r, elev, az):
80  x = r * math.sin(elev) * math.cos(az)
81  y = r * math.sin(elev) * math.sin(az)
82  z = r * math.cos(elev)
83  return x, y, z
84 
85 def add_angles_to_sph(sph, d_elev, d_az):
86  r = sph[0]
87  elev = sph[1] + d_elev
88  az = sph[2] + d_az
89  return r, elev, az
90 
92  norm = math.sqrt(vec[0]**2 + vec[1]**2 + vec[2]**2)
93  if (norm != 0):
94  return vec[0] / norm, vec[1] / norm, vec[2] / norm
95  else:
96  return vec
97 
99  x = float("{0:.5f}".format(vec[0]))
100  y = float("{0:.5f}".format(vec[1]))
101  z = float("{0:.5f}".format(vec[2]))
102  return x, y, z
103 
104 if __name__ == "__main__":
105  rospy.init_node('normal_generator_tool', anonymous=True)
106  rospack = rospkg.RosPack()
107 
108  #Read the parameters from the configuration file
109  f = open(rospack.get_path('asr_object_database') + '/src/normal_generator_tool/normalsToolParams.yaml', 'r')
110  yamlfile = load(f)
111  f.close()
112  upload_params('/', yamlfile)
113 
114  marker_frame = rospy.get_param('marker_frame')
115  pub_topic = rospy.get_param('pub_topic')
116  output_rel_path = rospy.get_param('output_rel_path')
117  base_vectors = rospy.get_param('base_vectors')
118  pan_min = rospy.get_param('pan')[0]
119  pan_max = rospy.get_param('pan')[1]
120  tilt_min = rospy.get_param('tilt')[0]
121  tilt_max = rospy.get_param('tilt')[1]
122  d_x = rospy.get_param('d_pan')
123  d_y = rospy.get_param('d_tilt')
124  publish_rate = rospy.get_param('publish_rate')
125 
126  publisher = rospy.Publisher(pub_topic, MarkerArray, queue_size=10)
127 
128  #Use those Rotations to rotate the input vectors from the zx-plane to the xy-plane for the creation of the additional normal vectors
129  # (to match the orientation of the object meshes)
130  an_x = 90.0*math.pi/180
131  rot_mat = get_rotation_matrix(an_x, 0.0, 0.0)
132  rot_mat_trans = get_rotation_matrix(-an_x, 0.0, 0.0)
133 
134  #Create the normals
135  normals = []
136  for base_vec in base_vectors:
137  base_vec = normalize_vector(base_vec)
138  base_vec = matrix_vector_mult(rot_mat, base_vec)
139  sp = xyz_to_sph(base_vec[0], base_vec[1], base_vec[2])
140  for pan_curr in range(pan_min, pan_max + 1, d_x):
141  for tilt_curr in range(tilt_min, tilt_max + 1, d_y):
142  d_az = pan_curr*math.pi/180
143  d_elev = tilt_curr*math.pi/180
144  new_sp = add_angles_to_sph(sp, d_elev, d_az)
145  new_normal = sph_to_xyz(new_sp[0], new_sp[1], new_sp[2])
146  result_normal = matrix_vector_mult(rot_mat_trans, new_normal)
147  normals.append(round_vector_elements(result_normal))
148 
149 
150  #Write the created normals to a file
151  output_string = ""
152  for normal in normals:
153  for idx,nor in enumerate(normal):
154  if idx < 2:
155  output_string += str(nor) + ","
156  else:
157  output_string += str(nor)
158  output_string += ";"
159 
160  print 'Created normals:'
161  print output_string
162  print '--------------------'
163 
164  fh = open(rospack.get_path('asr_object_database') + output_rel_path, 'w')
165  fh.writelines(output_string)
166  fh.close()
167 
168  #Create a marker array from the created normals
169  markerArray = MarkerArray()
170  marker_id = 0
171  size_vec = len(base_vectors)
172  color_step = 1
173  if size_vec > 0:
174  color_step = 1.0 / size_vec
175 
176  for normal in normals:
177  hue = (marker_id / (len(normals) / size_vec)) * color_step + 0.0
178  rgb = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
179 
180  marker = Marker()
181  marker.id = marker_id
182  marker.header.frame_id = marker_frame
183  marker.ns = 'normals'
184  marker.scale.x = 0.01
185  marker.scale.y = 0.1
186  marker.scale.z = 0.1
187  marker.color.r = rgb[0]
188  marker.color.g = rgb[1]
189  marker.color.b = rgb[2]
190  marker.color.a = 1.0
191 
192  point_start = Point()
193  point_end = Point()
194  point_end.x = normal[0]
195  point_end.y = normal[1]
196  point_end.z = normal[2]
197  marker.points.append(point_start)
198  marker.points.append(point_end)
199 
200  marker.type = marker.ARROW
201  markerArray.markers.append(marker)
202 
203  marker_id = marker_id +1
204 
205  #Publish the normal markers
206  print 'Publishing normals (Rate: ' + str(publish_rate) + ' Hz)'
207  rate = rospy.Rate(publish_rate)
208  while not rospy.is_shutdown():
209  publisher.publish(markerArray)
210  rate.sleep()
def normalize_vector(vec)
Definition: normalsTool.py:91
def round_vector_elements(vec)
Definition: normalsTool.py:98
def get_rotation_matrix(angle_x, angle_y, angle_z)
Definition: normalsTool.py:55
def matrix_vector_mult(matrix, vector)
Definition: normalsTool.py:48
def multiply_matrix(matrix_1, matrix_2)
Definition: normalsTool.py:32
def xyz_to_sph(x, y, z)
Definition: normalsTool.py:73
def add_angles_to_sph(sph, d_elev, d_az)
Definition: normalsTool.py:85
def sph_to_xyz(r, elev, az)
Definition: normalsTool.py:79


asr_object_database
Author(s): Allgeyer Tobias, Aumann Florian, Borella Jocelyn, Braun Kai, Heizmann Heinrich, Heller Florian, Kasper Alexander, Marek Felix, Mehlhaus Jonas, Meißner Pascal, Schleicher Ralf, Stöckle Patrick, Walter Milena
autogenerated on Mon Feb 28 2022 21:49:21