00001
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
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
00129
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
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
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
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
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()