-
Notifications
You must be signed in to change notification settings - Fork 0
/
camera.py
138 lines (113 loc) · 5.11 KB
/
camera.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import pybullet as p
import pybullet_data
import numpy as np
import threading
import cv2
import math
import random
import time
from ball import Ball, Simulation
class RSD435:
def __init__(self, cameraPosition=[0, 0, 0], targetPosition=[1, 0, 0]):
self.projectionMatrixRGB = None
self.projectionMatrixDepth = None
self.viewMatrix = None
self.nearPlane = 0.28
self.farPlane = 3
self.resolutionDepth = (640, 360)
self.resolutionRGB = (960, 540)
self.fovDepth = (87, 58) # Horizontal, Vertical FOV
self.fovRGB = (69, 42) # Horizontal, Vertical FOV
self.cameraPosition = cameraPosition
self.targetPosition = targetPosition
self.update_view_and_projection()
def update_view_and_projection(self):
"""Update view and projection matrices based on current camera position and target position."""
self.viewMatrix = p.computeViewMatrix(self.cameraPosition, self.targetPosition, [0, 0, 1])
self.projectionMatrixDepth = p.computeProjectionMatrixFOV(
self.fovDepth[1], self.resolutionDepth[0] / self.resolutionDepth[1], self.nearPlane, self.farPlane
)
self.projectionMatrixRGB = p.computeProjectionMatrixFOV(
self.fovRGB[1], self.resolutionRGB[0] / self.resolutionRGB[1], self.nearPlane, self.farPlane
)
def getDepthImage(self):
try:
_, _, _, depth_img, _ = p.getCameraImage(
width=self.resolutionDepth[0],
height=self.resolutionDepth[1],
viewMatrix=self.viewMatrix,
projectionMatrix=self.projectionMatrixDepth,
flags=p.ER_NO_SEGMENTATION_MASK
)
depth_img = np.array(depth_img).reshape(self.resolutionDepth[1], self.resolutionDepth[0])
depth_normalized = cv2.normalize(depth_img, None, 0, 255, cv2.NORM_MINMAX)
return depth_normalized.astype(np.uint8)
except Exception as e:
print(f"Error capturing depth image: {e}")
return None
def getRGBImage(self):
try:
_, _, rgb_image, _, _ = p.getCameraImage(
self.resolutionRGB[0], self.resolutionRGB[1],
self.viewMatrix, self.projectionMatrixRGB
)
rgb_image = np.reshape(rgb_image, (self.resolutionRGB[1], self.resolutionRGB[0], 4)) # Reshape with 4 channels (RGBA)
rgb_image = rgb_image[:, :, :3] # Discard the alpha channel
return rgb_image
except Exception as e:
print(f"Error capturing RGB image: {e}")
return None
def create_camera_box(self, position, size=0.05):
visual_shape_id = p.createVisualShape(shapeType=p.GEOM_BOX, halfExtents=[size/2]*3, rgbaColor=[1, 0, 0, 1])
collision_shape_id = p.createCollisionShape(shapeType=p.GEOM_BOX, halfExtents=[size/2]*3)
p.createMultiBody(baseMass=0, baseVisualShapeIndex=visual_shape_id, baseCollisionShapeIndex=collision_shape_id, basePosition=position)
def run_simulation(camera):
p.setRealTimeSimulation(0)
step_counter = 0
while p.isConnected():
p.stepSimulation()
if step_counter % 480 == 0:
ball.spawn() # Spawn the ball or perform simulation logic
step_counter += 1
time.sleep(1.0 / 240) # Sleep for a fixed time step (240 Hz)
def capture_images(camera):
last_capture_time = time.time()
capture_interval = 0.05
while p.isConnected():
current_time = time.time()
if current_time - last_capture_time >= capture_interval:
depth_img = camera.getDepthImage()
rgb_image = camera.getRGBImage()
if depth_img is not None:
cv2.imshow("Depth Image", depth_img)
if rgb_image is not None:
cv2.imshow("RGB Image", rgb_image)
last_capture_time = current_time
# Check for a key press to close the windows
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if __name__ == "__main__":
p.connect(p.DIRECT)
p.setAdditionalSearchPath(pybullet_data.getDataPath())
p.loadURDF("plane.urdf")
r2d2_id = p.loadURDF("r2d2.urdf", [2, 1, 1])
p.setGravity(0, 0, -9.8)
z_velocity = random.uniform(1, 2) # Random z velocity
y_velocity = random.uniform(-0.5, 0.5) # Random y velocity
x_velocity = random.uniform(-8, -4) # Random x velocity
ball = Ball((3, 0, 1), (x_velocity, y_velocity, z_velocity))
camera = RSD435([0, 0, 1], [1, 0.5, 1])
camera.create_camera_box(camera.cameraPosition)
#camera.create_fov_lines(camera.cameraPosition, camera.targetPosition, camera.fovRGB[0], camera.fovRGB[1])
# Create threads for simulation and image capture
simulation_thread = threading.Thread(target=run_simulation, args=(camera,))
image_capture_thread = threading.Thread(target=capture_images, args=(camera,))
# Start the threads
simulation_thread.start()
image_capture_thread.start()
# Wait for the threads to finish
simulation_thread.join()
image_capture_thread.join()
# Clean up
cv2.destroyAllWindows()
p.disconnect()