跳到主要内容

弧焊 C# SDK 使用示例

文档约定

以下各节结构统一为:

  1. 适用情况 — 何时需要本场景
  2. 目标 — 做完后系统应处于的状态
  3. 推荐步骤 — 顺序化操作要点;
  4. 常用接口与类型 — 便于检索 SDK 符号,非完整参数表
  5. 注意事项 — 常见易错点

通用编程约定

  1. 通过 robot.arcwelding() 取得 ArcWelding 实例,在其上调用工艺参数与焊机相关接口;运动队列仍在 robot 上操作。
  2. 各 API 使用 ErrorCode ec,多数接口为 out ecref ec 输出参数,每次调用后检查 ec.valueec.message
  3. 涉及「压队列再启动」的焊接轨迹,通常配合 MotionControlMode.NrtCommandmoveAppend / moveStart;与纯参数下发场景区分开。

公共代码前提(各场景「实现代码」共用)

以下与 SDK 包内 xCoreSDK-CSharp_examples_ArcWeldingDemo.csArcWeldingDemo 类)一致。

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 期望配置。

推荐步骤

关键步骤关系如下(与下文分步说明对应):

  1. connectToRobot 建立与控制器连接。

  2. getWelderStatus 查看焊机侧状态:若 state"disabled" 等表示尚未建立有效连接;为 "ok" 等表示已就绪(具体枚举以接口说明为准)。

  3. 若已连接:可用 getWelderSetting 读取当前协议、品牌 mfr、型号 model、电流规格 current_type 等。

  4. 若要更换焊机或重配参数:先 disconnectFromWelder,再按下方 EtherCAT模拟量 分支配置后重新 connectToWelder

  5. EtherCAT 焊机:需要setIsEniHaveWeld 需设为 true(与HMI上是否连接物理焊机等效),然后在HMI软件上上传该焊机对应的ENI文件。在 setWelder(或 WelderSetting)中设置 protocol 为 EtherCAT 对应取值(如 "ethercat",以 SDK 约定为准)、mfr 为下表中的厂商键名model 为下表中的型号键名current_type 必须为该机型的 current_range 中的某一档(与工艺包一致)。若该机型还提供 wire_diametershielding_gasprogram_numberdry_extensionfirmware_version 等约束,则 setWelder 时相应字段只能取自下列允许集合。

    厂商 / 型号与电流档位(及可选约束)一览(下发时 mfrmodel 字符串需与键名一致):

{
"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] 内)。

  1. 模拟量焊机:须按顺序完成下面三步,再 setWelder

    • ① IO 绑定:先调用 setIOSetting,将起弧、送丝、送丝回退、检气、电流/电压设定与回读、焊机就绪、故障等信号绑定到实际 DI/DO 或寄存器。 用 getIOSetting 进行核对。
    • ② 电流 / 电压曲线:使用 setCurrentCharacteristicCurveDatasetVoltageCharacteristicCurveData(及需要时的 calculateCurrentCurve / calculateVoltageCurve)在控制器中建立曲线数据并命名。
    • setWelder:协议设为模拟量(具体字符串以 SDK / 工艺包为准,如 "analog" 等);品牌 mfr 只能为 "manual_welding""aotai"型号 model 等与模拟量方案约定一致;current_filevoltage_file 填步骤 ② 中已下发的电流曲线数据名电压曲线数据名。其余字段按接口说明使用默认值或留空。
  2. 调用 connectToWelder 建立与焊机的连接并启用焊机功能;调试结束或更换焊机前可用 disconnectFromWelder

实现代码

模拟量焊机配置见同文件 setIOSettingsetCharacteristicCurveData

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);

常用接口与类型

getWelderStatusgetWelderSettingsetWelderWelderSettingconnectToWelderdisconnectFromWelderisEniHaveWeldsetIsEniHaveWeldsetIOSettinggetIOSettingIOSettingIODatasetCurrentCharacteristicCurveDatasetVoltageCharacteristicCurveDatagetCurrentCharacteristicCurveDatagetVoltageCharacteristicCurveDatacalculateCurrentCurvecalculateVoltageCurve

注意事项

更换焊机参数时,若已在弧焊连接状态,想要切换焊机,需先断开焊机连接再改参。

场景二:设置焊接运行参数

适用情况 需要统一调整空运行笛卡尔速度手动送/退丝速度气体检测时间等与焊接过程相关的全局运行选项(与单条起弧/焊接命名数据不同)。

目标 ArcWeldRunningParam 已写入控制器,空运行、送退丝、无参检气等行为与现场习惯一致。

推荐步骤

  1. 构造 ArcWeldRunningParam:按工艺包范围设置 test_run_speed(mm/s)、wire_feed_speed(m/min)、gas_detect_time(s)等(字段含义与取值范围见 附录:数据结构 中「运行参数 ArcWeldRunningParam」)。
  2. 调用 setRunningParam 下发;用 getRunningParam 读回核对。
  3. 无参重载 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);

常用接口与类型

setRunningParamgetRunningParamArcWeldRunningParamdetectGas

注意事项

手动送/退丝速度 取决于焊机是否可以设置该功能

场景三:设置防碰撞(碰枪检测)

适用情况 现场使用碰枪 / 防撞 DI,需要由程序配置信号名、是否启用、屏蔽与倒计时,并在上位机或逻辑中订阅防撞状态。

目标 防碰撞参数已下发;可通过查询或事件回调获取 signalenableblockcountdown 等与 HMI 或联锁一致。

推荐步骤

  1. 确定用于防撞的 DI 信号名(如 "DI0_0")。
  2. 调用 setAnticollision(signal, enable, block, countdown)enable 为是否启用,block 为屏蔽开关,countdown 为倒计时(秒级语义以工艺包为准)。
  3. 需要界面或逻辑联动时,使用 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}");

常用接口与类型

setAnticollisiongetAnticollisionStateEvent.anticollisionStateEventInfoKey.AnticollisionStatesetEventWatcher

注意事项

绑定的DI信号需要确保没有被其他系统功能占用

场景四:在程序中维护工艺参数

适用情况 希望由上位机或离线工具下发 / 修改起弧、焊接、收弧、摆动、间断焊等命名工艺数据,或与示教器 HMI 中已有参数名保持一致。

目标 控制器内保存在一组可引用的参数名,供后续 ArcOnCommand 等指令或示教程序使用。

推荐步骤

  1. 构造对应结构体(如 ArcOnDataArcDataArcOffDataWeaveDataSegData 等),填写 name 及工艺字段。
  2. 调用 setXxxData 写入;用 getXxxData(name, ec) 读回校验。
  3. 删除单条用 removeXxxData(name);批量删除可传入名称列表重载。
  4. 对示教器已有名称:可先 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 / removeArcOnData setArcData / getArcData / removeArcDataenableArcData
    setArcOffData / getArcOffData / removeArcOffData
    setWeaveData / getWeaveData / removeWeaveData
    setSegData / getSegData / removeSegData
    setWeaveAdaptiveData / getWeaveAdaptiveData

  • 多层多道
    setLayerData / getLayerData / removeLayerData
    setLayerCoutMpmlPathCheckGetLayerStartPoint

  • 激光跟踪 / 激光寻位(命名参数)
    setLaserTrackData / getLaserTrackData / removeLaserTrackData
    setLaserSearchData / getLaserSearchData / removeLaserSearchData

  • 电弧跟踪(命名参数)
    setArcTrackParam / getArcTrackParam / removeArcTrackParam

  • 电流 / 电压特性曲线(命名曲线数据)
    setCurrentCharacteristicCurveData / getCurrentCharacteristicCurveData
    setVoltageCharacteristicCurveData / getVoltageCharacteristicCurveData
    calculateCurrentCurvecalculateVoltageCurve(仅计算、不落库)

注意事项

按名读取不存在的参数时,控制器可能返回约定错误码(如 -272),需在逻辑中处理。

场景五:选择焊接模式,并对照手动 / 自动行为

适用情况 需要空运行验轨迹仿真验节拍与摆动、或实焊出弧,并理解示教器手动单步、手动连续、自动下的差异(起弧与否、速度滑条、间断焊、摆焊、电弧跟踪等)。

目标 当前焊接模式与产线阶段匹配(调试 → 仿真 → 实焊)。

推荐步骤

  1. 调用 setWeldMode,在 WeldMode.TestRun(空运行)、WeldMode.Simu(仿真)、WeldMode.Real(实焊)之间切换。
  2. getWeldMode 读回确认。
  3. 结合现场示教器运行方式,对照下表理解现象(与工艺包说明一致)。

实现代码

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()}");

焊接模式与运行方式组合(示意)

焊接模式具体定义

常用接口与类型

setWeldModegetWeldModeWeldMode

注意事项

场景六:典型焊缝——「起弧 → 直线/圆弧 焊接段 → 收弧」

适用情况 最常见的直线或圆弧焊缝:在非实时指令模式下,将普通运动与弧焊工艺指令按顺序压入同一队列并启动。

目标 机器人按序执行:接近段(可选)→ 起弧与焊接参数生效 → 带或不带摆动的焊接轨迹 → 收弧。

推荐步骤

  1. 需要先通过场景一启用焊机
  2. setMotionControlMode(NrtCommand, ec)
  3. 确认焊机已配置并 connectToWelder(与场景一一致)。
  4. 构造 ArcOnCommand,绑定已下发的起弧参数名、焊接参数名(如与示教器同名)。
  5. 构造焊接段:WMoveLCommand / WMoveCCommand 等;
  6. 构造 ArcOffCommand 并绑定收弧参数名。
  7. 使用同一队列 id 多次 moveAppend 按顺序入队;上电后 moveStart 执行。
  8. 需要暂停 / 继续时,可配合 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);

常用接口与类型

ArcOnCommandArcOffCommandWMoveLCommandWMoveCCommandmoveAppendmoveStartMoveLCommand

注意事项

点位、速度、Conf 需适配本机型。 mvoeStart() 是非阻塞接口,要注意避免直接退出程序。 在 arconarcoff 之前,必须要用普通的 MoveCommand 指令;在他们中间,必须要用 WMoveCommand。 在调用 moveAppend(arcon, id, ec); 时,需要保证控制器已经保存好arcon中对应的起弧参数和焊接参数,不要在这一行代码的上一行或者临近用 setArcOnData 保存数据,避免由于控制器的处理延迟导致调用报错。 如果是飞行起弧,就是 ArcOnData 中的提前起弧时间设置了不为0,则需要在 arcon 前面添加一条 MoveLCommand 指令。

场景七:焊接过程中使用 arc_set_opt(ArcSet)修改工艺参数

适用情况 已在起弧后的某一条焊缝上,希望某一段直线或圆弧改用另一套 arcdata,而不结束电弧、不拆程序。

目标 在压入队列的 WMoveLCommand / WMoveCCommand 等焊接运动上,通过 arc_set_opt 指定切换后的焊接参数名称。

推荐步骤

  1. 预先 setArcData 维护多套命名工艺(如 arcdata1arcdata2)。
  2. 直线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_optWMoveCCommand.arc_set_optsetArcData

场景八:直线 / 圆弧耦合摆动焊接

适用情况 平角或立角等焊缝需要在直线段圆弧段上叠加摆动(Weave),由工艺包按摆动数据名解析摆幅、频率等。

目标 摆动数据已下发并与焊接运动绑定;可用 WeaveOnCommand / WeaveOffCommand 包络多段

推荐步骤

  1. setWeaveData 写入摆动工艺名(如 weavedata1)。
  2. 创建 WeaveOnCommand WeaveOffCommand
  3. 直线:构造 WMoveLCommand 后调用 setWeaveData("…", ec),或使用带摆动索引的构造函数重载(以 SDK 为准)。
  4. 圆弧:构造 WMoveCCommand,同样 setWeaveData;辅助点、目标点与速度须满足机型与工艺包约束。
  5. 典型片段:ArcOnCommandWeaveOnCommand → 若干 WMoveL / WMoveCWeaveOffCommandArcOffCommand

实现代码

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);

常用接口与类型

setWeaveDataWMoveLCommandWMoveCCommandWeaveOnCommandWeaveOffCommand

注意事项

  1. 需要摆动的轨迹必须放在 WeaveOnCommandWeaveOffCommand之间,如果只单独给WMoveLCommandWMoveCCommand设置摆动参数则不会生效
  2. WeaveOnCommandWeaveOffCommand之间的轨迹如果不带摆动参数会默认执行WeaveOnCommand中的摆动参数

场景九:直线 / 圆弧耦合间断焊

适用情况 仅在部分轨迹上需要「焊—停—焊」节拍;不要求摆动,或摆动由其它段单独处理。

目标SegOnCommandSegOffCommand 之间,WMoveL / WMoveCSegData 执行间断节奏;区间外为连续焊或普通焊接运动。

推荐步骤

  1. setSegData 写入间断焊参数名(如 segdata1)。
  2. 队列: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);

常用接口与类型

setSegDataSegOnCommandSegOffCommandWMoveLCommandWMoveCCommand

场景十:直线 / 圆弧耦合间断焊 + 摆动

适用情况 间断节拍与摆动同时作用在同一电弧区间。

目标 WeaveOn 包络与 SegOnSegOff 区间在队列中顺序正确,且各 WMoveL / WMoveCarc_set_opt、偏移等与现场标定一致。

推荐步骤

  1. 同时完成 setWeaveDatasetSegData
  2. 参考 segOnExample 的典型顺序:ArcOnCommandWeaveOnCommand → 非间断的过渡 WMoveL(可选)→ SegOnCommand → 间断区间内的多条 WMoveL / WMoveCSegOffCommand → 后续运动 → WeaveOffCommandArcOffCommand
  3. 若间断段与连续段工艺不同,在对应指令上分别设置 arc_set_opt
  4. 圆弧段目标点、辅助点偏移建议与示例一致地在指令的 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

推荐步骤

  1. 按工艺包与示教数据填入 WMoveLPendulumCommand 各点(与 arcSetPendulumExample 一致)。
  2. ArcOnCommand / ArcOffCommand 组合方式与普通焊接运动相同,压入非实时队列后 moveStart
  3. 若同程序中还有普通摆焊,注意与场景八区分:钟摆为独立运动类型,一般不混用 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);

常用接口与类型

WMoveLPendulumCommandArcSetOptarc_set_opt 成员)

场景十二:电弧跟踪

适用情况 焊接过程中需根据电弧传感修正横向或高度方向

目标 指定轨迹段使用某套 ArcTrackParam;其它段不传跟踪名即不跟踪。

推荐步骤

  1. setArcTrackParam 下发跟踪参数名(如 arctrackdata1)。
  2. WMoveLCommand 等带摆动名的重载中传入跟踪数据名;圆弧若 SDK 提供同等重载,绑定方式相同(以接口说明 / 附录类型为准)。
  3. 典型队列:ArcOnCommandWeaveOnCommand → 多条带跟踪的焊接运动 → WeaveOffCommandArcOffCommand
  4. 等待运动结束并确认收弧完成(可结合场景十八事件订阅)。

实现代码

//设置电弧跟踪参数
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);

常用接口与类型

setArcTrackParamgetArcTrackParamWMoveLCommand(带跟踪参数的重载)、ArcOnCommandWeaveOnCommandWeaveOffCommandArcOffCommand

注意事项

跟踪效果与焊机、焊丝、电流波形及机型有关;点位需在本机重新标定。 开电弧跟踪的时候必须要开摆动

场景十三:激光寻位

适用情况 在焊接主程序前或中途,需要用激光测量得到焊缝或特征点的位姿修正量。

目标 LaserSearchData 已下发,executeLaserSearch 在约定超时内返回结果;手眼数据名与指令中引用一致。

推荐步骤

  1. 传感器网络、手眼关系、设备连接等基础配置场景十四LaserSensorCfgsetHandeyeDataconnLaserSensorDev 等)。
  2. setLaserSearchData 维护寻位工艺名与工艺包约定字段。
  3. 构造 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);

常用接口与类型

setLaserSearchDataLaserSearchCommandexecuteLaserSearchHandeyeData(名在指令中引用)

场景十四:激光跟踪——传感器配置、连接与队列用法

适用情况 要在上位机维护激光 IP、周期、类型;连接设备;焊缝跟踪。

目标 设备可连接、可监控;跟踪段内 LaserTrackOnCommandLaserTrackOffCommand 与焊接运动同队列。

推荐步骤(配置与连接)

  1. 填写 LaserSensorCfgsetLaserSensorCfg;可选 setEventWatcher(Event.lasertrackState, …)
  2. connLaserSensorDev / disconnLaserSensorDev;不用时 removeLaserSensorCfg
  3. 手眼关系:setHandeyeData / getHandeyeData;自动标定:startHandeyeCalibrationcalibratePointcalibrateEnd
  4. 跟踪工艺名:setLaserTrackData(与工艺包字段一致)。

推荐步骤(焊缝跟踪队列)

  1. 连接设备后 openLaserTrack("sensor1", ec)
  2. 队列:ArcOnCommandLaserTrackOnCommandWMoveL / WMoveC 等 → LaserTrackOffCommandArcOffCommand
  3. closeLaserTrack,再按规范 disconnLaserSensorDev

实现代码

以下依次为同文件中的 printLaserSensorStatesetLaserSensorStateWatcher(供配置示例注册回调)、LaserSensorSettingExampleLaserTrackCommandExample(使用公共段中的 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] + "}

常用接口与类型

LaserSensorCfgsetLaserSensorCfgconnLaserSensorDevopenLaserTrackcloseLaserTracksetLaserTrackDataLaserTrackOnCommandLaserTrackOffCommandGetLaserPos

注意事项

场景十五:多层多道与层道偏移

适用情况 同一焊缝截面需要多道堆叠,或每层起点/姿态按 LayerData 偏移。

目标 层道参数已下发;可选先做可达性校验,再在下料队列中用 OffsetOnCommand / OffsetOffCommand 包络各层轨迹。

推荐步骤

  1. setLayerData 为每层道维护名称与偏移、辅助点等。
  2. 使用 MpmlPathCheck 对路径点组、运动类型列表与层道列表做校验,收集不可达层名。
  3. 需要时 GetLayerStartPoint 获取建议起弧位姿。
  4. 队列中在对应层轨迹前插入 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);

常用接口与类型

setLayerDatagetLayerDataremoveLayerDataLayerDataMpmlPathCheckGetLayerStartPointOffsetOnCommandOffsetOffCommand

场景十六:整圆与复杂空间曲线(摆动 / 间断 / 跟踪可选)

适用情况 焊缝为整圆或 MoveCF 类曲线,且可能叠加摆动、间断焊或电弧跟踪。

目标 使用 WMoveCFCommand 等与工艺指令组合;具体组合顺序与注释中的多种模式以工艺验证为准。

推荐步骤

  1. 将圆或曲线以工艺包要求的辅助点与目标点形式构造 WMoveCFCommand
  2. 按需 setWeaveDatasetSegDatasetArcTrackParam 后,在指令上绑定名称或在队列中插入 SegOnCommand 等。
  3. 在仿真或空运行下验证轨迹与姿态,再切实焊。

实现代码

// 点位机型 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);// 继续

常用接口与类型

WMoveCFCommandMoveCFCommandRotTyperotType 成员)

场景十七:现场辅助动作与焊机状态

适用情况 调枪、引弧前送丝 / 退丝 / 检气;短时点焊铆焊;读取焊机实时量或清报警;在不实际焊接时,通过 enableArcData 选择工作模式并将电流/电压模式与设定值下发至焊机,对照焊机面板核对已生效数据是否与上位机一致。

目标 不依赖完整焊接轨迹即可完成维护性动作;HMI 可展示焊机状态。

推荐步骤

  1. 送丝、退丝、检气:调用 feedOnWirefeedBackWiredetectGas 等,持续时间需满足工艺包最小阈值(如大于 0.1 s);停止动作使用对应重载中的使能参数(见附录方法)。
  2. 铆焊:startWelding / stopWelding,区分一元化与分别模式等(见接口说明)。
  3. 状态:getWelderStatus;报警可恢复时 clearWelderAlarm
  4. enableArcData:用于在焊机侧使能/生效一条焊接工艺数据(含工作模式、电流/电压模式及电流、电压等设定),该数据不会被保存。在不建立焊接过程的前提下调用后,对照焊机面板显示与上位机下发值是否一致,便于现场对表与联调(不能为虚拟机、须连接焊机等前提见下文代码注释)。

实现代码

以下依次为同文件中的 feedOnWirefeedBackWiredetectGasgetWelderStateexampleWeldingclearWelderAlarmenableArcData

// 需要在启用焊机后执行
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);

常用接口与类型

feedOnWirefeedBackWiredetectGasstartWeldingstopWeldinggetWelderStatusclearWelderAlarmenableArcData(用途说明见上文推荐步骤第 4 条;示例见上文代码块)、FeedOnWireCommandFeedBackWireCommand

场景十八:运行过程观测

适用情况 需要在程序中订阅焊接电流电压、弧焊状态、运动段完成等。

目标 异步回调或主动查询得到一致的状态快照;可按轨迹 id 与路点索引判断段结束。

推荐步骤

  1. setEventWatcher(Event.arcWeldState, callback, ec)设置焊机状态回调, 解析 EventInfoKey.ArcWeldState 各键。
  2. setEventWatcher(Event.moveExecution, ...) 或使用 queryEventInfo 轮询,结合业务定义的「段完成」条件(如轨迹 id + 路点索引)。
  3. 收弧是否完成可结合弧焊状态中的「是否仍在焊接」等字段判断(以工艺包与 SDK 键名为准)。

实现代码

以下依次为 printWeldStatesetArcWeldStateWatcherqueryWeldStateprintMoveStatesetMoveStateWatcher

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);

常用接口与类型

setEventWatcherqueryEventInfoEvent.arcWeldStateEvent.moveExecutionEventInfoKey.ArcWeldStateEventInfoKey.MoveExecution

注意事项

  1. 焊机状态回调的周期是500ms

场景十九:其它几何与工艺辅助(按需查阅)

适用情况 三点建用户参考、焊机支持模式查询、焊接中 Jog 偏置等;

目标 在程序中完成辅助几何计算或读取焊机能力列表。

推荐步骤

  1. 按业务调用 getRefBy3PointsgetWelderWorkModesweldOffsetJog 等;

实现代码

以下依次为 getRefBy3PointsExamplegetWelderWorkModesweldingJogOffsetExample

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);

常用接口与类型

getRefBy3PointsgetWelderWorkModesweldOffsetJog

与详细文档的对应关系

需求文档
接口列表与参数含义接口说明
类型与数据结构附录:类型附录:数据结构
方法签名与重载细节附录:方法
错误码与异常错误码和异常