Spaces:
Sleeping
Sleeping
| """ZeroSense Robot Simulation | |
| Simulates a warehouse robot navigating and completing tasks. | |
| Each task completion triggers the ZK proof pipeline. | |
| Uses PyBullet for physics simulation (install: pip install pybullet) | |
| Fallback: simple ASCII animation for demo purposes. | |
| """ | |
| import asyncio | |
| import math | |
| import os | |
| import random | |
| import time | |
| from typing import Optional | |
| import httpx | |
| API_URL = os.getenv("ZEROSENSE_API_URL", "http://localhost:8000") | |
| class WarehouseRobot: | |
| """Simulated warehouse robot that generates sensor data.""" | |
| def __init__(self, robot_id: str = "robot-001"): | |
| self.robot_id = robot_id | |
| self.position = [0.0, 0.0] | |
| self.heading = 0.0 | |
| self.task_count = 0 | |
| self.speed = 0.1 | |
| # Try to initialize PyBullet | |
| self.pybullet_available = False | |
| try: | |
| import pybullet as p | |
| import pybullet_data | |
| self.p = p | |
| self.physics_client = p.connect(p.DIRECT) # Headless | |
| p.setAdditionalSearchPath(pybullet_data.getDataPath()) | |
| p.setGravity(0, 0, -9.81) | |
| p.loadURDF("plane.urdf") | |
| self.pybullet_available = True | |
| print(f"[Robot {robot_id}] β PyBullet physics simulation active") | |
| except Exception as e: | |
| print(f"[Robot {robot_id}] β οΈ PyBullet not available β using simple sim") | |
| def capture_sensor_frame(self) -> list[float]: | |
| """Capture a sensor frame (camera/LiDAR simulation).""" | |
| # Simulate 64 sensor readings (8x8 simplified LiDAR grid) | |
| frame = [] | |
| for i in range(64): | |
| angle = (i / 64) * 2 * math.pi + self.heading | |
| # Simulate distance readings with some noise | |
| base_distance = 0.5 + 0.3 * math.sin(angle * 3) | |
| noise = random.gauss(0, 0.05) | |
| frame.append(max(0.0, min(1.0, base_distance + noise))) | |
| return frame | |
| def navigate_to_task(self, target: tuple[float, float]) -> bool: | |
| """Navigate to a task location. Returns True when reached.""" | |
| dx = target[0] - self.position[0] | |
| dy = target[1] - self.position[1] | |
| distance = math.sqrt(dx**2 + dy**2) | |
| if distance < 0.1: | |
| return True # Task location reached | |
| # Move toward target | |
| self.heading = math.atan2(dy, dx) | |
| self.position[0] += self.speed * math.cos(self.heading) | |
| self.position[1] += self.speed * math.sin(self.heading) | |
| return False | |
| def generate_task_sensor_data(self, num_frames: int = 5) -> list[list[float]]: | |
| """Generate multiple sensor frames for a task.""" | |
| return [self.capture_sensor_frame() for _ in range(num_frames)] | |
| def ascii_display(self, task_desc: str = ""): | |
| """Simple ASCII robot status display.""" | |
| bars = "β" * int(self.task_count) | |
| print(f"\n{'β'*50}") | |
| print(f" π€ Robot: {self.robot_id}") | |
| print(f" π Position: ({self.position[0]:.2f}, {self.position[1]:.2f})") | |
| print(f" β Tasks: {self.task_count} | {bars}") | |
| if task_desc: | |
| print(f" π― Current: {task_desc}") | |
| print(f"{'β'*50}") | |
| async def run_simulation(num_tasks: int = 5): | |
| """Run the warehouse robot simulation. | |
| Each task completion triggers the full ZK proof pipeline. | |
| """ | |
| print("\n" + "β"*50) | |
| print(" π€ ZeroSense Warehouse Robot Simulation") | |
| print(" ZK-Verified AI Intelligence on Stellar") | |
| print("β"*50) | |
| robot = WarehouseRobot(robot_id="robot-001") | |
| # Define warehouse tasks | |
| tasks = [ | |
| {"id": f"task_{i:03d}", "location": (random.uniform(-5, 5), random.uniform(-5, 5)), | |
| "desc": random.choice(["Pick item A-42", "Deliver to Bay 7", "Scan shelf C-12", | |
| "Restock Zone 3", "Quality check D-99"])} | |
| for i in range(num_tasks) | |
| ] | |
| async with httpx.AsyncClient(base_url=API_URL, timeout=30.0) as client: | |
| for task in tasks: | |
| print(f"\nπ― Task: {task['desc']}") | |
| robot.ascii_display(task["desc"]) | |
| # Navigate to task location | |
| reached = False | |
| steps = 0 | |
| while not reached and steps < 50: | |
| reached = robot.navigate_to_task(task["location"]) | |
| steps += 1 | |
| if steps % 10 == 0: | |
| print(f" πΆ Navigating... ({steps} steps)") | |
| print(f" β Reached task location!") | |
| # Generate sensor data | |
| sensor_frames = robot.generate_task_sensor_data(num_frames=3) | |
| print(f" π‘ Captured {len(sensor_frames)} sensor frames") | |
| # Trigger ZK proof pipeline via API | |
| print(f" π Generating ZK proof...") | |
| try: | |
| response = await client.post("/generate-proof", json={ | |
| "robot_id": robot.robot_id, | |
| "task_id": task["id"], | |
| "sensor_frames": [ | |
| {"pixels": frame, "frame_id": i} | |
| for i, frame in enumerate(sensor_frames) | |
| ], | |
| }) | |
| if response.status_code == 200: | |
| data = response.json() | |
| print(f" β ZK Proof Generated!") | |
| print(f" Action: {data['action_label']} ({data['confidence']}% confidence)") | |
| print(f" Proof hash: {data['proof_hex'][:16]}...") | |
| # Submit to Stellar for verification + payment | |
| verify_response = await client.post("/verify-proof", json={ | |
| "robot_id": robot.robot_id, | |
| "task_id": task["id"], | |
| "proof_hex": data["proof_hex"], | |
| "model_hash": data["model_hash"], | |
| "confidence": data["confidence"], | |
| "action_type": data["action"], | |
| }) | |
| if verify_response.status_code == 200: | |
| vdata = verify_response.json() | |
| print(f" π Stellar TX: {vdata.get('stellar_tx', 'pending')}") | |
| if vdata.get("auto_payment"): | |
| print(f" β‘ XLM auto-paid! (confidence >= 95%)") | |
| robot.task_count += 1 | |
| except httpx.ConnectError: | |
| print(f" β οΈ API not running. Start with: uvicorn api.main:app --reload") | |
| # Simulate locally | |
| print(f" [DEMO] Proof: {task['id']}_zk_proof") | |
| print(f" [DEMO] Action: task_complete (95% confidence)") | |
| print(f" [DEMO] XLM auto-paid β‘") | |
| robot.task_count += 1 | |
| await asyncio.sleep(1) # Brief pause between tasks | |
| print("\n" + "β"*50) | |
| print(f" π Simulation Complete!") | |
| print(f" β {robot.task_count}/{num_tasks} tasks ZK-verified") | |
| print(f" β‘ XLM payments auto-triggered on Stellar") | |
| print(f" β ZREP reputation tokens minted") | |
| print("β"*50) | |
| if __name__ == "__main__": | |
| asyncio.run(run_simulation(num_tasks=5)) | |