Subscribing to Images in VRobotNode
To process camera feeds from the simulator, a VRobotNode must explicitly register image subscribers.
This is done using:
self.register_img_subscriber("left")
Topic Naming Convention
The VRobots simulator publishes image data in the format:
vr/[sysId]/cams/[side]/720p
sysId→ Robot system ID (e.g.,0,1,2).side→ Camera identifier (e.g.,left,right,down).
Example published topics:
[i] vr/0/cams/down/720p
[i] vr/0/cams/left/720p
[i] vr/0/cams/right/720p
[z] vr/0/states
Each robot may have a different set of cameras. For instance, the "multirotor" currently provides three: left, right, and down.
When registering subscribers, you must use the correct camera side name.
Example: Image Subscriber with OpenCV
from ubicoders_vrobots_ipc.vrobot_node import VRobotNodeBase, vrobot_client_runner
import cv2
class VRobotNode(VRobotNodeBase):
def __init__(self, sysId: int = 0):
super().__init__(sysId)
# ======================================================
# Arduino-like lifecycle: setup() and update()
# One-time setup
def setup(self):
# OpenCV window setup
cv2.namedWindow("CamLeft", cv2.WINDOW_NORMAL) # resizable window
cv2.resizeWindow("CamLeft", 640, 360)
# Subscribe to left camera stream
self.register_img_subscriber("left")
# Called every iteration
def update(self):
# State updates
if self.read_new_states():
ts = self.state.timestamp # Unix time (ms)
pos = self.state.linPos
elapsed_sec: float = (ts - self.first_ts) / 1000.0
print(f"State t={elapsed_sec:.3f} pos=({pos.x:.2f},{pos.y:.2f},{pos.z:.2f})")
# Image updates
if self.read_new_image("left"):
img = self.imgStates["left"].image_data
elapsed_sec: float = (self.imgStates["left"].ts - self.first_ts) / 1000.0
print(f"Image Left t={elapsed_sec:.3f} size=({img.shape[1]}x{img.shape[0]}x{img.shape[2]})")
# Display live feed
cv2.imshow("CamLeft", img)
cv2.waitKey(1)
# ======================================================
if __name__ == "__main__":
vrobot_client_runner([VRobotNode(sysId=0)])
Key Points
- Subscription naming: Match the correct camera
side(left,right,down). - One-time registration: Call
register_img_subscriber()insetup(). - Live display: Use OpenCV (
imshow,waitKey) to show images in real-time. - Integration: Image reading (
read_new_image()) and state reading (read_new_states()) can run in parallel each iteration.