Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
220 commits
Select commit Hold shift + click to select a range
729f4f5
Added homework description and starter code
krishauser Jan 27, 2025
da7f313
Merge with s2025
Jan 28, 2025
a6d9f85
Merge branch 'main' into s2025_teamA
krishauser Jan 29, 2025
7c35a51
test
rjsun06 Jan 31, 2025
bcf2949
test
rjsun06 Jan 31, 2025
43be594
added two subscribers for part1-1
ShellyRiver Jan 31, 2025
c76d058
Example commit for planning team A
animeshsingh98 Feb 1, 2025
31c3491
added publisher to blink.py
Feb 1, 2025
0242671
Merge pull request #99 from krishauser/A4_Planning_PReg
udymd Feb 2, 2025
2a75f28
script for capturing paird img/points
rjsun06 Feb 2, 2025
ae74011
debug subscriber to pacmod accel
ShellyRiver Feb 3, 2025
eb859dc
Merge branch 's2025' into s2025_teamA
krishauser Feb 3, 2025
8c55174
Changed matplotlib to 3D visualization
krishauser Feb 3, 2025
5c85705
Merge branch 's2025' into s2025_teamA
krishauser Feb 3, 2025
8790efb
Fixed diff that was somehow committed
krishauser Feb 3, 2025
8186b1a
Fixed to work with Klampt 0.10
krishauser Feb 3, 2025
c02746f
Fixed launch file to work with standard perception pipeline
krishauser Feb 3, 2025
6f4aa44
Merge branch 's2025' into s2025_teamA
krishauser Feb 3, 2025
b2c7fdd
blink.py publisher minor bug fix
mikayel2 Feb 3, 2025
a6376d6
Merge branch 's2025_teamA' into A1_control
mikayel2 Feb 3, 2025
2f1b7e7
HW1 Part 1.2 code (provided by Yifei Mao) works correctly in simulation.
mikayel2 Feb 3, 2025
8c48e22
blink_component code/have not been tested
Feb 4, 2025
98889c9
Merge branch 'A1_control' of https://github.com/krishauser/GEMstack i…
Feb 4, 2025
cabe2fc
updating some ros topics to match gem e4
AadarshHegde123 Feb 4, 2025
8368354
Merge branch 'EstCal_A' of https://github.com/krishauser/GEMstack int…
rjsun06 Feb 4, 2025
b39e690
Update capture_ouster_oak.py
rjsun06 Feb 4, 2025
88bdc23
changed node name for data capturing
rjsun06 Feb 4, 2025
26f0714
Merge branch 's2025_teamA' into A4_planning
udymd Feb 4, 2025
8725e34
Update longitudinal_planning.py
udymd Feb 4, 2025
a82b3af
try upload
dazhenc2 Feb 5, 2025
9f736bc
Merge branch 's2025_teamA' into EstCal_A
AadarshHegde123 Feb 5, 2025
2b6830c
Add Yielding planning, just stop in front of pedestrian
udymd Feb 5, 2025
63cd8f6
Fix the poses (align to absolute pose)
udymd Feb 5, 2025
e105880
lidar front camera data capture working, camera info intrinsic captur…
Feb 5, 2025
96a315e
Fixed fake_fake simulation calls and rename from YIELD -> YIELDING
krishauser Feb 6, 2025
7659c5d
Longitudinal planning setup where we the points are treated as way po…
SimonKato Feb 6, 2025
e77d8d4
Make simple simulation for pedestrian yielding
udymd Feb 7, 2025
edfc975
hw1.3
dazhenc2 Feb 7, 2025
9aacb10
Fixed Nan error, modified Brake mode
udymd Feb 7, 2025
8059c53
Fix bug causing crash at end of sim
udymd Feb 7, 2025
96b34a8
Make yielding logic and update simulation, upload test function
udymd Feb 7, 2025
df4ff9a
Merge branch 's2025_teamA' into A4_planning
udymd Feb 7, 2025
9074df0
Fixed the alignment between sim and collision detection
udymd Feb 7, 2025
06fa6e7
Fixed coordinate misalignment. There is still bug not to detect colli…
udymd Feb 7, 2025
67348fe
More/better comments
SimonKato Feb 7, 2025
403e71c
Merge branch 'A4_planning_part1_milestones' of github.com:krishauser/…
SimonKato Feb 7, 2025
f91796b
Part1 based on V_max and Triangle profile
RohitMurali18 Feb 8, 2025
15191c7
general code clean up + adding depth subscriber + creating klampt vis…
AadarshHegde123 Feb 8, 2025
2a0f9c2
working depth image capture
AadarshHegde123 Feb 8, 2025
0620cb3
HW1 Part 2: Parameter Tuning (crosstrack gain and decay speed)
mikayel2 Feb 9, 2025
3de8182
Modify buffer from 0.5m => 1m
udymd Feb 10, 2025
4ade5bb
Update longitudinal_planning.py
udymd Feb 10, 2025
d0771fa
visualization for lidar + oak working, but no intrinsics considered
AadarshHegde123 Feb 10, 2025
3c6bdc1
feat: init team folder
Averyyy Feb 10, 2025
e23a5cb
script to fit objects in a line
rjsun06 Feb 11, 2025
555cb55
calibration Lidar to Vehicle. Running OK. To be improved
rjsun06 Feb 11, 2025
734f0b3
update translation_z using magic numbers we measured
rjsun06 Feb 11, 2025
6a38ed0
enhenced visualization
rjsun06 Feb 11, 2025
88ec6ba
semi correct code for icp
jeffbyju Feb 11, 2025
a9fa4c8
better line fitting
rjsun06 Feb 11, 2025
124a75b
good visuals
rjsun06 Feb 12, 2025
559afd0
Merge branch 'infra_a_main' into Mohammad
Mhdfk Feb 12, 2025
34f89eb
Found a bug in longitutdinal_planning which used deceleration instead…
SimonKato Feb 12, 2025
e991f0e
feat: added a convert script to convert raw data to rosbags
Mhdfk Feb 12, 2025
dfbafe2
finalize hw1.3
dazhenc2 Feb 12, 2025
790b033
Merge branch 'A4_planning_part1' into A4_planning_part2
udymd Feb 13, 2025
a599e2a
Implement Part2.3: Keep slow until ped crossed
udymd Feb 13, 2025
c914a41
Little twick for rx,ry calculation
rjsun06 Feb 13, 2025
a84c3e9
Merge branch 'EstCal_A' of https://github.com/krishauser/GEMstack int…
rjsun06 Feb 13, 2025
ba645ed
Your commit message
RohitMurali18 Feb 13, 2025
d2235bc
after dynamic dt
RohitMurali18 Feb 13, 2025
299768a
Fixed aborting at the end of sim.
udymd Feb 13, 2025
d3d3bf0
Merge branch 'A1_control' into s2025_teamA_control-planning
udymd Feb 13, 2025
03f46c1
Fix jitter at the end of track for simulation
udymd Feb 13, 2025
b5cb190
Merge pull request #107 from krishauser/hw1.3
laneccolin Feb 13, 2025
bd94404
feat: remove ibeo msgs in setup_this machine.sh
Averyyy Feb 14, 2025
67eab16
Fine tuning tracking and comfort level, comfort index added as a metric
mikayel2 Feb 14, 2025
7dd38e3
Modified braking function for experiment
udymd Feb 14, 2025
0831c67
Implemented Part 1&2
udymd Feb 14, 2025
0f38270
manual cali lidar to camera
rjsun06 Feb 14, 2025
b21bb65
add logic to avoid unnecessary yielding
Patrick8894 Feb 14, 2025
5b4b97f
Added arg parser
Mhdfk Feb 14, 2025
3708973
Added arg parser to convert_to_rosbags.py script
Mhdfk Feb 14, 2025
0255d75
Edited data acquisition rate to be an input that must be specified
Mhdfk Feb 14, 2025
ca087e3
dumb bug fixed
rjsun06 Feb 14, 2025
1b82a7b
Merge branch 'EstCal_A' into s2025_teamA_control-planning
udymd Feb 14, 2025
ade0559
Modified braking function for experiment
udymd Feb 14, 2025
a825826
Merge branch 's2025_teamA_control-planning' of https://github.com/kri…
udymd Feb 14, 2025
46b6b04
modify code for integrating with other algorithm
Patrick8894 Feb 14, 2025
2b6c1d8
longitudinal plan now taking into account triangle velocity profile c…
SimonKato Feb 14, 2025
20b73b1
Adding cruising speed profile
animeshsingh98 Feb 14, 2025
450a2f8
Temporary fix of variables
udymd Feb 14, 2025
ca68b4e
Merge branch 'A4_planning_part1' into A4_planning_patrick
udymd Feb 14, 2025
6b276ed
Merging and consolidating part 1 branches
SimonKato Feb 14, 2025
b9f9e0e
Add condition that vehicle accels and ped walk to vehicle
udymd Feb 15, 2025
2872e78
Optimising the program
animeshsingh98 Feb 15, 2025
00ddf95
Update longitudinal_planning.py
animeshsingh98 Feb 15, 2025
52e56c3
tmp
Hansen1030 Feb 15, 2025
4b89d5b
Add dx
Hansen1030 Feb 15, 2025
32336da
Fixed syntax errors
udymd Feb 16, 2025
1fa8f9b
Merge pull request #109 from krishauser/Mohammad
Averyyy Feb 17, 2025
577d0c3
feat: logs management
nmashchenko Feb 17, 2025
d43adde
Merge pull request #114 from krishauser/feat/camera-data-logging
Averyyy Feb 17, 2025
14fcec9
Merge branch 'A4_planning_part1' into A4_planning_patrick
udymd Feb 17, 2025
4ba2efd
Merge branch 's2025' into s2025_teamA_control-planning
udymd Feb 17, 2025
d03fd63
interactive analyzer for csv files
Jason717717 Feb 15, 2025
822493a
add documentation and append timestamps to saved file names
Jason717717 Feb 16, 2025
080f8b0
Merge pull request #115 from krishauser/A1_control
alo-20 Feb 17, 2025
3020680
Optimising the program and adding commit by Kris
animeshsingh98 Feb 17, 2025
0cac268
Optimising the program and adding commit by Kris
animeshsingh98 Feb 17, 2025
d861a16
Finish klampt_visualization and mpl_visualization
Shiyang-Zhao Feb 17, 2025
526614c
Merge pull request #112 from krishauser/infra_a_analyze
Averyyy Feb 17, 2025
28e22dc
Merge pull request #108 from krishauser/remove-ibeo-msg
Averyyy Feb 17, 2025
0300ba9
merge part1 longitudinal_plan and longitudinal_brake with part2 yeild…
Patrick8894 Feb 17, 2025
5755476
Merge branch 'A4_planning_patrick' of github.com:krishauser/GEMstack …
Feb 17, 2025
e5a2232
Revert "merge part1 longitudinal_plan and longitudinal_brake with par…
Patrick8894 Feb 17, 2025
fd0d505
Merge pull request #116 from krishauser/Shiyang
Averyyy Feb 17, 2025
bca6233
merge part1 and part2
Patrick8894 Feb 17, 2025
f3804db
blink_component file test
laneccolin Feb 17, 2025
7568b2c
Merge branch 's2025' into s2025_teamA
krishauser Feb 18, 2025
0067d5c
detect_collision_via_optimization added
Henry-YiW Feb 18, 2025
97e5e63
Update longitudinal_planning.py
udymd Feb 19, 2025
3a8a282
Merge branch 'A4_planning' into s2025_teamA_control-planning
udymd Feb 19, 2025
466d887
Adjust Change dynamic_dt_k for simulation
udymd Feb 19, 2025
ef3a29a
Merge branch 's2025_teamA' into s2025_teamA_control-planning
udymd Feb 19, 2025
ab6fe4a
Added homework description and starter code
krishauser Jan 27, 2025
2be0d8e
Fixed Klampt drawing problem onboard... still mysterious
krishauser Jan 28, 2025
23eb3fb
added two subscribers for part1-1
ShellyRiver Jan 31, 2025
79616f3
added publisher to blink.py
Feb 1, 2025
ec12f16
debug subscriber to pacmod accel
ShellyRiver Feb 3, 2025
000a052
blink_component code/have not been tested
Feb 4, 2025
1e15536
blink.py publisher minor bug fix
mikayel2 Feb 3, 2025
fa57607
Changed matplotlib to 3D visualization
krishauser Feb 3, 2025
9496bde
Adding github action for linting and documentation
animeshsingh98 Feb 2, 2025
95c5071
Adding github action trigger on all commits
animeshsingh98 Feb 2, 2025
e2bf7c7
Upgrading version of upload artifact
animeshsingh98 Feb 2, 2025
b144c94
Optimizing the workflow yaml
animeshsingh98 Feb 2, 2025
9b3d5f8
Optimizing the workflow yaml
animeshsingh98 Feb 2, 2025
e7ed1a5
Correcting in the key names
animeshsingh98 Feb 2, 2025
c8b3c5a
Removing requirements.txt installation in documentation
animeshsingh98 Feb 2, 2025
8dcb9c9
Correcting name of build artifact for documentation folder
animeshsingh98 Feb 2, 2025
2e6abdf
Removing action trigger on PR
animeshsingh98 Feb 2, 2025
791720c
Fixed diff that was somehow committed
krishauser Feb 3, 2025
cf0485d
Fixed launch file to work with standard perception pipeline
krishauser Feb 3, 2025
f31aed0
HW1 Part 1.2 code (provided by Yifei Mao) works correctly in simulation.
mikayel2 Feb 3, 2025
6acbc59
try upload
dazhenc2 Feb 5, 2025
73b5c95
HW1 Part 2: Parameter Tuning (crosstrack gain and decay speed)
mikayel2 Feb 9, 2025
f063786
hw1.3
dazhenc2 Feb 7, 2025
44af541
finalize hw1.3
dazhenc2 Feb 12, 2025
701c378
Fine tuning tracking and comfort level, comfort index added as a metric
mikayel2 Feb 14, 2025
ba9f62a
Merge branch 'A1_control' of https://github.com/krishauser/GEMstack i…
alo-20 Feb 19, 2025
c4a9abe
Change brake active range to start at 0.25
alo-20 Feb 19, 2025
9a98cba
Change e4 dynamics to have 0.25 start of brake_active_range
alo-20 Feb 19, 2025
973da06
Update gem_e4_dynamics.yaml
laneccolin Feb 19, 2025
fdbed01
Update gem_e4_dynamics.yaml
laneccolin Feb 19, 2025
ad2bd16
Update gem_e4_dynamics.yaml
laneccolin Feb 19, 2025
404e393
Merge branch 'A1_control' into s2025_teamA_control-planning
udymd Feb 19, 2025
95194dc
Merge pull request #120 from krishauser/s2025_teamA_control-planning
laneccolin Feb 19, 2025
d777ab6
Merge pull request #121 from krishauser/A1_control
laneccolin Feb 19, 2025
844f035
change the logic in part 2
Patrick8894 Feb 19, 2025
0ec9d23
Fixed to move GEM (GNSS, brake, steering are working)
Feb 19, 2025
94d17e1
Adjust the parameters of vehicle xy temporalily (need to be fixed in …
Feb 19, 2025
04239a4
Merge branch 'A4_planning_part2' into A4_planning
udymd Feb 22, 2025
60e3d20
Fixed for test function
udymd Feb 23, 2025
591b385
Merge branch 's2025_teamA_control-planning' into A4_planning
udymd Feb 23, 2025
89b16df
Added args for sim/real and milestine/dt/dx in launch
udymd Feb 23, 2025
91632e2
Modified coordinates among real/sim and perception
udymd Feb 23, 2025
e6ec341
Merge pull request #127 from krishauser/A4_planning
udymd Feb 23, 2025
047f84f
get_minimum_deceleration_for_collision_avoidance completed
Henry-YiW Feb 23, 2025
c05d406
get_minimum_deceleration_for_collision_avoidance completed
Henry-YiW Feb 23, 2025
df80729
get_minimum_deceleration_for_collision_avoidance tested
Henry-YiW Feb 23, 2025
54e1af4
Modifying for multiple pedestrians
udymd Feb 23, 2025
1be8acf
Updated gem_e4_dynamics.yaml
laneccolin Feb 23, 2025
66884ba
Merge branch 's2025_teamA' into infra_a_main
Averyyy Feb 23, 2025
323cba2
Merge pull request #117 from krishauser/infra_a_main
Averyyy Feb 23, 2025
cab0bd0
Update the newest pedestrian detection code
rty727433198 Feb 23, 2025
1762b6e
Update gem_e4_dynamics.yaml
laneccolin Feb 23, 2025
96e55b4
Modify for real car
udymd Feb 23, 2025
bc56dc7
Merge branch 's2025_teamA' of https://github.com/krishauser/GEMstack …
udymd Feb 23, 2025
81311b2
Fix indent
udymd Feb 24, 2025
b7682f4
Modified for multiple pedestrians
udymd Feb 24, 2025
ec9d1a6
Merged update
krishauser Feb 24, 2025
d87f5a5
Merge branch 's2025' into s2025_teamA
krishauser Feb 24, 2025
41b39cf
longitudinal plan and brake handled
Henry-YiW Feb 24, 2025
5b5dbd3
Fix cz GNSS coordinate issue solved
udymd Feb 24, 2025
c166eb4
Merge branch 'A4_planning_H1P2_henry' into A4_planning
udymd Feb 24, 2025
d3ee30e
Modified yaml file to set params of planner
udymd Feb 24, 2025
e9d56d9
Merge branch 's2025_teamA' into A4_planning
udymd Feb 24, 2025
95419dc
Merge pull request #133 from krishauser/A4_planning
udymd Feb 24, 2025
1356375
Reorganizing code. Pending items - pure pursuit controller has oscill…
animeshsingh98 Feb 24, 2025
f10fbbe
Delete .DS_Store
animeshsingh98 Feb 24, 2025
ec606e3
Removing conflict flags
animeshsingh98 Feb 25, 2025
a5d05f9
Modify for perception coordinates
udymd Feb 25, 2025
34dedde
Make generating plots and metrics automatic upon exit of a run by aut…
Jason717717 Feb 25, 2025
90acf7c
add speed error as a factor of comfort index
Jason717717 Feb 25, 2025
92e4ba8
fix a typo for log folder
Jason717717 Feb 25, 2025
bb666ba
add safety index
Jason717717 Feb 25, 2025
24347d5
format metrics to 2 decimal places
Jason717717 Feb 25, 2025
e14d743
add auto_plot attribute in log as comment
Jason717717 Feb 25, 2025
90c25fd
add result for fake_sim with pedestrian_detection.yaml
Jason717717 Feb 25, 2025
93cb91a
Update pedestrian_detection.py
rty727433198 Feb 25, 2025
41e46df
Merge branch 's2025_teamA' of https://github.com/krishauser/GEMstack …
udymd Feb 25, 2025
998f75e
Modified to load param in a planner
udymd Feb 25, 2025
29a9d4e
Correcting logic for collision detection
animeshsingh98 Feb 25, 2025
07046eb
Make more points for milestone implementation
SimonKato Feb 25, 2025
e2c7a02
debug cruising speed
Patrick8894 Feb 25, 2025
8045f7c
Adding new modules in requirement.txt
animeshsingh98 Feb 25, 2025
36ff1d3
fixed a bug
SimonKato Feb 25, 2025
5115a4f
Update pedestrian_detection.py
rty727433198 Feb 25, 2025
2999a4f
remove result for fake_sim with pedestrian detection launch yaml file
Jason717717 Feb 25, 2025
66d2069
Merge pull request #139 from krishauser/infra_a_auto_plot
Averyyy Feb 25, 2025
d72f891
Bug where we weren't including the last milestone
SimonKato Feb 26, 2025
24a72c0
Merge branch 'A4_planning_part1_milestone_more_points' into s2025_teamA
SimonKato Feb 26, 2025
a0ed900
Update pedestrian_detection.py
rty727433198 Feb 26, 2025
4d99bb7
Tune Values in current.yaml so the car does not oscillate
jyl2017 Feb 26, 2025
de4d6d0
Adding new files for state machine logic
animeshsingh98 Apr 6, 2025
131a301
Integrating state machine in inspection yaml
animeshsingh98 Apr 8, 2025
3db9c84
feat: init webapp under repo
nmashchenko Apr 8, 2025
363eaed
fix: updated summon / server
nmashchenko Apr 9, 2025
85f7764
Merge remote-tracking branch 'origin/s2025_summoning_planning' into f…
nmashchenko Apr 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added GEMstack/.DS_Store
Binary file not shown.
2 changes: 1 addition & 1 deletion GEMstack/knowledge/vehicle/gem_e2_dynamics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ max_accelerator_power_reverse: 10000.0 #Watts. Power (backwards) in reverse gea

acceleration_model : kris_v1
accelerator_active_range : [0.32, 1.0] #range of accelerator pedal where output acceleration is not flat
brake_active_range : [0,1] #range of brake pedal where output deceleration is not flat
brake_active_range : [0.25,1] #range of brake pedal where output deceleration is not flat

internal_dry_deceleration: 0.2 #m/s^2: deceleration due to internal dry friction (non-speed dependent)
internal_viscous_deceleration: 0.05 #1/s: scales the current velocity to get deceleration due to internal viscous friction (speed dependent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ ros_topics:
front_camera: /oak/rgb/image_raw
front_depth: /oak/stereo/image_raw
gnss: /septentrio_gnss/insnavgeod

11 changes: 11 additions & 0 deletions GEMstack/mathutils/quadratic_equation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import math

def quad_root(a : float, b : float, c : float) -> float:
x1 = (-b + max(0,(b**2 - 4*a*c))**0.5)/(2*a)
x2 = (-b - max(0,(b**2 - 4*a*c))**0.5)/(2*a)

if math.isnan(x1): x1 = 0
if math.isnan(x2): x2 = 0

valid_roots = [n for n in [x1, x2] if not type(n) is complex]
return valid_roots
41 changes: 41 additions & 0 deletions GEMstack/offboard/calibration/camera_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# ROS Headers
import rospy
from sensor_msgs.msg import Image,PointCloud2, CameraInfo
import sensor_msgs.point_cloud2 as pc2
import ctypes
import struct
import pickle
import image_geometry

import numpy as np
import os
import time

camera_image = None

def camera_callback(info : CameraInfo):
global camera_image
camera_image = info

def get_intrinsics():
model = image_geometry.PinholeCameraModel()
model.fromCameraInfo(camera_image)
print(model.intrinsicMatrix())

def main(folder='data',start_index=1):
rospy.init_node("capture_cam_info",disable_signals=True)
caminfo_sub = rospy.Subscriber("/oak/rgb/camera_info", CameraInfo, camera_callback)
while True:
if camera_image:
time.sleep(1)
get_intrinsics()

if __name__ == '__main__':
import sys
folder = 'data'
start_index = 1
if len(sys.argv) >= 2:
folder = sys.argv[1]
if len(sys.argv) >= 3:
start_index = int(sys.argv[2])
main(folder,start_index)
179 changes: 179 additions & 0 deletions GEMstack/offboard/calibration/icp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#!/usr/bin/env python3

import os
import glob
import numpy as np
import cv2
import open3d as o3d

# --- Adjust these to match your intrinsics and data details ---
INTRINSICS = np.array([
[684.83331299, 0. , 573.37109375],
[ 0. , 684.60968018, 363.70092773],
[ 0. , 0. , 1. ]
], dtype=np.float32)

# Depth scale: how to go from raw .tif values to actual "Z" in meters.
# In your capture code, you used: dimage = (dimage/4000*0xffff)
# Possibly each pixel is stored with range 0..65535. Adjust as needed.
DEPTH_SCALE = 4000.0 # Example factor if your depth was in mm or a certain scale.

def depth_to_points(depth_img: np.ndarray, intrinsics: np.ndarray):
"""
Convert a single-channel depth image into an Nx3 array of 3D points
in the camera coordinate system.
- depth_img: 2D array of type uint16 or float with depth values
- intrinsics: 3x3 camera matrix
"""
fx = intrinsics[0,0]
fy = intrinsics[1,1]
cx = intrinsics[0,2]
cy = intrinsics[1,2]

# Indices of each pixel
h, w = depth_img.shape
i_range = np.arange(h)
j_range = np.arange(w)
jj, ii = np.meshgrid(j_range, i_range) # shape (h,w)

# Flatten
ii = ii.flatten().astype(np.float32)
jj = jj.flatten().astype(np.float32)
depth = depth_img.flatten().astype(np.float32)

# Filter out zero / invalid depths
valid_mask = (depth > 0)
ii = ii[valid_mask]
jj = jj[valid_mask]
depth = depth[valid_mask]

# Reproject to 3D (camera frame)
# X = (x - cx) * Z / fx, Y = (y - cy) * Z / fy, Z = depth
# Note: Z must be in meters or consistent units
z = depth / DEPTH_SCALE # Convert from your .tif scale to real meters
x = (jj - cx) * z / fx
y = (ii - cy) * z / fy
points3d = np.stack((x, y, z), axis=-1) # shape (N,3)

return points3d

def load_lidar_points(npz_file: str):
"""
Load the Nx3 LiDAR points from a .npz file created by 'np.savez'.
"""
data = np.load(npz_file)
# The capture code used: np.savez(lidar_fn, pc)
# So 'data' might have the default key 'arr_0' or 'pc' if named
# Inspect data.files to see. Let's assume 'arr_0' or single key:
arr_key = data.files[0]
points = data[arr_key]
# shape check, must be Nx3 or Nx4, ...
return points

def make_open3d_pcd(points: np.ndarray):
"""
Convert Nx3 numpy array into an Open3D point cloud object.
"""
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
return pcd

def perform_icp(camera_pcd: o3d.geometry.PointCloud,
lidar_pcd: o3d.geometry.PointCloud):
"""
Perform local ICP alignment of camera_pcd (source) to lidar_pcd (target).
Returns a transformation 4x4 that maps camera -> lidar (or vice versa).
"""
# 1) Estimate normals if you want point-to-plane
lidar_pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=1.0, max_nn=30))
camera_pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=1.0, max_nn=30))

# 2) Initial guess: identity or something better if you have one
init_guess = np.eye(4)

# 3) Choose a threshold for inlier distance
threshold = 0.5 # adjust based on your environment scale

# 4) Run ICP (point-to-plane or point-to-point)
print("[ICP] Running ICP alignment ...")
result = o3d.pipelines.registration.registration_icp(
camera_pcd, # source
lidar_pcd, # target
threshold,
init_guess,
estimation_method=o3d.pipelines.registration.TransformationEstimationPointToPlane()
)

print("[ICP] Done. Fitness = %.4f, RMSE = %.4f" % (result.fitness, result.inlier_rmse))
print("[ICP] Transformation:\n", result.transformation)
return result.transformation

def main(folder='data'):
color_files = sorted(glob.glob(os.path.join(folder, "color*.png")))
icp_results = [] # to store (index, transform, fitness, rmse)

for color_path in color_files:
# Extract index from filename, e.g. color10.png -> 10
basename = os.path.basename(color_path)
idx_str = basename.replace("color","").replace(".png","")

if int(idx_str) in range(77):
depth_path = os.path.join(folder, f"depth{idx_str}.tif")
lidar_path = os.path.join(folder, f"lidar{idx_str}.npz")

if not (os.path.exists(depth_path) and os.path.exists(lidar_path)):
continue

# Load depth / convert to 3D
depth_img = cv2.imread(depth_path, cv2.IMREAD_UNCHANGED)
if depth_img is None:
continue
camera_points = depth_to_points(depth_img, INTRINSICS)
camera_pcd = make_open3d_pcd(camera_points)

# Load LiDAR
lidar_points = load_lidar_points(lidar_path)
lidar_pcd = make_open3d_pcd(lidar_points)

lidar_pcd.estimate_normals(
search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=1.0, # Adjust based on your scene scale
max_nn=30
)
)

# Also estimate normals on the Camera (source) cloud (recommended)
camera_pcd.estimate_normals(
search_param=o3d.geometry.KDTreeSearchParamHybrid(
radius=1.0,
max_nn=30
)
)

# Now you can run Point-to-Plane ICP
init_guess = np.eye(4)
threshold = 0.5 # or some appropriate distance
result_icp = o3d.pipelines.registration.registration_icp(
camera_pcd,
lidar_pcd,
threshold,
init_guess,
o3d.pipelines.registration.TransformationEstimationPointToPlane()
)

print("ICP result:", result_icp.transformation)
print("Fitness:", result_icp.fitness, " RMSE:", result_icp.inlier_rmse)

# After processing all frames, we can analyze or average
if len(icp_results) > 0:
# Example: pick the best frame by highest fitness
best_frame = max(icp_results, key=lambda x: x[2]) # x[2] is fitness
print("\nBest frame by fitness was index=", best_frame[0],
" with fitness=", best_frame[2], " rmse=", best_frame[3])
else:
print("No frames processed properly.")

if __name__ == "__main__":
main()
Loading
Loading