mirror of
https://github.com/Mobile-Robotics-W20-Team-9/UMICH-NCLT-SLAP.git
synced 2025-09-09 12:23:14 +00:00
gitignore & Read Velodyne Data
- Add gitignore so VS Code and dataset files are not committed - Add python functions provided by NCLT dataset for reading velodyne data
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Visual Studio Code
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# Ignore downloaded dataset files
|
||||||
|
src/dataset/*
|
||||||
|
!src/dataset/*.py
|
16
src/localization/localization.py
Normal file
16
src/localization/localization.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# localization.py
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
from PoseList import PoseList
|
||||||
|
from scipy.spatial import distance
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
166
src/localization/project_vel_to_cam.py
Normal file
166
src/localization/project_vel_to_cam.py
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
# !/usr/bin/python
|
||||||
|
#
|
||||||
|
# Demonstrates how to project velodyne points to camera imagery. Requires a binary
|
||||||
|
# velodyne sync file, undistorted image, and assumes that the calibration files are
|
||||||
|
# in the directory.
|
||||||
|
#
|
||||||
|
# To use:
|
||||||
|
#
|
||||||
|
# python project_vel_to_cam.py vel img cam_num
|
||||||
|
#
|
||||||
|
# vel: The velodyne binary file (timestamp.bin)
|
||||||
|
# img: The undistorted image (timestamp.tiff)
|
||||||
|
# cam_num: The index (0 through 5) of the camera
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import struct
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.image as mpimg
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
#from undistort import *
|
||||||
|
|
||||||
|
def convert(x_s, y_s, z_s):
|
||||||
|
|
||||||
|
scaling = 0.005 # 5 mm
|
||||||
|
offset = -100.0
|
||||||
|
|
||||||
|
x = x_s * scaling + offset
|
||||||
|
y = y_s * scaling + offset
|
||||||
|
z = z_s * scaling + offset
|
||||||
|
|
||||||
|
return x, y, z
|
||||||
|
|
||||||
|
def load_vel_hits(filename):
|
||||||
|
|
||||||
|
f_bin = open(filename, "r")
|
||||||
|
|
||||||
|
hits = []
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
x_str = f_bin.read(2)
|
||||||
|
if x_str == '': # eof
|
||||||
|
break
|
||||||
|
|
||||||
|
x = struct.unpack('<H', x_str)[0]
|
||||||
|
y = struct.unpack('<H', f_bin.read(2))[0]
|
||||||
|
z = struct.unpack('<H', f_bin.read(2))[0]
|
||||||
|
i = struct.unpack('B', f_bin.read(1))[0]
|
||||||
|
l = struct.unpack('B', f_bin.read(1))[0]
|
||||||
|
|
||||||
|
x, y, z = convert(x, y, z)
|
||||||
|
|
||||||
|
# Load in homogenous
|
||||||
|
hits += [[x, y, z, 1]]
|
||||||
|
|
||||||
|
f_bin.close()
|
||||||
|
hits = np.asarray(hits)
|
||||||
|
|
||||||
|
return hits.transpose()
|
||||||
|
|
||||||
|
def ssc_to_homo(ssc):
|
||||||
|
|
||||||
|
# Convert 6-DOF ssc coordinate transformation to 4x4 homogeneous matrix
|
||||||
|
# transformation
|
||||||
|
|
||||||
|
sr = np.sin(np.pi/180.0 * ssc[3])
|
||||||
|
cr = np.cos(np.pi/180.0 * ssc[3])
|
||||||
|
|
||||||
|
sp = np.sin(np.pi/180.0 * ssc[4])
|
||||||
|
cp = np.cos(np.pi/180.0 * ssc[4])
|
||||||
|
|
||||||
|
sh = np.sin(np.pi/180.0 * ssc[5])
|
||||||
|
ch = np.cos(np.pi/180.0 * ssc[5])
|
||||||
|
|
||||||
|
H = np.zeros((4, 4))
|
||||||
|
|
||||||
|
H[0, 0] = ch*cp
|
||||||
|
H[0, 1] = -sh*cr + ch*sp*sr
|
||||||
|
H[0, 2] = sh*sr + ch*sp*cr
|
||||||
|
H[1, 0] = sh*cp
|
||||||
|
H[1, 1] = ch*cr + sh*sp*sr
|
||||||
|
H[1, 2] = -ch*sr + sh*sp*cr
|
||||||
|
H[2, 0] = -sp
|
||||||
|
H[2, 1] = cp*sr
|
||||||
|
H[2, 2] = cp*cr
|
||||||
|
|
||||||
|
H[0, 3] = ssc[0]
|
||||||
|
H[1, 3] = ssc[1]
|
||||||
|
H[2, 3] = ssc[2]
|
||||||
|
|
||||||
|
H[3, 3] = 1
|
||||||
|
|
||||||
|
return H
|
||||||
|
|
||||||
|
def project_vel_to_cam(hits, cam_num):
|
||||||
|
|
||||||
|
# Load camera parameters
|
||||||
|
K = np.loadtxt('K_cam%d.csv' % (cam_num), delimiter=',')
|
||||||
|
x_lb3_c = np.loadtxt('x_lb3_c%d.csv' % (cam_num), delimiter=',')
|
||||||
|
|
||||||
|
# Other coordinate transforms we need
|
||||||
|
x_body_lb3 = [0.035, 0.002, -1.23, -179.93, -0.23, 0.50]
|
||||||
|
|
||||||
|
# Now do the projection
|
||||||
|
T_lb3_c = ssc_to_homo(x_lb3_c)
|
||||||
|
T_body_lb3 = ssc_to_homo(x_body_lb3)
|
||||||
|
|
||||||
|
T_lb3_body = np.linalg.inv(T_body_lb3)
|
||||||
|
T_c_lb3 = np.linalg.inv(T_lb3_c)
|
||||||
|
|
||||||
|
T_c_body = np.matmul(T_c_lb3, T_lb3_body)
|
||||||
|
|
||||||
|
hits_c = np.matmul(T_c_body, hits)
|
||||||
|
hits_im = np.matmul(K, hits_c[0:3, :])
|
||||||
|
|
||||||
|
return hits_im
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
|
||||||
|
if len(args)<4:
|
||||||
|
print """Incorrect usage.
|
||||||
|
|
||||||
|
To use:
|
||||||
|
|
||||||
|
python project_vel_to_cam.py vel img cam_num
|
||||||
|
|
||||||
|
vel: The velodyne binary file (timestamp.bin)
|
||||||
|
img: The undistorted image (timestamp.tiff)
|
||||||
|
cam_num: The index (0 through 5) of the camera
|
||||||
|
"""
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
|
# Load velodyne points
|
||||||
|
hits_body = load_vel_hits(args[1])
|
||||||
|
|
||||||
|
# Load image
|
||||||
|
image = mpimg.imread(args[2])
|
||||||
|
|
||||||
|
cam_num = int(args[3])
|
||||||
|
|
||||||
|
hits_image = project_vel_to_cam(hits_body, cam_num)
|
||||||
|
|
||||||
|
x_im = hits_image[0, :]/hits_image[2, :]
|
||||||
|
y_im = hits_image[1, :]/hits_image[2, :]
|
||||||
|
z_im = hits_image[2, :]
|
||||||
|
|
||||||
|
idx_infront = z_im>0
|
||||||
|
x_im = x_im[idx_infront]
|
||||||
|
y_im = y_im[idx_infront]
|
||||||
|
z_im = z_im[idx_infront]
|
||||||
|
|
||||||
|
plt.figure(1)
|
||||||
|
plt.imshow(image)
|
||||||
|
plt.hold(True)
|
||||||
|
plt.scatter(x_im, y_im, c=z_im, s=5, linewidths=0)
|
||||||
|
plt.xlim(0, 1616)
|
||||||
|
plt.ylim(0, 1232)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main(sys.argv))
|
90
src/localization/read_vel_hits.py
Normal file
90
src/localization/read_vel_hits.py
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# !/usr/bin/python
|
||||||
|
#
|
||||||
|
# Example code to go through the velodyne_hits.bin
|
||||||
|
# file and read timestamps, number of hits, and the
|
||||||
|
# hits in each packet.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# To call:
|
||||||
|
#
|
||||||
|
# python read_vel_hits.py velodyne.bin
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import struct
|
||||||
|
|
||||||
|
def convert(x_s, y_s, z_s):
|
||||||
|
|
||||||
|
scaling = 0.005 # 5 mm
|
||||||
|
offset = -100.0
|
||||||
|
|
||||||
|
x = x_s * scaling + offset
|
||||||
|
y = y_s * scaling + offset
|
||||||
|
z = z_s * scaling + offset
|
||||||
|
|
||||||
|
return x, y, z
|
||||||
|
|
||||||
|
def verify_magic(s):
|
||||||
|
|
||||||
|
magic = 44444
|
||||||
|
|
||||||
|
m = struct.unpack('<HHHH', s)
|
||||||
|
|
||||||
|
return len(m)>=4 and m[0] == magic and m[1] == magic and m[2] == magic and m[3] == magic
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print "Please specifiy input bin file"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
f_bin = open(sys.argv[1], "r")
|
||||||
|
|
||||||
|
total_hits = 0
|
||||||
|
first_utime = -1
|
||||||
|
last_utime = -1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
magic = f_bin.read(8)
|
||||||
|
if magic == '': # eof
|
||||||
|
break
|
||||||
|
|
||||||
|
if not verify_magic(magic):
|
||||||
|
print "Could not verify magic"
|
||||||
|
|
||||||
|
num_hits = struct.unpack('<I', f_bin.read(4))[0]
|
||||||
|
utime = struct.unpack('<Q', f_bin.read(8))[0]
|
||||||
|
|
||||||
|
padding = f_bin.read(4) # padding
|
||||||
|
|
||||||
|
print "Have %d hits for utime %ld" % (num_hits, utime)
|
||||||
|
|
||||||
|
total_hits += num_hits
|
||||||
|
if first_utime == -1:
|
||||||
|
first_utime = utime
|
||||||
|
last_utime = utime
|
||||||
|
|
||||||
|
for i in range(num_hits):
|
||||||
|
|
||||||
|
x = struct.unpack('<H', f_bin.read(2))[0]
|
||||||
|
y = struct.unpack('<H', f_bin.read(2))[0]
|
||||||
|
z = struct.unpack('<H', f_bin.read(2))[0]
|
||||||
|
i = struct.unpack('B', f_bin.read(1))[0]
|
||||||
|
l = struct.unpack('B', f_bin.read(1))[0]
|
||||||
|
|
||||||
|
x, y, z = convert(x, y, z)
|
||||||
|
s = "%5.3f, %5.3f, %5.3f, %d, %d" % (x, y, z, i, l)
|
||||||
|
|
||||||
|
print s
|
||||||
|
|
||||||
|
raw_input("Press enter to continue...")
|
||||||
|
|
||||||
|
f_bin.close()
|
||||||
|
|
||||||
|
print "Read %d total hits from %ld to %ld" % (total_hits, first_utime, last_utime)
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main(sys.argv))
|
81
src/localization/read_vel_sync.py
Normal file
81
src/localization/read_vel_sync.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# !/usr/bin/python
|
||||||
|
#
|
||||||
|
# Example code to read a velodyne_sync/[utime].bin file
|
||||||
|
# Plots the point cloud using matplotlib. Also converts
|
||||||
|
# to a CSV if desired.
|
||||||
|
#
|
||||||
|
# To call:
|
||||||
|
#
|
||||||
|
# python read_vel_sync.py velodyne.bin [out.csv]
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import struct
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from mpl_toolkits.mplot3d import Axes3D
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
def convert(x_s, y_s, z_s):
|
||||||
|
|
||||||
|
scaling = 0.005 # 5 mm
|
||||||
|
offset = -100.0
|
||||||
|
|
||||||
|
x = x_s * scaling + offset
|
||||||
|
y = y_s * scaling + offset
|
||||||
|
z = z_s * scaling + offset
|
||||||
|
|
||||||
|
return x, y, z
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print('Please specify velodyne file')
|
||||||
|
return 1
|
||||||
|
|
||||||
|
f_bin = open(sys.argv[1], "rb")
|
||||||
|
|
||||||
|
if len(sys.argv) >= 3:
|
||||||
|
print('Writing to ', sys.argv[2])
|
||||||
|
f_csv = open(sys.argv[2], "w")
|
||||||
|
else:
|
||||||
|
f_csv = None
|
||||||
|
|
||||||
|
hits = []
|
||||||
|
|
||||||
|
while True:
|
||||||
|
|
||||||
|
x_str = f_bin.read(2)
|
||||||
|
if x_str == b'': # eof
|
||||||
|
break
|
||||||
|
|
||||||
|
x = struct.unpack('<H', x_str)[0]
|
||||||
|
y = struct.unpack('<H', f_bin.read(2))[0]
|
||||||
|
z = struct.unpack('<H', f_bin.read(2))[0]
|
||||||
|
i = struct.unpack('B', f_bin.read(1))[0]
|
||||||
|
l = struct.unpack('B', f_bin.read(1))[0]
|
||||||
|
|
||||||
|
x, y, z = convert(x, y, z)
|
||||||
|
|
||||||
|
s = "%5.3f, %5.3f, %5.3f, %d, %d" % (x, y, z, i, l)
|
||||||
|
|
||||||
|
if f_csv:
|
||||||
|
f_csv.write('%s\n' % s)
|
||||||
|
|
||||||
|
hits += [[x, y, z]]
|
||||||
|
|
||||||
|
f_bin.close()
|
||||||
|
|
||||||
|
if f_csv:
|
||||||
|
f_csv.close()
|
||||||
|
|
||||||
|
hits = np.asarray(hits)
|
||||||
|
|
||||||
|
fig = plt.figure()
|
||||||
|
ax = fig.add_subplot(111, projection='3d')
|
||||||
|
ax.scatter(hits[:, 0], hits[:, 1], -hits[:, 2], c=-hits[:, 2], s=5, linewidths=0)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main(sys.argv))
|
Reference in New Issue
Block a user