Updates to use process for camera stream

This commit is contained in:
Rune Harlyk
2024-03-07 15:14:10 +01:00
parent 971418fce8
commit 9e40e01065
5 changed files with 54 additions and 36 deletions
+5 -3
View File
@@ -27,8 +27,9 @@ def main():
)
kinematics = SpotModel()
camera = WebCamera()
camera = PyBulletCamera(env.spot.quadruped)
# camera = WebCamera()
frame_queue = Queue(maxsize=10)
camera = PyBulletCamera(env.spot.quadruped, frame_queue=frame_queue)
imu = IMU()
hardware_interface = PyBulletHardwareInterface(env)
# shared_controller_state = SharedState()
@@ -36,7 +37,8 @@ def main():
spot = Spot(
kinematics,
camera,
camera,
frame_queue,
imu,
hardware_interface,
controller_interface,
+1 -1
View File
@@ -8,7 +8,7 @@ class WebCamera(CameraBase):
self._last_frame = None
super().__init__()
def get_frame(self):
def get_image(self):
self._last_frame
def update(self) -> None:
+32 -21
View File
@@ -1,5 +1,6 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from threading import Thread
from multiprocessing import Process
import cv2
import time
@@ -12,42 +13,52 @@ class StreamingHandler(BaseHTTPRequestHandler):
self.end_headers()
try:
while True:
frame = self.server.camera.get_frame()
_, jpeg = cv2.imencode('.jpg', frame)
self.wfile.write(b'--frame\r\n')
self.send_header('Content-Type', 'image/jpeg')
self.send_header('Content-Length', len(jpeg))
self.end_headers()
self.wfile.write(jpeg.tobytes())
self.wfile.write(b'\r\n')
time.sleep(0.5)
if not self.server.frame_queue.empty():
frame = self.server.frame_queue.get()
_, jpeg = cv2.imencode('.jpg', frame)
self.wfile.write(b'--frame\r\n')
self.send_header('Content-Type', 'image/jpeg')
self.send_header('Content-Length', len(jpeg))
self.end_headers()
self.wfile.write(jpeg.tobytes())
self.wfile.write(b'\r\n')
time.sleep(0.1)
except Exception as e:
print(f"Stream stopped: {e}")
raise e
else:
self.send_error(404)
self.end_headers()
class StreamingServer(HTTPServer):
def __init__(self, server_address, camera):
def __init__(self, server_address, frame_queue):
super().__init__(server_address, StreamingHandler)
self.camera = camera
self.frame_queue = frame_queue
class StreamingServerThread:
def __init__(self, camera, port=8080):
self.camera = camera
def __init__(self, frame_queue, port=8080):
self.frame_queue = frame_queue
self.port = port
self.server_thread = None
def start(self):
def run_server():
address = ('', self.port)
server = StreamingServer(address, self.camera)
print(f"Starting server at http://localhost:{self.port}/stream.mjpg")
server.serve_forever()
def run_server(self, frame_queue):
address = ('', self.port)
server = StreamingServer(address, frame_queue)
print(f"Starting server at http://localhost:{self.port}/stream.mjpg")
server.serve_forever()
self.server_thread = Thread(target=run_server)
def start(self):
self.server_thread = Thread(target=self.run_server)
self.server_thread.daemon = True
self.server_thread.start()
def start_process(self):
self.server_process = Process(target=self.run_server, args=(self.frame_queue,))
self.server_process.start()
def stop(self):
self.server_thread.join()
if self.server_thread:
self.server_thread.join()
if self.server_process:
self.server_process.join()
+4 -5
View File
@@ -14,7 +14,7 @@ def map_value(x, from_low, from_high, to_low, to_high):
return ((x - from_low) / (from_high - from_low)) * (to_high - to_low) + to_low
class Spot:
def __init__(self, kinematic, camera:CameraBase, imu, hardware_interface, controller_interface, shared_controller_state):
def __init__(self, kinematic, camera:CameraBase, frame_queue, imu, hardware_interface, controller_interface, shared_controller_state):
self.kinematic = kinematic
self.camera = camera
self.imu = imu
@@ -22,7 +22,7 @@ class Spot:
self.controller_interface = controller_interface
self.shared_controller_state = shared_controller_state
self.camera_stream = StreamingServerThread(self.camera)
self.camera_stream = StreamingServerThread(frame_queue)
self.body_state = BodyState()
self.gait_state = GaitState()
@@ -31,9 +31,8 @@ class Spot:
self.body_state.worldFeetPositions = copy.deepcopy(self.kinematic.WorldToFoot)
def start(self):
self.controller_interface.start()
self.camera_stream.start()
self.camera_stream.start_process()
def stop(self):
self.controller_interface.stop()
@@ -52,7 +51,7 @@ class Spot:
# self.gait_state.target_yaw_rate = map_value(controller.rx, -127, 128, -2.0, 2.0)
def run(self, dt=.01):
# self.camera.update()
self.camera.update()
controller = self.shared_controller_state.get_latest_state()
self.handle_input(controller)
self.gait_state.update_gait_state(dt)