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 Wed Jan 8 2020 03:12:13