弧焊 C++ SDK 使用示例
文档约定
以下各节结构统一为:
- 适用情况 — 何时需要本场景
- 目标 — 做完后系统应处于的状态
- 推荐步骤 — 顺序化操作要点;
- 常用接口与类型 — 便于检索 SDK 符号,非完整参数表
- 注意事项 — 常见易错点
通用编程约定
- 通过
robot.arcWelding()取得ArcWelding引用,在其上调用工艺参数与焊机相关接口;运动队列仍在robot上操作。 - 各 API 均带
error_code &ec(或等价重载),每次调用后检查ec。 - 涉及「压队列再启动」的焊接轨迹,通常配合
MotionControlMode::NrtCommand与moveAppend/moveStart;与纯参数下发场景区分开。
公共代码前提(各场景「实现代码」共用)
以下与 SDK 包内 arcwelding_example.cpp 第 10–60 行一致(含 print_helper.hpp、匿名命名空间内的robot / arcWeld() / waitForFinish 等)。
#include "rokae/arcwelding.h"
#include "rokae/robot.h"
#include "print_helper.hpp"
#include "rokae/data_types.h"
#include <unordered_map>
#include <thread>
#include <iostream>
#include <chrono>
#include <future>
using namespace rokae;
using namespace std;
#define ROKAE_EXE(CMD) \
CMD; \
if(ec) { print(std::cerr, __LINE__, __FUNCTION__, ":", ec.message()); }
namespace {
xMateRobot robot;
ArcWelding& arcWeld() {
static ArcWelding v = robot.arcWelding();
return v;
}
void waitForFinish(BaseRobot &robot, const std::string &traj_id, int index){
using namespace rokae::EventInfoKey::MoveExecution;
error_code ec;
while(true) {
auto info = robot.queryEventInfo(Event::moveExecution, ec);
auto _id = std::any_cast<std::string>(info.at(ID));
auto _index = std::any_cast<int>(info.at(WaypointIndex));
if(auto _ec = std::any_cast<error_code>(info.at(Error))) {
print(std::cout, "路径", _id, ":", _index, "错误:", _ec.message());
return;
}
if(_id == traj_id && _index == index) {
if(std::any_cast<bool>(info.at(ReachTarget))) {
print(std::cout, "路径", traj_id, ":", index, "已完成");
}
return;
}
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
std::ostream &operator<<(std::ostream &os, const ArcWelding::WelderStatus &data) {
os << "Name: " << data.welding_name << ", Current: " << data.current << ", Voltage: " << data.voltage
<< ", Distance: " << data.welding_distance << ", Path num: " << data.welding_path_num << std::endl;
return os;
}
}
场景一:首次接机器人与焊机
适用情况 新工作站第一次跑弧焊程序,或更换焊机 / 总线配置后需要确认控制器与焊机侧就绪。
目标 机器人已连接;弧焊工艺包可用;焊机型号与通信参数与现场一致;必要时完成 IO 与 ENI 期望配置。
推荐步骤
关键步骤关系如下(与下文分步说明对应):
-
connectToRobot建立与控制器连接。 -
用
getWelderStatus查看焊机侧状态:若state为"disabled"等表示尚未建立有效连接;为"ok"等表示已就绪(具体枚举以接口说明为准)。 -
若已连接:可用
getWelderSetting读取当前协议、品牌mfr、型号model、电流规格current_type等。 -
若要更换焊机或重配参数:先
disconnectFromWelder,再按下方 EtherCAT 或 模拟量 分支配置后重新connectToWelder。 -
EtherCAT 焊机:需要
setIsEniHaveWeld需设为true(与HMI上是否连接物理焊机等效),然后在HMI软件上上传该焊机对应的ENI文件。在setWelder(或WelderSetting)中设置protocol为 EtherCAT 对应取值(如"ethercat",以 SDK 约定为准)、mfr为下表中的厂商键名、model为下表中的型号键名、current_type必须为该机型的current_range中的某一档(与工艺包一致)。若该机型还提供wire_diameter、shielding_gas、program_number、dry_extension、firmware_version等约束,则setWelder时相应字段只能取自下列允许集合。厂商 / 型号与电流档位(及可选约束)一览(下发时
mfr、model字符串需与键名一致):
{
"aotai": {
"RL/RPL": { "current_range": [350, 500, 630, 800] },
"RP/RPH": { "current_range": [350, 500, 630, 800] }
},
"megmeet": {
"Artsen Plus": { "current_range": [350, 400, 500] },
"Artsen Pro": { "current_range": [350, 400, 500] },
"Ehave2": { "current_range": [350, 500, 630] },
"Artsen3": { "current_range": [400, 500] },
"Dex2": { "current_range": [350, 400, 500] },
"Dex2 Ultra": { "current_range": [400] },
"Megwave": { "current_range": [350, 400, 500] },
"Megwave 400AC": { "current_range": [400] },
"MetaTig": { "current_range": [315, 400, 500] },
"RevoTig": { "current_range": [315, 400, 500] }
},
"riland": {
"TiTans Low Spatter": {
"current_range": [500],
"wire_diameter": [0.8, 1.0, 1.2, 1.6],
"shielding_gas": ["CO2", "80%Ar+20%CO2"]
},
"TiTans DP": {
"current_range": [400, 500, 600],
"wire_diameter": [0.8, 1.0, 1.2, 1.6],
"shielding_gas": ["CO2", "80%Ar+20%CO2"]
}
},
"panasonic": {
"GS6": {
"current_range": [350, 500],
"program_number": [1, 97],
"dry_extension": [10, 12, 15, 20, 25, 30, 35]
}
},
"tayor": {
"RB-350P": { "current_range": [350] },
"RB-500P": { "current_range": [500] }
},
"headux": {
"headux": { "current_range": [550] }
},
"beijingtime": {
"time": { "current_range": [1000] }
},
"hugong": {
"NVPM": { "current_range": [500] }
},
"ewm": {
"TIG": { "current_range": [1000], "program_number": [0, 15] },
"Plasma": { "current_range": [1000], "program_number": [0, 15] },
"Phoenix": { "current_range": [1000], "program_number": [0, 15] },
"alpha Q": { "current_range": [1000], "program_number": [0, 15] }
},
"bohler": {
"URANOS NX": {
"current_range": [3000, 4000, 5000],
"firmware_version": ["v.14-v.24", "v.25"]
}
},
"esab": {
"Aristo 500ix": { "current_range": [500] }
}
}
示例(奥太 RL/RPL、500A 档):mfr = "aotai",model = "RL/RPL",current_type = 500(须在 [350,500,630,800] 内)。
-
模拟量焊机:须按顺序完成下面三步,再
setWelder:- ① IO 绑定:先调用
setIOSetting,将起弧、送丝、送丝回退、检气、电流/电压设定与回读、焊机就绪、故障等信号绑定到实际 DI/DO 或寄存器。 用getIOSetting进行核对。 - ② 电流 / 电压曲线:使用
setCurrentCharacteristicCurveData、setVoltageCharacteristicCurveData(及需要时的calculateCurrentCurve/calculateVoltageCurve)在控制器中建立曲线数据并命名。 - ③
setWelder:协议设为模拟量(具体字符串以 SDK / 工艺包为准,如"analog"等);品牌mfr只能为"manual_welding"或"aotai";型号model等与模拟量方案约定一致;current_file、voltage_file填步骤 ② 中已下发的电流曲线数据名与电压曲线数据名。其余字段按接口说明使用默认值或留空。
- ① IO 绑定:先调用
-
调用
connectToWelder建立与焊机的连接并启用焊机功能;调试结束或更换焊机前可用disconnectFromWelder。
实现代码
模拟量焊机配置见同文件 setIOSetting、setCharacteristicCurveData。
// 选择焊机,启用焊接功能,断开焊机
void setWelderAndConnect() {
cout << "enter setWelder" << endl;
error_code ec;
auto printWelderSetting = [](const ArcWelding::WelderSetting &welderSetting) {
cout << "protocol: " << welderSetting.protocol << endl;
cout << "mfr: " << welderSetting.mfr << endl;
cout << "model: " << welderSetting.model << endl;
cout << "current_type: " << welderSetting.current_type << endl;
cout << "current_file: " << welderSetting.current_file << endl;
cout << "voltage_file: " << welderSetting.voltage_file << endl;
cout << "wire_diameter: " << welderSetting.wire_diameter << endl;
cout << "shielding_gas: " << welderSetting.shielding_gas << endl;
cout << "program_number: " << welderSetting.program_number << endl;
cout << "dry_extension: " << welderSetting.dry_extension << endl;
};
auto welderSetting = arcWeld().getWelderSetting(ec);// 获取当前焊机设置,部分参数如果该焊机不涉及可以忽略
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printWelderSetting(welderSetting);
welderSetting.protocol = "ethercat";
welderSetting.mfr = "aotai";
welderSetting.model = "RL/RPL";
welderSetting.current_type = 500;
welderSetting.current_file = "current2";
welderSetting.voltage_file = "voltage2";
welderSetting.wire_diameter = 0.8;
welderSetting.shielding_gas = "CO2";
welderSetting.program_number = 10;
welderSetting.dry_extension = 10;
arcWeld().setWelder(welderSetting, ec);// 设置焊机(方式一),部分参数如果该焊机不涉及可以忽略
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
welderSetting = arcWeld().getWelderSetting(ec);// 验证设置是否成功
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printWelderSetting(welderSetting);
arcWeld().setWelder("ethercat", "aotai", "RL/RPL", 500, ec);// 设置焊机(方式二)
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
arcWeld().connectToWelder(ec);// 启用和连接焊机
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
arcWeld().disconnectFromWelder(ec);// 断开和禁用焊机
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
// 读取和设置是否连接物理焊机(切换ENI文件)
void setEniHaveWeld(){
cout << "enter setEniHaveWeld" << endl;
error_code ec;
auto ret = arcWeld().isEniHaveWeld(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "isEniHaveWeld: " << ret << endl;
arcWeld().setIsEniHaveWeld(true, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ret = arcWeld().isEniHaveWeld(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "isEniHaveWeld: " << ret << endl;
arcWeld().setIsEniHaveWeld(false, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ret = arcWeld().isEniHaveWeld(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "isEniHaveWeld: " << ret << endl;
}
常用接口与类型
getWelderStatus、getWelderSetting、setWelder、WelderSetting、connectToWelder、disconnectFromWelder、isEniHaveWeld、setIsEniHaveWeld、setIOSetting、getIOSetting、IOSetting、IOData、setCurrentCharacteristicCurveData、setVoltageCharacteristicCurveData、getCurrentCharacteristicCurveData、getVoltageCharacteristicCurveData、calculateCurrentCurve、calculateVoltageCurve
注意事项
更换焊机参数时,若已在弧焊连接状态,想要切换焊机,需先断开焊机连接再改参。
场景二:设置焊接运行参数
适用情况 需要统一调整空运行笛卡尔速度、手动送/退丝速度、气体检测时间等与焊接过程相关的全局运行选项(与单条起弧/焊接命名数据不同)。
目标 ArcWeldRunningParam 已写入控制器,空运行、送退丝、无参检气等行为与现场习惯一致。
推荐步骤
- 构造
ArcWeldRunningParam:按工艺包范围设置test_run_speed(mm/s)、wire_feed_speed(m/min)、gas_detect_time(s)等(字段含义与取值范围见 附录:数据结构 中「运行参数ArcWeldRunningParam」)。 - 调用
setRunningParam下发;用getRunningParam读回核对。 - 无参重载
detectGas()的检气持续时间与运行参数中的gas_detect_time相关;带时间与使能的重载则按调用传入(见 接口说明)。
实现代码
// 读写运行参数
void setRunningParam()
{
cout << "enter setRunningParam" << endl;
error_code ec;
ArcWelding::ArcWeldRunningParam runningParam{100, 2, 10};
arcWeld().setRunningParam(runningParam, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
auto data = arcWeld().getRunningParam(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "test_run_speed: " << data.test_run_speed << endl;
cout << "wire_feed_speed: " << data.wire_feed_speed << endl;
cout << "gas_detect_time: " << data.gas_detect_time << endl;
}
常用接口与类型
setRunningParam、getRunningParam、ArcWeldRunningParam、detectGas
注意事项
手动送/退丝速度 取决于焊机是否可以设置该功能
场景三:设置防碰撞(碰枪检测)
适用情况 现场使用碰枪 / 防撞 DI,需要由程序配置信号名、是否启用、屏蔽与倒计时,并在上位机或逻辑中订阅防撞状态。
目标 防碰撞参数已下发;可通过查询或事件回调获取 signal、enable、block、countdown 等与 HMI 或联锁一致。
推荐步骤
- 确定用于防撞的 DI 信号名(如
"DI0_0")。 - 调用
setAnticollision(signal, enable, block, countdown):enable为是否启用,block为屏蔽开关,countdown为倒计时(秒级语义以工艺包为准)。 - 需要界面或逻辑联动时,使用
getAnticollisionState读取当前状态;或注册setEventWatcher(Event::anticollisionState, callback, ec),在回调中解析EventInfoKey::AnticollisionState各键(与 附录:数据结构 中AnticollisionState对应)。
实现代码
void printAnticollisionState(const EventInfo& info) {
using namespace rokae::EventInfoKey::AnticollisionState;
cout << "anticollision: \n"
<< "signale: " << std::any_cast<std::string>(info.at(Signal))
<< "\nenable: " << std::any_cast<bool>(info.at(Enable))
<< "\nblock: " << std::any_cast<bool>(info.at(Block))
<< "\ncountdown: " << std::any_cast<int>(info.at(Countdown)) << std::endl;
}
void SetAnticollision() {
error_code ec;
robot.setEventWatcher(Event::anticollisionState, printAnticollisionState, ec);
if (ec)
cout << "setEventWatcher" << ec.message() << std::endl;
arcWeld().setAnticollision("DI0_0", true, false, 30, ec);
if (ec)
cout << "setAnticollision" << ec.message() << std::endl;
auto ret = arcWeld().getAnticollisionState(ec);
if (ec)
cout << "getAnticollisionState" << ec.message() << std::endl;
cout << "anticollision: \n"
<< "signale: " << ret.signal << "\nenable: " << ret.enable << "\nblock: " << ret.block << "\ncountdown: " << ret.countdown << std::endl;
}
常用接口与类型
setAnticollision、getAnticollisionState、Event::anticollisionState、EventInfoKey::AnticollisionState、setEventWatcher
注意事项
绑定的DI信号需要确保没有被其他系统功能占用
场景四:在程序中维护工艺参数
适用情况 希望由上位机或离线工具下发 / 修改起弧、焊接、收弧、摆动、间断焊等命名工艺数据,或与示教器 HMI 中已有参数名保持一致。
目标 控制器内保存在一组可引用的参数名,供后续 ArcOnCommand 等指令或示教程序使用。
推荐步骤
- 构造对应结构体(如
ArcOnData、ArcData、ArcOffData、WeaveData、SegData等),填写name及工艺字段。 - 调用
setXxxData写入;用getXxxData(name, ec)读回校验。 - 删除单条用
removeXxxData(name);批量删除可传入名称列表重载。 - 对示教器已有名称:可先
get再改字段后set,实现覆盖或微调。
实现代码
以下按类分别摘录 setArcOnData(起弧)、setArcData(焊接)、setArcOffData(收弧)、setWeaveData(摆焊)、setSegData(间断焊)。各函数中的 printArcOnData / printArcData / printArcOffData / printWeaveData 定义于同文件更前处(约第 63–147 行),需与这些 void 函数置于同一编译单元。
// 读写起弧参数arcondata
void setArcOnData()
{
cout << "enter setArcOnData" << endl;
error_code ec;
// 默认参数
ArcWelding::ArcOnData arcOnData;
arcWeld().setArcOnData(arcOnData, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
auto data = arcWeld().getArcOnData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "default" << endl;
printArcOnData(data);
data = arcWeld().getArcOnData("aaa", ec); // 如果获取不存在的参数,提示-272
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
// 自定义参数
ArcWelding::ArcOnData arcOnData2 = {
"example_arcondata", "example_annotation", "low_spatter", "wire_feed", "unified", 100, 2, 0, 300, 4000, 500, 600, 0, 2, 300, 100, {true, 10, 100, 200, 15, 5}, // re_arcon
{true, 50, 100, 20} // scaratch_arcon
};
arcWeld().setArcOnData(arcOnData2, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
data = arcWeld().getArcOnData(arcOnData2.name, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "example_arcondata" << endl;
printArcOnData(data);
// 删除参数
arcWeld().removeArcOnData("default",ec);
data = arcWeld().getArcOnData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 批量删除
arcOnData.name = "remove1";
arcWeld().setArcOnData(arcOnData, ec);
arcOnData.name = "remove2";
arcWeld().setArcOnData(arcOnData, ec);
arcWeld().removeArcOnData(std::vector<std::string>({"remove1", "remove2"}), ec);
data = arcWeld().getArcOnData("remove1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
data = arcWeld().getArcOnData("remove2", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 可以对hmi工艺包的参数进行修改
data = arcWeld().getArcOnData("arcondata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printArcOnData(data);
arcOnData.name = "arcondata1";
arcWeld().setArcOnData(arcOnData, ec);
data = arcWeld().getArcOnData("arcondata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printArcOnData(data);
arcWeld().removeArcOnData("arcondata1",ec);
data = arcWeld().getArcOnData("arcondata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
}
// 读写焊接参数arcdata
void setArcData()
{
cout << "enter setArcData" << endl;
error_code ec;
// 默认参数
ArcWelding::ArcData arcData;
arcWeld().setArcData(arcData, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
auto data = arcWeld().getArcData(arcData.name, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "default" << endl;
printArcData(data);
// 自定义参数
ArcWelding::ArcData arcData2 = {
"example_arcdata", "example_annotation", "low_spatter", "wire_feed", "unified", 100, 20, 0, 30, 400, {500, "auto_arc_reignition", 15}};
arcWeld().setArcData(arcData2, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
data = arcWeld().getArcData(arcData2.name, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "example_arcdata" << endl;
printArcData(data);
// 删除参数
arcWeld().removeArcData("default", ec);
data = arcWeld().getArcData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 批量删除
arcData.name = "remove1";
arcWeld().setArcData(arcData, ec);
arcData.name = "remove2";
arcWeld().setArcData(arcData, ec);
arcWeld().removeArcData(std::vector<std::string>({"remove1", "remove2"}), ec);
data = arcWeld().getArcData("remove1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
data = arcWeld().getArcData("remove2", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 可以对hmi工艺包的参数进行修改
data = arcWeld().getArcData("arcdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printArcData(data);
arcData.name = "arcdata1";
arcWeld().setArcData(arcData, ec);
data = arcWeld().getArcData("arcdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printArcData(data);
arcWeld().removeArcData("arcdata1", ec);
data = arcWeld().getArcData("arcdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
}
// 读写收弧参数arcoffdata
void setArcOffData()
{
cout << "enter setArcOffData" << endl;
error_code ec;
// 默认参数
ArcWelding::ArcOffData arcOffData;
arcWeld().setArcOffData(arcOffData, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
auto data = arcWeld().getArcOffData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "default" << endl;
printArcOffData(data);
// 自定义参数
ArcWelding::ArcOffData arcOffData2 = {
"example_arcoffdata", "example_annotation", "low_spatter", "wire_feed", "unified", 100, 20, 0, 300, 400, 5500, 600, 700, {true, 20, 15, 100}};
arcWeld().setArcOffData(arcOffData2, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
data = arcWeld().getArcOffData(arcOffData2.name, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "example_arcoffdata" << endl;
printArcOffData(data);
// 删除参数
arcWeld().removeArcOffData("default", ec);
data = arcWeld().getArcOffData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 批量删除
arcOffData.name = "remove1";
arcWeld().setArcOffData(arcOffData, ec);
arcOffData.name = "remove2";
arcWeld().setArcOffData(arcOffData, ec);
arcWeld().removeArcOffData(std::vector<std::string>({"remove1", "remove2"}), ec);
data = arcWeld().getArcOffData("remove1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
data = arcWeld().getArcOffData("remove2", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 可以对hmi工艺包的参数进行修改
data = arcWeld().getArcOffData("arcoffdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printArcOffData(data);
arcOffData.name = "arcoffdata1";
arcWeld().setArcOffData(arcOffData, ec);
data = arcWeld().getArcOffData("arcoffdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printArcOffData(data);
arcWeld().removeArcOffData("arcoffdata1", ec);
data = arcWeld().getArcOffData("arcoffdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
}
// 读写摆动参数
void setWeaveData()
{
cout << "enter setWeaveData" << endl;
error_code ec;
// 默认参数
ArcWelding::WeaveData weaveData;
arcWeld().setWeaveData(weaveData, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
auto data = arcWeld().getWeaveData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "default" << endl;
printWeaveData(data);
// 自定义参数
ArcWelding::WeaveData weaveData2 = {
"example_weavedata", "example_annotation", "cycle", "sine", 1, {2, 2}, "weave_stop", {10, 0, 20}, 5, true, "v_pattern", {0, 0}, 0, 1, 10};
arcWeld().setWeaveData(weaveData2, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
data = arcWeld().getWeaveData(weaveData2.name, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "example_weavedata" << endl;
printWeaveData(data);
// 删除参数
arcWeld().removeWeaveData("default", ec);
data = arcWeld().getWeaveData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 批量删除
weaveData.name = "remove1";
arcWeld().setWeaveData(weaveData, ec);
weaveData.name = "remove2";
arcWeld().setWeaveData(weaveData, ec);
arcWeld().removeWeaveData(std::vector<std::string>({"remove1", "remove2"}), ec);
data = arcWeld().getWeaveData("remove1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
data = arcWeld().getWeaveData("remove2", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 可以对hmi工艺包的参数进行修改
data = arcWeld().getWeaveData("weavedata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printWeaveData(data);
weaveData.name = "weavedata1";
arcWeld().setWeaveData(weaveData, ec);
data = arcWeld().getWeaveData("weavedata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
printWeaveData(data);
arcWeld().removeWeaveData("weavedata1", ec);
data = arcWeld().getWeaveData("weavedata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
}
// 读写间断焊参数
void setSegData(){
cout << "enter setSegData" << endl;
error_code ec;
ArcWelding::SegData segdata{"segdata1","segannotation","normal","v10",10,20};
arcWeld().setSegData(segdata, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
auto data = arcWeld().getSegData("segdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "name: " << data.name << "\n"
<< "annotation: " << data.annotation << "\n"
<< "seg_type: " << data.seg_type << "\n"
<< "non_welded_speed: " << data.non_welded_speed << "\n"
<< "welded_distance: " << data.welded_distance << "\n"
<< "non_welded_distance: " << data.non_welded_distance << endl;
// 删除参数
arcWeld().removeSegData("segdata1", ec);
data = arcWeld().getSegData("segdata1", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
// 批量删除
segdata.name = "segdata2";
arcWeld().setSegData(segdata, ec);
segdata.name = "segdata3";
arcWeld().setSegData(segdata, ec);
arcWeld().removeSegData(std::vector<std::string>({"segdata2","segdata3"}), ec);
data = arcWeld().getSegData("segdata2", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl; // -272
}
常用接口与类型
按「设置 / 读取 / 删除」分组的命名工艺数据接口如下(签名与重载详见 接口说明、附录:方法)。
-
起弧 / 焊接 / 收弧 / 摆焊 / 间断焊
setArcOnData/getArcOnData/removeArcOnDatasetArcData/getArcData/removeArcData、enableArcData
setArcOffData/getArcOffData/removeArcOffData
setWeaveData/getWeaveData/removeWeaveData
setSegData/getSegData/removeSegData
setWeaveAdaptiveData/getWeaveAdaptiveData -
多层多道
setLayerData/getLayerData/removeLayerData
setLayerCout、MpmlPathCheck、GetLayerStartPoint -
激光跟踪 / 激光寻位(命名参数)
setLaserTrackData/getLaserTrackData/removeLaserTrackData
setLaserSearchData/getLaserSearchData/removeLaserSearchData -
电弧跟踪(命名参数)
setArcTrackParam/getArcTrackParam/removeArcTrackParam -
电流 / 电压特性曲线(命名曲线数据)
setCurrentCharacteristicCurveData/getCurrentCharacteristicCurveData
setVoltageCharacteristicCurveData/getVoltageCharacteristicCurveData
calculateCurrentCurve、calculateVoltageCurve(仅计算、不落库)
注意事项
按名读取不存在的参数时,控制器可能返回约定错误码(如 -272),需在逻辑中处理。
场景五:选择焊接模式,并对照手动 / 自动行为
适用情况 需要空运行验轨迹、仿真验节拍与摆动、或实焊出弧,并理解示教器手动单步、手动连续、自动下的差异(起弧与否、速度滑条、间断焊、摆焊、电弧跟踪等)。
目标 当前焊接模式与产线阶段匹配(调试 → 仿真 → 实焊)。
推荐步骤
- 调用
setWeldMode,在WeldMode::TestRun(空运行)、Simu(仿真)、Real(实焊)之间切换。 - 用
getWeldMode读回确认。 - 结合现场示教器运行方式,对照下表理解现象(与工艺包说明一致)。
实现代码
// 读写焊接模式
void setWeldMode()
{
cout << "enter setWeldMode" << endl;
error_code ec;
// 切换为空运行模式
arcWeld().setWeldMode(ArcWelding::WeldMode::TestRun, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
auto mode = arcWeld().getWeldMode(ec); // 读取当前模式
cout << "mode: " << mode << endl;
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
// 切换为仿真模式
arcWeld().setWeldMode(ArcWelding::WeldMode::Simu, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
mode = arcWeld().getWeldMode(ec);
cout << "mode: " << mode << endl;
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
// 切换为实焊模式
arcWeld().setWeldMode(ArcWelding::WeldMode::Real, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
mode = arcWeld().getWeldMode(ec);
cout << "mode: " << mode << endl;
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
焊接模式与运行方式组合(示意)

常用接口与类型
setWeldMode、getWeldMode、ArcWelding::WeldMode
注意事项
场景六:典型焊缝——「起弧 → 直线/圆弧 焊接段 → 收弧」
适用情况 最常见的直线或圆弧焊缝:在非实时指令模式下,将普通运动与弧焊工艺指令按顺序压入同一队列并启动。
目标 机器人按序执行:接近段(可选)→ 起弧与焊接参数生效 → 带或不带摆动的焊接轨迹 → 收弧。
推荐步骤
- 需要先通过场景一启用焊机
setMotionControlMode(NrtCommand, ec)。- 确认焊机已配置并
connectToWelder(与场景一一致)。 - 构造
ArcOnCommand,绑定已下发的起弧参数名、焊接参数名(如与示教器同名)。 - 构造焊接段:
WMoveLCommand/WMoveCCommand等; - 构造
ArcOffCommand并绑定收弧参数名。 - 使用同一队列 id 多次
moveAppend按顺序入队;上电后moveStart执行。 - 需要暂停 / 继续时,可配合
stop与再次moveStart(以运动控制文档为准)。
实现代码
// 指令示例
void exampleCommand()
{
cout << "enter exampleCommand" << endl;
error_code ec;
ArcWelding::ArcOnCommand arcon;
arcon.setArcOnData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
arcon.setArcData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ArcWelding::ArcOffCommand arcoff;
arcoff.setArcOffData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ArcWelding::WMoveLCommand wml({0.556769, -0.15, 0.4872, -M_PI, 0, M_PI}, 10, 1); // 直线摆动
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
MoveLCommand ml({0.556769, -0.15, 0.4872, -M_PI, 0, M_PI}, 10, 1); // 直线
ArcWelding::WMoveCCommand wmc({0.786, 0, 0.431, 3, 0.98, 3}, {0.786, 0, 0.431, 3, 0.98, 3}, 10, 1); // 圆弧摆动
robot.setMotionControlMode(MotionControlMode::NrtCommand, ec);
string id;
robot.moveAppend(arcon, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveAppend(wml, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveAppend(arcoff, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.setPowerState(true,ec);
robot.moveStart(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
robot.stop(ec); // 暂停
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveStart(ec);// 继续
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
常用接口与类型
ArcOnCommand、ArcOffCommand、WMoveLCommand、WMoveCCommand、moveAppend、moveStart、MoveLCommand
注意事项
点位、速度、Conf 需适配本机型。
mvoeStart() 是非阻塞接口,要注意避免直接退出程序。
在 arcon 和 arcoff 之前,必须要用普通的 MoveCommand 指令;在他们中间,必须要用 WMoveCommand。
在调用 moveAppend(arcon, id, ec); 时,需要保证控制器已经保存好arcon中对应的起弧参数和焊接参数,不要在这一行代码的上一行或者临近用 setArcOnData 保存数据,避免由于控制器的处理延迟导致调用报错。
如果是飞行起弧,就是 ArcOnData 中的提前起弧时间设置了不为0,则需要在 arcon 前面添加一条 MoveLCommand 指令。
场景七:焊接过程中使用 arc_set_opt(ArcSet)修改工艺参数
适用情况 已在起弧后的某一条焊缝上,希望某一段直线或圆弧改用另一套 arcdata,而不结束电弧、不拆程序。
目标 在压入队列的 WMoveLCommand / WMoveCCommand 等焊接运动上,通过 arc_set_opt 指定切换后的焊接参数名称。
推荐步骤
- 预先
setArcData维护多套命名工艺(如arcdata1、arcdata2)。 - 直线用
WMoveLCommand;圆弧用WMoveCCommand,在指令成员上设置arc_set_opt。
实现代码
/**
* @brief 示例 - 焊接过程中设置焊接参数。点位适用机型XMS5
*/
void arcSetExample() {
std::string cmd_id;
error_code ec;
ArcWelding::ArcOnCommand arc_on_command("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arc_off_command("arcoffdata1");
MoveAbsJCommand absj {{0, M_PI / 6, -M_PI_2, 0, -M_PI / 3, 0}, 1000};
MoveLCommand l {{0.614, 0.136, 0.389, -M_PI, 0, M_PI }, 500};
ArcWelding::WMoveLCommand wmovel1 {{0.553, -0.107, 0.309, -M_PI, 0, M_PI}, 20};
ArcWelding::WMoveLCommand wmovel2 {{0.553, 0.107, 0.309, -M_PI, 0, M_PI}, 20};
wmovel2.arc_set_opt = { "arcdata2", true, 80 };
robot.setPowerState(true, ec);
robot.moveAppend(absj, cmd_id, ec);
robot.moveAppend(l, cmd_id, ec);
robot.moveAppend(arc_on_command, cmd_id, ec);
robot.moveAppend({wmovel1, wmovel2}, cmd_id, ec);
robot.moveAppend(arc_off_command, cmd_id, ec);
robot.moveStart(ec);
while(getchar() != '\n');
robot.setPowerState(false, ec);
}
常用接口与类型
WMoveLCommand::arc_set_opt、WMoveCCommand::arc_set_opt、setArcData
场景八:直线 / 圆弧耦合摆动焊接
适用情况 平角或立角等焊缝需要在直线段或圆弧段上叠加摆动(Weave),由工艺包按摆动数据名解析摆幅、频率等。
目标 摆动数据已下发并与焊接运动绑定;可用 WeaveOnCommand / WeaveOffCommand 包络多段。
推荐步骤
setWeaveData写入摆动工艺名(如weavedata1)。- 创建
WeaveOnCommandWeaveOffCommand。 - 直线:构造
WMoveLCommand后调用setWeaveData("…", ec),或使用带摆动索引的构造函数重载(以 SDK 为准)。 - 圆弧:构造
WMoveCCommand,同样setWeaveData;辅助点、目标点与速度须满足机型与工艺包约束。 - 典型片段:
ArcOnCommand→WeaveOnCommand→ 若干WMoveL/WMoveC→WeaveOffCommand→ArcOffCommand。
实现代码
void weaveOnExample() {
error_code ec;
ArcWelding::ArcOnCommand arcon;
arcon.setArcOnData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
arcon.setArcData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ArcWelding::ArcOffCommand arcoff;
arcoff.setArcOffData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ArcWelding::WMoveLCommand wml({0.556769, -0.15, 0.4872, -M_PI, 0, M_PI}, 10, 1); // 直线摆动
wml.setWeaveData("default", ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "wml: " << wml.getWeaveData() << endl;
ArcWelding::WeaveOnCommand weaveon;
weaveon.setWeaveData("aaa", ec);
ArcWelding::WeaveOffCommand weaveoff;
robot.setMotionControlMode(MotionControlMode::NrtCommand, ec);
string id;
robot.moveAppend(arcon, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveAppend(weaveon, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveAppend(wml, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveAppend(weaveoff, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveAppend(arcoff, id, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.setPowerState(true,ec);
robot.moveStart(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
robot.stop(ec); // 暂停
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
robot.moveStart(ec);// 继续
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
常用接口与类型
setWeaveData、WMoveLCommand、WMoveCCommand、WeaveOnCommand、WeaveOffCommand
注意事项
- 需要摆动的轨迹必须放在
WeaveOnCommand和WeaveOffCommand之间,如果只单独给WMoveLCommand、WMoveCCommand设置摆动参数则不会生效 - 在
WeaveOnCommand和WeaveOffCommand之间的轨迹如果不带摆动参数会默认执行WeaveOnCommand中的摆动参数
场景九:直线 / 圆弧耦合间断焊
适用情况 仅在部分轨迹上需要「焊—停—焊」节拍;不要求摆动,或摆动由其它段单独处理。
目标 在 SegOnCommand 与 SegOffCommand 之间,WMoveL / WMoveC 按 SegData 执行间断节奏;区间外为连续焊或普通焊接运动。
推荐步骤
setSegData写入间断焊参数名(如segdata1)。- 队列:
ArcOnCommand→(可选空移或非间断段)→SegOnCommand("segdata1")→ 一条或多条直线/圆弧焊接运动 →SegOffCommand→ 后续连续焊或收弧。
实现代码
// 间断焊。适用CR机型,SR机型需要调整偏移量
void segOnExample(){
error_code ec;
// 根据起始轴角度,计算笛卡尔位姿
auto model = robot.model();
std::array<double, 6> drag_posture = {0, M_PI / 6, -M_PI_2, 0, -M_PI / 3, 0};
auto p_start = model.calcFk(drag_posture, ec);
print(std::cout, "start pose: ", p_start);
// 设置间断焊参数
ArcWelding::SegData segdata {"segdata1", "segannotation", "normal","v5",15,30};
arcWeld().setSegData(segdata, ec);
// 开始间断焊指令,设置间断焊参数为segdata1
ArcWelding::SegOnCommand segOnCmd("segdata1");
ArcWelding::SegOffCommand segOffCmd;
// 几条焊接运动指令
ArcWelding::WMoveLCommand non_seg_wmovel0(p_start, 20, 0);
non_seg_wmovel0.offset.type = CartesianPosition::Offset::Type::offs;
non_seg_wmovel0.offset.frame.trans = {0.01, 0.03, -0.02};
ArcWelding::WMoveLCommand seg_wmovel0(p_start, 20, 0);
seg_wmovel0.offset.type = CartesianPosition::Offset::Type::offs;
seg_wmovel0.offset.frame.trans = {0, -0.01, -0.02};
seg_wmovel0.arc_set_opt = { "arcdata2", true, 0 };
ArcWelding::WMoveLCommand seg_wmovel1(p_start, 20, 0);
seg_wmovel1.offset.type = CartesianPosition::Offset::Type::offs;
seg_wmovel1.offset.frame.trans = {0, 0.08, -0.02};
seg_wmovel1.arc_set_opt = { "arcdata3", true, 0 };
ArcWelding::WMoveCCommand seg_wmc(p_start, p_start, 10, 0);
seg_wmc.targetOffset.type = CartesianPosition::Offset::Type::offs;
seg_wmc.targetOffset.frame.trans = {0, -0.05, 0.01};
seg_wmc.auxOffset.type = CartesianPosition::Offset::Type::offs;
seg_wmc.auxOffset.frame.trans = {0, 0.070, 0};
ArcWelding::WMoveLCommand non_seg_wmovel1(p_start, 20, 1);
non_seg_wmovel1.offset.type = CartesianPosition::Offset::Type::offs;
non_seg_wmovel1.offset.frame.trans = {-0.05, 0, 0};
non_seg_wmovel1.arc_set_opt = { "arcdata1", true, 0 };
ArcWelding::ArcOnCommand arcOnCmd("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arcOffCmd("arcoffdata1");
MoveAbsJCommand absj {{0, M_PI / 6, -M_PI_2, 0, -M_PI / 3, 0}, 500};
string id;
robot.setPowerState(true, ec);
robot.moveAppend(absj, id, ec);
robot.moveAppend(arcOnCmd, id, ec);
robot.moveAppend({non_seg_wmovel0}, id, ec);
robot.moveAppend(segOnCmd, id, ec);
robot.moveAppend({seg_wmovel0, seg_wmovel1}, id, ec);
robot.moveAppend(seg_wmc, id, ec);
robot.moveAppend(segOffCmd, id, ec);
robot.moveAppend(non_seg_wmovel1, id, ec);
robot.moveAppend(arcOffCmd, id, ec);
robot.moveStart(ec);
while(getchar() != '\n');
}
常用接口与类型
setSegData、SegOnCommand、SegOffCommand、WMoveLCommand、WMoveCCommand
场景十:直线 / 圆弧耦合间断焊 + 摆动
适用情况 间断节拍与摆动同时作用在同一电弧区间。
目标 WeaveOn 包络与 SegOn~SegOff 区间在队列中顺序正确,且各 WMoveL / WMoveC 上 arc_set_opt、偏移等与现场标定一致。
推荐步骤
- 同时完成
setWeaveData与setSegData。 - 参考
segOnExample的典型顺序:ArcOnCommand→WeaveOnCommand→ 非间断的过渡WMoveL(可选)→SegOnCommand→ 间断区间内的多条WMoveL/WMoveC→SegOffCommand→ 后续运动 →WeaveOffCommand→ArcOffCommand。 - 若间断段与连续段工艺不同,在对应指令上分别设置
arc_set_opt。 - 圆弧段目标点、辅助点偏移建议与示例一致地在指令的
offset/targetOffset等成员上配置(以 SDK 头文件为准)。
实现代码
/**
* @brief 示例 - 间断焊。适用CR机型,SR机型需要调整偏移量
*/
void segOnExample(){
error_code ec;
// 根据起始轴角度,计算笛卡尔位姿
auto model = robot.model();
std::array<double, 6> drag_posture = {0, M_PI / 6, -M_PI_2, 0, -M_PI / 3, 0};
auto p_start = model.calcFk(drag_posture, ec);
print(std::cout, "start pose: ", p_start);
// 设置间断焊参数
ArcWelding::SegData segdata {"segdata1", "segannotation", "normal","v5",15,30};
arcWeld().setSegData(segdata, ec);
// 开始间断焊指令,设置间断焊参数为segdata1
ArcWelding::SegOnCommand segOnCmd("segdata1");
ArcWelding::SegOffCommand segOffCmd;
// 几条焊接运动指令
ArcWelding::WMoveLCommand non_seg_wmovel0(p_start, 20, 0);
non_seg_wmovel0.offset.type = CartesianPosition::Offset::Type::offs;
non_seg_wmovel0.offset.frame.trans = {0.01, 0.03, -0.02};
ArcWelding::WMoveLCommand seg_wmovel0(p_start, 20, 0);
seg_wmovel0.offset.type = CartesianPosition::Offset::Type::offs;
seg_wmovel0.offset.frame.trans = {0, -0.01, -0.02};
seg_wmovel0.arc_set_opt = { "arcdata2", true, 0 };
ArcWelding::WMoveLCommand seg_wmovel1(p_start, 20, 0);
seg_wmovel1.offset.type = CartesianPosition::Offset::Type::offs;
seg_wmovel1.offset.frame.trans = {0, 0.08, -0.02};
seg_wmovel1.arc_set_opt = { "arcdata3", true, 0 };
ArcWelding::WMoveCCommand seg_wmc(p_start, p_start, 10, 0);
seg_wmc.targetOffset.type = CartesianPosition::Offset::Type::offs;
seg_wmc.targetOffset.frame.trans = {0, -0.05, 0.01};
seg_wmc.auxOffset.type = CartesianPosition::Offset::Type::offs;
seg_wmc.auxOffset.frame.trans = {0, 0.070, 0};
ArcWelding::WMoveLCommand non_seg_wmovel1(p_start, 20, 1);
non_seg_wmovel1.offset.type = CartesianPosition::Offset::Type::offs;
non_seg_wmovel1.offset.frame.trans = {-0.05, 0, 0};
non_seg_wmovel1.arc_set_opt = { "arcdata1", true, 0 };
ArcWelding::ArcOnCommand arcOnCmd("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arcOffCmd("arcoffdata1");
MoveAbsJCommand absj {{0, M_PI / 6, -M_PI_2, 0, -M_PI / 3, 0}, 500};
ArcWelding::WeaveOnCommand weave_on_command("weavedata1");
ArcWelding::WeaveOffCommand weaveOffCmd;
string id;
robot.setPowerState(true, ec);
robot.moveAppend(absj, id, ec);
robot.moveAppend(arcOnCmd, id, ec);
robot.moveAppend(weave_on_command, id, ec);
robot.moveAppend({non_seg_wmovel0}, id, ec);
robot.moveAppend(segOnCmd, id, ec);
robot.moveAppend({seg_wmovel0, seg_wmovel1}, id, ec);
robot.moveAppend(seg_wmc, id, ec);
robot.moveAppend(segOffCmd, id, ec);
robot.moveAppend(non_seg_wmovel1, id, ec);
robot.moveAppend(weaveOffCmd, id, ec);
robot.moveAppend(arcOffCmd, id, ec);
robot.moveStart(ec);
while(getchar() != '\n');
}
常用接口与类型
同场景八与场景九所列类型组合使用。
注意事项
顺序错误可能导致摆动或间断未按预期生效;务必在仿真/空运行下先验证再实焊。
场景十一:钟摆形轨迹焊接
适用情况 焊缝几何由工艺定义为钟摆形路径(专用钟摆运动指令)。
目标 正确使用 WMoveLPendulumCommand 的起点、辅助点、目标点及速度等参数;需要切换规范时在成员上设置 arc_set_opt。
推荐步骤
- 按工艺包与示教数据填入
WMoveLPendulumCommand各点(与arcSetPendulumExample一致)。 - 与
ArcOnCommand/ArcOffCommand组合方式与普通焊接运动相同,压入非实时队列后moveStart。 - 若同程序中还有普通摆焊,注意与场景八区分:钟摆为独立运动类型,一般不混用
WeaveOn包络同一段钟摆(以工艺包说明为准)。
实现代码
/**
* @brief 示例 - 焊接钟摆过程中设置焊接参数。
*/
void arcSetPendulumExample() {
std::string cmd_id;
error_code ec;
// 设置起弧/收弧
ArcWelding::ArcData arcData;
arcData.name = "arcdata1";
arcWeld().setArcData(arcData, ec);
arcData.name = "arcdata2";
arcData.current = 20;
arcData.voltage = 15;
arcWeld().setArcData(arcData, ec);
arcData.name = "arcdata3";
arcData.current = 100;
arcData.voltage = 20;
arcData.weld_speed = 15;
arcWeld().setArcData(arcData, ec);
ArcWelding::ArcOnData arconData;
arconData.name = "arcondata1";
arcWeld().setArcOnData(arconData, ec);
ArcWelding::ArcOffData arcOffData;
arcOffData.name = "arcoffdata1";
arcWeld().setArcOffData(arcOffData, ec);
// 设置摆动
ArcWelding::WeaveData weaveData;
weaveData.weave_length_frequency = 3.5;
weaveData.amplitude.left = 6;
weaveData.amplitude.right = 4.5;
arcWeld().setWeaveData(weaveData, ec);
ArcWelding::ArcOnCommand arc_on_command("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arc_off_command("arcoffdata1");
MoveAbsJCommand absj{ {0.168,0.369, -0.883,-0.210,-0.637,-0.137}, 1000 };
// 使用栈上对象而不是堆上对象,避免内存泄漏
CartesianPosition start1{ 0.68015, -0.077702, 0.777555, -2.319, 1.112, -2.228 };
CartesianPosition startAux1{ 0.672849, -0.0777043, 0.777555, -2.319, 1.112, -2.228 };
CartesianPosition targetAux1{ 0.647849, -0.0943, 0.750882, -2.319, 1.112, -2.228 };
CartesianPosition target1{ 0.647849, -0.09473, 0.747882, -2.319, 1.112, -2.228 };
CartesianPosition targetAux2{ 0.437346, -0.2597, 0.793403, -2.319, 1.112, -2.228 };
CartesianPosition target2{ 0.435346, -0.2597, 0.796403, -2.319, 1.112, -2.228 };
CartesianPosition targetAux3{ 0.6117849, -0.14534, 0.666882, -2.319, 1.112, -2.228 };
CartesianPosition target3{ 0.599849, -0.14574, 0.667882, -2.319, 1.112, -2.228 };
MoveLCommand l{ start1, 500 };
// 钟摆
ArcWelding::WMoveLPendulumCommand wp1{ startAux1, target1, targetAux1, 20, 0.5, 100, 2 };
ArcWelding::WMoveLPendulumCommand wp2{ NULL, target2, targetAux2, 20, 3, 234, 1 };
wp2.arc_set_opt = { "arcdata2", true, 0 };
ArcWelding::WMoveLPendulumCommand wp3{ NULL, target3, targetAux3, USE_DEFAULT, 3.1, 4, 5 };
wp3.arc_set_opt = { "arcdata3", true, 0 };
robot.setPowerState(true, ec);
robot.moveAppend(absj, cmd_id, ec);
robot.moveAppend(l, cmd_id, ec);
robot.moveAppend(arc_on_command, cmd_id, ec);
robot.moveAppend(wp1, cmd_id, ec);
robot.moveAppend(wp2, cmd_id, ec);
robot.moveAppend(wp3, cmd_id, ec);
robot.moveAppend(arc_off_command, cmd_id, ec);
robot.moveStart(ec);
while (getchar() != '\n');
robot.setPowerState(false, ec);
}
常用接口与类型
WMoveLPendulumCommand、WMoveLCommand::arc_set_opt
场景十二:电弧跟踪
适用情况 焊接过程中需根据电弧传感修正横向或高度方向
目标 指定轨迹段使用某套 ArcTrackParam;其它段不传跟踪名即不跟踪。
推荐步骤
setArcTrackParam下发跟踪参数名(如arctrackdata1)。- 在
WMoveLCommand等带摆动名的重载中传入跟踪数据名;圆弧若 SDK 提供同等重载,绑定方式相同(以头文件为准)。 - 典型队列:
ArcOnCommand→WeaveOnCommand→ 多条带跟踪的焊接运动 →WeaveOffCommand→ArcOffCommand。 - 等待运动结束并确认收弧完成(可结合场景十八事件订阅)。
实现代码
/**
* @brief 示例 - 电弧跟踪,点位适配机型NB4h-R580-XX
*/
void arcTrackExample() {
error_code ec;
//设置电弧跟踪参数
ArcWelding::ArcTrackParam param;
param.name = "arctrackdata1";
param.annotation = "test1";
param.delay_time = 5;//其他的值类似设置就行,这里直接使用默认值
arcWeld().setArcTrackParam(param,ec);
//获取对应的电弧跟踪参数
auto param_get = arcWeld().getArcTrackParam(param.name, ec);
std::cout << "name: " << param_get.name << " annotation: " << param_get.annotation << " delay_time: " << param_get.delay_time << std::endl;
//本例验证时运行于NB4h-R580-3B(注意点位匹配)
auto p0 = { 0.357487, 0.000633967, 0.222628, 3.0, 0.0685018, 3.12448 };
auto p1 = { 0.357487, 0.143835, 0.222628, 3.13197, 0.0685018, 3.12448 };
auto p2 = { 0.456268, 0.000634313, 0.222628, 3.13197, 0.0685026, 3.12448 };
auto p3 = { 0.456268, 0.143835, 0.222628, 3.13197, 0.0685024, 3.12448 };
auto p4 = { 0.456268, -0.103198, 0.222628, 3.13197, 0.068502, 3.12448 };
ArcWelding::ArcOnCommand arcon("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arcoff("arcoffdata1");
MoveJCommand mj(p0, 100, 1);
// 第一条,开启电弧跟踪,用跟踪参数arctrackdata1
ArcWelding::WMoveLCommand wml1(p1, 20, 1, "weavedata1", "arctrackdata1");
// 第二条,开启电弧跟踪,用跟踪参数arctrackdata2
ArcWelding::WMoveLCommand wml2(p2, 20, 1, "weavedata1", "arctrackdata2");
// 第三条,电弧跟踪参数为空,不跟踪
ArcWelding::WMoveLCommand wml3(p3, 20, 1, "weavedata1");
// 第四条和第五条,开启电弧跟踪,用跟踪参数arctrackdata2
ArcWelding::WMoveLCommand wml4(p4, 20, 1, "weavedata1", "arctrackdata2");
ArcWelding::WMoveLCommand wml5(p3, 20, 1, "weavedata1", "arctrackdata2");
// 第六条,不跟踪
ArcWelding::WMoveLCommand wml6(p2, 20, 1, "weavedata1"); // 直线摆动
ArcWelding::WeaveOnCommand weaveon("weavedata1");
ArcWelding::WeaveOffCommand weaveoff;
auto wmove_list = {wml1, wml2, wml3, wml4, wml5, wml6};
string id, move_id;
robot.setPowerState(true, ec);
robot.moveAppend(mj, move_id, ec);
robot.moveAppend(arcon, id, ec); if(ec) std::cout << __LINE__ << ":" << ec.message() << std::endl;
robot.moveAppend(weaveon, id, ec); if(ec) std::cout << __LINE__ << ":" << ec.message() << std::endl;
robot.moveAppend(wmove_list, move_id, ec); if(ec) std::cout << __LINE__ << ":" << ec.message() << std::endl;
robot.moveAppend(weaveoff, id, ec); if(ec) std::cout << __LINE__ << ":" << ec.message() << std::endl;
robot.moveAppend(arcoff, id, ec); if(ec) std::cout << __LINE__ << ":" << ec.message() << std::endl;
robot.moveStart(ec); if(ec) std::cout << __LINE__ << ":" << ec.message() << std::endl;
waitForFinish(robot, move_id, (int)wmove_list.size() - 1);
while(-1 != std::any_cast<int>(robot.queryEventInfo(Event::arcWeldState, ec).at(EventInfoKey::ArcWeldState::ArcWelding))) {
// waiting for arc off
std::this_thread::sleep_for(std::chrono::milliseconds (10));
}
print(std::cout, "Finish running");
}
常用接口与类型
setArcTrackParam、getArcTrackParam、WMoveLCommand(带跟踪参数的重载)、ArcOnCommand、WeaveOnCommand、WeaveOffCommand、ArcOffCommand
注意事项
跟踪效果与焊机、焊丝、电流波形及机型有关;点位需在本机重新标定。 开电弧跟踪的时候必须要开摆动
场景十三:激光寻位
适用情况 在焊接主程序前或中途,需要用激光测量得到焊缝或特征点的位姿修正量。
目标 LaserSearchData 已下发,executeLaserSearch 在约定超时内返回结果;手眼数据名与指令中引用一致。
推荐步骤
- 传感器网络、手眼关系、设备连接等基础配置见场景十四(
LaserSensorCfg、setHandeyeData、connLaserSensorDev等)。 setLaserSearchData维护寻位工艺名与工艺包约定字段。- 构造
LaserSearchCommand(手眼数据名、寻位数据名、搜索位姿、速度等),调用executeLaserSearch;同步/异步、超时与线程安全由应用保证。
实现代码
void LaserSearchExample() {
// 保存手眼标定参数
ArcWelding::HandeyeData handeyedata0;
handeyedata0.mode = true;
handeyedata0.xyz_abc = {29.456, -14.151, 70.047, 4.5006 / 180.0 * M_PI, 4.0438 / 180.0 * M_PI, -97.358 / 180.0 * M_PI};
handeyedata0.name = "laserhandeyedata1";
error_code ec;
arcWeld().setHandeyeData(handeyedata0, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
// 保存寻位参数
ArcWelding::LaserSearchData laserSearchData{"lasersearchdata1", 2, "point", "continuous", 3, "lap_joint"};
arcWeld().setLaserSearchData(laserSearchData, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
CartesianPosition laserSearchPos;
laserSearchPos.rpy = {3.14, 0, 3.14};
laserSearchPos.trans ={0.563,0.3,0.43};
ArcWelding::LaserSearchCommand laserSearchCmd("laserhandeyedata1","lasersearchdata1",laserSearchPos, 10, 0);
bool isFound;
CartesianPosition pos;
std::tuple<bool, rokae::CartesianPosition> ret;
// 示例中选择同步等待寻位结果,设置超时时间为 30 秒。可根据轨迹速度和长度来设置超时时间。
std::chrono::seconds timeout(30);
// 一、单独运动
// 使用 std::async 启动一个线程执行 executeLaserSearch
auto future = std::async(std::launch::async,
[laserSearchCmd, timeout]() {
error_code _ec;
auto r = arcWeld().executeLaserSearch(laserSearchCmd, false, timeout, _ec);
cout << "executeLaserSearch ec: " << _ec.value() << ", " << _ec.message() << endl;
return r;
});
// 主线程执行 moveStart
std::this_thread::sleep_for(std::chrono::seconds(1)); // 注意处理异步之间的顺序,这里用延时代替
robot.moveStart(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
// 等待异步线程完成
ret = future.get();
isFound = std::get<0>(ret);
pos = std::get<1>(ret);
std::cout << "isFound: " << isFound << ", pos: ";
std::copy(pos.trans.begin(), pos.trans.end(), std::ostream_iterator<double>(std::cout, ", "));
std::cout << "rpy: ";
std::copy(pos.rpy.begin(), pos.rpy.end(), std::ostream_iterator<double>(std::cout, ", "));
std::cout << std::endl;
// 二、寻位并运动
robot.moveReset(ec);
ret = arcWeld().executeLaserSearch(laserSearchCmd, true,timeout, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
isFound = std::get<0>(ret);
pos = std::get<1>(ret);
std::cout << "isFound: " << isFound << ", pos: ";
std::copy(pos.trans.begin(), pos.trans.end(), std::ostream_iterator<double>(std::cout, ", "));
std::cout << "rpy: ";
std::copy(pos.rpy.begin(), pos.rpy.end(), std::ostream_iterator<double>(std::cout, ", "));
std::cout << std::endl;
}
常用接口与类型
setLaserSearchData、LaserSearchCommand、executeLaserSearch、HandeyeData(名在指令中引用)
场景十四:激光跟踪——传感器配置、连接与队列用法
适用情况 要在上位机维护激光 IP、周期、类型;连接设备;焊缝跟踪。
目标 设备可连接、可监控;跟踪段内 LaserTrackOnCommand~LaserTrackOffCommand 与焊接运动同队列。
推荐步骤(配置与连接)
- 填写
LaserSensorCfg,setLaserSensorCfg;可选setEventWatcher(Event::lasertrackState, …)。 connLaserSensorDev/disconnLaserSensorDev;不用时removeLaserSensorCfg。- 手眼关系:
setHandeyeData/getHandeyeData;自动标定:startHandeyeCalibration→calibratePoint→calibrateEnd。 - 跟踪工艺名:
setLaserTrackData(与工艺包字段一致)。
推荐步骤(焊缝跟踪队列)
- 连接设备后
openLaserTrack("sensor1", ec)。 - 队列:
ArcOnCommand→LaserTrackOnCommand→WMoveL/WMoveC等 →LaserTrackOffCommand→ArcOffCommand。 closeLaserTrack,再按规范disconnLaserSensorDev。
实现代码
以下依次为同文件中的 printLaserSensorState、setLaserSensorStateWatcher(供配置示例注册回调)、LaserSensorSettingExample、LaserTrackCommandExample(使用公共段中的 ROKAE_EXE 与 waitForFinish)。
//打印激光跟踪器状态
void printLaserSensorState(const EventInfo& info)
{
using namespace rokae::EventInfoKey::LaserTrackState;
print(std::cout, "[激光跟踪器状态信息] 设备名称: ", std::any_cast<std::string>(info.at(DeviceName)),
" 连接:", std::any_cast<bool>(info.at(Connect)) ? "YES " : "NO ",
"激光开启:", std::any_cast<bool>(info.at(LaserOn)) ? "YES " : "NO ",
"使能开启:", std::any_cast<bool>(info.at(PowerOn)) ? "YES " : "NO ");//注意:明图传感器没有使能状态,这里的使能状态无效
}
// 激光跟踪器状态监视
void setLaserSensorStateWatcher()
{
error_code ec;
robot.setEventWatcher(rokae::Event::lasertrackState, printLaserSensorState, ec);
if(ec) {
print(std::cerr, "Set laser state watcher failed:", ec);
}
}
/**
* @brief 示例 - 激光传感器相关设置
*/
void LaserSensorSettingExample() {
//设置激光跟踪器配置信息
ArcWelding::LaserSensorCfg cfg;
cfg.name = "sensor1";
cfg.ip = "192.168.2.3";
cfg.port = 502;
cfg.overtime = 800;
cfg.communication_cycle = 60;
cfg.type = ArcWelding::LaserSensorType::CRNT;//创想传感器
//cfg.type = ArcWelding::LaserSensorType::SMART_IMAGE;//明图传感器
//cfg.type = ArcWelding::LaserSensorType::INTELLIGENT;//英莱传感器
error_code ec;
//发送指令设置AddLaserSensorCfg
arcWeld().setLaserSensorCfg(cfg, ec);
if (ec) cout << ec.message()<<std::endl;
//查询设备配置信息
ArcWelding::LaserSensorCfg cfg_get = arcWeld().getLaserSensorCfg(cfg.name, ec);
cout << "name:" << cfg_get.name << " ip:" << cfg_get.ip << endl;
if (ec) cout << ec.message() << std::endl;
//设置传感器状态监控watch
setLaserSensorStateWatcher();
//连接激光跟踪器ConnLaserTrack
arcWeld().connLaserSensorDev(cfg.name, ec);
if (ec) cout << ec.message() << std::endl;
//断开连接DisConnLaserTrack
arcWeld().disconnLaserSensorDev(cfg.name,ec);
if (ec) cout << ec.message() << std::endl;
//删除设备配置信息RemoveLaserSensorCfg
arcWeld().removeLaserSensorCfg(cfg.name, ec);
if (ec) cout << ec.message() << std::endl;
//设置手眼标定结果
ArcWelding::HandeyeData handeyedata0;
handeyedata0.mode = true; // 使用XYZ_ABC的形式
handeyedata0.xyz_abc = { 29.456,-14.151,70.047,4.5006 / 180.0 * M_PI,4.0438 / 180.0 * M_PI,-97.358 / 180.0 * M_PI };
handeyedata0.name = "handeyedata0";
arcWeld().setHandeyeData(handeyedata0, ec);
if (ec) cout << ec.message() << std::endl;
//查询手眼标定结果
std::string name = "handeyedata0";
auto handeyedata0_get = arcWeld().getHandeyeData(name, ec);
if (ec) cout << ec.message() << std::endl;
cout << "name:" << handeyedata0_get.name << " xyz_abc:{" << handeyedata0_get.xyz_abc[0] << "," << handeyedata0_get.xyz_abc[2] << ","
<< handeyedata0_get.xyz_abc[2] << "," << handeyedata0_get.xyz_abc[3] << "," << handeyedata0_get.xyz_abc[4] << ","
<< handeyedata0_get.xyz_abc[5] << "}"<< endl;
//删除手眼标定结果
arcWeld().removeHandeyeData(name,ec);
if (ec) cout << ec.message() << std::endl;
}
/**
* @brief 示例 - 激光跟踪。点位适配机型XMS5
*/
void LaserTrackCommandExample(){
error_code ec;
// 设置传感器状态监控
setLaserSensorStateWatcher();
// 连接激光器
arcWeld().connLaserSensorDev("sensor1", ec);
if (ec) {
print(std::cerr, "Connected laser sensor failed", ec);
return;
}
ArcWelding::ArcOnCommand arcOnCmd("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arcOffCmd("arcoffdata1");
ArcWelding::LaserTrackOnCommand laserTrackOnCmd; // 默认手眼标定参数和激光跟踪参数名为"default",参考设置这两个参数的方式设置
ArcWelding::LaserTrackOffCommand laserTrackOffCmd;
MoveJCommand movej {{0.614, 0.136, 0.389, -M_PI, 0, M_PI }, 500};
ArcWelding::WMoveLCommand wmovel1 {{0.553, -0.107, 0.309, -M_PI, 0, M_PI}, 20};
ArcWelding::WMoveLCommand wmovel2 {{0.553, 0.107, 0.309, -M_PI, 0, M_PI}, 20};
string id, move_id;
robot.setOperateMode(rokae::OperateMode::automatic, ec);
robot.setPowerState(true, ec);
if(ec) {
print(std::cerr, "Set power state failed", ec);
return;
}
// 打开激光传感器
arcWeld().openLaserTrack("sensor1", ec);
if(ec) {
print(std::cerr, "Open laser sensor failed", ec);
return;
}
ROKAE_EXE(robot.moveAppend(movej, move_id, ec));
ROKAE_EXE(robot.moveAppend(arcOnCmd, id, ec));
ROKAE_EXE(robot.moveAppend(laserTrackOnCmd, id, ec));
ROKAE_EXE(robot.moveAppend({wmovel1, wmovel2}, move_id, ec));
ROKAE_EXE(robot.moveAppend(laserTrackOffCmd,id, ec));
ROKAE_EXE(robot.moveAppend(arcOffCmd, id, ec));
ROKAE_EXE(robot.moveStart(ec));
if(ec) return;
waitForFinish(robot, move_id, 1);
while(-1 != std::any_cast<int>(robot.queryEventInfo(Event::arcWeldState, ec).at(EventInfoKey::ArcWeldState::ArcWelding))) {
// waiting for arc off
std::this_thread::sleep_for(std::chrono::milliseconds (10));
}
// 关闭激光传感器
ROKAE_EXE(arcWeld().closeLaserTrack("sensor1", ec));
robot.setPowerState(false, ec);
robot.setOperateMode(rokae::OperateMode::manual, ec);
}
常用接口与类型
LaserSensorCfg、setLaserSensorCfg、connLaserSensorDev、openLaserTrack、closeLaserTrack、setLaserTrackData、LaserTrackOnCommand、LaserTrackOffCommand、GetLaserPos
注意事项
场景十五:多层多道与层道偏移
适用情况 同一焊缝截面需要多道堆叠,或每层起点/姿态按 LayerData 偏移。
目标 层道参数已下发;可选先做可达性校验,再在下料队列中用 OffsetOnCommand / OffsetOffCommand 包络各层轨迹。
推荐步骤
setLayerData为每层道维护名称与偏移、辅助点等。- 使用
MpmlPathCheck对路径点组、运动类型列表与层道列表做校验,收集不可达层名。 - 需要时
GetLayerStartPoint获取建议起弧位姿。 - 队列中在对应层轨迹前插入
OffsetOnCommand(layerName),层结束处OffsetOffCommand。
实现代码
// 点位适配机型XMC7-R850-B0X1A0
void arcLayerExample() {
std::string cmd_id;
error_code ec;
//设置多层多道参数
ArcWelding::LayerData layerData1;
layerData1.name = "layerdata1";
layerData1.start_offset = 10;
layerData1.end_offset = 01;
layerData1.y_offset = 10;
layerData1.z_offset = -0;
layerData1.tilt_angle = 0;
layerData1.travel_angle = 0;
layerData1.layer_reverse = false;
layerData1.offset_coord_system = 2;
layerData1.aux_type = 3;//三点法
//辅助点坐标值
layerData1.aux_point_1 = {514, -136, 410};
layerData1.aux_point_2 = {600, -120, 410};
layerData1.aux_point_3 = {500, -100, 410};
arcWeld().setLayerData(layerData1, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ArcWelding::LayerData layerData2;
layerData2.name = "layerdata2";
layerData2.start_offset = 0;
layerData2.end_offset = 20;
layerData2.y_offset = 50;
layerData2.z_offset = -0;
layerData2.tilt_angle = 0;
layerData2.travel_angle = 10;
layerData2.layer_reverse = true;
layerData2.offset_coord_system = 2;
layerData2.aux_type = 3;//三点法
//辅助点坐标值
layerData2.aux_point_1 = {514, -136, 410};
layerData2.aux_point_2 = {600, -120, 410};
layerData2.aux_point_3 = {500, -100, 410};
arcWeld().setLayerData(layerData2, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ArcWelding::LayerData layerData3;
layerData3.name = "layerdata3";
layerData3.start_offset = 0;
layerData3.end_offset = 0;
layerData3.y_offset = 100;
layerData3.z_offset = -0;
layerData3.tilt_angle = 10;
layerData3.travel_angle = 0;
layerData3.layer_reverse = true;
layerData3.offset_coord_system = 2;
layerData3.aux_type = 3;//三点法
//辅助点坐标值
layerData3.aux_point_1 = {514, -136, 410};
layerData3.aux_point_2 = {600, -120, 410};
layerData3.aux_point_3 = {500, -100, 410};
arcWeld().setLayerData(layerData3, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
ArcWelding::OffsetOnCommand offset_on_command1("layerdata1");
ArcWelding::OffsetOnCommand offset_on_command2("layerdata2");
ArcWelding::OffsetOnCommand offset_on_command3("layerdata3");
ArcWelding::OffsetOffCommand offset_off_command;
ArcWelding::ArcOnCommand arc_on_command("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arc_off_command("arcoffdata1");
CartesianPosition pos1_1{{0.600, -0.136, 0.589, -M_PI, 0, M_PI}};
CartesianPosition pos2_1{{0.500, -0.150, 0.489, -M_PI, 0, M_PI}};
CartesianPosition pos3_1{{0.400, -0.150, 0.489, -M_PI, 0, M_PI}};
CartesianPosition pos4_1{{0.300, -0.100, 0.489, -M_PI, 0, M_PI}};
CartesianPosition pos4_aux_1{{0.200, -0.150, 0.489, -M_PI, 0, M_PI}};
CartesianPosition pos5_1{{0.400, -0.150, 0.600, -M_PI, 0, M_PI}};
CartesianPosition pos1_2{{0.600, -0.136, 0.389, -M_PI, 0, M_PI}};
CartesianPosition pos2_2{{0.500, -0.150, 0.389, -M_PI, 0, M_PI}};
CartesianPosition pos3_2{{0.400, -0.150, 0.389, -M_PI, 0, M_PI}};
CartesianPosition pos1_3{{0.600, -0.136, 0.289, -M_PI, 0, M_PI}};
CartesianPosition pos2_3{{0.500, -0.150, 0.289, -M_PI, 0, M_PI}};
CartesianPosition pos3_3{{0.400, -0.150, 0.289, -M_PI, 0, M_PI}};
MoveJCommand movej_pos1_1{pos1_1, 100};
MoveLCommand movel_pos2_1{pos2_1, 20};
MoveLCommand movel_pos3_1{pos3_1, 20};
MoveLCommand movel_pos4_1{pos4_1, 20};
ArcWelding::WMoveCCommand movec_pos4_1{pos4_1, pos4_aux_1, 20};
movec_pos4_1.target.confData = {10, 25, -118, 0, -36, 6};
MoveLCommand movel_pos5_1{pos5_1, 20};
MoveJCommand movej_pos1_2{pos1_2, 100};
MoveLCommand movel_pos2_2{pos2_2, 20};
MoveLCommand movel_pos3_2{pos3_2, 20};
MoveJCommand movej_pos1_3{pos1_3, 100};
MoveLCommand movel_pos2_3{pos2_3, 20};
MoveLCommand movel_pos3_3{pos3_3, 20};
ArcWelding::WMoveLCommand arcwl1(pos3_1, 10, 1);
std::vector<std::vector<CartesianPosition>> point_groups = {
{pos2_1},
{pos3_1},
{pos4_aux_1, pos4_1},
};
std::vector<ArcWelding::MotionType> point_types = {
ArcWelding::MotionType::MOVE_LINEAR,
ArcWelding::MotionType::MOVE_LINEAR,
ArcWelding::MotionType::MOVE_CIRCLE,
};
std::vector<std::string> error_layer_list;
std::vector<ArcWelding::LayerData> layerdata_list;
// 模拟两层共计三道可达性校验
layerdata_list.push_back(layerData1);
layerdata_list.push_back(layerData2);
layerdata_list.push_back(layerData3);
bool check_res = arcWeld().MpmlPathCheck(point_groups, point_types, layerdata_list, error_layer_list, ec);
// 运动至起弧点示例
rokae::CartesianPosition start_position;
bool res = arcWeld().GetLayerStartPoint(point_groups, point_types, layerData2, start_position, ec);
robot.setPowerState(true, ec);
// 多层多道暂停|继续
int index = 1;
while (index < 4){
// 偏移启动
switch (++index) {
case 1:
robot.moveAppend(offset_on_command1, cmd_id, ec);
break;
case 2:
robot.moveAppend(offset_on_command2, cmd_id, ec);
break;
case 3:
robot.moveAppend(offset_on_command3, cmd_id, ec);
break;
default:
break;
}
if (index == 3)
robot.moveStart(ec, true);//暂停层道继续执行
robot.moveAppend(movej_pos1_1, cmd_id, ec);//0.600, -0.136, 0.589
robot.moveAppend(offset_on_command1, cmd_id, ec);
robot.moveAppend(movel_pos2_1, cmd_id, ec);//0.500, -0.150, 0.489
robot.moveAppend(arc_on_command, cmd_id, ec);
robot.moveAppend(arcwl1, cmd_id, ec);//0.400, -0.150, 0.489
robot.moveAppend(movec_pos4_1, cmd_id, ec);//0.400, -0.150, 0.600
robot.moveAppend(arc_off_command, cmd_id, ec);
robot.moveAppend(offset_off_command, cmd_id, ec);
if (index == 2)
robot.moveAppend(movel_pos4_1, cmd_id, ec, true);//0.400, -0.150, 0.589
else
robot.moveAppend(movel_pos4_1, cmd_id, ec);//0.400, -0.150, 0.589
robot.moveStart(ec);
index++;
}
robot.setPowerState(false, ec);
}
常用接口与类型
setLayerData、getLayerData、removeLayerData、LayerData、MpmlPathCheck、GetLayerStartPoint、OffsetOnCommand、OffsetOffCommand
场景十六:整圆与复杂空间曲线(摆动 / 间断 / 跟踪可选)
适用情况 焊缝为整圆或 MoveCF 类曲线,且可能叠加摆动、间断焊或电弧跟踪。
目标 使用 WMoveCFCommand 等与工艺指令组合;具体组合顺序与注释中的多种模式以工艺验证为准。
推荐步骤
- 将圆或曲线以工艺包要求的辅助点与目标点形式构造
WMoveCFCommand。 - 按需
setWeaveData、setSegData、setArcTrackParam后,在指令上绑定名称或在队列中插入SegOnCommand等。 - 在仿真或空运行下验证轨迹与姿态,再切实焊。
实现代码
void wmovecfExample() {
// 点位机型 XMC7-R850-W7G3B4C
cout << "enter exampleCommand" << endl;
auto rlPoint2sdkPoint = [](const std::vector<double> &rlPoint) -> std::array<double, 6> {
std::array<double, 6> sdkPoint;
for (int i = 0; i < 3; i++) {
sdkPoint[i] = rlPoint[i] / 1000.0;
}
for (int i = 3; i < 6; i++) {
sdkPoint[i] = rlPoint[i] / 180.0 * M_PI;
}
return sdkPoint;
};
error_code ec;
ArcWelding::ArcOnCommand arcon("arcondata1", "arcdata1");
ArcWelding::ArcOffCommand arcoff("arcoffdata1");
ArcWelding::SegOnCommand segon("segdata1");
ArcWelding::SegOffCommand segooff;
ArcWelding::WeaveOnCommand weaveon("weavedata1");
ArcWelding::WeaveOffCommand weaveoff;
std::vector<double> p1point({556.769126, 101.641184, 358.852436, 158.661084, -17.184105, -148.826026});
std::vector<double> p2point({590.049781, 101.641177, 358.852421, 158.66108, -17.184102, -148.826024});
std::vector<double> p3point({556.769146, 17.242862, 358.852448, 179.999964, -0.000009, -179.999957});
std::vector<double> p4point({556.769126, 101.641184, 358.852436, 179.999964, -0.000009, -179.999957});
std::vector<double> p5point({590.049781, 101.641177, 358.852421, 179.999964, -0.000009, -179.999957});
CartesianPosition p1(rlPoint2sdkPoint(p1point));
CartesianPosition p2(rlPoint2sdkPoint(p2point));
CartesianPosition p3(rlPoint2sdkPoint(p3point));
CartesianPosition p4(rlPoint2sdkPoint(p4point));
CartesianPosition p5(rlPoint2sdkPoint(p5point));
ArcWelding::WMoveLCommand wml(p3, 200, 1);
ArcWelding::WMoveCFCommand wmcf(p2, p1, 300 / 180.0 * M_PI);
ArcWelding::WMoveCFCommand wmcf2(p4, p5, 300 / 180.0 * M_PI);
// 设置旋转类型
// wmcf.rotType = MoveCFCommand::constPose;
wmcf.rotType = MoveCFCommand::constPose;
// wmcf.rotType = MoveCFCommand::rotAxis;
string id;
// 单独整圆运动
// robot.moveAppend(arcon, id, ec);
// robot.moveAppend(wmcf, id, ec);
// robot.moveAppend(arcoff, id, ec);
// robot.moveStart(ec);
// 搭配摆动运动
// wmcf.setWeaveData("weavedata1", ec);
// robot.moveAppend(arcon, id, ec);
// robot.moveAppend(weaveon, id, ec);
// robot.moveAppend(wmcf, id, ec);
// robot.moveAppend(weaveoff, id, ec);
// robot.moveAppend(arcoff, id, ec);
// robot.moveStart(ec);
// 搭配间断焊运动
// robot.moveAppend(arcon, id, ec);
// robot.moveAppend(segon, id, ec);
// robot.moveAppend(wmcf, id, ec);
// robot.moveAppend(segooff, id, ec);
// robot.moveAppend(arcoff, id, ec);
// robot.moveStart(ec);
// 搭配电弧跟踪,需要搭配摆动
// wmcf.setWeaveData("weavedata1", ec);
// wmcf.setTrackData("arctrackdata1", ec);
// robot.moveAppend(arcon, id, ec);
// robot.moveAppend(weaveon, id, ec);
// robot.moveAppend(wmcf, id, ec);
// robot.moveAppend(weaveoff, id, ec);
// robot.moveAppend(arcoff, id, ec);
// robot.moveStart(ec);
// arcdata中设置了断弧回退距离,暂停后继续运动会回退,需要有前置轨迹
// robot.setDefaultConfOpt(false,ec);
// robot.moveAppend(arcon, id, ec);
// robot.moveAppend(wml, id, ec);
// robot.moveAppend(wmcf, id, ec);
// robot.moveAppend(arcoff, id, ec);
// robot.moveStart(ec);
// std::this_thread::sleep_for(std::chrono::milliseconds(4000));
// robot.stop(ec); // 暂停
// std::this_thread::sleep_for(std::chrono::milliseconds(1000));
// robot.moveStart(ec);// 继续
}
常用接口与类型
WMoveCFCommand、MoveCFCommand::rotType
场景十七:现场辅助动作与焊机状态
适用情况 调枪、引弧前送丝 / 退丝 / 检气;短时点焊铆焊;读取焊机实时量或清报警;在不实际焊接时,通过 enableArcData 选择工作模式并将电流/电压模式与设定值下发至焊机,对照焊机面板核对已生效数据是否与上位机一致。
目标 不依赖完整焊接轨迹即可完成维护性动作;HMI 可展示焊机状态。
推荐步骤
- 送丝、退丝、检气:调用
feedOnWire、feedBackWire、detectGas等,持续时间需满足工艺包最小阈值(如大于 0.1 s);停止动作使用对应重载中的使能参数(见附录方法)。 - 铆焊:
startWelding/stopWelding,区分一元化与分别模式等(见接口说明)。 - 状态:
getWelderStatus;报警可恢复时clearWelderAlarm。 enableArcData:用于在焊机侧使能/生效一条焊接工艺数据(含工作模式、电流/电压模式及电流、电压等设定),该数据不会被保存。在不建立焊接过程的前提下调用后,对照焊机面板显示与上位机下发值是否一致,便于现场对表与联调(不能为虚拟机、须连接焊机等前提见下文代码注释)。
实现代码
以下依次为同文件中的 feedOnWire、feedBackWire、detectGas、getWelderState、exampleWelding、clearWelderAlarm、enableArcData。
// 送丝
void feedOnWire()
{
cout << "enter feedOnWire" << endl;
error_code ec;
double time = 0;
arcWeld().feedOnWire(time, ec); // 时间需要大于0.1,小于0.1错误码报错
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
time = 10;
arcWeld().feedOnWire(time, ec); // 时间大于0.1,错误码正常
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
arcWeld().feedOnWire(time, ec,false); // 停止送丝
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
// 退丝
void feedBackWire()
{
cout << "enter feedBackWire" << endl;
error_code ec;
double time = 0;
arcWeld().feedBackWire(time, ec); // 时间需要大于0.1,小于0.1错误码报错
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
time = 10;
arcWeld().feedBackWire(time, ec); // 时间大于0.1,错误码正常
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
arcWeld().feedBackWire(time, ec,false); // 停止退丝
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
// 送气
void detectGas()
{
cout << "enter detectGas" << endl;
error_code ec;
double time = 0;
arcWeld().detectGas(time, ec); // 时间需要大于0.1,小于0.1错误码报错
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
time = 2;
arcWeld().detectGas(time, ec); // 时间大于0.1,错误码正常
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
arcWeld().detectGas(time, ec,false); // 停止检气
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
// 获取焊机状态
void getWelderState()
{
cout << "enter getWelderState" << endl;
error_code ec;
auto welderState = arcWeld().getWelderStatus(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
cout << "state: " << welderState.state << endl;
cout << "current: " << welderState.current << endl;
cout << "voltage: " << welderState.voltage << endl;
cout << "speed: " << welderState.speed << endl;
cout << "welding_name: " << welderState.welding_name << endl;
cout << "arc_welding: " << welderState.arc_welding << endl;
cerr << "runing_error: " << welderState.running_error.value() << "," << welderState.running_error.message() << endl;
cout << "distance: " << welderState.welding_distance << endl;
cout << "welding_time: " << welderState.welding_time << endl;
cout << "welding_wire_used: " << welderState.welding_wire_used << endl;
cout << "welding_path_num: " << welderState.welding_path_num << endl;
cout << "welder_error_code: " << welderState.welder_error_code << endl;
cout << "welder_ready: " << welderState.welder_ready << endl;
}
// 铆焊
void exampleWelding(){
error_code ec;
cout << "enter exampleWelding" << endl;
arcWeld().startWelding(100,0,ec); // 默认一元化
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
arcWeld().startWelding(100,10,ec,"separate"); // 分别模式
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
std::this_thread::sleep_for(std::chrono::seconds(2));
arcWeld().stopWelding(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
// 清焊机面板告警
void clearWelderAlarm() {
error_code ec;
arcWeld().clearWelderAlarm(ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
// 生效参数
void enableArcData(){
cout << "enter enableArcData" << endl;
// 不能为虚拟机并且需要连接焊机
ArcWelding::ArcData arcData = {
"example_arcdata", "example_annotation", "low_spatter", "wire_feed", "unified", 100, 20,0, 30, 400, {500, "auto_arc_reignition", 15}};
error_code ec;
arcWeld().enableArcData(arcData, ec);
cout << "ec: " << ec.value() << ", " << ec.message() << endl;
}
常用接口与类型
feedOnWire、feedBackWire、detectGas、startWelding、stopWelding、getWelderStatus、clearWelderAlarm、enableArcData(用途说明见上文推荐步骤第 4 条;示例见上文代码块)、FeedOnWireCommand、FeedBackWireCommand
场景十八:运行过程观测
适用情况 需要在程序中订阅焊接电流电压、弧焊状态、运动段完成等。
目标 异步回调或主动查询得到一致的状态快照;可按轨迹 id 与路点索引判断段结束。
推荐步骤
setEventWatcher(Event::arcWeldState, callback, ec)设置焊机状态回调, 解析EventInfoKey::ArcWeldState各键。setEventWatcher(Event::moveExecution, ...)或使用queryEventInfo轮询,结合业务定义的「段完成」条件(如轨迹 id + 路点索引)。- 收弧是否完成可结合弧焊状态中的「是否仍在焊接」等字段判断(以工艺包与 SDK 键名为准)。
实现代码
以下依次为 printWeldState、setArcWeldStateWatcher、queryWeldState、printMoveState、setMoveStateWatcher。
void printWeldState(const EventInfo &info)
{
using namespace EventInfoKey::ArcWeldState;
double current = std::any_cast<double>(info.at(Current));
double voltage = std::any_cast<double>(info.at(Voltage));
string state = std::any_cast<string>(info.at(State));
int speed = std::any_cast<int>(info.at(Speed));
auto error = std::any_cast<error_code>(info.at(RunningError));
string weldingName = std::any_cast<string>(info.at(WeldingName));
int arcWelding = std::any_cast<int>(info.at(EventInfoKey::ArcWeldState::ArcWelding));
double distance = std::any_cast<double>(info.at(WeldingDistance));
double welding_time = std::any_cast<double>(info.at(WeldingTime));
double welding_wire_used = std::any_cast<double>(info.at(WeldingWireUsed));
int welder_error_code = std::any_cast<int>(info.at(WelderErrorCode));
bool welder_ready = std::any_cast<bool>(info.at(WelderReady));
cout << "[焊接状态] current: " << current << ", voltage: " << voltage << ", state: " << state << ", speed: " << speed << endl;
cout << "weldingName: " << weldingName << ", arcWelding: " << arcWelding << ", welding_time: " << welding_time << ", welding_wire_used: " << welding_wire_used
<< ", welder_error_code: " << welder_error_code << ", welder_ready: " << welder_ready << "." << endl;
if(info.count(WeldingPathNum)) {
int weldingPathNum = std::any_cast<int>(info.at(WeldingPathNum));
std::cout << "Distance: " << distance << " m, PathNum: " << weldingPathNum << "." << std::endl;
} else {
std::cout << "Distance: " << distance << " m." << std::endl;
}
if(error) {
std::cerr << "运行错误:" << error << std::endl;
}
}
void setArcWeldStateWatcher()
{
error_code ec;
robot.setEventWatcher(rokae::Event::arcWeldState, printWeldState, ec);
if(ec) {
print(std::cerr, "设置焊接状态监视失败:", ec);
}
}
void queryWeldState()
{
error_code ec;
auto info = robot.queryEventInfo(Event::arcWeldState, ec);
printWeldState(info);
}
void printMoveState(const EventInfo &info)
{
using namespace rokae::EventInfoKey::MoveExecution;
print(std::cout, "[运动执行信息] ID:", std::any_cast<std::string>(info.at(ID)), "Index:", std::any_cast<int>(info.at(WaypointIndex)),
"已完成: ", std::any_cast<bool>(info.at(ReachTarget)) ? "YES": "NO", std::any_cast<error_code>(info.at(Error)),
std::any_cast<std::string>(info.at(Remark)));
}
void setMoveStateWatcher()
{
error_code ec;
robot.setEventWatcher(rokae::Event::moveExecution, printMoveState, ec);
if(ec) {
print(std::cerr, "设置运动事件监视失败:", ec);
}
}
常用接口与类型
setEventWatcher、queryEventInfo、Event::arcWeldState、Event::moveExecution、EventInfoKey::ArcWeldState、EventInfoKey::MoveExecution
注意事项
- 焊机状态回调的周期是500ms
场景十九:其它几何与工艺辅助(按需查阅)
适用情况 三点建用户参考、焊机支持模式查询、焊接中 Jog 偏置等;
目标 在程序中完成辅助几何计算或读取焊机能力列表。
推荐步骤
- 按业务调用
getRefBy3Points、getWelderWorkModes、weldOffsetJog等;
实现代码
以下依次为 getRefBy3PointsExample、getWelderWorkModes、weldingJogOffsetExample。
void getRefBy3PointsExample() {
error_code ec;
// auto ret = robot.posture(CoordinateType::endInRef,ec);
CartesianPosition pos1{0.55676914536239797, -0.15000000000000005, 0.35885244785437498, -3.1415926535897931, 3.8857805861880484e-16, -3.1415926535897931};
CartesianPosition pos2{0.71096662191265758, -0.14999999687989679, 0.35885244769618885, -3.1415921387343229, 8.5631816663676866e-07, 3.1415926369370966};
CartesianPosition pos3{0.71096662302702562, 0.0055997244168811289, 0.35885244730431071, -3.1415926429162764, 7.8093868108499471e-07, -3.1415918107904255};
bool with_origin = false;
ArcWelding::DirType dir = ArcWelding::DirType::X_Plus_Y_Plus;
auto ret = arcWeld().getRefBy3Points(std::vector<CartesianPosition>{pos1, pos2, pos3}, with_origin, dir, ec);
cout << "getRefBy3PointsExample: ec: " << ec.value() << ", " << ec.message() << endl;
for (auto &p : ret.trans) {
cout << p << " ";
}
for (auto &p : ret.rpy) {
cout << p << " ";
}
}
void getWelderWorkModes() {
error_code ec;
auto ret = arcWeld().getWelderWorkModes(ec);
cout << "getWelderWorkModes: ec: " << ec.value() << ", " << ec.message() << endl;
cout << "work modes: ";
for (auto &p : ret) {
cout << p << " ";
}
cout << endl;
}
void weldingJogOffsetExample() {
error_code ec;
arcWeld().weldOffsetJog(ArcWelding::WeldOffsetJogDir::Y_PLUS,ec);
arcWeld().weldOffsetJog(ArcWelding::WeldOffsetJogDir::Y_MINUS,ec);
arcWeld().weldOffsetJog(ArcWelding::WeldOffsetJogDir::Z_PLUS,ec);
arcWeld().weldOffsetJog(ArcWelding::WeldOffsetJogDir::Z_MINUS,ec);
cout << "weldingJogOffset: ec: " << ec.value() << ", " << ec.message() << endl;
}
常用接口与类型
getRefBy3Points、getWelderWorkModes、weldOffsetJog
与详细文档的对应关系
| 需求 | 文档 |
|---|---|
| 接口列表与参数含义 | 接口说明 |
| 类型与数据结构 | 附录:类型、附录:数据结构 |
| 方法签名与重载细节 | 附录:方法 |
| 错误码与异常 | 错误码和异常 |