Skip to main content

Arc Welding C# SDK Usage Examples

Document Conventions

Each section follows this structure:

  1. Applicable Scenarios — When this scenario applies
  2. Objective — The expected system state after completion
  3. Recommended Steps — Ordered operational highlights
  4. Common APIs and Types — For quick SDK symbol lookup; not a complete parameter reference
  5. Notes — Common pitfalls

General Programming Conventions

  1. Obtain an ArcWelding instance via robot.arcwelding() and call process-parameter and welder-related APIs on it; motion queues are still operated on robot.
  2. APIs use ErrorCode ec; most take out ec or ref ec as an output parameter. After every call, check ec.value and ec.message.
  3. Welding motions that rely on enqueue-then-start typically use MotionControlMode.NrtCommand together with moveAppend / 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).

  1. connectToRobot establishes the connection to the controller.

  2. Use getWelderStatus to 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).

  3. When already connected: use getWelderSetting to read the current protocol, manufacturer key mfr, model key model, current rating current_type, and so on.

  4. When replacing the welder or reconfiguring: call disconnectFromWelder first, then configure along the EtherCAT or analog branch below before calling connectToWelder again.

  5. EtherCAT welders: setIsEniHaveWeld must be true (equivalent to whether a physical welder is connected on the HMI). Upload the welder-specific ENI file in the HMI software. In setWelder (or WelderSetting), set protocol to the EtherCAT value (e.g. "ethercat", per SDK convention), mfr and model to the manufacturer key and model key in the table below, and current_type must be one of the entries in that model’s current_range (consistent with the process package). When the model also constrains wire_diameter, shielding_gas, program_number, dry_extension, firmware_version, etc., setWelder must supply those fields only from the allowed sets below.

    Manufacturer / model, current ranges (and optional constraints) (mfr and model strings 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]).

  1. Analog welders: complete the following three steps in order, then call setWelder:

    • ① IO binding: Call setIOSetting first 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 with getIOSetting.
    • ② Current / voltage curves: Use setCurrentCharacteristicCurveData, setVoltageCharacteristicCurveData (and when needed calculateCurrentCurve / calculateVoltageCurve) to define named curve data on the controller.
    • setWelder: Set protocol to analog (exact string per SDK / process package, e.g. "analog"); mfr must be "manual_welding" or "aotai" only; model follows the analog scheme’s convention; current_file and voltage_file are the current curve data name and voltage curve data name from step ②. Leave other fields at defaults or empty per API documentation.
  2. Call connectToWelder to connect to the welder and enable welding features; use disconnectFromWelder when 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

  1. Build ArcWeldRunningParam and set test_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 parameters ArcWeldRunningParam”).
  2. Call setRunningParam to download; use getRunningParam to read back and verify.
  3. The parameterless detectGas() overload uses a duration related to gas_detect_time in 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

  1. Pick the DI signal name used for anticollision (e.g. "DI0_0").
  2. Call setAnticollision(signal, enable, block, countdown): enable turns the feature on or off; block is the inhibit switch; countdown is the countdown timer (seconds; exact semantics follow the process package).
  3. For HMI or logic integration, call getAnticollisionState for the current state, or register setEventWatcher(Event.anticollisionState, callback, ec) and parse the EventInfoKey.AnticollisionState keys in the callback (see AnticollisionState in 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

  1. Build the appropriate structs (ArcOnData, ArcData, ArcOffData, WeaveData, SegData, …), set name, and fill process fields.
  2. Call setXxxData to write; getXxxData(name, ec) to read back and verify.
  3. Remove one record with removeXxxData(name); overloads accepting a list of names remove multiple items.
  4. For names already defined on the teach pendant: often get, adjust fields, then set to 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 / removeArcOnData setArcData / 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

  1. Call setWeldMode, switching among WeldMode.TestRun (dry run), WeldMode.Simu (simulation), and WeldMode.Real (real weld).
  2. Confirm with getWeldMode.
  3. 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)

Welding mode definitions

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

  1. Enable the welder first (Scenario 1).
  2. setMotionControlMode(NrtCommand, ec).
  3. Ensure the welder is configured and connectToWelder (as in Scenario 1).
  4. Build ArcOnCommand binding the downloaded arc-on and weld data names (often matching the teach pendant).
  5. Build weld segments: WMoveLCommand / WMoveCCommand, etc.
  6. Build ArcOffCommand with the arc-off data name.
  7. Call moveAppend multiple times with the same queue id in order; after power-on, moveStart runs the queue.
  8. For pause / resume, pair stop with another moveStart (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

  1. Maintain multiple named weld records upfront with setArcData (e.g. arcdata1, arcdata2).
  2. Straight: WMoveLCommand; arc: WMoveCCommand; set arc_set_opt on 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

  1. Use setWeaveData to store the weave process name (e.g. weavedata1).
  2. Instantiate WeaveOnCommand and WeaveOffCommand.
  3. Straight: After constructing WMoveLCommand, call setWeaveData("…", ec) or use a constructor overload that carries the weave index (per SDK).
  4. Arc: Construct WMoveCCommand and apply setWeaveData likewise; auxiliary and target poses and speeds must satisfy the robot and process constraints.
  5. Typical slice: ArcOnCommandWeaveOnCommand → one or more WMoveL / WMoveCWeaveOffCommandArcOffCommand.

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

  1. Motions that must weave belong between WeaveOnCommand and WeaveOffCommand; setting weave parameters only on WMoveLCommand / WMoveCCommand alone has no effect.
  2. Paths between WeaveOnCommand and WeaveOffCommand that omit weave parameters inherit the weave defined on WeaveOnCommand.

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

  1. setSegData stores the segmented-weld data name (e.g. segdata1).
  2. 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 SegOnSegOff interval are queued in the correct order, with arc_set_opt and offsets per site calibration on each WMoveL / WMoveC.

Recommended Steps

  1. Complete both setWeaveData and setSegData.
  2. Follow the segOnExample pattern: ArcOnCommandWeaveOnCommand → optional bridging WMoveL outside segmentation → SegOnCommand → multiple WMoveL / WMoveC inside the segmented window → SegOffCommand → following moves → WeaveOffCommandArcOffCommand.
  3. If segmented vs. continuous zones use different process data, set arc_set_opt on the corresponding commands separately.
  4. For arc segments, configure target/auxiliary offsets via the instruction’s offset / targetOffset fields 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

  1. Fill in all WMoveLPendulumCommand poses from process data and taught points (as in arcSetPendulumExample).
  2. Combine with ArcOnCommand / ArcOffCommand like ordinary weld motions, enqueue under non-real-time command mode, then moveStart.
  3. 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

  1. Download tracking parameters with setArcTrackParam by name (e.g. arctrackdata1).
  2. Pass the tracking data name in WMoveLCommand overloads that include the weave name; for circles, use the equivalent overload when available (see API appendix types).
  3. Typical queue: ArcOnCommandWeaveOnCommand → multiple tracked weld motions → WeaveOffCommandArcOffCommand.
  4. 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.

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

  1. For sensor networking, hand–eye calibration, device connection, etc., see Scenario 14 (LaserSensorCfg, setHandeyeData, connLaserSensorDev, …).
  2. Maintain search process names and process-package fields with setLaserSearchData.
  3. Build LaserSearchCommand (hand–eye name, search data name, search pose, speeds, …), then call executeLaserSearch; 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; LaserTrackOnCommandLaserTrackOffCommand spans share the queue with weld motions.

Recommended Steps (Configuration and Connection)

  1. Populate LaserSensorCfg, call setLaserSensorCfg; optionally setEventWatcher(Event.lasertrackState, …).
  2. connLaserSensorDev / disconnLaserSensorDev; when idle, removeLaserSensorCfg.
  3. Hand–eye: setHandeyeData / getHandeyeData; auto calibration: startHandeyeCalibrationcalibratePointcalibrateEnd.
  4. Tracking process name: setLaserTrackData (fields per process package).

Recommended Steps (Seam Tracking Queue)

  1. After connecting, openLaserTrack("sensor1", ec).
  2. Queue: ArcOnCommandLaserTrackOnCommandWMoveL / WMoveC, etc. → LaserTrackOffCommandArcOffCommand.
  3. closeLaserTrack, then disconnLaserSensorDev as 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

  1. Use setLayerData for each layer: name, offsets, auxiliary poses, and related fields.
  2. Use MpmlPathCheck on path point sets, motion-type lists, and layer lists; collect unreachable layer names.
  3. When useful, call GetLayerStartPoint for suggested arc-start pose.
  4. Before each layer trajectory insert OffsetOnCommand(layerName); terminate the layer with OffsetOffCommand.

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

  1. Build WMoveCFCommand with auxiliary and target poses as required by the process package.
  2. After optional setWeaveData, setSegData, or setArcTrackParam, bind names on commands or insert SegOnCommand sequences as needed.
  3. 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

  1. 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).
  2. Spot/rivet: startWelding / stopWelding; distinguish synergy vs separate modes (API docs).
  3. Status: getWelderStatus; alarms: clearWelderAlarm when recoverable.
  4. 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

  1. setEventWatcher(Event.arcWeldState, callback, ec) for welder state; parse EventInfoKey.ArcWeldState keys.
  2. setEventWatcher(Event.moveExecution, …) or poll queryEventInfo with application-defined “segment done” rules (e.g. motion id + waypoint index).
  3. 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

  1. 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

  1. 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

NeedDocument
API list and parameter meaningsAPI Description
Types and data structuresAppendix: Types, Appendix: Data Structures
Method signatures and overloadsAppendix: Methods
Error codes and exceptionsError Codes and Exceptions