增加局域网发布消息+全图+锥桶
This commit is contained in:
176
README.md
176
README.md
@@ -0,0 +1,176 @@
|
||||
# Origincar Simulation
|
||||
|
||||
基于 MotrixSim 的阿克曼小车仿真,支持键盘控制和 HTTP API 局域网共享。
|
||||
|
||||
## 启动
|
||||
|
||||
```bash
|
||||
uv run mxpython main.py
|
||||
```
|
||||
|
||||
## HTTP API(端口 8765)
|
||||
|
||||
仿真启动后,局域网内其他设备可通过 HTTP 获取摄像头图像、IMU 数据和发送控制指令。
|
||||
|
||||
### GET `/image`
|
||||
|
||||
获取前置摄像头最新 JPEG 图像。浏览器可直接打开。
|
||||
|
||||
```bash
|
||||
# 浏览器
|
||||
http://<仿真机IP>:8765/image
|
||||
|
||||
# curl
|
||||
curl http://192.168.1.100:8765/image -o frame.jpg
|
||||
|
||||
# Python
|
||||
import requests
|
||||
r = requests.get("http://192.168.1.100:8765/image")
|
||||
with open("frame.jpg", "wb") as f:
|
||||
f.write(r.content)
|
||||
```
|
||||
|
||||
### GET `/state`
|
||||
|
||||
获取小车当前状态(JSON)。
|
||||
|
||||
```bash
|
||||
curl http://192.168.1.100:8765/state
|
||||
```
|
||||
|
||||
返回示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"x": -2.0,
|
||||
"y": -2.3,
|
||||
"z": 0.08,
|
||||
"yaw_deg": 0.0,
|
||||
"speed_target": 1.0,
|
||||
"speed_actual": 0.98,
|
||||
"steer_target": 0.0,
|
||||
"speed_amp": 1.0,
|
||||
"steer_amp": 0.35
|
||||
}
|
||||
```
|
||||
|
||||
### GET `/imu`
|
||||
|
||||
获取 IMU 数据(含 MPU6050 噪声),JSON。
|
||||
|
||||
```bash
|
||||
curl http://192.168.1.100:8765/imu
|
||||
```
|
||||
|
||||
返回示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"orientation": {"w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0},
|
||||
"angular_velocity": {"x": 0.001, "y": -0.003, "z": 0.008},
|
||||
"linear_acceleration": {"x": 0.02, "y": -0.01, "z": 9.81}
|
||||
}
|
||||
```
|
||||
|
||||
噪声参数(MPU6050 级别):
|
||||
- 陀螺仪白噪声 σ = 0.01 rad/s,bias 随机游走
|
||||
- 加速度计白噪声 σ = 0.05 m/s²,bias 随机游走
|
||||
|
||||
### POST `/cmd`
|
||||
|
||||
发送控制指令(JSON)。
|
||||
|
||||
```bash
|
||||
curl -X POST http://192.168.1.100:8765/cmd \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"speed": 1.0, "steer": 0.3}'
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `speed` | float | 目标速度 m/s,正=前进,负=后退 |
|
||||
| `steer` | float | 目标转向角 rad,正=左转,负=右转 |
|
||||
|
||||
**Python 客户端示例**:
|
||||
|
||||
```python
|
||||
import time
|
||||
import requests
|
||||
|
||||
IP = "192.168.1.100"
|
||||
|
||||
# 获取图像
|
||||
r = requests.get(f"http://{IP}:8765/image")
|
||||
with open("frame.jpg", "wb") as f:
|
||||
f.write(r.content)
|
||||
|
||||
# 获取状态
|
||||
state = requests.get(f"http://{IP}:8765/state").json()
|
||||
print(f"位置: ({state['x']}, {state['y']}), 速度: {state['speed_actual']} m/s")
|
||||
|
||||
# 发送控制指令
|
||||
requests.post(f"http://{IP}:8765/cmd", json={"speed": 1.0, "steer": 0.2})
|
||||
time.sleep(2)
|
||||
requests.post(f"http://{IP}:8765/cmd", json={"speed": 0.0, "steer": 0.0})
|
||||
```
|
||||
|
||||
**ROS2 桥接示例**:
|
||||
|
||||
```python
|
||||
import rclpy
|
||||
from rclpy.node import Node
|
||||
from sensor_msgs.msg import Image as RosImage
|
||||
from geometry_msgs.msg import Twist
|
||||
from cv_bridge import CvBridge
|
||||
import requests
|
||||
import numpy as np
|
||||
import cv2
|
||||
|
||||
IP = "192.168.1.100"
|
||||
|
||||
class OrigincarBridge(Node):
|
||||
def __init__(self):
|
||||
super().__init__("origincar_bridge")
|
||||
self.bridge = CvBridge()
|
||||
self.pub = self.create_publisher(RosImage, "/image", 10)
|
||||
self.sub = self.create_subscription(Twist, "/cmd_vel", self.cmd_cb, 10)
|
||||
self.timer = self.create_timer(0.1, self.fetch_and_publish)
|
||||
|
||||
def fetch_and_publish(self):
|
||||
r = requests.get(f"http://{IP}:8765/image", timeout=1)
|
||||
if r.status_code == 200:
|
||||
arr = np.frombuffer(r.content, np.uint8)
|
||||
cv_img = cv2.imdecode(arr, cv2.IMREAD_COLOR)
|
||||
msg = self.bridge.cv2_to_imgmsg(cv_img, "bgr8")
|
||||
self.pub.publish(msg)
|
||||
|
||||
def cmd_cb(self, msg: Twist):
|
||||
requests.post(f"http://{IP}:8765/cmd", json={
|
||||
"speed": msg.linear.x,
|
||||
"steer": msg.angular.z
|
||||
})
|
||||
|
||||
rclpy.init()
|
||||
node = OrigincarBridge()
|
||||
rclpy.spin(node)
|
||||
```
|
||||
|
||||
## 键盘控制
|
||||
|
||||
| 按键 | 方式 | 作用 |
|
||||
|------|------|------|
|
||||
| W/S | 按住 | 前进/后退 |
|
||||
| A/D | 按住 | 左转/右转 |
|
||||
| ↑/↓ | 点按 | 速度幅度 ±0.2 m/s(0~2.0) |
|
||||
| ←/→ | 点按 | 转向幅度 ±0.05 rad(0~0.5) |
|
||||
| Space | 点按 | 截图保存到 `captures/` |
|
||||
|
||||
键盘与 HTTP `/cmd` 可同时使用:按住 W/A/S/D 时键盘优先,松开后自动切回 HTTP 控制。
|
||||
|
||||
## 场景结构
|
||||
|
||||
```
|
||||
scene.xml — 5m×5m 地图 + 40cm 白色围栏 + 阿克曼小车
|
||||
main.py — 仿真控制 + HTTP API 服务
|
||||
origincar.urdf / origincar.xacro — 小车模型(参考)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user