- 选型指南
- 概述
- 入门指南
- 机械臂参数
- 示教器使用
-
二次开发
-
API(C++)
- 快速开始
- 接口说明
- 7000端口接口说明
- 使用示例
- 返回值说明
-
API(Python)
- 快速开始
- 接口说明
- 7000端口接口说明
- 使用示例
- 返回值说明
- ROS2开发
-
API(C++)
- 相关下载
MoveJ / MoveL使用示例
MoveJ / MoveL 使用示例
Python
# /**
# * ex_move_control.py
# * @brief 运动控制相关接口(包括MoveJ、MoveL)
# * @attention
# * - 运行模式:示教模式
# * - 开始前需: connect_robot → set_servo_state(1) → set_servo_poweron
# * - 退出前需: set_servo_poweroff → disconnect_robot
# * - 确保机械臂供电正常、网络通信正常
# * @note 运行步骤
# * 运行: python3 ex_move_control.py
# */
import sys
import os
import platform
# 基于脚本所在目录构建 SDK Python 绑定的绝对路径
_script_dir = os.path.dirname(os.path.abspath(__file__))
# 自动检测平台,添加对应 SDK Python 绑定路径
if platform.system() == "Windows":
sys.path.append(os.path.join(_script_dir, "../../lib/windows/python"))
elif platform.machine() in ("aarch64", "arm64"):
sys.path.append(os.path.join(_script_dir, "../../lib/linux/arm64/python"))
else:
sys.path.append(os.path.join(_script_dir, "../../lib/linux/x86/python"))
# Windows: 将 tl_host.dll 所在目录加入 DLL 搜索路径
if platform.system() == "Windows":
_dll_dir = os.path.join(_script_dir, "../../lib/windows")
os.add_dll_directory(_dll_dir)
from tl_interface import *
import time
# ============================================================
# 工具函数
# ============================================================
def print_result(msg, ret):
"""输出操作结果
@param msg 操作描述
@param ret 返回码(Result枚举值)
"""
if ret == SUCCESS:
print(" [成功] " + msg)
else:
print(" [失败] " + msg + ",错误码: " + str(ret))
def print_separator(title):
"""输出分隔标题"""
print("\n========== " + title + " ==========")
def enable_servo(socket_fd):
"""使能上电 ------
先清错,再检查伺服状态,报警则报错退出,最后上电
@param socket_fd 6001端口 socket
"""
print("--- 检查伺服状态 ---")
# 1. 先清除控制器错误和报警,再下电复位确保状态同步
clear_error(socket_fd)
time.sleep(0.3)
set_servo_poweroff(socket_fd)
time.sleep(0.3)
# 2. 检查伺服状态
state = -1
ret, state = get_servo_state(socket_fd, state)
if ret != SUCCESS:
print(f"[ERROR] 获取伺服状态失败: {ret}")
return
print(f" [信息] 当前伺服状态: {state} (0=停止 1=就绪 2=报警 3=运行)")
if state == 2:
print("[ERROR] 伺服处于报警状态,无法上电,请排查报警原因后重试")
return
if state == 3:
print("[INFO] 机械臂已在使能上电状态")
return
# 3. 上电流程
if state == 0:
print(" [信息] 伺服处于停止状态,设置就绪...")
ret = set_servo_state(socket_fd, 1)
if ret != SUCCESS and ret != OPERATION_NOT_ALLOWED:
print(f"[ERROR] 设置伺服就绪失败: {ret}")
return
time.sleep(0.5)
print(" [信息] 上电使能...")
ret = set_servo_poweron(socket_fd)
if ret != SUCCESS:
print(f"[ERROR] 上电失败: {ret}")
return
time.sleep(2)
# 4. 确认结果
_, state = get_servo_state(socket_fd, state)
if state == 3:
print("[INFO] 机械臂使能上电成功(servo_state = " + str(state) + ")")
else:
print("[ERROR] 机械臂使能上电失败(servo_state = " + str(state) + ")")
def disable_servo(socket_fd):
"""使能下电
@param socket_fd 6001端口 socket
"""
state = -1
_, state = get_servo_state(socket_fd, state)
if state == 1:
print("[INFO] 机械臂已使能下电")
elif state == 3:
set_servo_poweroff(socket_fd)
_, state = get_servo_state(socket_fd, state)
print("[INFO] 机械臂使能下电成功(servo_state = " + str(state) + ")")
return
print("[INFO] 机械臂使能下电失败(servo_state = " + str(state) + ")")
def wait_motion_done(socket_fd, timeout_sec):
"""轮询机器人运行状态等待运动完成,替代固定延时
@param socket_fd TCP socket
@param timeout_sec 超时秒数
@return True 运动完成 / False 超时
"""
deadline = time.time() + timeout_sec
last_print = 0
time.sleep(0.1)
while time.time() < deadline:
ret, state = get_robot_running_state(socket_fd, -1)
if ret == SUCCESS and state == 0:
print(" [信息] 运动完成")
return True
time.sleep(0.2)
elapsed = int(time.time() - (deadline - timeout_sec))
if elapsed - last_print >= 5:
print(f" [信息] 等待运动中... (已过 {elapsed}s)")
last_print = elapsed
print(f" [WARN] 等待运动超时 ({timeout_sec}s)")
return False
# ============================================================
# 主函数
# ============================================================
def main():
# ---- 定义IP地址和端口 ----
ip = "192.168.1.13"
port = "6001"
# ---- 获取 SDK 版本 ----
version = get_library_version()
print("[INFO] SDK 版本: " + version)
# ---- 连接控制器 ----
print("[INFO] 连接控制器...")
socket_fd = connect_robot(ip, port)
if socket_fd < 0:
print("[ERROR] 连接失败,程序退出!")
return -1
print("[INFO] 连接成功 (socket=" + str(socket_fd) + ")")
# ---- 切换为示教模式 ----
print("--- 切换示教模式 ---")
ret = set_current_mode(socket_fd, 0)
if ret != SUCCESS:
print("[ERROR] 切换示教模式失败,程序退出!")
return -1
print("[INFO] 已切换为示教模式")
print()
# ---- 使能上电 ----
enable_servo(socket_fd)
# ---- 设置全局速度 ----
ret = set_speed(socket_fd, 30)
print_result("set_speed", ret)
time.sleep(0.2)
# ---- MoveJ运动控制 ----
print("[INFO] **********MoveJ运动控制**********")
cmd = MoveCmd()
cmd.targetPosType = PosType_PType
cmd.targetPosName = ""
cmd.coord = 0 # 关节坐标系
cmd.velocity = 40 # 关节速度百分比 (1,100]
cmd.acc = 10
cmd.dec = 10
cmd.pl = 0 # 平滑参数 [0,5]
cmd.targetPosValue = VectorDouble([
20.0, 10.0, -10.0,
0.0, 0.0, 0.0, 0.0]) # 关节坐标下单位为度
ret = robot_movej(socket_fd, cmd)
if ret != SUCCESS:
print("[ERROR] MoveJ运动控制失败,程序退出!")
return -1
# 等待运动到位
wait_motion_done(socket_fd, 30)
print("[INFO] MoveJ运动控制成功")
print()
# ---- MoveL运动控制 ----
print("[INFO] **********MoveL运动控制**********")
cmd.targetPosName = ""
cmd.coord = 1 # 直角坐标系
cmd.targetPosValue = VectorDouble([
280, 90.0, 270,
3.14, 0.0, 0.0]) # 直角坐标下位移单位是mm,旋转单位是弧度
ret = robot_movel(socket_fd, cmd)
if ret != SUCCESS:
print("[ERROR] MoveL运动控制失败,程序退出!")
return -1
# 等待运动到位
wait_motion_done(socket_fd, 30)
print("[INFO] MoveL运动控制成功")
print()
# ---- 使能下电 ----
disable_servo(socket_fd)
# ---- 断开控制器连接 ----
print("[INFO] 断开控制器连接...")
ret = disconnect_robot(socket_fd)
if ret != SUCCESS:
print("[ERROR] 断开连接失败,程序退出!")
return -1
print("[INFO] 断开连接成功")
return 0
if __name__ == "__main__":
main()
