运行 JavaScript SDK 示例
本文以 Windows 环境为例,说明如何运行 JavaScript SDK 相关示例代码。
前置准备
示例代码
与机器人通讯分为使用 RobotProxy 连接与单独使用客户端两种方式。
使用 RobotProxy 连接(推荐)
RobotProxy是 SDK 的统一入口类,一次connectServer()即可同时建立 RPC(9012)、RTDE(9013)、Script(30003)三条连接,并通过一次disConnectFromServer()统一断开。它内部维护当前选中的机器人,接口写法统一为robot.xxx(),适合常规业务开发和示例教学。单独使用客户端
只创建并使用某一个具体通道的 Client:
RpcClient(仅连 9012)、RtdeClient(仅连 9013)、ScriptClient(仅连 30003)。每个 Client 需要单独建立连接、单独断开。适合只需要某一条通道、或者排查某个端口连接问题的场景。
说明:
运行示例代码前请确认:
确认机械臂通讯正常。
JavaScript 开发包已安装。
SDK 客户端连接真实机械臂时,必须将代码中的 IP 地址设置成机械臂的 IP 地址。
如果在 Aubo Sim 虚拟机中运行工程并且 SDK 客户端连接的是虚拟机,则 IP 地址为虚拟机的 IP 地址。
使用 RobotProxy 连接
获取机器人关节位置示例
本示例调用以下接口完成连接、登录、获取关节位置、断开连接流程。
调用接口
RobotProxy
connectServer:同时建立 RPC(9012)、RTDE(9013)、Script(30003)三条连接。login:登录控制器。selectRobot:选择当前操作的机器人。disConnectFromServer:断开控制器连接。
RobotState
getJointPositions:读取当前关节位置(单位:弧度)。
操作步骤
创建 robot_connect.js 文件,并写入以下示例代码。
单击查看示例代码
js// AUBO JavaScript SDK 示例:连接控制器 -> 读取关节位置 -> 断开连接 // 运行:node robot_connect.js const { RobotProxy } = require("@aubo/aubo_sdk"); const robot = new RobotProxy(); // 控制器连接参数,请按现场实际修改 IP const controller = { ip: "192.XXX.XXX.133", rpcPort: 9012, rtdePort: 9013, scriptPort: 30003, username: "", password: "", }; async function main() { let connected = false; try { // 连接控制器 console.log(`正在连接控制器:${controller.ip}`); const connectResult = await robot.connectServer( controller.ip, controller.rpcPort, controller.rtdePort, controller.scriptPort ); if (!connectResult) { throw new Error("控制器连接失败,请检查 IP、端口和网络状态"); } connected = true; console.log("控制器连接成功"); // 登录 const loginResult = await robot.login( controller.username, controller.password ); if (!loginResult) { throw new Error("控制器登录失败,请检查账号、密码和 SDK 版本"); } console.log("控制器登录成功"); // 获取机器人列表 const robotNames = robot.getRobotNames() || []; if (robotNames.length === 0) { throw new Error("控制器中未发现机器人"); } console.log("机器人列表:", robotNames); // 选择第 1 台机器人(索引从 0 开始) const selectResult = robot.selectRobot(0); if (selectResult !== 0) { throw new Error(`机器人选择失败,返回值:${selectResult}`); } console.log("当前机器人:", robot.getCurrentRobotName()); // 读取关节位置(单位:弧度) const jointPositions = await robot.getRobotState().getJointPositions(); if (!Array.isArray(jointPositions)) { throw new Error("读取关节位置失败"); } console.log("关节位置:", jointPositions); } finally { // 断开连接 if (connected) { try { await robot.disConnectFromServer(); console.log("控制器连接已断开"); } catch (error) { console.error("断开控制器连接失败:", error); } } } } main().catch((error) => { console.error("SDK 示例运行失败:", error.message); process.exitCode = 1; });运行示例代码,查看终端输出的机器人关节位姿。

机器人上电与启动示例
本示例调用以下接口完成连接、登录、上电、等待就绪、启动、断开连接流程。
调用接口
RobotProxy
connectServer:同时建立 RPC(9012)、RTDE(9013)、Script(30003)三条连接。login:登录控制器。selectRobot:选择当前操作的机器人。disConnectFromServer:断开控制器连接。
RobotManage
poweron:机器人上电。startup:机器人启动。
RobotState
isSteady:查询机器人是否处于稳定状态。isPowerOn:查询机器人是否已上电。
警告:
本示例会让机器人上电、松刹车并进入可运行状态,属于改变机器人状态的操作。执行前必须确认机器人工作区域、急停装置、工具负载和安全配置均处于可控状态,并在低速条件下调试。
操作步骤
创建 robot_startup.js 文件,并写入以下示例代码。
单击查看示例代码
js// AUBO JavaScript SDK 示例:机器人上电 + 启动 // 运行:node robot_startup.js const { RobotProxy } = require("@aubo/aubo_sdk"); const IP = "192.XXX.XXX.133"; // 控制器 IP,请按现场实际修改 const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); async function main() { const robot = new RobotProxy(); try { // 连接 / 登录 / 选择机器人 if (!(await robot.connectServer(IP, 9012, 9013, 30003))) { throw new Error("控制器连接失败"); } if (!(await robot.login("", ""))) throw new Error("控制器登录失败"); if (robot.selectRobot(0) !== 0) throw new Error("机器人选择失败"); console.log("当前机器人:", robot.getCurrentRobotName()); const manage = robot.getRobotManage(); const state = robot.getRobotState(); // 上电(异步,需要等 isSteady / isPowerOn 都为真才算就绪) const powerOnResult = await manage.poweron(); if (powerOnResult !== 0) throw new Error(`上电失败,错误码:${powerOnResult}`); for (let i = 0; i < 60; i++) { if ((await state.isSteady()) && (await state.isPowerOn())) break; if (i === 59) throw new Error("等待上电完成超时"); await sleep(500); } // 启动;返回 3(busy)时等待 1 秒重试 for (let i = 1; i <= 10; i++) { const startupResult = await manage.startup(); if (startupResult === 0) { console.log("机器人上电并启动成功"); return; } if (startupResult !== 3 || i === 10) { throw new Error(`启动失败,错误码:${startupResult}`); } console.log(`启动返回 3(busy),1 秒后重试(${i}/10)`); await sleep(1000); } } finally { // 断开连接 try { await robot.disConnectFromServer(); console.log("控制器连接已断开"); } catch (error) { console.error("断开控制器连接失败:", error); } } } main().catch((error) => { console.error("机器人启动流程失败:", error.message); process.exitCode = 1; });运行示例代码,查看终端输出,可以看到【机器人已启动】提示。

查看 AuboStudio APP 日志,可以看到机器人已启动。

RTDE 实时数据订阅示例
本示例调用以下接口完成连接、登录、订阅话题、接收实时数据、取消订阅、断开连接流程。
调用接口
RobotProxy
connectServer:同时建立 RPC(9012)、RTDE(9013)、Script(30003)三条连接。login:登录控制器。selectRobot:选择当前操作的机器人。disConnectFromServer:断开控制器连接。batchAddRtdeTopicCallbacks:批量订阅 RTDE 话题并注册回调。deleteRtdeTopicCallbacks:取消已订阅的 RTDE 话题。
操作步骤
创建 rtde_subscribe.js 文件,并写入以下示例代码。
单击查看示例代码
js// RTDE 实时数据订阅示例:订阅 actual_q / robot_mode,限频打印实时数据 // 运行:node rtde_subscribe.js const { RobotProxy } = require("@aubo/aubo_sdk"); const IP = "192.XXX.XXX.133"; // 控制器 IP,请按现场实际修改 // 话题名无需 R1_ 前缀,SDK 会自动补全: const TOPICS = ["actual_q", "robot_mode"]; // 顺序须与回调数组一一对应 const INTERVAL_MS = 100; // 推送间隔(ms) const DURATION_MS = 10000; // 运行时长(ms) const PRINT_INTERVAL_MS = 1000; // 打印限频间隔(ms) const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); async function main() { const robot = new RobotProxy(); // 回调里只存值,打印由 printIfDue 限频 let frames = 0; let lastPrint = 0; let latestQ = null; let latestMode = null; const printIfDue = () => { // 等两个话题都有值再打印 if (latestQ === null || latestMode === null) return; const now = Date.now(); if (now - lastPrint < PRINT_INTERVAL_MS) return; lastPrint = now; console.log( `[第 ${frames} 帧] 关节(rad): ${latestQ.map((v) => v.toFixed(4)).join(", ")} 模式: ${latestMode}` ); }; try { // 1. 连接 if (!(await robot.connectServer(IP, 9012, 9013, 30003))) { throw new Error("控制器连接失败"); } // 2. 登录 if (!(await robot.login("", ""))) throw new Error("控制器登录失败"); // 3. 选择机器人 const robotIndex = 0; if (robot.selectRobot(robotIndex) !== 0) throw new Error("机器人选择失败"); console.log("当前机器人:", robot.getCurrentRobotName()); // 4. 批量订阅:callbacks 与 topics 按下标一一对应 robot.batchAddRtdeTopicCallbacks( robotIndex, TOPICS, [ (q) => { // actual_q:关节位置(rad) frames++; latestQ = q; printIfDue(); }, (mode) => { // robot_mode:机器人模式 latestMode = mode; }, ], INTERVAL_MS ); console.log(`已订阅 ${TOPICS.join(", ")},运行 ${DURATION_MS / 1000} 秒(Ctrl+C 可提前结束)`); // 5. 保持运行,持续收数据 await sleep(DURATION_MS); // 6. 取消订阅 robot.deleteRtdeTopicCallbacks(robotIndex, TOPICS); console.log(`已取消订阅:共收到 ${frames} 帧,平均 ${(frames / (DURATION_MS / 1000)).toFixed(1)} 帧/秒`); } finally { // 7. 断开连接 try { await robot.disConnectFromServer(); console.log("控制器连接已断开"); } catch (error) { console.error("断开控制器连接失败:", error); } } } main().catch((error) => { console.error("RTDE 订阅示例运行失败:", error.message); process.exitCode = 1; });在 AuboStudio APP 中编写一个简单的循环程序,机器人将在路点 0 与路点 1 执行循环关节运动。

运行 AuboStudio APP 中的程序,再运行 WebStorm 中的示例脚本。
在终端中可以实时看到机械臂各个关节的位姿变化。

发送 Lua 脚本示例
本示例调用以下接口完成连接、登录、下发 Lua 脚本、断开连接流程。
调用接口
RobotProxy
connectServer:同时建立 RPC(9012)、RTDE(9013)、Script(30003)三条连接。login:登录控制器。selectRobot:选择当前操作的机器人。disConnectFromServer:断开控制器连接。sendScriptStrByWs:通过 WebSocket(30003 端口)下发 Lua 脚本并执行,也可改用sendScriptStrByHttp。registerScriptError:注册脚本执行错误回调,脚本内的报错只能通过该回调获取。
说明:
下发的 Lua 脚本在机器人控制器上执行,脚本中的 require('aubo')、textmsg 等是控制器内置的 Lua 库,与 JavaScript SDK 无关。
操作步骤
创建 send_lua.js 文件,并写入以下示例代码。
单击查看示例代码
js// 发送 Lua 脚本示例:通过 WebSocket 下发 Lua 程序并执行 // 运行:node send_lua.js const { RobotProxy } = require("@aubo/aubo_sdk"); const IP = "192.XXX.XXX.133"; // 控制器 IP,请按现场实际修改 const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // 下发的 Lua 程序:控制器加载后自动调用 app:start,执行 p_Untitled_1 发送一条 textmsg const luaScript = ` local app = {} local aubo = require('aubo') local sched = sched or aubo.sched -- 全局无 sched,从 aubo 取 function p_Untitled_1() local _ENV = sched.select_robot(1) -- 取机器人指令环境,textmsg 等由它提供 textmsg("Hello from JavaScript SDK") end function app:start(api) -- 启动回调,控制器自动调用 self.api = api p_Untitled_1() end return app -- 必须返回程序对象 `; async function main() { const robot = new RobotProxy(); // 连接 / 登录 / 选择机器人 if (!(await robot.connectServer(IP, 9012, 9013, 30003))) throw new Error("控制器连接失败"); if (!(await robot.login("", ""))) throw new Error("控制器登录失败"); if (robot.selectRobot(0) !== 0) throw new Error("机器人选择失败"); console.log("当前机器人:", robot.getCurrentRobotName()); // 脚本报错只能从这个回调拿到 robot.registerScriptError((error) => console.error("脚本执行报错:", error.data)); robot.sendScriptStrByWs(luaScript); // 或 robot.sendScriptStrByHttp(luaScript) console.log("已发送 Lua 脚本"); await sleep(3000); // 等脚本执行完 / 报错回传 await robot.disConnectFromServer(); console.log("控制器连接已断开"); } main().catch((error) => { console.error("示例运行失败:", error.message); process.exitCode = 1; });运行示例代码,可在终端中看到 Lua 脚本已发送。

在 AuboStudio APP 中查看日志,可看到 Lua 脚本的调试消息。

单独使用客户端
RPC 客户端示例
本示例不经过 RobotProxy,直接使用 RpcClient 完成 RPC 连接、登录、获取机器人列表、读取关节位置、断开连接流程。
调用接口
RpcClient
connectRpcServer:连接 RPC 服务(端口 9012)。login:登录控制器(登录成功后getRobotNames才有数据)。getRobotNames:获取控制器中的机器人名称列表。getRobotInterface:按机器人名称获取RobotInterface接口对象。disconnectRpcServer:断开 RPC 连接。
RobotInterface
getRobotState:获取RobotState接口对象(getJointPositions等接口都挂在它上面)。
操作步骤
创建 rpc_client.js 文件,并写入以下示例代码。
单击查看示例代码
js// RPC 客户端示例:只连 RPC 服务(9012)读取关节位置 // 运行:node rpc_client.js const { RpcClient } = require("@aubo/aubo_sdk"); const IP = "192.XXX.XXX.133"; // 控制器 IP,请按现场实际修改 async function main() { // RpcClient 只管理 RPC 一条连接,需要自己建立、自己断开 const rpc = new RpcClient(); try { // 连接 RPC 服务,返回 true 表示连接成功 if (!(await rpc.connectRpcServer(IP, 9012))) { throw new Error("RPC 连接失败"); } console.log("RPC 连接成功"); // 登录。login 内部会拉取一次机器人列表,登录成功后 getRobotNames 才有数据 if (!(await rpc.login("", ""))) throw new Error("RPC 登录失败"); // 取机器人列表(同步方法,直接返回字符串数组) const robotNames = rpc.getRobotNames() || []; if (robotNames.length === 0) throw new Error("控制器中未发现机器人"); console.log("机器人列表:", robotNames); // 按机器人名称获取接口对象(注意是名称,不是下标) // RobotInterface 上挂着 getRobotState / getRobotManage 等, // 用法和 RobotProxy 上的同名方法一致 const robotInterface = rpc.getRobotInterface(robotNames[0]); const jointPositions = await robotInterface.getRobotState().getJointPositions(); console.log("关节位置:", jointPositions); } finally { // 断开 RPC 连接 await rpc.disconnectRpcServer(); console.log("RPC 连接已断开"); } } main().catch((error) => { console.error("RPC 客户端示例运行失败:", error.message); process.exitCode = 1; });运行示例代码,查看终端输出。

RTDE 客户端示例
本示例不经过 RobotProxy,直接使用 RtdeClient 完成 RTDE 连接、订阅话题、接收实时数据、取消订阅、断开连接流程。
调用接口
RtdeClient
connectRtdeServer:连接 RTDE 服务(端口 9013)。registeredMsgCallBack:注册收包回调。subscribeTopicWithChannel:按通道订阅话题。unsubscribeChannel:按通道取消订阅。disconnectRtdeServer:断开 RTDE 连接。
说明:
直接使用 RtdeClient 时,话题名不会自动加 R1_ 前缀,必须写控制器侧的完整名称(如 R1_robot_mode),与 RobotProxy 的写法正好相反。
操作步骤
创建 rtde_client.js 文件,并写入以下示例代码。
单击查看示例代码
js// RTDE 客户端示例:连接 RTDE 服务(9013)-> 订阅话题 -> 接收数据 -> 取消订阅 -> 断开 // 运行:node rtde_client.js const { RtdeClient } = require("@aubo/aubo_sdk"); const IP = "192.XXX.XXX.133"; // 控制器 IP,请按现场实际修改 const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // 话题名必须写控制器侧的完整名称,SDK 不会自动加前缀: // 机器人相关话题要写成 R + (robotIndex + 1) + "_" + 话题名,如 R1_robot_mode const topics = ["line_number", "runtime_state", "R1_robot_mode"]; async function main() { const rtde = new RtdeClient(); try { // 连接 RTDE 服务 if (!(await rtde.connectRtdeServer(IP, 9013))) { throw new Error("RTDE 连接失败"); } console.log("RTDE 连接成功"); // 收包回调:channel 为订阅时的通道号,data 为该通道一帧数据(顺序与话题一致) let lastPrint = 0; rtde.registeredMsgCallBack((channel, data) => { const now = Date.now(); if (now - lastPrint < 1000) return; // 每秒只打印一次,避免刷屏 lastPrint = now; console.log(`[通道 ${channel}]`, data); }); // 订阅:subscribeTopicWithChannel(topics, 推送间隔 ms, 通道号 0~99) rtde.subscribeTopicWithChannel(topics, 100, 1); console.log(`已订阅:${topics.join(", ")},通道 1,每 100 ms 推送一次`); // 保持进程存活,让回调持续接收数据 await sleep(10000); // 取消订阅(传入订阅时的通道号) rtde.unsubscribeChannel(1); console.log("已取消订阅"); } finally { // 断开 RTDE 连接 await rtde.disconnectRtdeServer(); console.log("RTDE 连接已断开"); } } main().catch((error) => { console.error("RTDE 客户端示例运行失败:", error.message); process.exitCode = 1; });在 AuboStudio APP 中重新运行循环程序。

运行示例代码,查看终端输出。

说明:
终端输出遵循
["line_number", "runtime_state", "R1_robot_mode"]。- line_number:运行的程序行号
- runtime_state:控制器运行状态
- R1_robot_mode:机器人模式
Script 客户端示例
本示例不经过 RobotProxy,直接使用 ScriptClient 完成 Script 连接、下发 Lua 脚本、断开连接流程。
调用接口
ScriptClient
connectScriptServer:连接 Script 服务(端口 30003)。registerScriptError:注册脚本执行错误回调。sendScriptStrByWs:通过 WebSocket 下发 Lua 脚本并执行。disconnectScriptServer:断开 Script 连接。
说明:
脚本在控制器上真实执行。sendScriptStrByWs 是同步方法、返回 void,发送成功不代表执行成功,执行结果需通过 registerScriptError 回调判断。
操作步骤
创建 script_client.js 文件,并写入以下示例代码。
单击查看示例代码
js// Script 客户端示例:只连 Script 服务(30003)下发 Lua 脚本 // 运行:node script_client.js const { ScriptClient } = require("@aubo/aubo_sdk"); const IP = "192.XXX.XXX.133"; // 控制器 IP,请按现场实际修改 const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // 下发的 Lua 程序:控制器加载后自动调用 app:start,执行 p_Untitled_1 发送一条 textmsg // 注意:textmsg 由机器人指令环境提供,必须先 sched.select_robot(1) 取环境再调用 const luaScript = ` local app = {} local aubo = require('aubo') local sched = sched or aubo.sched function p_Untitled_1() local _ENV = sched.select_robot(1) -- 取机器人指令环境,textmsg 等由它提供 textmsg("Hello from ScriptClient") end function app:start(api) -- 启动回调,控制器自动调用 self.api = api p_Untitled_1() end return app -- 必须返回程序对象 `; async function main() { const script = new ScriptClient(); try { // 连接 Script 服务 if (!(await script.connectScriptServer(IP, 30003))) { throw new Error("Script 连接失败"); } console.log("Script 连接成功"); // 注册脚本错误回调(可选但建议):脚本在控制器上执行出错时会回调这里 script.registerScriptError((error) => { console.error("脚本执行报错:", error); }); // 通过 WebSocket 下发脚本 script.sendScriptStrByWs(luaScript); console.log("已下发 Lua 脚本"); // 等待脚本执行完并接收可能的错误回调 await sleep(3000); } finally { // 断开 Script 连接 await script.disconnectScriptServer(); console.log("Script 连接已断开"); } } main().catch((error) => { console.error("Script 客户端示例运行失败:", error.message); process.exitCode = 1; });运行示例代码,可在终端中看到 Lua 脚本已发送。

在 AuboStudio APP 中查看日志,可看到 Lua 脚本的调试消息。

接口汇总
RobotProxy 常用接口:
分类 常用接口 连接 connectServer()、hasConnect()、disConnectFromServer()会话 login()、logout()、getRobotNames()、selectRobot()机器人状态 getRobotState()、getCurrentRobotName()、getRobotIndex()机器人控制 getRobotManage()、getMotionControl()、getIoControl()、getForceControl()配置与算法 getRobotConfig()、getRobotAlgorithm()、getMath()控制器接口 getRuntimeMachine()、getRegisterControl()、getSystemInfo()实时数据 addRtdeTopicCallback()、batchAddRtdeTopicCallbacks()、deleteRtdeTopicCallbacks()脚本 sendScriptStrByWs()、sendScriptStrByHttp()、registerScriptError()单独使用客户端时的接口(
RpcClient、RtdeClient、ScriptClient、RobotInterface)见上文各小节。

