Arc Welding C# SDK Usage Examples
Document Conventions
Each section follows this structure:
- Applicable Scenarios — When this scenario applies
- Objective — The expected system state after completion
- Recommended Steps — Ordered operational highlights
- Common APIs and Types — For quick SDK symbol lookup; not a complete parameter reference
- Notes — Common pitfalls
General Programming Conventions
- Obtain an
ArcWeldinginstance viarobot.arcwelding()and call process-parameter and welder-related APIs on it; motion queues are still operated onrobot. - APIs use
ErrorCode ec; most takeout ecorref ecas an output parameter. After every call, checkec.valueandec.message. - Welding motions that rely on enqueue-then-start typically use
MotionControlMode.NrtCommandtogether withmoveAppend/moveStart; distinguish these from scenarios that only download parameters without queueing motion.
Shared Prerequisites (Common to Sample Code in Each Scenario)
The following matches the SDK sample xCoreSDK-CSharp_examples_ArcWeldingDemo.cs (class 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}");
}
Scenario 1: Initial Robot and Welder Setup
Applicable Scenarios First-time arc welding on a new station, or after changing the welder / bus configuration, when you need to verify that the controller and welder side are ready.
Objective The robot is connected; the arc welding process package is available; welder model and communication parameters match the site; IO and ENI expectations are configured when required.
Recommended Steps
The relationship of key steps is shown below (aligned with the numbered walkthrough that follows).
-
connectToRobotestablishes the connection to the controller. -
Use
getWelderStatusto inspect the welder side: values such as"disabled"indicate no effective connection yet;"ok"and similar values mean ready (see the API documentation for the exact enumeration). -
When already connected: use
getWelderSettingto read the current protocol, manufacturer keymfr, model keymodel, current ratingcurrent_type, and so on. -
When replacing the welder or reconfiguring: call
disconnectFromWelderfirst, then configure along the EtherCAT or analog branch below before callingconnectToWelderagain. -
EtherCAT welders:
setIsEniHaveWeldmust betrue(equivalent to whether a physical welder is connected on the HMI). Upload the welder-specific ENI file in the HMI software. InsetWelder(orWelderSetting), setprotocolto the EtherCAT value (e.g."ethercat", per SDK convention),mfrandmodelto the manufacturer key and model key in the table below, andcurrent_typemust be one of the entries in that model’scurrent_range(consistent with the process package). When the model also constrainswire_diameter,shielding_gas,program_number,dry_extension,firmware_version, etc.,setWeldermust supply those fields only from the allowed sets below.Manufacturer / model, current ranges (and optional constraints) (
mfrandmodelstrings when downloading must match the keys exactly).
{
"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] }
}
}
Example (Riland Aotai RL/RPL, 500 A tier): mfr = "aotai", model = "RL/RPL", current_type = 500 (must be within [350,500,630,800]).
-
Analog welders: complete the following three steps in order, then call
setWelder:- ① IO binding: Call
setIOSettingfirst to bind arc start, wire feed, wire retract, gas check, current/voltage setpoint and feedback, welder ready, fault, and similar signals to the actual DI/DO or registers. Verify withgetIOSetting. - ② Current / voltage curves: Use
setCurrentCharacteristicCurveData,setVoltageCharacteristicCurveData(and when neededcalculateCurrentCurve/calculateVoltageCurve) to define named curve data on the controller. - ③
setWelder: Set protocol to analog (exact string per SDK / process package, e.g."analog");mfrmust be"manual_welding"or"aotai"only;modelfollows the analog scheme’s convention;current_fileandvoltage_fileare the current curve data name and voltage curve data name from step ②. Leave other fields at defaults or empty per API documentation.
- ① IO binding: Call
-
Call
connectToWelderto connect to the welder and enable welding features; usedisconnectFromWelderwhen debugging ends or before swapping welders.
Sample Code
Analog welder setup is illustrated in the same sample file via setIOSetting and 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);
Common APIs and Types
getWelderStatus, getWelderSetting, setWelder, WelderSetting, connectToWelder, disconnectFromWelder, isEniHaveWeld, setIsEniHaveWeld, setIOSetting, getIOSetting, IOSetting, IOData, setCurrentCharacteristicCurveData, setVoltageCharacteristicCurveData, getCurrentCharacteristicCurveData, getVoltageCharacteristicCurveData, calculateCurrentCurve, calculateVoltageCurve
Notes
When changing welder settings while arc welding is connected, switch welders only after disconnecting the welder first.
Scenario 2: Welding Runtime Parameters
Applicable Scenarios You need consistent global weld-run options tied to the process—not single named arc-start / weld records—such as test-run Cartesian speed, manual wire feed / retract speed, and gas check duration.
Objective ArcWeldRunningParam is written to the controller so test-run, wire feeding/retraction, parameterless gas check, etc. match site practice.
Recommended Steps
- Build
ArcWeldRunningParamand settest_run_speed(mm/s),wire_feed_speed(m/min),gas_detect_time(s), etc., within process-package limits (field meanings and ranges: Appendix: Data Structures, section “Running parametersArcWeldRunningParam”). - Call
setRunningParamto download; usegetRunningParamto read back and verify. - The parameterless
detectGas()overload uses a duration related togas_detect_timein the running params; overloads that take time and enable follow the arguments you pass (API Description).
Sample Code
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);
Common APIs and Types
setRunningParam, getRunningParam, ArcWeldRunningParam, detectGas
Notes
Manual wire feed/retract speed depends on whether the welder supports configuring that capability.
Scenario 3: Anti-Collision (Torch Collision Detection)
Applicable Scenarios The station uses torch touch / anticollision DIs that must be configured in software (signal name, enable, inhibit, countdown) while the IPC or PLC logic subscribes to anticollision status.
Objective Anticollision parameters are downloaded; signal, enable, block, countdown, etc., can be read consistently with the HMI or interlocks via query or callbacks.
Recommended Steps
- Pick the DI signal name used for anticollision (e.g.
"DI0_0"). - Call
setAnticollision(signal, enable, block, countdown):enableturns the feature on or off;blockis the inhibit switch;countdownis the countdown timer (seconds; exact semantics follow the process package). - For HMI or logic integration, call
getAnticollisionStatefor the current state, or registersetEventWatcher(Event.anticollisionState, callback, ec)and parse theEventInfoKey.AnticollisionStatekeys in the callback (seeAnticollisionStatein Appendix: Data Structures).
Sample Code
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}");
Common APIs and Types
setAnticollision, getAnticollisionState, Event.anticollisionState, EventInfoKey.AnticollisionState, setEventWatcher
Notes
Ensure the bound DI signal is not already used by another system function.
Scenario 4: Maintain Named Process Data in Application
Applicable Scenarios You want the IPC or an offline tool to download or edit named process data for arc start, weld, arc end, weaving, segmented welding, etc., keeping names aligned with existing parameters on the teach pendant HMI.
Objective The controller retains a set of reusable parameter names referenced later by commands such as ArcOnCommand or teach-program blocks.
Recommended Steps
- Build the appropriate structs (
ArcOnData,ArcData,ArcOffData,WeaveData,SegData, …), setname, and fill process fields. - Call
setXxxDatato write;getXxxData(name, ec)to read back and verify. - Remove one record with
removeXxxData(name); overloads accepting a list of names remove multiple items. - For names already defined on the teach pendant: often
get, adjust fields, thensetto overwrite or tweak.
Sample Code
The snippets below excerpt SetArcOnDataExample (arc on), SetArcDataExample (weld), SetArcOffDataExample (arc off), SetWeaveDataExample (weave), and SetSegDataExample (segmented weld). Code bodies come from matching methods on ArcWeldingDemo; printing uses local Action delegates inside each method (e.g. 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);
Common APIs and Types
Named process-data APIs grouped by set / get / remove follow (signatures and overloads: API Description, Appendix: Methods).
-
Arc on / Weld / Arc off / Weave / Segmented weld
setArcOnData/getArcOnData/removeArcOnDatasetArcData/getArcData/removeArcData,enableArcData
setArcOffData/getArcOffData/removeArcOffData
setWeaveData/getWeaveData/removeWeaveData
setSegData/getSegData/removeSegData
setWeaveAdaptiveData/getWeaveAdaptiveData -
Multi-pass / multi-layer
setLayerData/getLayerData/removeLayerData
setLayerCout,MpmlPathCheck,GetLayerStartPoint -
Laser tracking / laser search (named parameters)
setLaserTrackData/getLaserTrackData/removeLaserTrackData
setLaserSearchData/getLaserSearchData/removeLaserSearchData -
Arc sensing / arc tracking (named parameters)
setArcTrackParam/getArcTrackParam/removeArcTrackParam -
Current / voltage characteristic curves (named curve data)
setCurrentCharacteristicCurveData/getCurrentCharacteristicCurveData
setVoltageCharacteristicCurveData/getVoltageCharacteristicCurveData
calculateCurrentCurve,calculateVoltageCurve(compute only; does not persist)
Notes
Reading a missing name may return an agreed error code (e.g. -272); handle it in application logic.
Scenario 5: Welding Mode Selection and Manual / Auto Behavior
Applicable Scenarios You need test-run path verification, simulation timing and weave, or real welding with arc, and to understand differences under teach pendant manual step, manual continuous, and automatic modes (arc on/off, speed slider, segmented weld, weave, arc tracking, etc.).
Objective The active weld mode matches the production stage (debug → simulation → real weld).
Recommended Steps
- Call
setWeldMode, switching amongWeldMode.TestRun(dry run),WeldMode.Simu(simulation), andWeldMode.Real(real weld). - Confirm with
getWeldMode. - Cross-check behavior with teach pendant execution mode against the illustration below (consistent with process package docs).
Sample Code
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()}");
Welding Mode vs. Run Mode (Illustration)

Common APIs and Types
setWeldMode, getWeldMode, WeldMode
Notes
Scenario 6: Typical Seam — Arc On → Linear/Arc Weld → Arc Off
Applicable Scenarios Typical straight or arc seams: under non-real-time command mode, enqueue ordinary motions and arc-welding process commands in order into one queue and start.
Objective The robot runs in order: approach (optional) → arc-on and weld parameters active → welded path with or without weave → arc off.
Recommended Steps
- Enable the welder first (Scenario 1).
setMotionControlMode(NrtCommand, ec).- Ensure the welder is configured and
connectToWelder(as in Scenario 1). - Build
ArcOnCommandbinding the downloaded arc-on and weld data names (often matching the teach pendant). - Build weld segments:
WMoveLCommand/WMoveCCommand, etc. - Build
ArcOffCommandwith the arc-off data name. - Call
moveAppendmultiple times with the same queue id in order; after power-on,moveStartruns the queue. - For pause / resume, pair
stopwith anothermoveStart(see motion control documentation).
Sample Code
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);
Common APIs and Types
ArcOnCommand, ArcOffCommand, WMoveLCommand, WMoveCCommand, moveAppend, moveStart, MoveLCommand
Notes
Adapt poses, speeds, and Conf for your robot model.
moveStart() is non-blocking; avoid exiting the application immediately afterward.
Ordinary MoveCommand motions are required before arcon and after the segment leading to arcoff; between them you must use WMoveCommand weld motions.
When calling moveAppend(arcon, id, ec), ensure the arc-on and weld data referenced by arcon are already stored on the controller. Do not call setArcOnData on the preceding line or too close nearby, or controller latency may cause the append to fail.
For flying arc start (ArcOnData pre-arc lead time ≠ 0), insert a MoveLCommand before arcon.
Scenario 7: Change Process Parameters During Welding with arc_set_opt (ArcSet)
Applicable Scenarios After arc start on a seam, one straight or circular segment needs a different arcdata set without dropping the arc or splitting the program.
Objective On queued weld motions (WMoveLCommand / WMoveCCommand, …), select the weld data name after the switch via arc_set_opt.
Recommended Steps
- Maintain multiple named weld records upfront with
setArcData(e.g.arcdata1,arcdata2). - Straight:
WMoveLCommand; arc:WMoveCCommand; setarc_set_opton the command fields.
Sample Code
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);
Common APIs and Types
WMoveLCommand.arc_set_opt, WMoveCCommand.arc_set_opt, setArcData
Scenario 8: Linear / Arc Weaving Welding
Applicable Scenarios Fillet or vertical joints need weave (superimposed oscillation) on straight or circular segments; amplitude, frequency, etc. come from the weave data name in the process package.
Objective Weave data is downloaded and tied to weld moves; WeaveOnCommand / WeaveOffCommand can wrap multiple segments.
Recommended Steps
- Use
setWeaveDatato store the weave process name (e.g.weavedata1). - Instantiate
WeaveOnCommandandWeaveOffCommand. - Straight: After constructing
WMoveLCommand, callsetWeaveData("…", ec)or use a constructor overload that carries the weave index (per SDK). - Arc: Construct
WMoveCCommandand applysetWeaveDatalikewise; auxiliary and target poses and speeds must satisfy the robot and process constraints. - Typical slice:
ArcOnCommand→WeaveOnCommand→ one or moreWMoveL/WMoveC→WeaveOffCommand→ArcOffCommand.
Sample Code
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);
Common APIs and Types
setWeaveData, WMoveLCommand, WMoveCCommand, WeaveOnCommand, WeaveOffCommand
Notes
- Motions that must weave belong between
WeaveOnCommandandWeaveOffCommand; setting weave parameters only onWMoveLCommand/WMoveCCommandalone has no effect. - Paths between
WeaveOnCommandandWeaveOffCommandthat omit weave parameters inherit the weave defined onWeaveOnCommand.
Scenario 9: Linear / Arc Segmented Welding
Applicable Scenarios Only part of the path needs a weld–pause–weld rhythm; weaving is not required, or other segments handle weave separately.
Objective Between SegOnCommand and SegOffCommand, WMoveL / WMoveC follow SegData segmented timing; outside that window motion is continuous weld or ordinary weld motion.
Recommended Steps
setSegDatastores the segmented-weld data name (e.g.segdata1).- Queue:
ArcOnCommand→ (optional non-weld jog or continuous segment) →SegOnCommand("segdata1")→ one or more line/arc weld moves →SegOffCommand→ further continuous weld or arc off.
Sample Code
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);
Common APIs and Types
setSegData, SegOnCommand, SegOffCommand, WMoveLCommand, WMoveCCommand
Scenario 10: Linear / Arc Segmented Welding with Weaving
Applicable Scenarios Segmented weld rhythm and weave apply together over the same arcing interval.
Objective The WeaveOn envelope and the SegOn–SegOff interval are queued in the correct order, with arc_set_opt and offsets per site calibration on each WMoveL / WMoveC.
Recommended Steps
- Complete both
setWeaveDataandsetSegData. - Follow the
segOnExamplepattern:ArcOnCommand→WeaveOnCommand→ optional bridgingWMoveLoutside segmentation →SegOnCommand→ multipleWMoveL/WMoveCinside the segmented window →SegOffCommand→ following moves →WeaveOffCommand→ArcOffCommand. - If segmented vs. continuous zones use different process data, set
arc_set_opton the corresponding commands separately. - For arc segments, configure target/auxiliary offsets via the instruction’s
offset/targetOffsetfields as in the example (see SDK API appendix types).
Sample Code
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);
Common APIs and Types
Use the API types listed under Scenario 8 and Scenario 9 together.
Notes
Wrong ordering can leave weave or segmentation ineffective; validate in simulation or test-run before live welding.
Scenario 11: Pendulum Path Welding
Applicable Scenarios The seam geometry is defined by the process as a pendulum path using the dedicated pendulum motion command.
Objective Correctly set start, auxiliary, target poses, speeds, etc. on WMoveLPendulumCommand; assign arc_set_opt when switching weld data sets.
Recommended Steps
- Fill in all
WMoveLPendulumCommandposes from process data and taught points (as inarcSetPendulumExample). - Combine with
ArcOnCommand/ArcOffCommandlike ordinary weld motions, enqueue under non-real-time command mode, thenmoveStart. - If conventional weave welding exists in the same program, distinguish it from Scenario 8: pendulum is an independent motion type; do not usually wrap the same pendulum segment with
WeaveOn(follow process package docs).
Sample Code
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);
Common APIs and Types
WMoveLPendulumCommand, ArcSetOpt (arc_set_opt member)
Scenario 12: Arc Tracking
Applicable Scenarios During welding, arc sensing adjusts lateral or height direction tracking.
Objective Selected path segments use a given ArcTrackParam; segments without a tracking name do not track.
Recommended Steps
- Download tracking parameters with
setArcTrackParamby name (e.g.arctrackdata1). - Pass the tracking data name in
WMoveLCommandoverloads that include the weave name; for circles, use the equivalent overload when available (see API appendix types). - Typical queue:
ArcOnCommand→WeaveOnCommand→ multiple tracked weld motions →WeaveOffCommand→ArcOffCommand. - Wait for motion to finish and confirm arc-off completion (combine with Scenario 18 event subscription if useful).
Sample Code
//设置电弧跟踪参数
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);
Common APIs and Types
setArcTrackParam, getArcTrackParam, WMoveLCommand overloads that take tracking parameters, ArcOnCommand, WeaveOnCommand, WeaveOffCommand, ArcOffCommand
Notes
Tracking quality depends on the welder, wire, current waveform, and robot model; re-teach poses on your machine. Arc tracking must be used with weave enabled.
Scenario 13: Laser Search
Applicable Scenarios Before or during the main weld program, laser measurement is needed to obtain pose corrections for the seam or feature points.
Objective LaserSearchData is downloaded; executeLaserSearch returns within the agreed timeout; hand–eye data names match those referenced in commands.
Recommended Steps
- For sensor networking, hand–eye calibration, device connection, etc., see Scenario 14 (
LaserSensorCfg,setHandeyeData,connLaserSensorDev, …). - Maintain search process names and process-package fields with
setLaserSearchData. - Build
LaserSearchCommand(hand–eye name, search data name, search pose, speeds, …), then callexecuteLaserSearch; the application must handle sync/async, timeout, and thread safety.
Sample Code
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);
Common APIs and Types
setLaserSearchData, LaserSearchCommand, executeLaserSearch, HandeyeData (referenced by name in commands)
Scenario 14: Laser Tracking — Sensor Setup, Connection, and Queue Usage
Applicable Scenarios Maintain laser IP, cycle, and type on the IPC; connect the device; seam tracking.
Objective The device connects and can be monitored; LaserTrackOnCommand–LaserTrackOffCommand spans share the queue with weld motions.
Recommended Steps (Configuration and Connection)
- Populate
LaserSensorCfg, callsetLaserSensorCfg; optionallysetEventWatcher(Event.lasertrackState, …). connLaserSensorDev/disconnLaserSensorDev; when idle,removeLaserSensorCfg.- Hand–eye:
setHandeyeData/getHandeyeData; auto calibration:startHandeyeCalibration→calibratePoint→calibrateEnd. - Tracking process name:
setLaserTrackData(fields per process package).
Recommended Steps (Seam Tracking Queue)
- After connecting,
openLaserTrack("sensor1", ec). - Queue:
ArcOnCommand→LaserTrackOnCommand→WMoveL/WMoveC, etc. →LaserTrackOffCommand→ArcOffCommand. closeLaserTrack, thendisconnLaserSensorDevas required.
Sample Code
The snippets below come from the same demo file as printLaserSensorState, setLaserSensorStateWatcher (callback registration for configuration), LaserSensorSettingExample, and LaserTrackCommandExample, reusing shared helpers such as printErrorCode and waitForFinish where applicable.
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] + "}
Common APIs and Types
LaserSensorCfg, setLaserSensorCfg, connLaserSensorDev, openLaserTrack, closeLaserTrack, setLaserTrackData, LaserTrackOnCommand, LaserTrackOffCommand, GetLaserPos
Notes
Scenario 15: Multi-Pass Layers and Layer Offsets
Applicable Scenarios Multiple beads stack on one joint cross-section, or layer start poses/orientations shift via LayerData.
Objective Layer parameters are downloaded; optionally run reachability checks first, then wrap each layer’s motion using OffsetOnCommand / OffsetOffCommand in the download queue.
Recommended Steps
- Use
setLayerDatafor each layer: name, offsets, auxiliary poses, and related fields. - Use
MpmlPathCheckon path point sets, motion-type lists, and layer lists; collect unreachable layer names. - When useful, call
GetLayerStartPointfor suggested arc-start pose. - Before each layer trajectory insert
OffsetOnCommand(layerName); terminate the layer withOffsetOffCommand.
Sample Code
//设置多层多道偏移参数
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);
Common APIs and Types
setLayerData, getLayerData, removeLayerData, LayerData, MpmlPathCheck, GetLayerStartPoint, OffsetOnCommand, OffsetOffCommand
Scenario 16: Full Circle and Complex Curves (Weave / Seg / Tracking Optional)
Applicable Scenarios Seam is a full circle or MoveCF-style curve, optionally with weave, segmented welding, or arc tracking.
Objective Combine WMoveCFCommand with process commands; choose sequencing among commented patterns validated with the process stack.
Recommended Steps
- Build
WMoveCFCommandwith auxiliary and target poses as required by the process package. - After optional
setWeaveData,setSegData, orsetArcTrackParam, bind names on commands or insertSegOnCommandsequences as needed. - Verify trajectory and orientation in simulation or test-run before real welding.
Sample Code
// 点位机型 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);// 继续
Common APIs and Types
WMoveCFCommand, MoveCFCommandRotType (rotType member)
Scenario 17: Field Auxiliary Actions and Welder Status
Applicable Scenarios Torch alignment, wire feed / retract / gas check before arc start, brief spot/rivet weld bursts, reading live weld measurements or clearing alarms, and—with no full weld program yet—using enableArcData so work mode plus current/voltage mode and targets are applied at the welder for cross-checking against the IPC panel.
Objective Maintenance actions finish without full weld motions; welder state appears on HMI panels.
Recommended Steps
- Wire feed/retract/gas check: call
feedOnWire,feedBackWire,detectGas; dwell times must satisfy process minimum thresholds (e.g. greater than 0.1 s); stop actions use overload enable bits (appendix methods). - Spot/rivet:
startWelding/stopWelding; distinguish synergy vs separate modes (API docs). - Status:
getWelderStatus; alarms:clearWelderAlarmwhen recoverable. enableArcData: Applies/actuates weld process data at the welder (mode, current/voltage mode, setpoints, …) without persisting it as a recipe. Useful to compare panel display vs. IPC before a real weld (not on virtual hardware; connected welder required—see code comments).
Sample Code
The blocks below excerpt feedOnWire, feedBackWire, detectGas, getWelderState, exampleWelding, clearWelderAlarm, enableArcData from the same file.
// 需要在启用焊机后执行
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);
Common APIs and Types
feedOnWire, feedBackWire, detectGas, startWelding, stopWelding, getWelderStatus, clearWelderAlarm, enableArcData (purpose per Recommended Step 4 above; snippets in preceding blocks), FeedOnWireCommand, FeedBackWireCommand
Scenario 18: Runtime Monitoring
Applicable Scenarios Subscribe in software to weld current/voltage, arc-welding state, segment completion, etc.
Objective Async callbacks or explicit queries produce consistent state snapshots; segment end can be judged from motion id and waypoint index.
Recommended Steps
setEventWatcher(Event.arcWeldState, callback, ec)for welder state; parseEventInfoKey.ArcWeldStatekeys.setEventWatcher(Event.moveExecution, …)or pollqueryEventInfowith application-defined “segment done” rules (e.g. motion id + waypoint index).- Arc-off completion can be inferred from fields such as “still welding” in arc state (per process package / SDK key names).
Sample Code
Excerpts: 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);
Common APIs and Types
setEventWatcher, queryEventInfo, Event.arcWeldState, Event.moveExecution, EventInfoKey.ArcWeldState, EventInfoKey.MoveExecution
Notes
- Welder status callbacks run on a 500 ms cadence.
Scenario 19: Other Geometry and Process Helpers (As Needed)
Applicable Scenarios Build a user frame from three points, query welder-capable modes, welding jog offsets, etc.
Objective Perform helper geometry in code or read welder capability lists.
Recommended Steps
- Call
getRefBy3Points,getWelderWorkModes,weldOffsetJog, etc., as needed.
Sample Code
Excerpts: 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);
Common APIs and Types
getRefBy3Points, getWelderWorkModes, weldOffsetJog
Related Documentation
| Need | Document |
|---|---|
| API list and parameter meanings | API Description |
| Types and data structures | Appendix: Types, Appendix: Data Structures |
| Method signatures and overloads | Appendix: Methods |
| Error codes and exceptions | Error Codes and Exceptions |