-
This commit is contained in:
+9
-2
@@ -1010,13 +1010,20 @@ def api_arm_get_angles():
|
|||||||
@app.route("/api/arm/set_angles", methods=["POST"])
|
@app.route("/api/arm/set_angles", methods=["POST"])
|
||||||
def api_arm_set_angles():
|
def api_arm_set_angles():
|
||||||
"""设置关节角度"""
|
"""设置关节角度"""
|
||||||
data = request.json
|
data = request.json or {}
|
||||||
angles = data.get("angles", [])
|
angles = data.get("angles", [])
|
||||||
speed = data.get("speed", 500)
|
speed = data.get("speed", 500)
|
||||||
|
if not isinstance(angles, list) or len(angles) != 6:
|
||||||
|
return jsonify({"ok": False, "error": "角度数据必须包含 6 个关节值"}), 400
|
||||||
|
try:
|
||||||
|
angles = [float(a) for a in angles]
|
||||||
|
speed = int(speed)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return jsonify({"ok": False, "error": "角度或速度格式错误"}), 400
|
||||||
if not gs.arm_client:
|
if not gs.arm_client:
|
||||||
return jsonify({"ok": False, "error": "未连接机械臂"}), 400
|
return jsonify({"ok": False, "error": "未连接机械臂"}), 400
|
||||||
ok = gs.arm_client.set_angles(angles, speed)
|
ok = gs.arm_client.set_angles(angles, speed)
|
||||||
return jsonify({"ok": ok})
|
return jsonify({"ok": ok, "error": None if ok else "机械臂执行失败"})
|
||||||
|
|
||||||
@app.route("/api/arm/set_angle", methods=["POST"])
|
@app.route("/api/arm/set_angle", methods=["POST"])
|
||||||
def api_arm_set_angle():
|
def api_arm_set_angle():
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|||||||
|
|
||||||
# ========== 网络配置(集中管理所有 IP 地址 — 修改此处即可全局生效)==========
|
# ========== 网络配置(集中管理所有 IP 地址 — 修改此处即可全局生效)==========
|
||||||
AGV_HOST = "192.168.50.93"
|
AGV_HOST = "192.168.50.93"
|
||||||
ARM_HOST = "192.168.50.90"
|
ARM_HOST = "192.168.50.91"
|
||||||
|
|
||||||
# ========== AGV 参数 ==========
|
# ========== AGV 参数 ==========
|
||||||
AGV_CONFIG = {
|
AGV_CONFIG = {
|
||||||
|
|||||||
@@ -858,12 +858,24 @@ createApp({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
async applyAngles(angles = null) {
|
async applyAngles(angles = null) {
|
||||||
const targetAngles = angles || this.angleInputs
|
const targetAngles = Array.isArray(angles) ? angles : this.angleInputs
|
||||||
await fetch(API + '/api/arm/set_angles', {
|
if (!Array.isArray(targetAngles) || targetAngles.length !== 6) {
|
||||||
|
alert('角度数据无效,请先刷新角度')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const res = await fetch(API + '/api/arm/set_angles', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ angles: targetAngles, speed: 500 })
|
body: JSON.stringify({ angles: targetAngles, speed: 500 })
|
||||||
})
|
})
|
||||||
|
const data = await res.json()
|
||||||
|
if (!data.ok) {
|
||||||
|
alert('应用角度失败: ' + (data.error || '机械臂未响应'))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this.angleInputs = [...targetAngles]
|
||||||
|
setTimeout(() => this.refreshAngles(), 2000)
|
||||||
|
return true
|
||||||
},
|
},
|
||||||
async mirrorAngles() {
|
async mirrorAngles() {
|
||||||
// 镜像角度:只取反 J1,其它不变
|
// 镜像角度:只取反 J1,其它不变
|
||||||
@@ -872,7 +884,8 @@ createApp({
|
|||||||
|
|
||||||
// 应用到机械臂
|
// 应用到机械臂
|
||||||
try {
|
try {
|
||||||
await this.applyAngles(mirrored)
|
const ok = await this.applyAngles(mirrored)
|
||||||
|
if (!ok) return
|
||||||
this.angleInputs = mirrored // 只有在成功后才更新显示
|
this.angleInputs = mirrored // 只有在成功后才更新显示
|
||||||
alert('✅ 角度已镜像并应用(仅 J1 取反)')
|
alert('✅ 角度已镜像并应用(仅 J1 取反)')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -509,7 +509,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="btn-row">
|
<div class="btn-row">
|
||||||
<button class="btn btn-primary" @click="refreshAngles">🔄 刷新角度</button>
|
<button class="btn btn-primary" @click="refreshAngles">🔄 刷新角度</button>
|
||||||
<button class="btn btn-secondary" @click="applyAngles">✅ 应用角度</button>
|
<button class="btn btn-secondary" @click="applyAngles()">✅ 应用角度</button>
|
||||||
<button class="btn btn-warning" @click="mirrorAngles">🔄 镜像角度</button>
|
<button class="btn btn-warning" @click="mirrorAngles">🔄 镜像角度</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|||||||
|
|
||||||
# ========== 网络配置(集中管理所有 IP 地址 — 修改此处即可全局生效)==========
|
# ========== 网络配置(集中管理所有 IP 地址 — 修改此处即可全局生效)==========
|
||||||
AGV_HOST = "192.168.50.93"
|
AGV_HOST = "192.168.50.93"
|
||||||
ARM_HOST = "192.168.50.90"
|
ARM_HOST = "192.168.50.91"
|
||||||
|
|
||||||
# ========== AGV 参数 ==========
|
# ========== AGV 参数 ==========
|
||||||
AGV_CONFIG = {
|
AGV_CONFIG = {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
# 机械臂端依赖(最少依赖)
|
# 机械臂端依赖(最少依赖)
|
||||||
# RoboFlow 已在树莓派上运行,此端仅做透传
|
# RoboFlow 已在树莓派上运行,此端仅做透传
|
||||||
flask>=2.0
|
flask>=1.0,<2.3
|
||||||
|
|||||||
+8
-1
@@ -2,4 +2,11 @@
|
|||||||
# 启动机械臂服务端
|
# 启动机械臂服务端
|
||||||
|
|
||||||
cd ~/work/arm_server
|
cd ~/work/arm_server
|
||||||
python3 arm_server.py
|
PYTHON_BIN="${PYTHON_BIN:-/usr/bin/python3}"
|
||||||
|
|
||||||
|
if ! "$PYTHON_BIN" -c "import flask" >/dev/null 2>&1; then
|
||||||
|
echo "Flask 未安装,正在安装 requirements.txt..."
|
||||||
|
"$PYTHON_BIN" -m pip install --user -r requirements.txt
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$PYTHON_BIN" arm_server.py
|
||||||
|
|||||||
Reference in New Issue
Block a user