跳转到内容

运行 JavaScript SDK 示例

本文以 Windows 环境为例,说明如何运行 JavaScript SDK 相关示例代码。

前置准备

  1. 在 WebStorm IDE 新建 JavaScript 项目。

  2. 参考 运行环境要求 确认运行环境(Node.js 8 及以上)。

  3. 参考 安装指南 对 JavaScript 项目进行配置。

示例代码

与机器人通讯分为使用 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:读取当前关节位置(单位:弧度)。

操作步骤

  1. 创建 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;
    });
  2. 运行示例代码,查看终端输出的机器人关节位姿。

机器人上电与启动示例

本示例调用以下接口完成连接、登录、上电、等待就绪、启动、断开连接流程。

调用接口

  • RobotProxy

    • connectServer:同时建立 RPC(9012)、RTDE(9013)、Script(30003)三条连接。
    • login:登录控制器。
    • selectRobot:选择当前操作的机器人。
    • disConnectFromServer:断开控制器连接。
  • RobotManage

    • poweron:机器人上电。
    • startup:机器人启动。
  • RobotState

    • isSteady:查询机器人是否处于稳定状态。
    • isPowerOn:查询机器人是否已上电。

警告:

本示例会让机器人上电、松刹车并进入可运行状态,属于改变机器人状态的操作。执行前必须确认机器人工作区域、急停装置、工具负载和安全配置均处于可控状态,并在低速条件下调试。

操作步骤

  1. 创建 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;
    });
  2. 运行示例代码,查看终端输出,可以看到【机器人已启动】提示。

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

RTDE 实时数据订阅示例

本示例调用以下接口完成连接、登录、订阅话题、接收实时数据、取消订阅、断开连接流程。

调用接口

  • RobotProxy

    • connectServer:同时建立 RPC(9012)、RTDE(9013)、Script(30003)三条连接。
    • login:登录控制器。
    • selectRobot:选择当前操作的机器人。
    • disConnectFromServer:断开控制器连接。
    • batchAddRtdeTopicCallbacks:批量订阅 RTDE 话题并注册回调。
    • deleteRtdeTopicCallbacks:取消已订阅的 RTDE 话题。

操作步骤

  1. 创建 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;
    });
  2. 在 AuboStudio APP 中编写一个简单的循环程序,机器人将在路点 0 与路点 1 执行循环关节运动。

  3. 运行 AuboStudio APP 中的程序,再运行 WebStorm 中的示例脚本。

  4. 在终端中可以实时看到机械臂各个关节的位姿变化。

发送 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 无关。

操作步骤

  1. 创建 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;
    });
  2. 运行示例代码,可在终端中看到 Lua 脚本已发送。

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

单独使用客户端

RPC 客户端示例

本示例不经过 RobotProxy,直接使用 RpcClient 完成 RPC 连接、登录、获取机器人列表、读取关节位置、断开连接流程。

调用接口

  • RpcClient

    • connectRpcServer:连接 RPC 服务(端口 9012)。
    • login:登录控制器(登录成功后 getRobotNames 才有数据)。
    • getRobotNames:获取控制器中的机器人名称列表。
    • getRobotInterface:按机器人名称获取 RobotInterface 接口对象。
    • disconnectRpcServer:断开 RPC 连接。
  • RobotInterface

    • getRobotState:获取 RobotState 接口对象(getJointPositions 等接口都挂在它上面)。

操作步骤

  1. 创建 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;
    });
  2. 运行示例代码,查看终端输出。

RTDE 客户端示例

本示例不经过 RobotProxy,直接使用 RtdeClient 完成 RTDE 连接、订阅话题、接收实时数据、取消订阅、断开连接流程。

调用接口

  • RtdeClient

    • connectRtdeServer:连接 RTDE 服务(端口 9013)。
    • registeredMsgCallBack:注册收包回调。
    • subscribeTopicWithChannel:按通道订阅话题。
    • unsubscribeChannel:按通道取消订阅。
    • disconnectRtdeServer:断开 RTDE 连接。

说明:

直接使用 RtdeClient 时,话题名不会自动加 R1_ 前缀,必须写控制器侧的完整名称(如 R1_robot_mode),与 RobotProxy 的写法正好相反。

操作步骤

  1. 创建 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;
    });
  2. 在 AuboStudio APP 中重新运行循环程序。

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

    说明:

    终端输出遵循 ["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 回调判断。

操作步骤

  1. 创建 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;
    });
  2. 运行示例代码,可在终端中看到 Lua 脚本已发送。

  3. 在 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()
  • 单独使用客户端时的接口(RpcClientRtdeClientScriptClientRobotInterface)见上文各小节。