normalsTool.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 '''
00004 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
00005 
00006 This program is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License along
00017 with this program; if not, write to the Free Software Foundation, Inc.,
00018 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019 '''
00020 
00021 import sys
00022 import math
00023 import rospy
00024 from visualization_msgs.msg import MarkerArray
00025 from visualization_msgs.msg import Marker
00026 from geometry_msgs.msg import Point
00027 from rosparam import upload_params
00028 from yaml import load
00029 import rospkg
00030 import colorsys
00031 
00032 def multiply_matrix(matrix_1,matrix_2):
00033 
00034     result_matrix = []
00035     if len(matrix_1[0]) != len(matrix_2):
00036         print "Invalid Matrix"
00037         return False
00038     for i in range(len(matrix_1)):
00039         line = []
00040         for j in range(len(matrix_2[0])):
00041             element = 0
00042             for k in range(len(matrix_1[0])):
00043                 element = element + matrix_1[i][k] * matrix_2[k][j]
00044             line.append(element)
00045         result_matrix.append(line)
00046     return result_matrix
00047 
00048 def matrix_vector_mult(matrix,vector):
00049     result_vect = []
00050     for mat in matrix:
00051         result_vect.append(mat[0]*vector[0]+mat[1]*vector[1]+mat[2]*vector[2])
00052     return result_vect
00053 
00054 
00055 def get_rotation_matrix(angle_x, angle_y, angle_z):
00056     rotation_matrix_x = []
00057     rotation_matrix_x.append([1,0,0])
00058     rotation_matrix_x.append([0,math.cos(angle_x),-math.sin(angle_x)])
00059     rotation_matrix_x.append([0,math.sin(angle_x),math.cos(angle_x)])
00060 
00061     rotation_matrix_y = []
00062     rotation_matrix_y.append([math.cos(angle_y),0,math.sin(angle_y)])
00063     rotation_matrix_y.append([0,1,0])
00064     rotation_matrix_y.append([-math.sin(angle_y),0,math.cos(angle_y)])
00065 
00066     rotation_matrix_z = []
00067     rotation_matrix_z.append([math.cos(angle_z),-math.sin(angle_z),0])
00068     rotation_matrix_z.append([math.sin(angle_z),math.cos(angle_z),0])
00069     rotation_matrix_z.append([0,0,1])
00070 
00071     return multiply_matrix(rotation_matrix_z,multiply_matrix(rotation_matrix_y,rotation_matrix_x))
00072 
00073 def xyz_to_sph(x, y, z):
00074     r = math.sqrt(x**2 + y**2 + z**2)
00075     elev = math.acos(z / r)
00076     az = math.atan2(y,x)
00077     return r, elev, az
00078 
00079 def sph_to_xyz(r, elev, az):
00080     x = r * math.sin(elev) * math.cos(az)
00081     y = r * math.sin(elev) * math.sin(az)
00082     z = r * math.cos(elev)
00083     return x, y, z
00084     
00085 def add_angles_to_sph(sph, d_elev, d_az):
00086     r = sph[0]
00087     elev = sph[1] + d_elev
00088     az = sph[2] + d_az
00089     return r, elev, az
00090 
00091 def normalize_vector(vec):
00092     norm = math.sqrt(vec[0]**2 + vec[1]**2 + vec[2]**2)
00093     if (norm != 0):
00094         return vec[0] / norm, vec[1] / norm, vec[2] / norm
00095     else:
00096         return vec
00097 
00098 def round_vector_elements(vec):
00099     x = float("{0:.5f}".format(vec[0]))
00100     y = float("{0:.5f}".format(vec[1]))
00101     z = float("{0:.5f}".format(vec[2]))
00102     return x, y, z
00103 
00104 if __name__ == "__main__":
00105     rospy.init_node('normal_generator_tool', anonymous=True)
00106     rospack = rospkg.RosPack()
00107 
00108     #Read the parameters from the configuration file
00109     f = open(rospack.get_path('asr_object_database') + '/src/normal_generator_tool/normalsToolParams.yaml', 'r')
00110     yamlfile = load(f)
00111     f.close()
00112     upload_params('/', yamlfile)
00113 
00114     marker_frame = rospy.get_param('marker_frame')
00115     pub_topic = rospy.get_param('pub_topic')
00116     output_rel_path = rospy.get_param('output_rel_path')
00117     base_vectors = rospy.get_param('base_vectors')
00118     pan_min = rospy.get_param('pan')[0]
00119     pan_max = rospy.get_param('pan')[1]
00120     tilt_min = rospy.get_param('tilt')[0]
00121     tilt_max = rospy.get_param('tilt')[1]
00122     d_x = rospy.get_param('d_pan')
00123     d_y = rospy.get_param('d_tilt')
00124     publish_rate = rospy.get_param('publish_rate')
00125 
00126     publisher = rospy.Publisher(pub_topic, MarkerArray, queue_size=10)
00127 
00128     #Use those Rotations to rotate the input vectors from the zx-plane to the xy-plane for the creation of the additional normal vectors
00129     # (to match the orientation of the object meshes)
00130     an_x = 90.0*math.pi/180
00131     rot_mat = get_rotation_matrix(an_x, 0.0, 0.0)
00132     rot_mat_trans = get_rotation_matrix(-an_x, 0.0, 0.0)
00133 
00134     #Create the normals
00135     normals = []
00136     for base_vec in base_vectors:
00137         base_vec = normalize_vector(base_vec)
00138         base_vec = matrix_vector_mult(rot_mat, base_vec)
00139         sp = xyz_to_sph(base_vec[0], base_vec[1], base_vec[2])
00140         for pan_curr in range(pan_min, pan_max + 1, d_x):
00141             for tilt_curr in range(tilt_min, tilt_max + 1, d_y):
00142                 d_az = pan_curr*math.pi/180
00143                 d_elev = tilt_curr*math.pi/180
00144                 new_sp = add_angles_to_sph(sp, d_elev, d_az)
00145                 new_normal = sph_to_xyz(new_sp[0], new_sp[1], new_sp[2])
00146                 result_normal = matrix_vector_mult(rot_mat_trans, new_normal)
00147                 normals.append(round_vector_elements(result_normal))
00148 
00149 
00150     #Write the created normals to a file
00151     output_string = ""
00152     for normal in normals:
00153         for idx,nor in enumerate(normal):
00154             if idx < 2:
00155                 output_string += str(nor) + ","
00156             else:
00157                 output_string += str(nor)
00158         output_string += ";"
00159 
00160     print 'Created normals:'
00161     print output_string
00162     print '--------------------'
00163 
00164     fh = open(rospack.get_path('asr_object_database') + output_rel_path, 'w')
00165     fh.writelines(output_string)
00166     fh.close()
00167     
00168     #Create a marker array from the created normals
00169     markerArray = MarkerArray()
00170     marker_id = 0
00171     size_vec  = len(base_vectors)
00172     color_step = 1
00173     if size_vec > 0:
00174         color_step = 1.0 / size_vec 
00175     
00176     for normal in normals:
00177         hue = (marker_id / (len(normals) / size_vec)) * color_step + 0.0
00178         rgb = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
00179 
00180         marker = Marker()
00181         marker.id = marker_id
00182         marker.header.frame_id = marker_frame
00183         marker.ns = 'normals'
00184         marker.scale.x = 0.01
00185         marker.scale.y = 0.1
00186         marker.scale.z = 0.1
00187         marker.color.r = rgb[0]
00188         marker.color.g = rgb[1] 
00189         marker.color.b = rgb[2] 
00190         marker.color.a = 1.0
00191         
00192         point_start = Point()
00193         point_end = Point()
00194         point_end.x = normal[0]
00195         point_end.y = normal[1]
00196         point_end.z = normal[2]
00197         marker.points.append(point_start)
00198         marker.points.append(point_end)
00199 
00200         marker.type = marker.ARROW
00201         markerArray.markers.append(marker)
00202        
00203         marker_id = marker_id +1
00204 
00205     #Publish the normal markers
00206     print 'Publishing normals (Rate: ' + str(publish_rate) + ' Hz)'
00207     rate = rospy.Rate(publish_rate)
00208     while not rospy.is_shutdown():
00209         publisher.publish(markerArray)
00210         rate.sleep()


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 Thu Jun 6 2019 21:11:02