弧焊 C# SDK 使用示例
文档约定
以下各节结构统一为:
- 适用情况 — 何时需要本场景
- 目标 — 做完后系统应处于的状态
- 推荐步骤 — 顺序化操作要点;
- 常用接口与类型 — 便于检索 SDK 符号,非完整参数表
- 注意事项 — 常见易错点
通用编程约定
- 通过
robot.arcwelding()取得ArcWelding实例,在其上调用工艺参数与焊机相关接口;运动队列仍在robot上操作。 - 各 API 使用
ErrorCode ec,多数接口为out ec或ref ec输出参数,每次调用后检查ec.value与ec.message。 - 涉及「压队列再启动」的焊接轨迹,通常配合
MotionControlMode.NrtCommand与moveAppend/moveStart;与纯参数下发场景区分开。
公共代码前提(各场景「实现代码」共用)
以下与 SDK 包内 xCoreSDK-CSharp_examples_ArcWeldingDemo.cs(ArcWeldingDemo 类)一致。
using System;
using System.Threading;
using System.Threading.Tasks;
using rokae.clr;
using static rokae.clr.ArcWelding;
using EventInfos = System.Collections.Generic.Dictionary<string, object>;
// 连接机器人后:
var robot = new xMateRobot();
robot.connectToRobot("192.168.0.160"); // 按机型与网络修改
ArcWelding arcWelding = robot.arcwelding();
ErrorCode ec = new ErrorCode(0, "");
void printErrorCode(string funcName, ErrorCode ec)
{
if (ec.value != 0)
System.Diagnostics.Debug.WriteLine($"{funcName}: {ec.message}");
}
场景一:首次接机器人与焊机
适用情况 新工作站第一次跑弧焊程序,或更换焊机 / 总线配置后需要确认控制器与焊机侧就绪。
目标 机器人已连接;弧焊工艺包可用;焊机型号与通信参数与现场一致;必要时完成 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。
printInfo("enter SetWelderAndConnectExample");
// 设置焊机(方式一)
arcwelding.setWelder("ethercat", "aotai", "RL/RPL", 500, out ec);
printErrorCode("setWelder", ec);
// 设置焊机(方式二),不是所有焊机都支持所有字段,参考工艺包焊机连接界面
WelderSetting welderSetting = new WelderSetting
{
mfr = "aotai",
model = "RL/RPL",
protocol = "ethercat",
current_type = 500,
current_file = "current1", // 用于模拟量连接
voltage_file = "voltage1", // 用于模拟量连接
wire_diameter = 1.0,
shielding_gas = "CO2",
program_number = 10
};
arcwelding.setWelder(welderSetting, out ec);
printErrorCode("setWelder", ec);
// 读取焊机设置
var welderSettingRet = arcwelding.getWelderSetting(out ec);
printErrorCode("getWelderSetting", ec);
printInfo("mfr: " + welderSettingRet.mfr);
printInfo("model: " + welderSettingRet.model);
printInfo("protocol: " + welderSettingRet.protocol);
printInfo("current_type: " + welderSettingRet.current_type);
printInfo("current_file: " + welderSettingRet.current_file);
printInfo("voltage_file: " + welderSettingRet.voltage_file);
printInfo("wire_diameter: " + welderSettingRet.wire_diameter);
printInfo("shielding_gas: " + welderSettingRet.shielding_gas);
printInfo("program_number: " + welderSettingRet.program_number);
// 连接焊机
arcwelding.connectToWelder(out ec);
printErrorCode("connectToWelder", ec);
// 断开焊机
arcwelding.disconnectFromWelder(out ec);
printErrorCode("disconnectFromWelder", ec);
printInfo("enter SetEniHaveWeldExample");
// 读取是否连接物理焊机(ENI文件)
var eniHaveWeld = arcwelding.isEniHaveWeld(out ec);
printErrorCode("isEniHaveWeld", ec);
printInfo("eniHaveWeld: " + eniHaveWeld);
// 设置是否连接物理焊机
arcwelding.setIsEniHaveWeld(true, out ec);
printErrorCode("setIsEniHaveWeld", ec);
常用接口与类型
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相关;带时间与使能的重载则按调用传入(见 接口说明)。
实现代码
printInfo("enter SetRunningParamExample");
// 下发运行参数
ArcWeldRunningParam runningParam = new ArcWeldRunningParam
{
test_run_speed = 200,
wire_feed_speed = 2,
gas_detect_time = 10,
};
arcwelding.setRunningParam(runningParam, out ec);
printErrorCode("setRunningParam", ec);
// 读取运行参数
var runningParamRet = arcwelding.getRunningParam(out ec);
printErrorCode("getRunningParam", ec);
printInfo("test_run_speed: " + runningParamRet.test_run_speed);
printInfo("wire_feed_speed: " + runningParamRet.wire_feed_speed);
printInfo("gas_detect_time: " + runningParamRet.gas_detect_time);
常用接口与类型
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对应)。
实现代码
printInfo("enter PrintAnticollisionState");
var signal = (String)info["signal"];
var enable = (bool)info["enable"];
var block = (bool)info["block"];
var countdown = (int)info["countdown"];
printInfo("anticollision: \n" +
$"signale: {signal}\n" +
$"enable: {enable}\n" +
$"block: {block}\n" +
$"countdown: {countdown}");
robot.setEventWatcher(Event.anticollisionState, PrintAnticollisionState, out ec);
printErrorCode("setEventWatcher", ec);
arcWelding.setAnticollision("DI0_0", true, false, 30, out ec);
printErrorCode("setAnticollision", ec);
var ret = arcWelding.getAnticollisionState(out ec);
printErrorCode("getAnticollisionState", ec);
printInfo("anticollision: \n" +
$"signale: {ret.signal}\n" +
$"enable: {ret.enable}\n" +
$"block: {ret.block}\n" +
$"countdown: {ret.countdown}");
常用接口与类型
setAnticollision、getAnticollisionState、Event.anticollisionState、EventInfoKey.AnticollisionState、setEventWatcher
注意事项
绑定的DI信号需要确保没有被其他系统功能占用
场景四:在程序中维护工艺参数
适用情况 希望由上位机或离线工具下发 / 修改起弧、焊接、收弧、摆动、间断焊等命名工艺数据,或与示教器 HMI 中已有参数名保持一致。
目标 控制器内保存在一组可引用的参数名,供后续 ArcOnCommand 等指令或示教程序使用。
推荐步骤
- 构造对应结构体(如
ArcOnData、ArcData、ArcOffData、WeaveData、SegData等),填写name及工艺字段。 - 调用
setXxxData写入;用getXxxData(name, ec)读回校验。 - 删除单条用
removeXxxData(name);批量删除可传入名称列表重载。 - 对示教器已有名称:可先
get再改字段后set,实现覆盖或微调。
实现代码
以下按类分别摘录 SetArcOnDataExample(起弧)、SetArcDataExample(焊接)、SetArcOffDataExample(收弧)、SetWeaveDataExample(摆焊)、SetSegDataExample(间断焊)。代码摘自 ArcWeldingDemo 类对应方法体;打印逻辑见各方法内的局部 Action 委托(如 printArcOnData)。
printInfo("enter SetArcOnDataExample");
// 下发ArcOnData默认值
ArcOnData arcOnDataDefault = ArcOnData.CreateDefault();
arcwelding.setArcOnData(arcOnDataDefault, out ec);
printErrorCode("setArcOnData", ec);
// 下发ArcOnData自定义值
ArcOnData arcOnDataCustom = new ArcOnData
{
name = "Custom1_name",
annotation = "Custom1_annotation",
mode = "low_spatter",
current_mode = "wire_feed",
voltage_mode = "separate",
current = 120,
voltage = 2,
hold_time = 200,
detect_time = 500,
confirm_time = 50,
preflow_time = 200,
prearc_time = 50,
slow_wire_feed_speed = 8,
pre_wirefeed_time = 10,
ramp_time = 100,
re_arcon = new ReArcOnParam
{
enable = true,
retry_time = 3,
wire_retract_delay_time = 0,
wire_retract_time = 100,
current_step = 10,
voltage_step = 0.1,
},
scratch_arcon = new ScratchArconParam
{
enable = false,
distance = 50,
back_speed = 10,
step = 5,
}
};
arcwelding.setArcOnData(arcOnDataCustom, out ec);
printErrorCode("setArcOnData", ec);
// 获取ArcOnData
var arcOnDataDefaultRet = arcwelding.getArcOnData(arcOnDataDefault.name, out ec);
printErrorCode("getArcOnData", ec);
var arcOnDataCustomRet = arcwelding.getArcOnData(arcOnDataCustom.name, out ec);
printErrorCode("getArcOnData", ec);
// 打印ArcOnData
Action<ArcOnData> printArcOnData = data =>
{
printInfo($"Name: {data.name}");
printInfo($"Annotation: {data.annotation}");
printInfo($"Mode: {data.mode}");
printInfo($"Current Mode: {data.current_mode}");
printInfo($"Voltage Mode: {data.voltage_mode}");
printInfo($"Current: {data.current}");
printInfo($"Voltage: {data.voltage}");
printInfo($"Hold Time: {data.hold_time}");
printInfo($"Detect Time: {data.detect_time}");
printInfo($"Confirm Time: {data.confirm_time}");
printInfo($"Preflow Time: {data.preflow_time}");
printInfo($"Prearc Time: {data.prearc_time}");
printInfo($"Slow Wire Feed Speed: {data.slow_wire_feed_speed}");
printInfo($"Pre Wirefeed Time: {data.pre_wirefeed_time}");
printInfo($"Ramp Time: {data.ramp_time}");
printInfo("Re Arc On Parameters:");
printInfo($" Enable: {data.re_arcon.enable}");
printInfo($" Retry Time: {data.re_arcon.retry_time}");
printInfo($" Wire Retract Delay Time: {data.re_arcon.wire_retract_delay_time}");
printInfo($" Wire Retract Time: {data.re_arcon.wire_retract_time}");
printInfo($" Current Step: {data.re_arcon.current_step}");
printInfo($" Voltage Step: {data.re_arcon.voltage_step}");
printInfo("Scratch Arc On Parameters:");
printInfo($" Enable: {data.scratch_arcon.enable}");
printInfo($" Distance: {data.scratch_arcon.distance}");
printInfo($" Back Speed: {data.scratch_arcon.back_speed}");
printInfo($" Step: {data.scratch_arcon.step}");
};
printArcOnData(arcOnDataDefaultRet);
printArcOnData(arcOnDataCustomRet);
// 删除参数
arcwelding.removeArcOnData("default", out ec);
printErrorCode("removeArcOnData", ec);
arcwelding.removeArcOnData(new List<string> { "remove1", "remove2" }, out ec);
printErrorCode("removeArcOnData", ec);
printInfo("enter SetArcDataExample");
// 下发ArcData默认值
ArcData arcDataDefault = ArcData.CreateDefault();
arcwelding.setArcData(arcDataDefault, out ec);
printErrorCode("setArcData", ec);
// 下发ArcData自定义值
ArcData arcDataCustom = new ArcData
{
name = "Custom1_name",
annotation = "Custom1_annotation",
mode = "low_spatter",
current_mode = "wire_feed",
voltage_mode = "separate",
current = 80,
voltage = 2,
weld_speed = 50,
ramp_time = 200,
arc_break_param = new ArcBreakParam
{
detect_time = 50,
arc_break_option = "stop_and_alarm",
restart_back_distance = 0
}
};
arcwelding.setArcData(arcDataCustom, out ec);
printErrorCode("setArcData", ec);
// 获取ArcData
var arcDataDefaultRet = arcwelding.getArcData(arcDataDefault.name, out ec);
printErrorCode("getArcData", ec);
var arcDataCustomRet = arcwelding.getArcData(arcDataCustom.name, out ec);
printErrorCode("getArcData", ec);
// 打印ArcData
Action<ArcData> printArcData = data =>
{
printInfo($"Name: {data.name}");
printInfo($"Annotation: {data.annotation}");
printInfo($"Mode: {data.mode}");
printInfo($"Current Mode: {data.current_mode}");
printInfo($"Voltage Mode: {data.voltage_mode}");
printInfo($"Current: {data.current}");
printInfo($"Voltage: {data.voltage}");
printInfo($"Weld Speed: {data.weld_speed}");
printInfo($"Ramp Time: {data.ramp_time}");
printInfo("Arc Break Parameters:");
printInfo($" Detect Time: {data.arc_break_param.detect_time}");
printInfo($" Arc Break Option: {data.arc_break_param.arc_break_option}");
printInfo($" Restart Back Distance: {data.arc_break_param.restart_back_distance}");
};
printArcData(arcDataDefaultRet);
printArcData(arcDataCustomRet);
// 删除ArcData
arcwelding.removeArcData("default", out ec);
printErrorCode("removeArcData", ec);
arcwelding.removeArcData(new List<string> { "remove1,remove2" }, out ec);
printErrorCode("removeArcData", ec);
printInfo("SetArcOffDataExample");
// 下发ArcOffData
ArcOffData arcOffDataDefault = ArcOffData.CreateDefault(); // 默认值
arcwelding.setArcOffData(arcOffDataDefault, out ec);
printErrorCode("setArcOffData", ec);
ArcOffData arcOffDataCustom = new ArcOffData // 自定义值
{
name = "Custom1_name",
annotation = "Custom1_annotation",
mode = "low_spatter",
current_mode = "wire_feed",
voltage_mode = "separate",
current = 160,
voltage = 5,
hold_time = 200,
delay_gasoff_time = 200,
detect_time = 100,
retract_time = 80,
wire_stick_detection_time = 80,
anti_wire_stick_param = new AntiWireStickParam
{
enable = false,
current = 0,
voltage = 0,
time = 100,
}
};
arcwelding.setArcOffData(arcOffDataCustom, out ec);
printErrorCode("setArcOffData", ec);
// 获取ArcOffData
var arcOffDataDefaultRet = arcwelding.getArcOffData(arcOffDataDefault.name, out ec);
printErrorCode("getArcOffData", ec);
var arcOffDataCustomRet = arcwelding.getArcOffData(arcOffDataCustom.name, out ec);
printErrorCode("getArcOffData", ec);
// 打印ArcOffData
Action<ArcOffData> printArcOffData = data =>
{
printInfo($"Name: {data.name}");
printInfo($"Annotation: {data.annotation}");
printInfo($"Mode: {data.mode}");
printInfo($"Current Mode: {data.current_mode}");
printInfo($"Voltage Mode: {data.voltage_mode}");
printInfo($"Current: {data.current}");
printInfo($"Voltage: {data.voltage}");
printInfo($"Hold Time: {data.hold_time}");
printInfo($"Delay Gas Off Time: {data.delay_gasoff_time}");
printInfo($"Detect Time: {data.detect_time}");
printInfo($"Retract Time: {data.retract_time}");
printInfo($"Wire Stick Detection Time: {data.wire_stick_detection_time}");
printInfo("Anti Wire Stick Parameters:");
printInfo($" Enable: {data.anti_wire_stick_param.enable}");
printInfo($" Current: {data.anti_wire_stick_param.current}");
printInfo($" Voltage: {data.anti_wire_stick_param.voltage}");
printInfo($" Time: {data.anti_wire_stick_param.time}");
};
printArcOffData(arcOffDataDefaultRet);
printArcOffData(arcOffDataCustomRet);
// 删除ArcOffData
arcwelding.removeArcOffData("default", out ec);
printErrorCode("removeArcOffData", ec);
arcwelding.removeArcOffData(new List<string> { "remove1,remove2" }, out ec);
printErrorCode("removeArcOffData", ec);
printInfo("enter SetWeaveDataExample");
// 下发WeaveData
WeaveData weaveDataDefault = WeaveData.CreateDefault(); // 默认值
arcwelding.setWeaveData(weaveDataDefault, out ec);
printErrorCode("setWeaveData", ec);
WeaveData weaveDataCustom = new WeaveData // 自定义值
{
name = "Custom_name",
annotation = "Custom_annotation",
weaving_reference = "cycle",
pattern = "sine",
weave_length_frequency = 1,
amplitude = new Amplitude
{
left = 2,
right = 2,
},
dwell_type = "weave_stop",
dwell_time = new int[] { 10, 0, 20 },
radius = 5,
phase_invert = true,
elevation_type = "v_pattern",
elevation_angle = new ElevationAngle
{
left = 0,
right = 0,
},
inclination_angle = 0,
acc = 1,
jerk = 10
};
arcwelding.setWeaveData(weaveDataCustom, out ec);
printErrorCode("setWeaveData", ec);
// 获取WeaveData
var weaveDataDefaultRet = arcwelding.getWeaveData(weaveDataDefault.name, out ec);
printErrorCode("getWeaveData", ec);
var weaveDataCustomRet = arcwelding.getWeaveData(weaveDataCustom.name, out ec);
printErrorCode("getWeaveData", ec);
// 打印WeaveData
Action<WeaveData> printWeaveData = data =>
{
printInfo($"Name: {data.name}");
printInfo($"Annotation: {data.annotation}");
printInfo($"Weaving Reference: {data.weaving_reference}");
printInfo($"Pattern: {data.pattern}");
printInfo($"Weave Length Frequency: {data.weave_length_frequency}");
printInfo("Amplitude:");
printInfo($" Left: {data.amplitude.left}");
printInfo($" Right: {data.amplitude.right}");
printInfo($"Dwell Type: {data.dwell_type}");
printInfo($"Dwell Time: {data.dwell_time[0]}, {data.dwell_time[1]}, {data.dwell_time[2]}");
printInfo($"Radius: {data.radius}");
printInfo($"Phase Invert: {data.phase_invert}");
printInfo($"Elevation Type: {data.elevation_type}");
printInfo("Elevation Angle:");
printInfo($" Left: {data.elevation_angle.left}");
printInfo($" Right: {data.elevation_angle.right}");
printInfo($"Inclination Angle: {data.inclination_angle}");
printInfo($"Acc: {data.acc}");
printInfo($"Jerk: {data.jerk}");
};
printWeaveData(weaveDataDefaultRet);
printWeaveData(weaveDataCustomRet);
// 删除WeaveData
arcwelding.removeWeaveData("default", out ec);
printErrorCode("removeWeaveData", ec);
arcwelding.removeWeaveData(new List<string> { "remove1,remove2" }, out ec);
printErrorCode("removeWeaveData", ec);
printInfo("enter SetSegDataExample");
// 下发SegData
SegData segDataDefault = SegData.CreateDefault(); // 默认值
arcwelding.setSegData(segDataDefault, out ec);
printErrorCode("setSegData", ec);
SegData segDataCustom = new SegData // 自定义值
{
name = "Custom_name",
annotation = "Custom_annotation",
seg_type = "normal", /// 普通间断焊: "normal";指定焊接段数:"bycount"
non_welded_speed = "v10",
welded_distance = 10,
non_welded_distance = 20,//适配普通间断焊
welded_count = 4, //适配指定焊接段数
};
arcwelding.setSegData(segDataCustom, out ec);
printErrorCode("setSegData", ec);
// 获取SegData
var segDataDefaultRet = arcwelding.getSegData("default", out ec);
printErrorCode("getSegData", ec);
var segDataCustomRet = arcwelding.getSegData(segDataCustom.name, out ec);
printErrorCode("getSegData", ec);
// 打印SegData
Action<SegData> printSegData = data =>
{
printInfo($"Name: {data.name}");
printInfo($"Annotation: {data.annotation}");
printInfo($"Segment Type: {data.seg_type}");
printInfo($"Non-Welded Speed: {data.non_welded_speed}");
printInfo($"Welded Distance: {data.welded_distance}");
printInfo($"Non-Welded Distance: {data.non_welded_distance}");
printInfo($"Welded Count: {data.welded_count}");
};
printSegData(segDataDefaultRet);
printSegData(segDataCustomRet);
// 删除SegData
arcwelding.removeSegData("default", out ec);
printErrorCode("removeSegData", ec);
arcwelding.removeSegData(new List<string> { "remove1,remove2" }, out ec);
printErrorCode("removeSegData", ec);
常用接口与类型
按「设置 / 读取 / 删除」分组的命名工艺数据接口如下(签名与重载详见 接口说明、附录:方法)。
-
起弧 / 焊接 / 收弧 / 摆焊 / 间断焊
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(空运行)、WeldMode.Simu(仿真)、WeldMode.Real(实焊)之间切换。 - 用
getWeldMode读回确认。 - 结合现场示教器运行方式,对照下表理解现象(与工艺包说明一致)。
实现代码
printInfo("enter SetWeldModeExample");
WeldMode weldMode = WeldMode.TestRun;
arcwelding.setWeldMode(weldMode, out ec);
printErrorCode("setWeldMode", ec);
WeldMode weldModeRet = arcwelding.getWeldMode(out ec);
printErrorCode("getWeldMode", ec);
printInfo($"set: TestRun, return: {weldModeRet.ToString()}");
Thread.Sleep(1000);
weldMode = WeldMode.Simu;
arcwelding.setWeldMode(weldMode, out ec);
printErrorCode("setWeldMode", ec);
weldModeRet = arcwelding.getWeldMode(out ec);
printErrorCode("getWeldMode", ec);
printInfo($"set: Simu, return: {weldModeRet.ToString()}");
Thread.Sleep(1000);
weldMode = WeldMode.Real;
arcwelding.setWeldMode(weldMode, out ec);
printErrorCode("setWeldMode", ec);
weldModeRet = arcwelding.getWeldMode(out ec);
printErrorCode("getWeldMode", ec);
printInfo($"set: Real, return: {weldModeRet.ToString()}");
焊接模式与运行方式组合(示意)

常用接口与类型
setWeldMode、getWeldMode、WeldMode
注意事项
场景六:典型焊缝——「起弧 → 直线/圆弧 焊接段 → 收弧」
适用情况 最常见的直线或圆弧焊缝:在非实时指令模式下,将普通运动与弧焊工艺指令按顺序压入同一队列并启动。
目标 机器人按序执行:接近段(可选)→ 起弧与焊接参数生效 → 带或不带摆动的焊接轨迹 → 收弧。
推荐步骤
- 需要先通过场景一启用焊机
setMotionControlMode(NrtCommand, ec)。- 确认焊机已配置并
connectToWelder(与场景一一致)。 - 构造
ArcOnCommand,绑定已下发的起弧参数名、焊接参数名(如与示教器同名)。 - 构造焊接段:
WMoveLCommand/WMoveCCommand等; - 构造
ArcOffCommand并绑定收弧参数名。 - 使用同一队列 id 多次
moveAppend按顺序入队;上电后moveStart执行。 - 需要暂停 / 继续时,可配合
stop与再次moveStart(以运动控制文档为准)。
实现代码
printInfo("enter ExampleCommand");
// 以下点位基于CR7
// 需要先启用焊机
arcwelding.setWelder("ethercat", "aotai", "RL/RPL", 500, out ec); // 设置焊机
printErrorCode("setWelder", ec);
arcwelding.connectToWelder(out ec); // 启用和连接焊机
printErrorCode("connectToWelder", ec);
arcwelding.setArcOnData(ArcOnData.CreateDefault(), out ec);
arcwelding.setArcData(ArcData.CreateDefault(), out ec);
arcwelding.setArcOffData(ArcOffData.CreateDefault(), out ec);
FeedOnWireCommand feedon = new FeedOnWireCommand(0.1, 1.1, true); // 送丝 时间,单位:秒 速度,单位:m/min
FeedBackWireCommand feedback = new FeedBackWireCommand(0.2, 1.2, true); // 退丝 时间,单位:秒 速度,单位:m/min
ArcOnCommand arcon = new ArcOnCommand("default", "default");
ArcOffCommand arcoff = new ArcOffCommand("default");
CartesianPosition target = new CartesianPosition
{
//trans = new double[] { 0.556769, -0.15, 0.4872 },
trans = new double[] { 0.315189, -0.15, 0.414397 },
rpy = new double[] { -Math.PI, 0.0, Math.PI },
};
WMoveLCommand wml = new WMoveLCommand(target, 10, 1, "default"); // 直线摆动
CartesianPosition targetMC = new CartesianPosition
{
trans = new double[] { 0.615167, 0.141585, 0.507386 },
rpy = new double[] { 180.000 * Math.PI / 180, 0.0, -167.039 * Math.PI / 180 },
};
CartesianPosition auxMC = new CartesianPosition
{
trans = new double[] { 0.583553, 0.134309, 0.628928 },
rpy = new double[] { 180.000 * Math.PI / 180, 11.286 * Math.PI / 180, -167.039 * Math.PI / 180 },
};
WMoveCCommand wmc = new WMoveCCommand(targetMC, auxMC, 10, 1, "default"); // 圆弧摆动
WeaveData weaveDataDefault = WeaveData.CreateDefault(); // 设置摆动参数
weaveDataDefault.amplitude.left = 2;
weaveDataDefault.amplitude.right = 2;
weaveDataDefault.weave_length_frequency = 2;
arcwelding.setWeaveData(weaveDataDefault, out ec);
WeaveOnCommand weaveon = new WeaveOnCommand("default");
WeaveOffCommand weaveoff = new WeaveOffCommand();
robot.setMotionControlMode(MotionControlMode.NrtCommand, out ec);
printErrorCode("setMotionControlMode", ec);
String id = "";
robot.moveAppend(feedon, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(arcon, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(weaveon, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(wml, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(weaveoff, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(arcoff, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(feedback, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.setPowerState(true, out ec);
printErrorCode("setPowerState", ec);
robot.moveStart(out ec);
printErrorCode("moveStart", ec);
robot.stop(out ec); // 暂停
printErrorCode("stop", ec);
robot.moveStart(out ec);// 继续
printErrorCode("moveStart", ec);
常用接口与类型
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。
实现代码
printInfo("enter ArcSetExample");
// 以下点位基于SR5
String cmd_id = "";
ArcOnCommand arc_on_command = new ArcOnCommand();
ArcOffCommand arc_off_command = new ArcOffCommand();
MoveCommand absj = new MoveCommand
{
jointTarget = new JointPosition { joints = new List<double> { 0, Math.PI / 6, -Math.PI, 0, -Math.PI / 3, 0 } },
speed = 1000
};
MoveCommand l = new MoveCommand
{
cartTarget = new CartesianPosition { trans = new double[] { 0.614, 0.136, 0.389 }, rpy = new double[] { -Math.PI, 0, Math.PI } },
speed = 500
};
CartesianPosition wmlTarget1 = new CartesianPosition { trans = new double[] { 0.553, -0.107, 0.309 }, rpy = new double[] { -Math.PI, 0, Math.PI } };
WMoveLCommand wmovel1 = new WMoveLCommand();
wmovel1.target = wmlTarget1;
wmovel1.speed = 500;
CartesianPosition wmlTarget2 = new CartesianPosition { trans = new double[] { 0.553, 0.107, 0.309 }, rpy = new double[] { -Math.PI, 0, Math.PI } };
WMoveLCommand wmovel2 = new WMoveLCommand();
wmovel2.target = wmlTarget2;
wmovel2.speed = 500;
wmovel2.arc_set_opt = new ArcSetOpt { arc_data = "arcdata1", ref_start = true, distance = 80 };
robot.setPowerState(true, out ec);
printErrorCode("setPowerState", ec);
robot.moveAppend(MoveCommand.Type.MoveAbsJ, absj, ref cmd_id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(MoveCommand.Type.MoveL, l, ref cmd_id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(arc_on_command, ref cmd_id, out ec);
printErrorCode("moveAppend", ec);
List<ArcWeldingCommand> wmls = new List<ArcWeldingCommand> { wmovel1, wmovel2 };
robot.moveAppend(wmovel1,ref cmd_id, out ec);
robot.moveAppend(wmls, ref cmd_id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(arc_off_command, ref cmd_id, out ec);
printErrorCode("moveAppend", ec);
robot.moveStart(out ec);
printErrorCode("moveStart", ec);
while (Console.ReadKey().Key != ConsoleKey.Enter) ;
robot.setPowerState(false, out ec);
printErrorCode("setPowerState", 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。
实现代码
printInfo("enter ExampleCommand");
// 以下点位基于CR7
// 需要先启用焊机
arcwelding.setWelder("ethercat", "aotai", "RL/RPL", 500, out ec); // 设置焊机
printErrorCode("setWelder", ec);
arcwelding.connectToWelder(out ec); // 启用和连接焊机
printErrorCode("connectToWelder", ec);
arcwelding.setArcOnData(ArcOnData.CreateDefault(), out ec);
arcwelding.setArcData(ArcData.CreateDefault(), out ec);
arcwelding.setArcOffData(ArcOffData.CreateDefault(), out ec);
FeedOnWireCommand feedon = new FeedOnWireCommand(0.1, 1.1, true); // 送丝 时间,单位:秒 速度,单位:m/min
FeedBackWireCommand feedback = new FeedBackWireCommand(0.2, 1.2, true); // 退丝 时间,单位:秒 速度,单位:m/min
ArcOnCommand arcon = new ArcOnCommand("default", "default");
ArcOffCommand arcoff = new ArcOffCommand("default");
CartesianPosition target = new CartesianPosition
{
//trans = new double[] { 0.556769, -0.15, 0.4872 },
trans = new double[] { 0.315189, -0.15, 0.414397 },
rpy = new double[] { -Math.PI, 0.0, Math.PI },
};
WMoveLCommand wml = new WMoveLCommand(target, 10, 1, "default"); // 直线摆动
CartesianPosition targetMC = new CartesianPosition
{
trans = new double[] { 0.615167, 0.141585, 0.507386 },
rpy = new double[] { 180.000 * Math.PI / 180, 0.0, -167.039 * Math.PI / 180 },
};
CartesianPosition auxMC = new CartesianPosition
{
trans = new double[] { 0.583553, 0.134309, 0.628928 },
rpy = new double[] { 180.000 * Math.PI / 180, 11.286 * Math.PI / 180, -167.039 * Math.PI / 180 },
};
WMoveCCommand wmc = new WMoveCCommand(targetMC, auxMC, 10, 1, "default"); // 圆弧摆动
WeaveData weaveDataDefault = WeaveData.CreateDefault(); // 设置摆动参数
weaveDataDefault.amplitude.left = 2;
weaveDataDefault.amplitude.right = 2;
weaveDataDefault.weave_length_frequency = 2;
arcwelding.setWeaveData(weaveDataDefault, out ec);
WeaveOnCommand weaveon = new WeaveOnCommand("default");
WeaveOffCommand weaveoff = new WeaveOffCommand();
robot.setMotionControlMode(MotionControlMode.NrtCommand, out ec);
printErrorCode("setMotionControlMode", ec);
String id = "";
robot.moveAppend(feedon, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(arcon, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(weaveon, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(wml, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(weaveoff, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(arcoff, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.moveAppend(feedback, ref id, out ec);
printErrorCode("moveAppend", ec);
robot.setPowerState(true, out ec);
printErrorCode("setPowerState", ec);
robot.moveStart(out ec);
printErrorCode("moveStart", ec);
robot.stop(out ec); // 暂停
printErrorCode("stop", ec);
robot.moveStart(out ec);// 继续
printErrorCode("moveStart", ec);
常用接口与类型
setWeaveData、WMoveLCommand、WMoveCCommand、WeaveOnCommand、WeaveOffCommand
注意事项
- 需要摆动的轨迹必须放在
WeaveOnCommand和WeaveOffCommand之间,如果只单独给WMoveLCommand、WMoveCCommand设置摆动参数则不会生效 - 在
WeaveOnCommand和WeaveOffCommand之间的轨迹如果不带摆动参数会默认执行WeaveOnCommand中的摆动参数
场景九:直线 / 圆弧耦合间断焊
适用情况 仅在部分轨迹上需要「焊—停—焊」节拍;不要求摆动,或摆动由其它段单独处理。
目标 在 SegOnCommand 与 SegOffCommand 之间,WMoveL / WMoveC 按 SegData 执行间断节奏;区间外为连续焊或普通焊接运动。
推荐步骤
setSegData写入间断焊参数名(如segdata1)。- 队列:
ArcOnCommand→(可选空移或非间断段)→SegOnCommand("segdata1")→ 一条或多条直线/圆弧焊接运动 →SegOffCommand→ 后续连续焊或收弧。
实现代码
printInfo("enter segOnExample");
// 根据起始轴角度,计算笛卡尔位姿
double[] dragPosture = { 0, Math.PI / 6, -Math.PI / 2, 0, -Math.PI / 3, 0 };
var p_start = robot.calcFk(dragPosture,out ec);
printInfo($"start pose: {p_start}");
// 设置间断焊参数
// 普通间断焊
var segData1 = new SegData { name = "segdata1",annotation = "segannotation",seg_type = "normal",non_welded_speed = "v200",welded_distance = 15,non_welded_distance = 30};
// 指定焊接段数
var segData2 = new SegData { name = "segdata1",annotation = "segannotation",seg_type = "bycount",non_welded_speed = "v200",welded_distance = 15, welded_count = 4 };
arcWelding.setSegData(segData2, out ec);
// 开始间断焊指令,设置间断焊参数为segdata1
SegOnCommand segOnCmd = new SegOnCommand("segdata1");
SegOffCommand segOffCmd = new SegOffCommand();
// 几条焊接运动指令
WMoveLCommand seg_wmovel0 = new WMoveLCommand();
seg_wmovel0.target = p_start;
seg_wmovel0.speed = 20;
seg_wmovel0.zone = 0;
seg_wmovel0.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmovel0.cartTargetOffset.frame.trans = new double[] { 0, -0.11, -0.12};
WMoveLCommand seg_wmovel1 = new WMoveLCommand();
seg_wmovel1.target = p_start;
seg_wmovel1.speed = 20;
seg_wmovel1.zone = 0;
seg_wmovel1.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmovel1.cartTargetOffset.frame.trans = new double[]{ 0, 0.08, -0.02};
WMoveCCommand seg_wmc = new WMoveCCommand();
seg_wmc.target = p_start;
seg_wmc.aux = p_start;
seg_wmc.speed = 10;
seg_wmc.zone = 0;
seg_wmc.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmc.cartTargetOffset.frame.trans = new double[]{ 0, -0.05, 0.01};
seg_wmc.auxPointOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmc.auxPointOffset.frame.trans = new double[]{ 0, 0.070, 0};
WMoveLCommand non_seg_wmovl = new WMoveLCommand();
non_seg_wmovl.target = p_start;
non_seg_wmovl.speed = 20;
non_seg_wmovl.zone = 1;
non_seg_wmovl.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
non_seg_wmovl.cartTargetOffset.frame.trans = new double[]{ -0.05, 0, 0};
ArcOnCommand arcOnCmd = new ArcOnCommand("arcondata1", "arcdata1");
ArcOffCommand arcOffCmd = new ArcOffCommand("arcoffdata1");
MoveCommand absj = new MoveCommand{ jointTarget= new JointPosition { joints = new List<double> { 0, Math.PI / 6, -Math.PI/2, 0, -Math.PI / 3, 0 } },speed = 500};
WeaveOnCommand weave_on_command = new WeaveOnCommand("weavedata1");
WeaveOffCommand weaveOffCmd = new WeaveOffCommand();
String id="";
robot.setPowerState(true, out ec);
robot.moveAppend(MoveCommand.Type.MoveAbsJ, absj,ref id,out ec);
robot.moveStart(out ec);
while (true)
{
Thread.Sleep(1000);
var st = robot.operationState(out ec);
if (st == OperationState.idle || st == OperationState.unknown) break;
}
printInfo("运动到初始点");
robot.moveAppend(arcOnCmd,ref id,out ec);
robot.moveAppend(weave_on_command, ref id, out ec);
robot.moveAppend(segOnCmd,ref id,out ec);
List<ArcWeldingCommand> wmovels = new List<ArcWeldingCommand> { seg_wmovel0, seg_wmovel1 };
robot.moveAppend(wmovels,ref id,out ec);
robot.moveAppend(seg_wmc, ref id, out ec);
robot.moveAppend(segOffCmd,ref id,out ec);
robot.moveAppend(non_seg_wmovl, ref id, out ec);
robot.moveAppend(weaveOffCmd, ref id, out ec);
robot.moveAppend(arcOffCmd, ref id, out ec);
robot.moveStart(out ec);
常用接口与类型
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 接口说明 / 附录类型为准)。
实现代码
printInfo("enter segOnExample");
// 根据起始轴角度,计算笛卡尔位姿
double[] dragPosture = { 0, Math.PI / 6, -Math.PI / 2, 0, -Math.PI / 3, 0 };
var p_start = robot.calcFk(dragPosture,out ec);
printInfo($"start pose: {p_start}");
// 设置间断焊参数
// 普通间断焊
var segData1 = new SegData { name = "segdata1",annotation = "segannotation",seg_type = "normal",non_welded_speed = "v200",welded_distance = 15,non_welded_distance = 30};
// 指定焊接段数
var segData2 = new SegData { name = "segdata1",annotation = "segannotation",seg_type = "bycount",non_welded_speed = "v200",welded_distance = 15, welded_count = 4 };
arcWelding.setSegData(segData2, out ec);
// 开始间断焊指令,设置间断焊参数为segdata1
SegOnCommand segOnCmd = new SegOnCommand("segdata1");
SegOffCommand segOffCmd = new SegOffCommand();
// 几条焊接运动指令
WMoveLCommand seg_wmovel0 = new WMoveLCommand();
seg_wmovel0.target = p_start;
seg_wmovel0.speed = 20;
seg_wmovel0.zone = 0;
seg_wmovel0.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmovel0.cartTargetOffset.frame.trans = new double[] { 0, -0.11, -0.12};
WMoveLCommand seg_wmovel1 = new WMoveLCommand();
seg_wmovel1.target = p_start;
seg_wmovel1.speed = 20;
seg_wmovel1.zone = 0;
seg_wmovel1.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmovel1.cartTargetOffset.frame.trans = new double[]{ 0, 0.08, -0.02};
WMoveCCommand seg_wmc = new WMoveCCommand();
seg_wmc.target = p_start;
seg_wmc.aux = p_start;
seg_wmc.speed = 10;
seg_wmc.zone = 0;
seg_wmc.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmc.cartTargetOffset.frame.trans = new double[]{ 0, -0.05, 0.01};
seg_wmc.auxPointOffset.type = CartesianPosition.Offset.Type.offs;
seg_wmc.auxPointOffset.frame.trans = new double[]{ 0, 0.070, 0};
WMoveLCommand non_seg_wmovl = new WMoveLCommand();
non_seg_wmovl.target = p_start;
non_seg_wmovl.speed = 20;
non_seg_wmovl.zone = 1;
non_seg_wmovl.cartTargetOffset.type = CartesianPosition.Offset.Type.offs;
non_seg_wmovl.cartTargetOffset.frame.trans = new double[]{ -0.05, 0, 0};
ArcOnCommand arcOnCmd = new ArcOnCommand("arcondata1", "arcdata1");
ArcOffCommand arcOffCmd = new ArcOffCommand("arcoffdata1");
MoveCommand absj = new MoveCommand{ jointTarget= new JointPosition { joints = new List<double> { 0, Math.PI / 6, -Math.PI/2, 0, -Math.PI / 3, 0 } },speed = 500};
WeaveOnCommand weave_on_command = new WeaveOnCommand("weavedata1");
WeaveOffCommand weaveOffCmd = new WeaveOffCommand();
String id="";
robot.setPowerState(true, out ec);
robot.moveAppend(MoveCommand.Type.MoveAbsJ, absj,ref id,out ec);
robot.moveStart(out ec);
while (true)
{
Thread.Sleep(1000);
var st = robot.operationState(out ec);
if (st == OperationState.idle || st == OperationState.unknown) break;
}
printInfo("运动到初始点");
robot.moveAppend(arcOnCmd,ref id,out ec);
robot.moveAppend(weave_on_command, ref id, out ec);
robot.moveAppend(segOnCmd,ref id,out ec);
List<ArcWeldingCommand> wmovels = new List<ArcWeldingCommand> { seg_wmovel0, seg_wmovel1 };
robot.moveAppend(wmovels,ref id,out ec);
robot.moveAppend(seg_wmc, ref id, out ec);
robot.moveAppend(segOffCmd,ref id,out ec);
robot.moveAppend(non_seg_wmovl, ref id, out ec);
robot.moveAppend(weaveOffCmd, ref id, out ec);
robot.moveAppend(arcOffCmd, ref id, out ec);
robot.moveStart(out ec);
常用接口与类型
同场景八与场景九所列类型组合使用。
注意事项
顺序错误可能导致摆动或间断未按预期生效;务必在仿真/空运行下先验证再实焊。
场景十一:钟摆形轨迹焊接
适用情况 焊缝几何由工艺定义为钟摆形路径(专用钟摆运动指令)。
目标 正确使用 WMoveLPendulumCommand 的起点、辅助点、目标点及速度等参数;需要切换规范时在成员上设置 arc_set_opt。
推荐步骤
- 按工艺包与示教数据填入
WMoveLPendulumCommand各点(与arcSetPendulumExample一致)。 - 与
ArcOnCommand/ArcOffCommand组合方式与普通焊接运动相同,压入非实时队列后moveStart。 - 若同程序中还有普通摆焊,注意与场景八区分:钟摆为独立运动类型,一般不混用
WeaveOn包络同一段钟摆(以工艺包说明为准)。
实现代码
string cmd_id = "";
// 设置起弧/收弧
ArcData arcData = ArcData.CreateDefault();
arcData.name = "arcdata1";
arcWelding.setArcData(arcData, out ec);
arcData.name = "arcdata2";
arcData.current = 20;
arcData.voltage = 15;
arcWelding.setArcData(arcData, out ec);
arcData.name = "arcdata3";
arcData.current = 100;
arcData.voltage = 20;
arcData.weld_speed = 15;
arcWelding.setArcData(arcData, out ec);
ArcOnData arconData = ArcOnData.CreateDefault();
arconData.name = "arcondata1";
arcWelding.setArcOnData(arconData, out ec);
ArcOffData arcOffData = ArcOffData.CreateDefault();
arcOffData.name = "arcoffdata1";
arcWelding.setArcOffData(arcOffData, out ec);
// 设置摆动
WeaveData weaveData = WeaveData.CreateDefault();
weaveData.weave_length_frequency = 3.5;
weaveData.amplitude.left = 6;
weaveData.amplitude.right = 4.5;
arcWelding.setWeaveData(weaveData, out ec);
ArcOnCommand arc_on_command = new ArcOnCommand("arcondata1", "arcdata1");
ArcOffCommand arc_off_command = new ArcOffCommand("arcoffdata1");
WeaveOnCommand weave_on = new WeaveOnCommand();
WeaveOffCommand weave_off = new WeaveOffCommand();
MoveCommand absj = new MoveCommand
{
jointTarget = new JointPosition { joints = new List<double> { 0.168, 0.369, -0.883, -0.210, -0.637, -0.137 } },
speed = 1000
};
CartesianPosition start1 = new CartesianPosition(new double[] { 0.68015, -0.077702, 0.777555, -2.319, 1.112, -2.228 });
CartesianPosition startAux1 = new CartesianPosition(new double[] { 0.672849, -0.0777043, 0.777555, -2.319, 1.112, -2.228 });
CartesianPosition targetAux1 = new CartesianPosition(new double[] { 0.647849, -0.0943, 0.750882, -2.319, 1.112, -2.228 });
CartesianPosition target1 = new CartesianPosition(new double[] { 0.647849, -0.09473, 0.747882, -2.319, 1.112, -2.228 });
CartesianPosition targetAux2 = new CartesianPosition(new double[] { 0.437346, -0.2597, 0.793403, -2.319, 1.112, -2.228 });
CartesianPosition target2 = new CartesianPosition(new double[] { 0.435346, -0.2597, 0.796403, -2.319, 1.112, -2.228 });
CartesianPosition targetAux3 = new CartesianPosition(new double[] { 0.6117849, -0.14534, 0.666882, -2.319, 1.112, -2.228 });
CartesianPosition target3 = new CartesianPosition(new double[] { 0.599849, -0.14574, 0.667882, -2.319, 1.112, -2.228 });
MoveCommand l = new MoveCommand
{
cartTarget = start1,
speed = 500
};
// 钟摆
WMoveLPendulumCommand wp1 = new WMoveLPendulumCommand(startAux1, target1, targetAux1, 20, 0.5, 100, 2);
WMoveLPendulumCommand wp2 = new WMoveLPendulumCommand(target2, targetAux2, 20, 3, 234, 1);
wp2.arc_set_opt = new ArcSetOpt { arc_data = "arcdata2", ref_start = true, distance = 0 };
WMoveLPendulumCommand wp3 = new WMoveLPendulumCommand(target3, targetAux3, -1, 3.1, 4, 5);
wp3.arc_set_opt = new ArcSetOpt { arc_data = "arcdata3", ref_start = true, distance = 0 };
robot.setPowerState(true, out ec);
robot.moveAppend(MoveCommand.Type.MoveAbsJ, absj, ref cmd_id, out ec);
robot.moveAppend(MoveCommand.Type.MoveL, l, ref cmd_id, out ec);
robot.moveAppend(arc_on_command, ref cmd_id, out ec);
//robot.moveAppend(wp1, ref cmd_id, out ec);
robot.moveAppend(wp2, ref cmd_id, out ec);
//robot.moveAppend(wp3, ref cmd_id, out ec);
robot.moveAppend(arc_off_command, ref cmd_id, out ec);
robot.moveStart(out ec);
while (Console.KeyAvailable)
{
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
}
robot.setPowerState(false, out ec);
常用接口与类型
WMoveLPendulumCommand、ArcSetOpt(arc_set_opt 成员)
场景十二:电弧跟踪
适用情况 焊接过程中需根据电弧传感修正横向或高度方向
目标 指定轨迹段使用某套 ArcTrackParam;其它段不传跟踪名即不跟踪。
推荐步骤
setArcTrackParam下发跟踪参数名(如arctrackdata1)。- 在
WMoveLCommand等带摆动名的重载中传入跟踪数据名;圆弧若 SDK 提供同等重载,绑定方式相同(以接口说明 / 附录类型为准)。 - 典型队列:
ArcOnCommand→WeaveOnCommand→ 多条带跟踪的焊接运动 →WeaveOffCommand→ArcOffCommand。 - 等待运动结束并确认收弧完成(可结合场景十八事件订阅)。
实现代码
//设置电弧跟踪参数
ArcTrackParam param = ArcTrackParam.CreateDefault();
param.name = "arctrackdata1";
param.annotation = "test1";
param.delay_time = 5;//其他的值类似设置就行,这里直接使用默认值
arcwelding.setArcTrackParam(param,out ec);
//获取对应的电弧跟踪参数
var param_get = arcwelding.getArcTrackParam(param.name,out ec);
//本例验证时运行于NB4h-R580-3B(注意点位匹配)
double[] p0 = { 0.357487, 0.000633967, 0.222628, 3.0, 0.0685018, 3.12448 };
double[] p1 = { 0.357487, 0.143835, 0.222628, 3.13197, 0.0685018, 3.12448 };
double[] p2 = { 0.456268, 0.000634313, 0.222628, 3.13197, 0.0685026, 3.12448 };
double[] p3 = { 0.456268, 0.143835, 0.222628, 3.13197, 0.0685024, 3.12448 };
double[] p4 = { 0.456268, -0.103198, 0.222628, 3.13197, 0.068502, 3.12448 };
ArcOnCommand arcon = new ArcOnCommand("arcondata1", "arcdata1");
ArcOffCommand arcoff = new ArcOffCommand("arcoffdata1");
MoveCommand mj = new MoveCommand {
cartTarget = new CartesianPosition(p0),
speed = 100,
zone = 1
};
// 第一条,开启电弧跟踪,用跟踪参数arctrackdata1
WMoveLCommand wml1 = new WMoveLCommand(new CartesianPosition(p1), 20, 1, "weavedata1", "arctrackdata1");
// 第二条,开启电弧跟踪,用跟踪参数arctrackdata2
WMoveLCommand wml2 = new WMoveLCommand(new CartesianPosition(p2), 20, 1, "weavedata1", "arctrackdata2");
// 第三条,电弧跟踪参数为空,不跟踪
WMoveLCommand wml3 = new WMoveLCommand(new CartesianPosition(p3), 20, 1, "weavedata1");
// 第四条和第五条,开启电弧跟踪,用跟踪参数arctrackdata2
WMoveLCommand wml4 = new WMoveLCommand(new CartesianPosition(p4), 20, 1, "weavedata1", "arctrackdata2");
WMoveLCommand wml5 = new WMoveLCommand(new CartesianPosition(p3), 20, 1, "weavedata1", "arctrackdata2");
// 第六条,不跟踪
WMoveLCommand wml6 = new WMoveLCommand(new CartesianPosition(p2), 20, 1, "weavedata1"); // 直线摆动
WeaveOnCommand weaveon= new WeaveOnCommand("weavedata1");
WeaveOffCommand weaveoff = new WeaveOffCommand();
List<ArcWeldingCommand> wmove_list = new List<ArcWeldingCommand> { wml1, wml2, wml3, wml4, wml5, wml6 };
string id = "";
string move_id = "";
robot.setPowerState(true, out ec);
robot.moveAppend(MoveCommand.Type.MoveJ, mj,ref move_id,out ec);
robot.moveAppend(arcon, ref id, out ec);
robot.moveAppend(weaveon,ref id, out ec);
robot.moveAppend(wmove_list,ref move_id, out ec);
robot.moveAppend(weaveoff, ref id,out ec);
robot.moveAppend(arcoff, ref id, out ec);
robot.moveStart(out ec);
常用接口与类型
setArcTrackParam、getArcTrackParam、WMoveLCommand(带跟踪参数的重载)、ArcOnCommand、WeaveOnCommand、WeaveOffCommand、ArcOffCommand
注意事项
跟踪效果与焊机、焊丝、电流波形及机型有关;点位需在本机重新标定。 开电弧跟踪的时候必须要开摆动
场景十三:激光寻位
适用情况 在焊接主程序前或中途,需要用激光测量得到焊缝或特征点的位姿修正量。
目标 LaserSearchData 已下发,executeLaserSearch 在约定超时内返回结果;手眼数据名与指令中引用一致。
推荐步骤
- 传感器网络、手眼关系、设备连接等基础配置见场景十四(
LaserSensorCfg、setHandeyeData、connLaserSensorDev等)。 setLaserSearchData维护寻位工艺名与工艺包约定字段。- 构造
LaserSearchCommand(手眼数据名、寻位数据名、搜索位姿、速度等),调用executeLaserSearch;同步/异步、超时与线程安全由应用保证。
实现代码
printInfo("enter LaserSearchExample");
// 保存手眼标定参数
HandeyeData handeyedata0 = HandeyeData.CreateDefault();
handeyedata0.mode = true;
handeyedata0.xyz_abc = new double[] { 29.456, -14.151, 70.047, 4.5006 / 180.0 * Math.PI, 4.0438 / 180.0 * Math.PI, -97.358 / 180.0 * Math.PI };
handeyedata0.name = "laserhandeyedata1";
arcwelding.setHandeyeData(handeyedata0, out ec);
Debug.WriteLineIf(ec.value != 0, $"setHandeyeData, ec: {ec.message}");
// 保存寻位参数
LaserSearchData laserSearchData = new LaserSearchData { name = "lasersearchdata1", job_number = 2, search_type = "point", search_mode = "continuous", step_length = 3, joint_type = "lap_joint" };
arcwelding.setLaserSearchData(laserSearchData,out ec);
Debug.WriteLineIf(ec.value != 0, $"setLaserSearchData, ec: {ec.message}");
CartesianPosition laserSearchPos = new CartesianPosition {rpy = new double[]{ 3.14, 0, 3.14 },trans = new double[]{ 0.563, 0.3, 0.43 } };
LaserSearchCommand laserSearchCmd = new LaserSearchCommand("laserhandeyedata1","lasersearchdata1",laserSearchPos,1,1);
var timeout = TimeSpan.FromSeconds(10);
// CR7 拖拽点位做初始点
Action moveRobot = () =>
{
MoveCommand absj = new MoveCommand { jointTarget = new JointPosition { joints = new List<double> { 0, Math.PI / 6, -Math.PI / 2, 0, -Math.PI / 3, 0 } }, speed = 500 };
String id = "";
robot.setPowerState(true, out ec);
robot.moveAppend(MoveCommand.Type.MoveAbsJ, absj, ref id, out ec);
robot.setPowerState(true, out ec);
robot.moveStart(out ec);
while (true)
{
Thread.Sleep(1000);
var st = robot.operationState(out ec);
if (st == OperationState.idle || st == OperationState.unknown) break;
}
};
// 连接激光器
LaserSensorCfg cfg;
cfg.name = "sensor1";
cfg.ip = "192.168.110.90";
cfg.port = 502;
cfg.overtime = 800;
cfg.communication_cycle = 60;
cfg.type = LaserSensorType.CRNT;//创想传感器
arcwelding.setLaserSensorCfg(cfg, out ec);
printErrorCode("setLaserSensorCfg", ec);
SetLaserSensorStateWatcher(robot, ref ec);
arcwelding.connLaserSensorDev(cfg.name, out ec);
printErrorCode("connLaserSensorDev", ec);
// 方式一、单独运动
// 使用 Task.Run 在后台线程执行 executeLaserSearch
moveRobot();
var future = Task.Run(() =>
{
ErrorCode _ec;
var r = arcwelding.executeLaserSearch(laserSearchCmd, false, timeout, out _ec);
Debug.WriteLineIf(ec.value != 0, $"executeLaserSearch, ec: {ec.message}");
return r;
});
// 主线程执行 moveStart
Thread.Sleep(1000); // 注意处理异步之间的顺序,这里用延时代替
robot.setPowerState(true, out ec);
robot.moveStart(out ec);
Debug.WriteLineIf(ec.value != 0, $"moveStart, ec: {ec.message}");
// 等待异步线程完成
var ret = await future;
var isFound = ret.Item1;
var pos = ret.Item2;
printInfo("寻位方式一:");
printInfo($"isFound: {isFound}, pos: ");
printInfo(string.Join(", ", pos.trans));
printInfo("rpy: ");
printInfo(string.Join(", ", pos.rpy));
// 方式二、寻位并运动
moveRobot();
robot.setPowerState(true, out ec);
robot.moveReset(out ec);
var ret2 = arcwelding.executeLaserSearch(laserSearchCmd, true, timeout, out ec);
Debug.WriteLineIf(ec.value != 0, $"executeLaserSearch, ec: {ec.message}");
var isFound2 = ret2.Item1;
var pos2 = ret2.Item2;
printInfo("寻位方式二:");
printInfo($"isFound: {isFound2}, pos: ");
printInfo(string.Join(", ", pos2.trans));
printInfo("rpy: ");
printInfo(string.Join(", ", pos2.rpy));
robot.setPowerState(false, out ec);
常用接口与类型
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(使用公共段中的 printErrorCode 等错误检查 与 waitForFinish)。
printInfo("enter PrintLaserSensorState");
var device_name = (String)info["device_name"];
var connect = (bool)info["connect"];
var laser_on = (bool)info["laser_state"];
var power_on = (bool)info["power_state"]; //注意:明图传感器没有使能状态,这里的使能状态无效
printInfo("[激光跟踪器状态信息] 设备名称: " + device_name + " 连接:" + (connect ? "YES " : "NO ") + "激光开启:" + (laser_on ? "YES " : "NO ") + "使能开启:" + (power_on ? "YES " : "NO "));
printInfo("enter SetLaserSensorStateWatcher");
robot.setEventWatcher(Event.lasertrackState, PrintLaserSensorState, out ec);
printErrorCode("setEventWatcher", ec);
printInfo("enter LaserTrackExample");
//设置激光跟踪器配置信息
LaserSensorCfg cfg;
cfg.name = "sensor1";
cfg.ip = "192.168.110.90";
cfg.port = 502;
cfg.overtime = 800;
cfg.communication_cycle = 60;
cfg.type = LaserSensorType.CRNT;//创想传感器
//cfg.type = LaserSensorType.SMART_IMAGE;//明图传感器
//发送指令设置AddLaserSensorCfg
arcwelding.setLaserSensorCfg(cfg, out ec);
printErrorCode("setLaserSensorCfg", ec);
//查询设备配置信息
LaserSensorCfg cfg_get = arcwelding.getLaserSensorCfg(cfg.name, out ec);
printErrorCode("getLaserSensorCfg", ec);
printInfo("name: " + cfg_get.name + " ip:" + cfg_get.ip);
//设置传感器状态监控watch
SetLaserSensorStateWatcher(robot, ref ec);
//连接激光跟踪器ConnLaserTrack
arcwelding.connLaserSensorDev(cfg.name, out ec);
printErrorCode("connLaserSensorDev", ec);
//开启焊缝跟踪器,开始获取激光传感器数据OpenLaserTrack
arcwelding.openLaserTrack(cfg.name, out ec);
printErrorCode("openLaserTrack", ec);
//关闭焊缝跟踪器CloseLaserTrack
arcwelding.closeLaserTrack(cfg.name, out ec);
printErrorCode("closeLaserTrack", ec);
//断开连接DisConnLaserTrack
arcwelding.disconnLaserSensorDev(cfg.name, out ec);
printErrorCode("disconnLaserSensorDev", ec);
//删除设备配置信息RemoveLaserSensorCfg
arcwelding.removeLaserSensorCfg(cfg.name, out ec);
printErrorCode("removeLaserSensorCfg", ec);
//设置手眼标定结果
HandeyeData handeyedata0 = HandeyeData.CreateDefault();
handeyedata0.mode = true;
handeyedata0.xyz_abc = new double[] { 29.456, -14.151, 70.047, 4.5006 / 180.0 * Math.PI, 4.0438 / 180.0 * Math.PI, -97.358 / 180.0 * Math.PI };
handeyedata0.name = "handeyedata0";
arcwelding.setHandeyeData(handeyedata0, out ec);
printErrorCode("setHandeyeData", ec);
//查询手眼标定结果
String name = "handeyedata0";
var handeyedata0_get = arcwelding.getHandeyeData(name, out ec);
printErrorCode("getHandeyeData", ec);
printInfo("name:" + handeyedata0_get.name + " xyz_abc: " + handeyedata0_get.xyz_abc[0] + "," + handeyedata0_get.xyz_abc[2] + "," + handeyedata0_get.xyz_abc[3] + "," + handeyedata0_get.xyz_abc[4] + "," + handeyedata0_get.xyz_abc[5] + "}
printInfo("enter LaserTrackExample");
//设置激光跟踪器配置信息
LaserSensorCfg cfg;
cfg.name = "sensor1";
cfg.ip = "192.168.110.90";
cfg.port = 502;
cfg.overtime = 800;
cfg.communication_cycle = 60;
cfg.type = LaserSensorType.CRNT;//创想传感器
//cfg.type = LaserSensorType.SMART_IMAGE;//明图传感器
//发送指令设置AddLaserSensorCfg
arcwelding.setLaserSensorCfg(cfg, out ec);
printErrorCode("setLaserSensorCfg", ec);
//查询设备配置信息
LaserSensorCfg cfg_get = arcwelding.getLaserSensorCfg(cfg.name, out ec);
printErrorCode("getLaserSensorCfg", ec);
printInfo("name: " + cfg_get.name + " ip:" + cfg_get.ip);
//设置传感器状态监控watch
SetLaserSensorStateWatcher(robot, ref ec);
//连接激光跟踪器ConnLaserTrack
arcwelding.connLaserSensorDev(cfg.name, out ec);
printErrorCode("connLaserSensorDev", ec);
//开启焊缝跟踪器,开始获取激光传感器数据OpenLaserTrack
arcwelding.openLaserTrack(cfg.name, out ec);
printErrorCode("openLaserTrack", ec);
//关闭焊缝跟踪器CloseLaserTrack
arcwelding.closeLaserTrack(cfg.name, out ec);
printErrorCode("closeLaserTrack", ec);
//断开连接DisConnLaserTrack
arcwelding.disconnLaserSensorDev(cfg.name, out ec);
printErrorCode("disconnLaserSensorDev", ec);
//删除设备配置信息RemoveLaserSensorCfg
arcwelding.removeLaserSensorCfg(cfg.name, out ec);
printErrorCode("removeLaserSensorCfg", ec);
//设置手眼标定结果
HandeyeData handeyedata0 = HandeyeData.CreateDefault();
handeyedata0.mode = true;
handeyedata0.xyz_abc = new double[] { 29.456, -14.151, 70.047, 4.5006 / 180.0 * Math.PI, 4.0438 / 180.0 * Math.PI, -97.358 / 180.0 * Math.PI };
handeyedata0.name = "handeyedata0";
arcwelding.setHandeyeData(handeyedata0, out ec);
printErrorCode("setHandeyeData", ec);
//查询手眼标定结果
String name = "handeyedata0";
var handeyedata0_get = arcwelding.getHandeyeData(name, out ec);
printErrorCode("getHandeyeData", ec);
printInfo("name:" + handeyedata0_get.name + " xyz_abc: " + handeyedata0_get.xyz_abc[0] + "," + handeyedata0_get.xyz_abc[2] + "," + handeyedata0_get.xyz_abc[3] + "," + handeyedata0_get.xyz_abc[4] + "," + handeyedata0_get.xyz_abc[5] + "}
常用接口与类型
LaserSensorCfg、setLaserSensorCfg、connLaserSensorDev、openLaserTrack、closeLaserTrack、setLaserTrackData、LaserTrackOnCommand、LaserTrackOffCommand、GetLaserPos
注意事项
场景十五:多层多道与层道偏移
适用情况 同一焊缝截面需要多道堆叠,或每层起点/姿态按 LayerData 偏移。
目标 层道参数已下发;可选先做可达性校验,再在下料队列中用 OffsetOnCommand / OffsetOffCommand 包络各层轨迹。
推荐步骤
setLayerData为每层道维护名称与偏移、辅助点等。- 使用
MpmlPathCheck对路径点组、运动类型列表与层道列表做校验,收集不可达层名。 - 需要时
GetLayerStartPoint获取建议起弧位姿。 - 队列中在对应层轨迹前插入
OffsetOnCommand(layerName),层结束处OffsetOffCommand。
实现代码
//设置多层多道偏移参数
LayerData param = LayerData.CreateDefault();
param.name = "layerdata1";
param.annotation = "test1";
param.start_offset = 10;
param.y_offset = -11;
param.z_offset = 4;
arcwelding.setLayerData(param, out ec);
//本例验证时运行于XMC7-R850-B0X1A0(注意点位匹配)
double[] p0 = { 0.614, 0.136, 0.389, -3.141592653589793, 0.0, 3.141592653589793 };
double[] p1 = { 0.514, -0.136, 0.410, -3.141592653589793, 0.0, 3.141592653589793 };
double[] p2 = { 0.563, -0.147, 0.410, -3.141592653589793, 0.0, 3.141592653589793 };
double[] p3 = { 0.550, -0.127, 0.410, -3.141592653589793, 0.0, 3.141592653589793 };
double[] p4 = { 0.643, 0.100, 0.410, -3.141592653589793, 0.0, 3.141592653589793 };
double[] p5 = { 0.713, -0.000, 0.410, -3.141592653589793, 0.0, 3.141592653589793 };
OffsetOnCommand offseton = new OffsetOnCommand("layerdata1");
OffsetOffCommand offsetoff = new OffsetOffCommand();
ArcOnCommand arcon = new ArcOnCommand("arcondata1", "arcdata1");
ArcOffCommand arcoff = new ArcOffCommand("arcoffdata1");
MoveCommand mj = new MoveCommand
{
cartTarget = new CartesianPosition(p0),
speed = 100,
zone = 1,
};
MoveCommand ml = new MoveCommand
{
cartTarget = new CartesianPosition(p1),
speed = 100,
zone = 1
};
// 第一条
WMoveLCommand wml1 = new WMoveLCommand(new CartesianPosition(p2), 20, 1, "weavedata1");
// 第二条
WMoveLCommand wml2 = new WMoveLCommand(new CartesianPosition(p3), 20, 1, "weavedata1");
// 第三条
WMoveCCommand wmc3 = new WMoveCCommand(new CartesianPosition(p4), new CartesianPosition(p5), 20, 1, "weavedata1");
WeaveOnCommand weaveon = new WeaveOnCommand("weavedata1");
WeaveOffCommand weaveoff = new WeaveOffCommand();
ChangeLayerDataCommand changeLayerData = new ChangeLayerDataCommand("layerdata1", 10.00, 10.00, 10.00, 10.00, 0, 5.00);
string id = "";
string move_id = "";
robot.setPowerState(true, out ec);
//robot.moveAppend(changeLayerData, ref move_id, out ec);
robot.moveAppend(MoveCommand.Type.MoveJ, mj, ref move_id, out ec);
robot.moveAppend(offseton, ref id, out ec);
robot.moveAppend(MoveCommand.Type.MoveL, ml, ref move_id, out ec);
robot.moveAppend(arcon, ref id, out ec);
robot.moveAppend(weaveon, ref id, out ec);
robot.moveAppend(wml1, ref move_id, out ec);
robot.moveAppend(wml2, ref move_id, out ec);
robot.moveAppend(wmc3, ref move_id, out ec);
robot.moveAppend(weaveoff, ref id, out ec);
robot.moveAppend(arcoff, ref id, out ec);
robot.moveAppend(offsetoff, ref id, out ec);
robot.moveStart(out ec);
常用接口与类型
setLayerData、getLayerData、removeLayerData、LayerData、MpmlPathCheck、GetLayerStartPoint、OffsetOnCommand、OffsetOffCommand
场景十六:整圆与复杂空间曲线(摆动 / 间断 / 跟踪可选)
适用情况 焊缝为整圆或 MoveCF 类曲线,且可能叠加摆动、间断焊或电弧跟踪。
目标 使用 WMoveCFCommand 等与工艺指令组合;具体组合顺序与注释中的多种模式以工艺验证为准。
推荐步骤
- 将圆或曲线以工艺包要求的辅助点与目标点形式构造
WMoveCFCommand。 - 按需
setWeaveData、setSegData、setArcTrackParam后,在指令上绑定名称或在队列中插入SegOnCommand等。 - 在仿真或空运行下验证轨迹与姿态,再切实焊。
实现代码
// 点位机型 XMC7-R850-W7G3B4C
printInfo("enter WMoveCFExample");
Func<List<double>, double[]> rlPoint2sdkPoint = rlPoint =>
{
double[] sdkPoint = new double[6];
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 * Math.PI;
}
return sdkPoint;
};
ArcOnCommand arcon = new ArcOnCommand("arcondata1", "arcdata1");
ArcOffCommand arcoff = new ArcOffCommand("arcoffdata1");
SegOnCommand segon = new SegOnCommand("segdata1");
SegOffCommand segooff = new SegOffCommand();
WeaveOnCommand weaveon = new WeaveOnCommand("weavedata1");
WeaveOffCommand weaveoff = new WeaveOffCommand();
List<double> p1point = new List<double> { 556.769126, 101.641184, 358.852436, 158.661084, -17.184105, -148.826026 };
List<double> p2point = new List<double> { 590.049781, 101.641177, 358.852421, 158.66108, -17.184102, -148.826024 };
List<double> p3point = new List<double> { 556.769146, 17.242862, 358.852448, 179.999964, -0.000009, -179.999957 };
List<double> p4point = new List<double> { 556.769126, 101.641184, 358.852436, 179.999964, -0.000009, -179.999957 };
List<double> p5point = new List<double> { 590.049781, 101.641177, 358.852421, 179.999964, -0.000009, -179.999957 };
CartesianPosition p1 = new CartesianPosition(rlPoint2sdkPoint(p1point));
CartesianPosition p2 = new CartesianPosition(rlPoint2sdkPoint(p2point));
CartesianPosition p3 = new CartesianPosition(rlPoint2sdkPoint(p3point));
CartesianPosition p4 = new CartesianPosition(rlPoint2sdkPoint(p4point));
CartesianPosition p5 = new CartesianPosition(rlPoint2sdkPoint(p5point));
WMoveLCommand wml = new WMoveLCommand(p3, 200, 1);
WMoveCFCommand wmcf = new WMoveCFCommand(p2, p1, 300 / 180.0 * Math.PI,200,1);
WMoveCFCommand wmcf2 = new WMoveCFCommand(p4, p5, 300 / 180.0 * Math.PI, 200, 1);
// 设置旋转类型
wmcf.rotType = 0; // 不变姿态
//wmcf.rotType = 1; // 动轴旋转
//wmcf.rotType = 2; // 定轴旋转
string id = "";
// 单独整圆运动
robot.moveAppend(arcon, ref id, out ec);
robot.moveAppend(wmcf, ref id, out ec);
robot.moveAppend(arcoff, ref id, out ec);
robot.moveStart(out ec);
// 搭配摆动运动
//wmcf.setWeaveData("weavedata1", out ec);
//robot.moveAppend(arcon, ref id, out ec);
//robot.moveAppend(weaveon, ref id, out ec);
//robot.moveAppend(wmcf, ref id, out ec);
//robot.moveAppend(weaveoff, ref id, out ec);
//robot.moveAppend(arcoff, ref id, out ec);
//robot.moveStart(out ec);
// 搭配间断焊运动
//robot.moveAppend(arcon, ref id, out ec);
//robot.moveAppend(segon, ref id, out ec);
//robot.moveAppend(wmcf, ref id, out ec);
//robot.moveAppend(segooff, ref id, out ec);
//robot.moveAppend(arcoff, ref id, out ec);
//robot.moveStart(out ec);
// 搭配电弧跟踪,需要搭配摆动
//wmcf.setWeaveData("weavedata1",out ec);
//wmcf.setTrackData("arctrackdata1", out ec);
//robot.moveAppend(arcon, ref id, out ec);
//robot.moveAppend(weaveon, ref id, out ec);
//robot.moveAppend(wmcf, ref id, out ec);
//robot.moveAppend(weaveoff, ref id, out ec);
//robot.moveAppend(arcoff, ref id, out ec);
//robot.moveStart(out ec);
// arcdata中设置了断弧回退距离,暂停后继续运动会回退,需要有前置轨迹
//robot.setDefaultConfOpt(false, out ec);
//robot.moveAppend(arcon,ref id,out ec);
//robot.moveAppend(wml, ref id,out ec);
//robot.moveAppend(wmcf,ref id, out ec);
//robot.moveAppend(arcoff,ref id,out ec);
//robot.moveStart(out ec);
//Thread.Sleep(4000);
//robot.stop(out ec); // 暂停
//Thread.Sleep(2000);
//robot.moveStart(out ec);// 继续
常用接口与类型
WMoveCFCommand、MoveCFCommandRotType(rotType 成员)
场景十七:现场辅助动作与焊机状态
适用情况 调枪、引弧前送丝 / 退丝 / 检气;短时点焊铆焊;读取焊机实时量或清报警;在不实际焊接时,通过 enableArcData 选择工作模式并将电流/电压模式与设定值下发至焊机,对照焊机面板核对已生效数据是否与上位机一致。
目标 不依赖完整焊接轨迹即可完成维护性动作;HMI 可展示焊机状态。
推荐步骤
- 送丝、退丝、检气:调用
feedOnWire、feedBackWire、detectGas等,持续时间需满足工艺包最小阈值(如大于 0.1 s);停止动作使用对应重载中的使能参数(见附录方法)。 - 铆焊:
startWelding/stopWelding,区分一元化与分别模式等(见接口说明)。 - 状态:
getWelderStatus;报警可恢复时clearWelderAlarm。 enableArcData:用于在焊机侧使能/生效一条焊接工艺数据(含工作模式、电流/电压模式及电流、电压等设定),该数据不会被保存。在不建立焊接过程的前提下调用后,对照焊机面板显示与上位机下发值是否一致,便于现场对表与联调(不能为虚拟机、须连接焊机等前提见下文代码注释)。
实现代码
以下依次为同文件中的 feedOnWire、feedBackWire、detectGas、getWelderState、exampleWelding、clearWelderAlarm、enableArcData。
// 需要在启用焊机后执行
printInfo("enter FeedOnWireExample");
double time = 10;
// 送丝
arcwelding.feedOnWire(time, true, out ec); // 送丝和停止送丝时间参数都要大于0.1
printErrorCode("feedOnWire", ec);
// 停止送丝
arcwelding.feedOnWire(time, false, out ec);
printErrorCode("feedOnWire", ec);
// 需要在启用焊机后执行
printInfo("enter FeedBackWireExample");
double time = 10;
// 退丝
arcwelding.feedBackWire(time, true, out ec);// 退丝和停止退丝时间都要大于0.1
printErrorCode("feedBackWire", ec);
// 停止退丝
arcwelding.feedBackWire(time, false, out ec);
printErrorCode("feedBackWire", ec);
// 需要在启用焊机后执行
printInfo("enter DetectGasExample");
double time = 10;
// 检气
arcwelding.detectGas(time, true, out ec); // 检气和停止检气时间参数都要大于0
printErrorCode("detectGas", ec);
// 停止检气
arcwelding.detectGas(time, false, out ec);
printErrorCode("detectGas", ec);
printInfo("enter GetWelderStateExample");
var welderState = arcwelding.getWelderStatus(out ec);
printErrorCode("getWelderStatus", ec);
printInfo("state: " + welderState.state);
printInfo("current: " + welderState.current);
printInfo("voltage: " + welderState.voltage);
printInfo("speed: " + welderState.speed);
printInfo("welding_name: " + welderState.welding_name);
printInfo("arc_welding: " + welderState.arc_welding);
printInfo("runing_error: " + welderState.running_error.message);
printInfo("distance: " + welderState.welding_distance);
printInfo("num: " + welderState.welding_path_num);
printInfo("enter ExampleWelding");
arcwelding.startWelding(100, 0, "unified", out ec); // 一元化模式
printErrorCode("startWelding", ec);
arcwelding.startWelding(100, 0, "separate", out ec); // 分别模式
printErrorCode("startWelding", ec);
arcwelding.stopWelding(out ec);
printErrorCode("stopWelding", ec);
// 清焊机面板告警
arcWelding.clearWelderAlarm(out ec);
printErrorCode("clearWelderAlarm", ec);
printInfo("enter EnableArcData");
// 不能为虚拟机, 并且需要连接焊机
ArcData arcDataCustom = new ArcData
{
name = "Custom1_name",
annotation = "Custom1_annotation",
mode = "low_spatter",
current_mode = "wire_feed",
voltage_mode = "separate",
current = 80,
voltage = 2,
weld_speed = 50,
ramp_time = 200,
arc_break_param = new ArcBreakParam
{
detect_time = 50,
arc_break_option = "stop_and_alarm",
restart_back_distance = 0
}
};
arcWelding.enableArcData(arcDataCustom, out ec);
printErrorCode("enableArcData", ec);
常用接口与类型
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。
printInfo("enter PrintWeldState");
double current = info.TryGetValue("current", out object currentObj) ? (double)currentObj : 0.0;
double voltage = info.TryGetValue("voltage", out object voltageObj) ? (double)voltageObj : 0.0;
string state = info.TryGetValue("state", out object stateObj) ? (string)stateObj : string.Empty;
int speed = info.TryGetValue("welding_speed", out object speedObj) ? (int)speedObj : 0;
ErrorCode error = info.TryGetValue("runningError", out object errorObj) ? (ErrorCode)errorObj : new ErrorCode(0,"");
string weldingName = info.TryGetValue("welding_name", out object weldingNameObj) ? (string)weldingNameObj : string.Empty;
int arcwelding = info.TryGetValue("arc_welding", out object arcweldingObj) ? (int)arcweldingObj : 0;
double distance = (double)info["distance"];
printInfo("[焊接状态] current: " + current + ", voltage: " + voltage + ", state: " + state + ", speed: " + speed);
printInfo("weldingName: " + weldingName + ", arcwelding: " + arcwelding+ ", distance: "+ distance);
printInfo("error: " + error.message);
if (info.ContainsKey("pathNumber"))
{
int pathNumber = (int)info["pathNumber"];
printInfo("pathNumber: " + pathNumber);
}
printInfo("enter SetArcWeldStateWatcher");
robot.setEventWatcher(Event.arcWeldState, PrintWeldState, out ec);
printErrorCode("setEventWatcher", ec);
// 与焊接状态监视一起用,容易为空
printInfo("enter QueryWeldStateExample");
var info = robot.queryEventInfo(Event.arcWeldState, out ec);
printErrorCode("queryEventInfo", ec);
PrintWeldState(info);
printInfo("enter PrintMoveState");
var _cmdID = (String)info["cmdID"]; // 指令ID
var _idx = (int)info["wayPointIndex"]; // 路点下标, 从0开始标号
var _err = (ErrorCode)info["error"]; // 错误信息
var _remark = (string)info["remark"]; // 警告信息(相近定位)
var _reach = (bool)info["reachTarget"]; // 是否到达目标点
printInfo("[运动执行信息] ID:" + _cmdID + " Index:" + _idx + " 已完成: " + (_reach ? "YES" : "NO") + " error: " + (_err.message) + " remark: " + _remark);
printInfo("enter setMoveStateWatcher");
robot.setEventWatcher(Event.moveExecution, PrintMoveState, out ec);
printErrorCode("setEventWatcher", ec);
常用接口与类型
setEventWatcher、queryEventInfo、Event.arcWeldState、Event.moveExecution、EventInfoKey.ArcWeldState、EventInfoKey.MoveExecution
注意事项
- 焊机状态回调的周期是500ms
场景十九:其它几何与工艺辅助(按需查阅)
适用情况 三点建用户参考、焊机支持模式查询、焊接中 Jog 偏置等;
目标 在程序中完成辅助几何计算或读取焊机能力列表。
推荐步骤
- 按业务调用
getRefBy3Points、getWelderWorkModes、weldOffsetJog等;
实现代码
以下依次为 getRefBy3PointsExample、getWelderWorkModes、weldingJogOffsetExample。
CartesianPosition pos1 = new CartesianPosition
{
trans = new double[] { 0.55676914536239797, -0.15000000000000005, 0.35885244785437498 },
rpy = new double[] { -3.1415926535897931, 3.8857805861880484e-16, -3.1415926535897931 }
}
;
CartesianPosition pos2 = new CartesianPosition
{
trans = new double[] { 0.71096662191265758, -0.14999999687989679, 0.35885244769618885 },
rpy = new double[] { -3.1415921387343229, 8.5631816663676866e-07, 3.1415926369370966 }
}
;
CartesianPosition pos3 = new CartesianPosition
{
trans = new double[] { 0.71096662302702562, 0.0055997244168811289, 0.35885244730431071 }
,
rpy = new double[] { -3.1415926429162764, 7.8093868108499471e-07, -3.1415918107904255 }
}
;
bool with_origin = false;
ArcWelding.DirType dir = ArcWelding.DirType.X_Plus_Y_Plus;
var ret = arcWelding.getRefBy3Points(new CartesianPosition[] { pos1, pos2, pos3 }, with_origin, dir, out ec);
printErrorCode("getRefBy3PointsExample:", ec);
foreach (var p in ret.trans)
{
printInfo(p + " ");
}
foreach (var p in ret.rpy)
{
printInfo(p + " ");
}
var workModes = arcWelding.getWelderWorkModes(out ec);
printErrorCode("getWelderWorkModes", ec);
printInfo("work modes: " + string.Join(" ", workModes));
arcWelding.weldOffsetJog(WeldOffsetJogDir.Y_PLUS, out ec);
arcWelding.weldOffsetJog(WeldOffsetJogDir.Y_MINUS, out ec);
arcWelding.weldOffsetJog(WeldOffsetJogDir.Z_PLUS, out ec);
arcWelding.weldOffsetJog(WeldOffsetJogDir.Z_MINUS, out ec);
printErrorCode("weldOffsetJog", ec);
常用接口与类型
getRefBy3Points、getWelderWorkModes、weldOffsetJog
与详细文档的对应关系
| 需求 | 文档 |
|---|---|
| 接口列表与参数含义 | 接口说明 |
| 类型与数据结构 | 附录:类型、附录:数据结构 |
| 方法签名与重载细节 | 附录:方法 |
| 错误码与异常 | 错误码和异常 |