Spaces:
Paused
Paused
File size: 6,835 Bytes
24857f8 | 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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | # FoundationPose Quick Start Guide
## Overview
This Hugging Face Space provides two modes:
1. **Placeholder Mode** (default) - Returns empty results, useful for testing the API without GPU requirements
2. **Real Mode** - Uses actual FoundationPose model for 6D pose estimation (requires GPU and model weights)
## Testing Locally (Placeholder Mode)
The easiest way to test the API structure:
```bash
cd foundationpose
pip install -r requirements.txt
python app.py
```
Visit http://localhost:7860 to see the UI.
## Deploying to Hugging Face Spaces
### Option 1: Placeholder Mode (No Setup Required)
Just push to your Space:
```bash
cd foundationpose
git add .
git commit -m "Deploy FoundationPose Space"
git push
```
The Space will run in placeholder mode by default. This is useful for:
- Testing the API structure
- Developing client integrations
- Demos without GPU costs
### Option 2: Real FoundationPose (Requires Setup)
**Step 1: Clone FoundationPose Repository**
```bash
# Inside your local foundationpose directory
git clone https://github.com/NVlabs/FoundationPose.git
```
**Step 2: Download Model Weights**
Download weights from the official Google Drive:
https://drive.google.com/drive/folders/1GCyGE-LbFGgRC-FuGsF3a1zeBuzsQ1Da
Extract to:
```
foundationpose/weights/
├── 2023-10-28-18-33-37/ (refiner weights)
└── 2024-01-11-20-02-45/ (scorer weights)
```
**Step 3: Add Weights to Git LFS**
```bash
git lfs install
git lfs track "weights/**/*.pth"
git lfs track "weights/**/*.ckpt"
git add .gitattributes
git add weights/
git commit -m "Add model weights"
```
**Step 4: Enable Real Mode**
Add to your Space settings (or use .env file locally):
```
USE_REAL_MODEL=true
```
**Step 5: Push to HF**
```bash
git push
```
## Using the API
### Python Client
```python
from foundationpose.client import FoundationPoseClient
import cv2
import numpy as np
# Initialize client
client = FoundationPoseClient("https://gpue-foundationpose.hf.space")
# Load reference images
ref_images = []
for i in range(1, 16):
img = cv2.imread(f"reference/image_{i:03d}.jpg")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ref_images.append(img)
# Register object
client.initialize("target_cube", ref_images)
# Estimate pose
query_img = cv2.imread("query.jpg")
query_img = cv2.cvtColor(query_img, cv2.COLOR_BGR2RGB)
poses = client.estimate_pose("target_cube", query_img)
print(f"Detected {len(poses)} poses")
for pose in poses:
print(f"Position: {pose['position']}")
print(f"Orientation: {pose['orientation']}")
print(f"Confidence: {pose['confidence']}")
```
### Direct HTTP API
```bash
# Initialize
curl -X POST https://gpue-foundationpose.hf.space/api/initialize \
-H "Content-Type: application/json" \
-d '{
"object_id": "target_cube",
"reference_images_b64": ["'$(base64 -w 0 ref1.jpg)'", "'$(base64 -w 0 ref2.jpg)'"],
"camera_intrinsics": "{\"fx\": 500, \"fy\": 500, \"cx\": 320, \"cy\": 240}"
}'
# Estimate
curl -X POST https://gpue-foundationpose.hf.space/api/estimate \
-H "Content-Type: application/json" \
-d '{
"object_id": "target_cube",
"query_image_b64": "'$(base64 -w 0 query.jpg)'"
}'
```
## Integration with robot-ml Training
Update `/training/nova_sim_trainer/perception/foundation_pose_wrapper.py`:
```python
from foundationpose.client import FoundationPoseClient
class FoundationPoseWrapper(PoseEstimator):
def __init__(self, api_url: str, tracked_objects: List[Dict], **kwargs):
super().__init__()
self.client = FoundationPoseClient(api_url)
# Initialize each tracked object
for obj_config in tracked_objects:
object_id = obj_config["object_id"]
ref_dir = Path(obj_config["reference_images_dir"])
# Load reference images
ref_images = []
for img_path in sorted(ref_dir.glob("*.jpg")):
img = cv2.imread(str(img_path))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
ref_images.append(img)
# Register object
self.client.initialize(object_id, ref_images)
logger.info(f"Registered {object_id} with {len(ref_images)} images")
def estimate_poses(self, frame, camera_intrinsics, scene_objects):
# Call API for pose estimation
poses = self.client.estimate_pose(
self.tracked_objects[0]["object_id"], # For now, single object
frame,
camera_intrinsics
)
# Convert to DetectedPose format
return [DetectedPose(**pose) for pose in poses]
```
Update `observations.yaml`:
```yaml
perception:
enabled: true
model: foundation_pose
api_url: https://gpue-foundationpose.hf.space
tracked_objects:
- object_id: target_cube
reference_images_dir: ./perception/reference/target_cube
```
## Performance Tips
### Cold Start Latency
- First request takes 15-30s (GPU allocation + model loading)
- Subsequent requests: 0.5-2s
### Keeping GPU Warm
Send periodic keep-alive requests:
```python
import time
import threading
def keep_warm():
while True:
try:
client.estimate_pose("target_cube", dummy_image)
except:
pass
time.sleep(60) # Every minute
threading.Thread(target=keep_warm, daemon=True).start()
```
### Batch Processing
For recorded episodes, process all frames in one session:
```python
# Initialize once
client.initialize("target_cube", ref_images)
# Process all frames
poses_list = []
for frame in frames:
poses = client.estimate_pose("target_cube", frame)
poses_list.append(poses)
```
## Troubleshooting
### Space shows "Placeholder mode"
- Set `USE_REAL_MODEL=true` in Space secrets
- Verify weights are uploaded correctly
- Check Space logs for errors
### "Model weights not found"
- Ensure weights are in `weights/` directory
- Check git-lfs tracked files: `git lfs ls-files`
- Re-upload if needed
### GPU timeout
- Increase `@spaces.GPU(duration=X)` in app.py
- Reduce image resolution
- Process fewer reference images
### Out of memory
- Use lower resolution images
- Process fewer objects simultaneously
- Request more GPU resources in Space settings
## Cost Optimization
ZeroGPU is free but has usage limits:
- **Development**: Use placeholder mode
- **Testing**: Enable real mode for specific tests only
- **Production**: Consider dedicated GPU deployment (RunPod, Modal, etc.)
## Next Steps
1. Test locally in placeholder mode
2. Upload weights for real mode
3. Integrate with robot-ml training pipeline
4. Monitor GPU usage and costs
5. Optimize batch processing for your use case
## Support
- **Issues**: https://github.com/gpuschel/robot-ml/issues
- **FoundationPose**: https://github.com/NVlabs/FoundationPose
- **HF Spaces**: https://huggingface.co/docs/hub/spaces
|