Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 09:05:02 +08:00
commit 265175ed82
23 changed files with 3329 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
# Camera Frustums in Robotics Visualization
## Overview
Camera frustums are essential for visualizing camera viewpoints in robotics applications. Vuer allows you to programmatically insert camera frustums into the scene to represent camera positions and orientations.
## Basic Frustum
```python
from vuer import Vuer
from vuer.schemas import Scene, Frustum, DefaultScene
import asyncio
app = Vuer()
@app.spawn(start=True)
async def main(session):
session.set @ Scene(
DefaultScene(),
Frustum(
position=[0, 1, 2],
rotation=[0, 0, 0],
scale=[1, 1, 1],
showImagePlane=True,
showFrustum=True,
showFocalPlane=True,
key="camera-frustum",
),
)
while True:
await asyncio.sleep(1.0)
app.run()
```
## Frustum Configuration Options
### showImagePlane
Display the image plane (where the image is captured).
### showFrustum
Show the frustum wireframe (pyramid shape representing the camera's field of view).
### showFocalPlane
Display the focal plane (plane at the focal length).
### Position and Orientation
- **position**: `[x, y, z]` coordinates
- **rotation**: Euler angles `[x, y, z]` in radians
- **scale**: `[x, y, z]` scale factors
## Stress Test Example: 1,728 Frustums
The tutorial demonstrates a stress-test implementation with a large grid of frustums:
```python
from vuer import Vuer, VuerSession
from vuer.schemas import Scene, Frustum, DefaultScene
import asyncio
app = Vuer()
@app.spawn(start=True)
async def main(session: VuerSession):
frustums = []
# Create 12×12×12 grid of frustums
for x in range(12):
for y in range(12):
for z in range(12):
frustums.append(
Frustum(
position=[x * 2, y * 2, z * 2],
scale=[0.5, 0.5, 0.5],
showImagePlane=True,
showFrustum=True,
showFocalPlane=False,
key=f"frustum-{x}-{y}-{z}",
)
)
session.set @ Scene(
DefaultScene(),
*frustums, # Unpack all frustums into the scene
)
while True:
await asyncio.sleep(1.0)
app.run()
```
This creates **1,728 frustum objects** (12³), demonstrating the framework's capability to handle large numbers of camera visualization objects simultaneously.
## Practical Use Case: Multi-Camera Robot
```python
from vuer import Vuer
from vuer.schemas import Scene, Frustum, Urdf, DefaultScene
import asyncio
app = Vuer()
@app.spawn(start=True)
async def main(session):
session.set @ Scene(
DefaultScene(),
# Robot model
Urdf(
src="/static/robot.urdf",
position=[0, 0, 0],
key="robot",
),
# Front camera
Frustum(
position=[0.5, 0.5, 0],
rotation=[0, 0, 0],
scale=[0.3, 0.3, 0.3],
showImagePlane=True,
showFrustum=True,
key="front-camera",
),
# Left camera
Frustum(
position=[0, 0.5, 0.5],
rotation=[0, -1.57, 0],
scale=[0.3, 0.3, 0.3],
showImagePlane=True,
showFrustum=True,
key="left-camera",
),
# Right camera
Frustum(
position=[0, 0.5, -0.5],
rotation=[0, 1.57, 0],
scale=[0.3, 0.3, 0.3],
showImagePlane=True,
showFrustum=True,
key="right-camera",
),
)
while True:
await asyncio.sleep(1.0)
app.run()
```
## Dynamic Frustum Updates
You can update frustum positions in real-time:
```python
import math
@app.spawn(start=True)
async def main(session):
session.set @ Scene(DefaultScene())
for i in range(1000):
# Orbit the frustum around the origin
x = 3 * math.cos(i * 0.05)
z = 3 * math.sin(i * 0.05)
rotation_y = i * 0.05
session.upsert @ Frustum(
position=[x, 1, z],
rotation=[0, rotation_y, 0],
showImagePlane=True,
showFrustum=True,
key="orbiting-camera",
)
await asyncio.sleep(0.033) # ~30 FPS
app.run()
```
## Performance Considerations
The stress test with 1,728 frustums demonstrates that Vuer can handle:
- Large numbers of visualization objects
- Complex geometric primitives
- Real-time rendering of camera representations
This makes it practical for robotics applications requiring:
- Multi-camera system visualization
- SLAM trajectory visualization
- Sensor fusion displays
- Camera calibration tools
## Source
Documentation: https://docs.vuer.ai/en/latest/tutorials/robotics/frustums.html