/**
 * @file arcwelding.h
 * @brief 弧焊接口
 * @copyright Copyright (C) 2024 ROKAE (Beijing) Technology Co., LTD. All Rights Reserved.
 * Information in this file is the intellectual property of Rokae Technology Co., Ltd,
 * And may contains trade secrets that must be stored and viewed confidentially.
 */
#ifndef ROKAEAPI_ARCWELDING_H_
#define ROKAEAPI_ARCWELDING_H_

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
#pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <tuple>
#include "base.h"
#include "data_types.h"

namespace rokae
{

#if defined(XCORESDK_SUPPRESS_DLL_WARNING)
#pragma warning(push)
#pragma warning(disable : 4251)
#endif

 // forward declarations
 class XService;
 class XCORE_API ArcWelding : public Base<ArcWelding>
 {
  public:
   /// @cond DO_NOT_DOCUMENT
   /**
    * @brief ArcWelding constructor
    * @throw ExecutionException 焊接工艺包未授权
    */
   explicit ArcWelding(std::shared_ptr<XService> rpc);
   virtual ~ArcWelding();

   /// @endcond

   /// @brief 焊接模式
   enum WeldMode
   {
     TestRun, ///< 空运行
     Simu,    ///< 仿真
     Real     ///< 实焊
   };

   /// @brief 再起弧参数
   struct ReArcOnParam
   {
     bool enable{false};              ///< 是否再起弧
     int retry_time{3};               ///< 起弧次数。范围：[1 - 20]
     int wire_retract_delay_time{50}; ///< 再起弧退丝等待时间。单位：ms，范围：[0 - 10000] ms
     int wire_retract_time{200};      ///< 再起弧退丝时间。单位：ms，范围：[0 - 10000] ms
     double current_step{0};          ///< 再起弧电流增量。单位：电流下为 A，范围：[0 - 50] A
     double voltage_step{0};          ///< 再起弧电压增量。单位：分别下为 V，一元化下为 %，范围：[0 - 10] V，[0 - 10] %
   };

   /// @brief 刮擦起弧参数
   struct ScratchArconParam
   {
     bool enable{false}; ///< 是否刮擦起弧
     int distance{20};   ///< 刮擦距离。单位：mm，范围：[0 - 500] mm
     int back_speed{50}; ///< 返回速度，单位：mm/s，范围(0 - 7000] mm/s
     int step{5};        ///< 刮擦步长，单位：mm，范围：[0 - 500] mm
   };

   /// @brief 起弧参数
   struct ArcOnData {
     std::string name{"default"};///< 文件号名
     std::string annotation;     ///< 注释
     std::string mode{"flat_characteristic"};///< 焊机工作模式。平特性："flat_characteristic"，低飞溅："low_spatter"，脉冲： "pulse"，双脉冲："double_pulse"，直流点焊："dc_spot_welding"，
                                             ///< 脉冲点焊："pulsed_spot_welding"，大熔深："deep_penetration"，快速脉冲："fast_pulse", 低飞溅点焊："low_spatter_spot_welding", ASMT："asmt",
                                             ///< ASMT点焊："asmt_spot_welding", 调用："job", 面板控制："panel_control", 高速焊："high_speed_welding", 聚能焊："constrict_arc", 根焊："root_pass"
     std::string current_mode{"current"};    ///< 电流模式。电流："current"，送丝速度："wire_feed"
     std::string voltage_mode{"unified"};    ///< 电压模式。分别："separate"，一元化："unified"
     double current{0};                      ///< 起弧电流. 单位：电流下为 A，送丝速度下为 mm/s，范围[0 - 2000]
     double voltage{0};                      ///< 起弧电压。单位：分别下为 V，范围[0, 100]，一元化下为 V 或者 %，范围[-30, 30]
     int hold_time{200};                     ///< 起弧保持时间。单位：ms，范围：[0 - 10000] ms
     int detect_time{2000};                  ///< 起弧检测时间。单位：ms，范围：[0 - 10000] ms
     int confirm_time{200};                  ///< 起弧确认时间。单位：ms，范围：[0 - 10000] ms
     int preflow_time{200};                  ///< 提前送气时间。单位：ms，范围：[1 - 10000] ms
     int prearc_time{0};                     ///< 提前起弧时间。单位：ms，范围: [0, +∞] ms
     double slow_wire_feed_speed{1};         ///< 慢送丝速度。单位：m/min，范围：[1 - 21] m/min
     int pre_wirefeed_time{200};             ///< 提前送丝时间。单位：ms, 范围：[0, 10000] ms
     int ramp_time{200};                     ///< 渐变时间。单位：ms，范围：[1 - 10000] ms
     ReArcOnParam re_arcon;                  ///< 再起弧参数
     ScratchArconParam scratch_arcon;        ///< 刮擦起弧参数
   };

   /// @brief 断弧和再起弧参数
   struct ArcBreakParam
   {
     int detect_time{200};                             ///< 断弧检测时间。单位：ms，范围：[0 - 10000] ms
     std::string arc_break_option{"stop_and_alarm"};   ///< 断弧选项。停机并告警："stop_and_alarm"，自动再起弧："auto_arc_reignition"
     int restart_back_distance{10};                    ///< 再启动回退距离。单位：mm，范围：[0 - 100] mm
   };

   /// @brief 焊接参数
   struct ArcData {
     std::string name{"default"};            ///< 文件号名
     std::string annotation;                 ///< 文件号注释
     std::string mode{"flat_characteristic"};///< 焊机工作模式。平特性："flat_characteristic"，低飞溅："low_spatter"，脉冲： "pulse"，双脉冲："double_pulse"，直流点焊："dc_spot_welding"，
                                             ///< 脉冲点焊："pulsed_spot_welding"，大熔深："deep_penetration"，快速脉冲："fast_pulse", 低飞溅点焊："low_spatter_spot_welding", ASMT："asmt",
                                             ///< ASMT点焊："asmt_spot_welding", 调用："job", 面板控制："panel_control", 高速焊："high_speed_welding", 聚能焊："constrict_arc", 根焊："root_pass"
     std::string current_mode{"current"};    ///< 电流模式。电流："current"，送丝速度："wire_feed"
     std::string voltage_mode{"unified"};    ///< 电压模式。分别："separate"，一元化："unified"
     double current{0};                      ///< 起弧电流. 单位：电流下为 A，送丝速度下为 mm/s。范围[0, 2000]
     double voltage{0};                      ///< 起弧电压。单位：分别下为 V, 范围[0, 100]，一元化下为 V 或者 %，范围[-30, 30]
     double weld_speed{10};                  ///< 焊接速度.单位：mm/s, 范围(0, 10000]
     int ramp_time{200};                     ///< 渐变时间。单位：ms，范围：[1 - 10000] ms
     ArcBreakParam arc_break_param;          ///< 断弧和再起弧参数
   };

   /// @brief 防粘丝参数
   struct AntiWireStickParam
   {
     bool enable{false}; ///< 防粘丝开关
     double current{30}; ///< 防粘丝电流。单位：A，范围：[0 - 100] A
     double voltage{10}; ///< 防粘丝电压。一元化：单位：%，范围：[0 - 50] %；分别：单位：V，范围：[0 - 20] V
     int time{500};      ///< 防粘丝时间。单位：ms，范围：[0 - 10000] ms
   };

   /// @brief 收弧参数
   struct ArcOffData {
     std::string name{"default"};             ///< 文件号名
     std::string annotation;                  ///< 文件号注释
     std::string mode{"flat_characteristic"}; ///< 焊机工作模式。平特性："flat_characteristic"，低飞溅："low_spatter"，脉冲： "pulse"，双脉冲："double_pulse"，直流点焊："dc_spot_welding"，
                                              ///< 脉冲点焊："pulsed_spot_welding"，大熔深："deep_penetration"，快速脉冲："fast_pulse", 低飞溅点焊："low_spatter_spot_welding", ASMT："asmt",
                                              ///< ASMT点焊："asmt_spot_welding", 调用："job", 面板控制："panel_control", 高速焊："high_speed_welding", 聚能焊："constrict_arc", 根焊："root_pass"
     std::string current_mode{"current"};     ///< 电流模式。电流："current"，送丝速度："wire_feed"
     std::string voltage_mode{"unified"};     ///< 电压模式。分别："separate"，一元化："unified"
     double current{0};                       ///< 起弧电流. 单位：电流下为 A，送丝速度下为 mm/s。范围[0, 2000]
     double voltage{0};                       ///< 起弧电压。单位：分别下为 V, 范围[0, 100]，一元化下为 V 或者 %。范围[-30, 30]
     int hold_time{500};                      ///< 收弧保持时间。单位：ms，范围：[0 - 10000] ms
     int delay_gasoff_time{200};              ///< 滞后关气时间。单位：ms，范围：[0 - 10000] ms
     int detect_time{5000};                   ///< 收弧检测时间。单位：ms，范围：[0 - 10000] ms
     int retract_time{100};                   ///< 收弧退丝时间。单位：ms，范围：[0 - 10000] ms
     int wire_stick_detection_time{500};      ///< 粘丝检测时间。单位：ms，范围：[0 - 10000] ms
     AntiWireStickParam anti_wire_stick_param;///< 防粘丝参数
   };

   /// @brief 摆动幅度。暂不支持左右幅度分别设置，取左幅度数值
   struct Amplitude
   {
     double left{0.1};  ///< 左幅度。单位：mm，范围：[ 0.1, 50 ]
     double right{0.1}; ///< 右幅度。单位：mm，范围：[ 0.1, 50 ]
   };

   /// @brief 仰角。暂不支持设置
   struct ElevationAngle
   {
     double left{0};  ///< 左仰角。单位：°，范围：[ -90, 90 ]
     double right{0}; ///< 右仰角。单位：°，范围：[ -90, 90 ]
   };

   /// @brief 摆弧参数
   struct WeaveData
   {
     std::string name{"default"};             ///< 文件号名
     std::string annotation;                  ///< 文件号注释
     std::string weaving_reference{"cycle"};  ///< 摆弧基准（只支持基于周期的摆动）。长度："length"，周期："cycle"。
     std::string pattern{"triangular"};       ///< 摆弧形状（只支持三角摆、正弦摆和圆弧摆）。三角："triangular"，正弦："sine"，圆弧："circular"，8字："figure_8"。
     double weave_length_frequency{0.1};      ///< 摆弧长度、频率（与摆弧基准匹配）。长度：单位：mm，范围：[ 1, 500 ]；频率：单位：Hz，范围：[ 0.1, 5 ]
     Amplitude amplitude;                     ///< 摆弧幅度。摆动频率乘左右振幅需小于50。
     std::string dwell_type{"robot_stay"};    ///< 等待类型（三角摆和正弦摆有效，圆弧摆需要设为摆动停止）。机器人等待："robot_stay"，摆动停止："weave_stop"。
     int dwell_time[3]{0, 0, 0};              ///< 等待时间（左、中、右）。单位：ms。
     double radius { 0.1 };                   ///< 摆弧半径（圆弧、8字生效）。单位：ms，范围：[ 0.1, 100 ]
     bool phase_invert{false};                ///< 波形反向（暂不支持，默认正向）。反向：true；正向：false。
     std::string elevation_type{"v_pattern"}; ///< 仰角类型（三角摆和正弦摆生效，当前只支持v型）。v型："v_pattern"，三角："triangular"。
     ElevationAngle elevation_angle;          ///< 仰角。当仰角类型为“ V 型” 时，角度设置为 0，机器人在单平面动；当仰角类型为” 三角“ 时，两个角度之和不能为 0、180、-180。
     double inclination_angle{0};             ///< 倾斜角（三角摆和正弦摆生效）。单位：°，范围：[-90, 90]。
     double acc{0.5};                         ///< 摆动加速度。单位：mm/s^2，范围：(0, 5)，开区间
     double jerk{5};                          ///< 摆动加加速度。单位：mm/s^3，范围：(0, 50]
   };

   /// @brief 摆弧自适应参数
   struct WeaveAdaptiveData
   {
        bool isAdaptive{ false };               ///< 是否自适应。true: 是，false: 否。
        double groove_width_standard{ 4.00 };   ///< 标准坡口宽度。单位：mm。
        double groove_width_ratio{ 4.00 };      ///< 坡口宽度比例。
        double max_groove_width{ 6.00 };        ///< 最大坡口宽度。单位：mm。
        double max_electric{ 300.0 };           ///< 最大电流。单位：A。
        double max_speed{ 8.00 };               ///< 最大速度。单位：mm/s。
   };

   /// @brief 间断焊参数
   struct SegData
   {
     std::string name{"default"};        ///< 文件号名
     std::string annotation;             ///< 文件号注释
     std::string seg_type{"normal"};     ///< 间断焊类型。普通："normal"
     std::string non_welded_speed{"v5"}; ///< 非焊接段速度，xCore预定义的v5、v10...
     double welded_distance{0.1};        ///< 焊接段长度。单位：mm，范围：大于0.1
     double non_welded_distance{0.1};    ///< 非焊接段长度。单位：mm，范围：大于0.1
   };

   /// @brief 激光跟踪参数
   struct LaserTrackData
   {
     std::string name{"default"}; ///< 文件号名
     int job_number{0};           ///< 跟踪器工艺编号。范围：[0,63]
     bool y_comp{false};          ///< Y方向补偿开关
     bool z_comp{false};          ///< Z方向补偿开关
     double max_invalid_length { 10 }; ///< 最大无效焊缝停止距离, 单位mm, 范围(0, 50]
   };

   /// @brief 激光寻位参数
   struct LaserSearchData
   {
     std::string name{"default"};            ///< 文件号名
     int job_number{0};                      ///< 激光寻位工艺编号。范围：[0,63]
     std::string search_type{"point"};       ///< 寻位类型。点寻位："point"
     std::string search_mode{"continuous"};  ///< 寻位模式。连续："continuous" | 静态寻位 "static" | 步进："step"。（当前支持连续和静态寻位）
     double step_length{2.0};                ///< 步进距离。单位：mm
     std::string joint_type{"corner_joint"}; ///< 焊缝类型。角接："corner_joint" ，搭接："lap_joint"，对接："butt_joint"
   };

   /// @brief IO端口
   struct IOData
   {
     std::string name{""}; ///< 名称。DI0，DO1， AO2，AI3...或寄存器名
     int type{0};          ///< 类型。0：未设置；1：DI；2：DO；3：AO；4：AI；5：寄存器
     int bias{0};          ///< 偏差。类型为寄存器的时候有效
     bool enable{false};   ///< 是否启用
   };

   /// @brief IO设置
   struct IOSetting
   {
     IOData arc_on;               ///< 起弧端口
     IOData wire_feed;            ///< 送丝
     IOData wire_feed_back;       ///< 回抽丝
     IOData gas_test;             ///< 气体检测
     IOData positioning_enable;   ///< 寻位使能信号
     IOData arc_on_success;       ///< 引弧成功判断
     IOData positioning_feedback; ///< 寻位反馈信号
     IOData current_set;          ///< 电流指定
     IOData voltage_set;          ///< 电压/弧长校正给定
     IOData current_get;          ///< 电流获取
     IOData voltage_get;          ///< 电压获取
     IOData robot_ready;          ///< 机器人准备好
     IOData error;                ///< 报警
   };

   /// @brief 特性曲线参数
   struct CharacteristicCurveData
   {
     std::string name{"default"};               ///< 文件号名
     double intercept{0};                       ///< 截距
     std::vector<std::array<double, 2>> points; ///< 点位数组
     double slope{0};                           ///< 斜率
   };

   /// @brief 运行参数
   struct ArcWeldRunningParam
   {
     double test_run_speed{200}; ///< 空运行笛卡尔速度。单位：mm/s，范围：[ 1, 250 ]
     double wire_feed_speed{1};  ///< 手动点动送/退丝速度。单位：m/min。跟焊机本身有关，范围(0, +∞]
     int gas_detect_time{15};    ///< 气体检测时间。单位：s，范围：[ 1, 30 ]
   };

   /// @brief 焊接状态
   struct WelderStatus
   {
     double current{0};             ///< 当前电流。单位：A
     double voltage{0};             ///< 当前电压。单位：V
     std::string state{"disabled"}; ///< 焊机状态
     int speed{0};                  ///< 焊接速度。单位：mm/s
     std::error_code running_error; ///< 运行错误码
     std::string welding_name{""};  ///< 正在焊接的文件号; 类型string，结合arc_welding使用
     int arc_welding{-1};           ///< 当前的焊接状态; 类型int，0 - 起弧，1 - 焊接状态，2 - 熄弧状态，-1 - 默认值
     double welding_distance { 0 }; ///< 一次起弧收弧的已经完成焊接距离，下次起弧清空；单位：m
     int welding_path_num { 0 };    ///< 一次起弧收弧的焊接路径数量, 即已经开始执行的WMoveLCommand/WMoveCCommand指令数量，下次起弧清空
   };

   /// @brief 焊机设置
   struct WelderSetting {
     std::string protocol{"ethercat"};///< 协议
     std::string mfr{""};             ///< 厂商
     std::string model{""};           ///< 焊机型号
     int current_type{0};             ///< 电流类型
     std::string current_file{""};    ///< 电流文件号
     std::string voltage_file{""};    ///< 电压文件号
     double wire_diameter{0};         ///< 焊丝直径。
     std::string shielding_gas{""};   ///< 保护气体
     int program_number{0};           ///< 程序号
   };

   /// @brief 手眼标定结果
   struct HandeyeData {
     std::string name{};                                           ///< 手眼标定结果文件号
     bool mode{ false };                                           ///< 标定结果形式 true:xyz_abc false:RT矩阵
     std::array<double, 6> xyz_abc{ {0.0,0.0,0.0,0.0,0.0,0.0} };   ///< 笛卡尔空间位姿形式 单位：mm rad
     std::array<double, 9> rotMatrix{ {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0} }; ///< 旋转矩阵的行优先向量
     std::array<double, 3> transVector{ {0.0,0.0,0.0} };           ///< 平移向量
   };

   /// @brief 自动标定点位结果
   struct CalibrationResult{
     int id{0};                                   ///< 点位序号
     std::vector<double> p_robot{0.0, 0.0, 0.0, 0.0, 0.0, 0.0};  ///< 机器人坐标
     std::vector<double> p_laser{0.0, 0.0, 0.0};  ///< 相机坐标
   };

   /// @brief 激光传感器品牌选择
   enum LaserSensorType : unsigned int {
     CRNT=0,          //< 创想激光器
     SMART_IMAGE=1,   //< 明图传感器
     INTELLIGENT=2    //< 英莱传感器
   };

   /// @brief 激光传感器配置信息设置
   struct LaserSensorCfg
   {
     std::string name{"sensor0"};                      ///< 设备名
     std::string ip{"192.168.2.3"};                    ///< IP地址
     int port{502};                                    ///< 端口号
     LaserSensorType type{ LaserSensorType::CRNT };    ///< 激光器厂家类别（目前支持：创想CRNT、明图SMART_IMAGE、英莱INTELLIGENT）
     int overtime{1000};                               ///< 连接超时时间设置 单位：ms 范围：1-100000
     int communication_cycle{70};                      ///< 控制器和激光跟踪器通信周期 单位：ms 范围：1-10000
   };

   /// @brief 电弧跟踪左右跟踪参数
   struct LrTrackParam {
     double pid{5.0};                             ///< 比例增益：调节左右跟踪的快慢，范围：[ 0, 10 ]
     double curr_bias_offset{5.0};                ///< 电流偏差系数：补偿正常摆动时左右电流固有偏差，范围：[ 0, 10 ]
	   double min_compensation{0.01};               ///< 最小补偿量：单次补偿最小值，控制量小于该值不予补偿，单位 mm，范围：[ 0, 10 ]
     double max_compensation{0.7};                ///< 最大补偿量：单次补偿最大值 单位 mm，范围：[ 0, 10 ]
   };

   /// @brief 电弧跟踪上下跟踪参数
   struct UdTrackParam {
	   double pid{5.0};                             ///< 比例增益：调节上下跟踪的快慢，范围：[ 0, 10 ]
	   double curr_bias_offset{5.0};                ///< 电流偏差系数：补偿正常摆动时上下电流固有偏差，范围：[ 0, 10 ]
	   double min_compensation{0.01};               ///< 最小补偿量：单次补偿最小值，控制量小于该值不予补偿，单位 mm，范围：[ 0, 10 ]
	   double max_compensation{0.7};                ///< 最大补偿量：单次补偿最大值，单位 mm，范围：[ 0, 10 ]
	   double base_current{0.0};                    ///< 基准电流值：当“ 基准电流方法” 为“ 定值” 时才需要设置该参数 单位:A，范围[ 0, 1000 ]
     int sampling_start_period{5};                ///< 自适应上下基准电流开始采样周期，范围[ 2, 50 ]
     int sampling_duration_period{1};             ///< 自适应上下基准电流持续采样周期，范围[ 1, 50 ]
   };

   /// @brief 电弧跟踪参数设置
   struct ArcTrackParam {
     std::string name;                               ///< 文件号
     std::string annotation{};                       ///< 文件号注释
     int delay_time{0};                              ///< 延迟时间：电流采样和传输时间的延迟 单位 ms 范围：[ 0, 50 ]
     int cycle{6};                                   ///< 开始周期，范围：[ 3, 50 ]
     bool lr_enable{false};                          ///< 是否开启左右跟踪
     bool ud_enable{false};                          ///< 是否开启上下跟踪
     LrTrackParam lr_param;                          ///< 左右跟踪参数
     UdTrackParam ud_param;                          ///< 上下跟踪参数
   };

   /**
    * @brief 焊接参数设置，用于WMoveLCommand/WMoveCCommand运行时调整焊接参数，不断弧
    */
   struct ArcSetOpt {
     std::string arc_data { }; ///< 焊接参数名称, 非空时代表需要调整焊接参数
     bool ref_start { true }; ///< true - 相对下一条路径起点执行焊接参数修改 | false - 相对下一条路径终点
     double distance { 0 }; ///< 焊接参数在路径上开始发生变化的位置, 单位毫米。注：如果比路径长，则调整发生在路径的端点；对于有转弯区的情形，调整发生在转弯区中点
   };

   /**
    * @brief 防撞器状态
    */
   struct AnticollisionState {
       std::string signal{""};  ///< DI信号名称
       bool enable{false};      ///< 打开/关闭
       bool block{false};       ///< 屏蔽开关,开启屏蔽置true，屏蔽时间结束后置false
       int countdown{60};       ///< 倒计时
   };

   /**
    * @brief 获取起弧参数
    * @param[in] arconDataName 起弧参数名称
    * @param[out] ec 错误码
    * @return 起弧参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   ArcOnData getArcOnData(const std::string &arconDataName, error_code &ec) noexcept;

   /**
    * @brief 设置起弧参数
    * @param[in] arconData 起弧参数
    * @param[out] ec 错误码
    */
   void setArcOnData(const ArcOnData &arconData, error_code &ec) noexcept;

   /**
    * @brief 删除起弧参数
    * @param[in] arconDataName 起弧参数名称
    * @param[out] ec 错误码
    */
   void removeArcOnData(const std::string &arconDataName, error_code &ec) noexcept;

   /**
    * @brief 批量删除起弧参数
    * @param[in] arconDataNames 起弧参数名称列表
    * @param[out] ec 错误码
    */
   void removeArcOnData(const std::vector<std::string> &arconDataNames, error_code &ec) noexcept;

   /**
    * @brief 获取焊接参数
    * @param[in] arcDataName 焊接参数名称
    * @param[out] ec 错误码
    * @return 焊接参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   ArcData getArcData(const std::string &arcDataName, error_code &ec) noexcept;

   /**
    * @brief 设置焊接参数
    * @param[in] arcData 焊接参数名称
    * @param[out] ec 错误码
    */
   void setArcData(const ArcData &arcData, error_code &ec) noexcept;

   /**
    * @brief 删除焊接参数
    * @param[in] arcDataName 焊接参数名称
    * @param[out] ec 错误码
    */
   void removeArcData(const std::string &arcDataName, error_code &ec) noexcept;

   /**
    * @brief 批量删除焊接参数
    * @param[in] arcDataNames 焊接参数名称列表
    * @param[out] ec 错误码
    */
   void removeArcData(const std::vector<std::string> &arcDataNames, error_code &ec) noexcept;

   /**
    * @brief 生效焊接参数
    * @note 在未运行时将焊接参数发送给焊机，观察焊机面板显示，用于检查通讯是否建立，设置是否准确，不保存
    * @param[in] arcData 焊接参数
    * @param[out] ec 错误码
    */
   void enableArcData(const ArcData &arcData, error_code &ec) noexcept;

   /**
    * @brief 获取收弧参数
    * @param[in] arcoffDataName 收弧参数名称
    * @param[out] ec 错误码
    * @return 收弧参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   ArcOffData getArcOffData(const std::string &arcoffDataName, error_code &ec) noexcept;

   /**
    * @brief 设置收弧参数
    * @param[in] arcoffData 收弧参数
    * @param[out] ec 错误码
    */
   void setArcOffData(const ArcOffData &arcoffData, error_code &ec) noexcept;

   /**
    * @brief 删除收弧参数
    * @param[in] arcoffDataName 收弧参数名称
    * @param[out] ec 错误码
    */
   void removeArcOffData(const std::string &arcoffDataName, error_code &ec) noexcept;

   /**
    * @brief 批量删除收弧参数
    * @param[in] arcoffDataNames 收弧参数名称列表
    * @param[out] ec 错误码
    */
   void removeArcOffData(const std::vector<std::string> &arcoffDataNames, error_code &ec) noexcept;

   /**
    * @brief 获取摆焊参数
    * @param[in] weaveDataName 摆焊参数名称
    * @param[out] ec 错误码
    * @return 摆焊参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   WeaveData getWeaveData(const std::string &weaveDataName, error_code &ec) noexcept;

   /**
    * @brief 设置摆焊参数
    * @param[in] weaveData 摆焊参数
    * @param[out] ec 错误码
    */
   void setWeaveData(const WeaveData &weaveData, error_code &ec) noexcept;

   /**
    * @brief 删除摆焊参数
    * @param[in] weaveDataName 摆焊参数名称
    * @param[out] ec 错误码
    */
   void removeWeaveData(const std::string &weaveDataName, error_code &ec) noexcept;

   /**
    * @brief 批量删除摆焊参数
    * @param[in] weaveDataNames 摆焊参数名称列表
    * @param[out] ec 错误码
    */
   void removeWeaveData(const std::vector<std::string> &weaveDataNames, error_code &ec) noexcept;
   
   /**
    * @brief 获取摆焊-自适应参数
    * @param[out] ec 错误码
    * @return 摆焊-自适应参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   WeaveAdaptiveData getWeaveAdaptiveData(error_code& ec) noexcept;

   /**
    * @brief 设置摆焊-自适应参数
    * @param[in] weaveAdaptiveData 摆焊-自适应参数
    * @param[out] ec 错误码
    */
   void setWeaveAdaptiveData(const WeaveAdaptiveData& weaveAdaptiveData, error_code& ec) noexcept;

   /**
    * @brief 获取间断焊参数
    * @param[in] segDataName 间断焊参数名称
    * @param[out] ec 错误码
    * @return 间断焊参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   SegData getSegData(const std::string &segDataName, error_code &ec) noexcept;

   /**
    * @brief 设置间断焊参数
    * @param[in] segData 间断焊参数
    * @param[out] ec 错误码
    */
   void setSegData(const SegData &segData, error_code &ec) noexcept;

    /**
     * @brief 删除间断焊参数
     * @param[in] segDataName 间断焊参数名称
     * @param[out] ec 错误码
     */
    void removeSegData(const std::string &segDataName, error_code &ec) noexcept;

    /**
     * @brief 批量删除间断焊参数
     * @param[in] segDataNames 间断焊参数名称列表
     * @param[out] ec 错误码
     */
    void removeSegData(const std::vector<std::string> &segDataNames, error_code &ec) noexcept;

   /**
    * @brief 获取激光跟踪参数
    * @param[in] laserTrackDataName 激光跟踪参数名称
    * @param[out] ec 错误码
    * @return 激光跟踪参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   LaserTrackData getLaserTrackData(const std::string &laserTrackDataName, error_code &ec) noexcept;

   /**
    * @brief 设置激光跟踪参数
    * @param[in] laserTrackData 激光跟踪参数
    * @param[out] ec 错误码
    */
   void setLaserTrackData(const LaserTrackData &laserTrackData, error_code &ec) noexcept;

   /**
    * @brief 删除激光跟踪参数
    * @param[in] laserTrackDataName 激光跟踪参数名称
    * @param[out] ec 错误码
    */
   void removeLaserTrackData(const std::string &laserTrackDataName, error_code &ec) noexcept;

   /**
    * @brief 批量删除激光跟踪参数
    * @param[in] laserTrackDataNames 激光跟踪参数名称列表
    * @param[out] ec 错误码
    */
   void removeLaserTrackData(const std::vector<std::string> &laserTrackDataNames, error_code &ec) noexcept;

   /**
    * @brief 获取激光寻位参数
    * @param[in] laserSearchDataName 激光寻位参数名称
    * @param[out] ec 错误码
    * @return 激光寻位参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   LaserSearchData getLaserSearchData(const std::string &laserSearchDataName, error_code &ec) noexcept;

   /**
    * @brief 设置激光寻位参数
    * @param[in] laserSearchData 激光寻位参数
    * @param[out] ec 错误码
    */
   void setLaserSearchData(const LaserSearchData &laserSearchData, error_code &ec) noexcept;

   /**
    * @brief 删除激光寻位参数
    * @param[in] laserSearchDataName 激光寻位参数名称
    * @param[out] ec 错误码
    */
   void removeLaserSearchData(const std::string &laserSearchDataName, error_code &ec) noexcept;

   /**
    * @brief 批量删除激光寻位参数
    * @param[in] laserSearchDataNames 激光寻位参数名称列表
    * @param[out] ec 错误码
    */
   void removeLaserSearchData(const std::vector<std::string> &laserSearchDataNames, error_code &ec) noexcept;

   /**
    * @brief 获取IO设置
    * @param[out] ec 错误码
    * @return IO设置，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   IOSetting getIOSetting(error_code &ec) noexcept;

   /**
    * @brief 设置IO设置，必须在未启用焊接时才能设置
    * @param[in] ioSetting IO设置
    * @param[out] ec 错误码
    */
   void setIOSetting(const IOSetting &ioSetting, error_code &ec) noexcept;

   /**
    * @brief 获取电流特性曲线参数
    * @param[in] name 文件名称
    * @param[out] ec 错误码
    * @return 电流特性曲线参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   CharacteristicCurveData getCurrentCharacteristicCurveData(const std::string &name, error_code &ec) noexcept;

   /**
    * @brief 设置电流特性曲线参数，同时执行计算并保存
    * @param[in] data 电流特性曲线参数，只需要设置name和points
    * @param[out] ec 错误码
    */
   void setCurrentCharacteristicCurveData(const CharacteristicCurveData &data, error_code &ec) noexcept;

   /**
    * @brief 获取电压特性曲线参数
    * @param[in] name 文件名称
    * @param[out] ec 错误码
    * @return 电压特性曲线参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   CharacteristicCurveData getVoltageCharacteristicCurveData(const std::string &name, error_code &ec) noexcept;

   /**
    * @brief 设置电压特性曲线参数，同时执行计算并保存
    * @param[in] data 电压特性曲线参数，只需要设置name和points
    * @param[out] ec 错误码
    */
   void setVoltageCharacteristicCurveData(const CharacteristicCurveData &data, error_code &ec) noexcept;

   /**
    * @brief 计算电流特性曲线参数，只计算，不保存
    * @param[in] data 电流特性曲线参数，只需要设置name和points
    * @param[out] ec 错误码
    * @return 电流特性曲线参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   CharacteristicCurveData calculateCurrentCurve(const CharacteristicCurveData &data, error_code &ec) noexcept;

   /**
    * @brief 计算电压特性曲线参数，只计算，不保存
    * @param[in] data 电压特性曲线参数，只需要设置name和points
    * @param[out] ec 错误码
    * @return 电压特性曲线参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   CharacteristicCurveData calculateVoltageCurve(const CharacteristicCurveData &data, error_code &ec) noexcept;

   /**
    * @brief 获取焊机状态
    * @param[out] ec 错误码
    * @return 焊机状态，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   WelderStatus getWelderStatus(error_code &ec) noexcept;

   /**
    * @brief 设置焊机
    * @param[in] protocol 协议。ethercat
    * @param[in] mfr 厂商。aotai
    * @param[in] type 类型。RL/RPL、RP/RPH
    * @param[in] current 电流类型。350,500,630,800
    * @param[out] ec 错误码
    */
   void setWelder(const std::string &protocol, const std::string &mfr, const std::string &type, int current, error_code &ec) noexcept;

   /**
    * @brief 设置焊机
    * @param[in] welderSetting 焊机设置参数
    * @param[out] ec 错误码
    */
   void setWelder(const ArcWelding::WelderSetting &welderSetting, error_code &ec) noexcept;

   /**
    * @brief 获取焊机设置
    * @param[out] ec 错误码
    * @return 焊机设置，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   WelderSetting getWelderSetting(error_code &ec) noexcept;

   /**
    * @brief 连接焊机，启用弧焊功能
    * @param[out] ec 错误码
    */
   void connectToWelder(error_code &ec) noexcept;

   /**
    * @brief 断开焊机连接，关闭弧焊功能
    * @param[out] ec 错误码
    */
   void disconnectFromWelder(error_code &ec) noexcept;

   /**
    * @brief 读取当前是否连接物理焊机（仅EthreCAT焊机，由当前使用ENI文件确定）
    * @param[out] ec 错误码
    * @return 是否连接物理焊机，在错误码为0时有效，如果错误码不为0，返回false
    */
   bool isEniHaveWeld(error_code &ec) noexcept;

   /**
    * @brief 设置是否连接物理焊机（仅EtherCAT焊机，切换ENI文件，重启控制器生效）
    * @note 不成功原因多半为缺少对应ENI文件，请导入对应ENI文件
    * @param[in] isEniHaveWeld 是否连接物理焊机
    * @param[out] ec 错误码
    */
   void setIsEniHaveWeld(bool isEniHaveWeld, error_code &ec) noexcept;

   /**
    * @brief 获取焊接模式
    * @param[out] ec 错误码
    * @return 焊接模式，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   WeldMode getWeldMode(error_code &ec) noexcept;

   /**
    * @brief 设置焊接模式
    * @param[in] weldMode 焊接模式
    * @param[out] ec 错误码
    */
   void setWeldMode(const WeldMode &weldMode, error_code &ec) noexcept;

   /**
    * @brief 读取焊接运行参数
    * @param[out] ec 错误码
    * @return 运行参数，在错误码为0时有效，如果错误码不为0，返回默认值
    */
   ArcWeldRunningParam getRunningParam(error_code &ec) noexcept;

   /**
    * @brief 设置焊接运行参数
    * @param[in] data 运行参数
    * @param[out] ec 错误码
    */
   void setRunningParam(const ArcWeldRunningParam &data, error_code &ec) noexcept;

   /**
    * @brief 送丝
    * @param[in] time 送丝时间，单位：秒，范围：大于0.1。enable为true时，生效
    * @param[in] enable 是否送丝. true：送丝；false：停止送丝
    * @param[out] ec 错误码
    */
   void feedOnWire(double time, error_code &ec, bool enable = true) noexcept;

   /**
    * @brief 退丝
    * @param[in] time 退丝时间，单位：秒，范围：大于0.1, enable为true时，生效
    * @param[in] enable 是否退丝. true：退丝；false：停止退丝
    * @param[out] ec 错误码
    */
   void feedBackWire(double time, error_code &ec, bool enable = true) noexcept;

   /**
    * @brief 检气
    * @param[in] time 检气时间，单位：秒，范围：大于0.1, enable为true时，生效
    * @param[in] enable 是否检气. true：检气；false：停止检气
    * @param[out] ec 错误码
    */
   void detectGas(double time, error_code &ec, bool enable = true) noexcept;

   /**
    * @brief 在线设置电流和电压，只有在焊接状态才生效
    * @param[in] current 电流或送丝速度，单位：A 或 mm/s，对应当前焊接的电流模式。
    * @param[in] voltage 电压，单位：V 或 %，对应当前焊接的电压模式。
    * @param[out] ec 错误码
    */
   void setCurrentAndVoltage(double current, double voltage, error_code &ec) noexcept;

   /**
    * @brief 在线保存电流和电压，只有在焊接状态才生效
    * @param[in] current 电流或送丝速度，单位：A 或 mm/s，对应当前焊接的电流模式。
    * @param[in] voltage 电压，单位：V 或 %，对应当前焊接的电压模式。
    * @param[out] ec 错误码
    */
   void saveCurrentAndVoltage(double current, double voltage, error_code &ec) noexcept;

   /**
    * @brief 开始铆焊。工作模式为直流，电流模式为电流，电压模式默认为一元化
    * @param[in] current 电流，单位：A, 范围[1,300]; 送丝速度，单位：mm/s, 范围[1,500]
    * @param[in] voltage 电压，单位：V | %，范围[-30,30]
    * @param[out] ec 错误码
    * @param[in] voltage_mode 电压模式，"separate"-分别，"unified"-一元化，默认为"unified"
    * @param[in] current_mode 电流模式，"current"-电流，"wire_feed"-送丝速度，默认为"current"
    * @param[in] work_mode 工作模式，默认为"flat_characteristic"
    */
   void startWelding(double current, double voltage, error_code &ec, std::string voltage_mode = "unified", std::string current_mode = "current", std::string work_mode = "flat_characteristic") noexcept;

   /**
    * @brief 停止铆焊
    * @param[out] ec 错误码
    */
   void stopWelding(error_code &ec) noexcept;

   // **********************************************************************
   // *********************** 激光器标定 ************************************
   // **********************************************************************

   /**
    * @brief 添加设置手眼标定结果参数
    * @param[in] handeyedata 手眼标定结果
    * @param[out] ec 错误码
    */
   void setHandeyeData(const HandeyeData& handeyedata, error_code& ec) noexcept;

   /**
    * @brief 获得目前设置的手眼标定结果
    * @param[in] name 手眼标定结果文件号
    * @param[out] ec 错误码
    * @return 手眼标定结果
    */
   HandeyeData getHandeyeData(const std::string& name, error_code& ec) noexcept;

   /**
    * @brief 删除手眼标定结果
    * @param[in] name 手眼标定文件号
    * @param[out] ec 错误码
    */
   void removeHandeyeData(const std::string& name, error_code& ec) noexcept;

   /**
    * @brief 删除多个手眼标定结果
    * @param[in] names 手眼标定文件号列表
    * @param[out] ec 错误码
    */
   void removeHandeyeData(const std::vector<std::string>& names, error_code& ec) noexcept;

   /**
    * @brief 开始手眼标定，需要已经连接激光传感器
    * @param[in] name 手眼标定文件号
    * @param[in] type 标定点数，目前只能是6
    * @param[out] ec 错误码
    */
   void startHandeyeCalibration(const std::string name, int type, error_code& ec) noexcept;

   /**
    * @brief 手眼标定添加点位
    * @param[in] id 点位编号.0:尖端采集点，1-6:标定点
    * @param[out] ec 错误码
    * @return 点位结果
    */ 
   CalibrationResult calibratePoint(int id, error_code& ec) noexcept;

   /**
    * @brief 手眼标定结束，计算标定结果
    * @param[out] handeyedata 手眼标定结果
    * @param[out] ec 错误码
    * @return 自校验误差[max,min,mean]
    */ 
   std::array<double,3> calibrateEnd(HandeyeData& handeyedata, error_code& ec) noexcept;

   /**
    * @brief 添加设置激光传感器配置参数
    * @param[in] cfg 激光传感器基础配置数据
    * @param[out] ec 错误码
    */
   void setLaserSensorCfg(const LaserSensorCfg& cfg , error_code& ec) noexcept;

   /**
    * @brief 获取激光传感器配置参数
    * @param[in] name 激光传感器名称
    * @param[out] ec 错误码
    * @return 传感器配置参数
    */
   LaserSensorCfg getLaserSensorCfg(const std::string& name, error_code& ec) noexcept;

   /**
    * @brief 删除激光传感器配置参数
    * @param[in] device_name 激光传感器设备名称
    * @param[out] ec 错误码
    */
   void removeLaserSensorCfg(const std::string& device_name , error_code& ec) noexcept;

   /**
    * @brief 删除多个激光传感器配置参数
    * @param[in] device_names 激光传感器设备名称列表
    * @param[out] ec 错误码
    */
   void removeLaserSensorCfg(const std::vector<std::string>& device_names , error_code& ec) noexcept;

   /**
    * @brief 连接激光传感器
    * @param[in] device_name 激光传感器设备名称
    * @param[out] ec 错误码
    */
   void connLaserSensorDev(const std::string& device_name, error_code& ec) noexcept;

   /**
    * @brief 断开连接激光传感器
    * @param[in] device_name 激光传感器设备名称
    * @param[out] ec 错误码
    */
   void disconnLaserSensorDev(const std::string& device_name, error_code& ec) noexcept;

   /**
    * @brief 打开焊缝跟踪器，开始获取激光器焊缝数据
    * @param[in] device_name 激光传感器设备名称
    * @param[out] ec 错误码
    */
   void openLaserTrack(const std::string& device_name, error_code& ec) noexcept;

   /**
    * @brief 关闭焊缝跟踪器，停止获取激光器焊缝数据
    * @param[in] device_name 激光传感器设备名称
    * @param[out] ec 错误码
    */
   void closeLaserTrack(const std::string& device_name, error_code& ec) noexcept;

   /**
    * @brief 设置电弧跟踪参数
	  * @param[in] arctrack_param 电弧跟踪参数
	  * @param[out] ec 错误码
    */
   void setArcTrackParam(const ArcTrackParam& param, error_code& ec) noexcept;

   /**
    * @brief 获取电弧跟踪参数设置
	  * @param[in] name 电弧跟踪参数文件号
	  * @param[out] ec 错误码
	  * @return 电弧跟踪参数
    */
   ArcTrackParam getArcTrackParam(const std::string name, error_code& ec) noexcept;

   /**
    * @brief 删除电弧跟踪参数
    * @param[in] name 电弧跟踪参数文件号
    * @param[out] ec 错误码
    */
   void removeArcTrackParam(const std::string& name, error_code& ec) noexcept;

   /**
    * @brief 删除多个电弧跟踪参数
    * @param[in] names 电弧跟踪参数文件号
    * @param[out] ec 错误码
    */
   void removeArcTrackParam(const std::vector<std::string>& names, error_code& ec) noexcept;

   /**
    * @brief 设置防碰撞传感器
    * @param[in] signal DI信号名称
    * @param[in] enable 打开/关闭
    * @param[in] block 屏蔽开关
    * @param[in] countdown 倒计时，倒计时结束后打开防撞器
    * @param[out] ec 错误码，-260 - 缺少必要参数；-14510 - 绑定系统输入失败（DI信号不存在或已绑定为系统输入）
    */
   void setAnticollision(const std::string& signal, bool enable, bool block, int countdown, error_code& ec) noexcept;

   /**
    * @brief 获取防碰撞传感器设置或状态
    * @param[out] ec 错误码
    * @return 防碰撞设置或状态，错误码不为0无效
    */
   AnticollisionState getAnticollisionState(error_code& ec) noexcept;

   /**
    * @brief 焊接参数-再启动回退距离不为零时，实焊模式下再启动都会回退一段再起弧焊接。
    * 暂停状态下调用该接口，可以暂时关闭回退一次，从暂停点开始运动
    */
   void cancelAutoGoBackOnce(error_code &ec) noexcept;

   /**
    * @class ArcOnCommand
    * @brief 焊接指令 - 起弧，起弧参数和焊接参数默认都为default
    */
   class XCORE_API ArcOnCommand
   {
    public:
     /**
      * @param[in] arcOnData 起弧参数名称
      * @param[in] arcData 焊接参数名称
      */
     ArcOnCommand(const std::string &arcOnData = "default", const std::string &arcData = "default");

     /**
      * @brief 设置起弧参数
      * @param[in] arcOnData 起弧参数名称
      * @param[out] ec 错误码
      */
     void setArcOnData(const std::string &arcOnData, error_code &ec) noexcept;

     /**
      * @brief 获取起弧参数
      * @return 起弧参数名
      */
     std::string getArcOnData() const noexcept;

     /**
      * @brief 设置焊接参数
      * @param[in] arcData 焊接参数名称
      * @param[out] ec 错误码
      */
     void setArcData(const std::string &arcData, error_code &ec) noexcept;

     /**
      * @brief 获取焊接参数
      * @return 焊接参数名
      */
     std::string getArcData() const noexcept;

    private:
     std::string m_arcOnData{"default"}; ///< 起弧参数名
     std::string m_arcData{"default"};   ///< 焊接参数名
   };

   /**
    * @class ArcOffCommand
    * @brief 焊接指令 - 收弧，收弧参数默认为default
    */
   class XCORE_API ArcOffCommand
   {
    public:
     /**
      * @param[in] arcOffData 收弧参数名称
      */
     ArcOffCommand(const std::string &arcOffData = "default");

     /**
      * @brief 设置收弧参数
      * @param[in] arcOffData 收弧参数名称
      * @param[out] ec 错误码
      */
     void setArcOffData(const std::string &arcOffData, error_code &ec) noexcept;

     /**
      * @brief 获取收弧参数
      * @return 收弧参数名
      */
     std::string getArcOffData() const noexcept;

    private:
     std::string m_arcOffData{"default"}; ///< 收弧参数名
   };

   /**
    * @class FeedOnWireCommand
    * @brief 焊接指令 - 送丝，默认送丝速度1.0 m/min, 送丝生效
    */
   class XCORE_API FeedOnWireCommand {
    public:
     /**
      * @param[in] time 时间，单位：秒
      * @param[in] speed 速度，单位：m/min
      * @param[in] isFeed 是否送丝，默认生效
      */
     FeedOnWireCommand(double time, double speed = 1.0, bool isFeed = true);

     /**
      * @brief 设置送丝参数
      * @param[in] time 时间，单位：秒
      * @param[in] speed 速度，单位：m/min
      * @param[in] isFeed 是否送丝，true生效
      * @param[out] ec 错误码
      */
     void setFeedOnWireData(const double &time, const double &speed, const bool &isFeed, error_code &ec) noexcept;

     /**
      * @brief 获取送丝参数
      * @param[out] time 时间，单位：秒
      * @param[out] speed 速度，单位：m/min
      * @param[out] isFeed 是否送丝，true生效
      */
     void getFeedOnWireData(double &time, double &speed, bool &isFeed) const noexcept;

    private:
     double m_time;
     double m_speed;
     bool m_isFeed;
   };

   /**
    * @class FeedBackWireCommand
    * @brief 焊接指令 - 退丝，默认退丝速度1.0 m/min, 退丝生效
    */
   class XCORE_API FeedBackWireCommand {
    public:
     /**
      * @param[in] time 时间，单位：秒
      * @param[in] speed 速度，单位：m/min
      * @param[in] isReverse 是否退丝，默认生效
      */
     FeedBackWireCommand(double time, double speed = 1.0, bool isReverse = true);

     /**
      * @brief 设置退丝参数
      * @param[in] time 时间，单位：秒
      * @param[in] speed 速度，单位：m/min
      * @param[in] isReverse 是否退丝，true生效
      * @param[out] ec 错误码
      */
     void setFeedBackWireData(const double &time, const double &speed, const bool &isReverse, error_code &ec) noexcept;

     /**
      * @brief 获取退丝参数
      * @param[out] time 时间，单位：秒
      * @param[out] speed 速度，单位：m/min
      * @param[out] isReverse 是否退丝，true生效
      */
     void getFeedBackWireData(double &time, double &speed, bool &isReverse) const noexcept;

    private:
     double m_time;
     double m_speed;
     bool m_isReverse;
   };

   /**
    * @class WMoveLCommand
    * @brief 焊接指令 - 直线轨迹，摆动参数默认为空
    */
   class XCORE_API WMoveLCommand : public MoveLCommand
   {
    public:
     /**
      * @param target 目标笛卡尔点位
      * @param speed 速率
      * @param zone 转弯区
      * @param weaveData 摆动参数名称
      * @param trackData 电弧跟踪参数名称
      */
     WMoveLCommand(CartesianPosition target, int speed = USE_DEFAULT, int zone = USE_DEFAULT, const std::string &weaveData = "", const std::string &trackData = "");

     /**
      * @brief 设置摆动参数
      * @param[in] weaveData 摆动参数名称
      * @param[out] ec 错误码
      */
     void setWeaveData(const std::string &weaveData, error_code &ec) noexcept;

     /**
      * @brief 获取摆动参数
      * @return 摆动参数名
      */
     std::string getWeaveData() const noexcept;

     /**
      * @brief 设置电弧跟踪参数
      * @param[in] trackData 电弧跟踪参数名称
      * @param[out] ec 错误码
      */
     void setTrackData(const std::string& trackData, error_code& ec) noexcept;

     /**
      * @brief 获取电弧跟踪参数
      * @param[out] ec 错误码
      * @return 摆动参数名
      */
     std::string getTrackData() const noexcept;

     ArcSetOpt arc_set_opt; ///< 设置焊接参数选项

    private:
     std::string m_weaveData; ///< 摆动参数名
     std::string m_trackData; ///< 电弧跟踪参数名
   };

   /**
    * @class WMoveCCommand
    * @brief 焊接指令 - 圆弧轨迹，摆动参数默认为空
    */
   class XCORE_API WMoveCCommand : public MoveCCommand
   {
    public:
     /**
      * @param target 目标点
      * @param aux 辅助点
      * @param speed 运行速度
      * @param zone 转弯区
      * @param weaveData 摆动参数名称
      * @param trackData 电弧跟踪参数名称
      */
     WMoveCCommand(CartesianPosition target, CartesianPosition aux, int speed = USE_DEFAULT, int zone = USE_DEFAULT, const std::string &weaveData = "", const std::string& trackData = "");

     /**
      * @brief 设置摆动参数
      * @param[in] weaveData 摆动参数名称
      * @param[out] ec 错误码
      */
     void setWeaveData(const std::string &weaveData, error_code &ec) noexcept;

     /**
      * @brief 获取摆动参数
      * @return 摆动参数名
      */
     std::string getWeaveData() const noexcept;

     /**
      * @brief 设置电弧跟踪参数
      * @param[in] trackData 电弧跟踪参数名称
      * @param[out] ec 错误码
      */
     void setTrackData(const std::string& trackData, error_code& ec) noexcept;

     /**
      * @brief 获取电弧跟踪参数
      * @param[out] ec 错误码
      * @return 摆动参数名
      */
     std::string getTrackData() const noexcept;

     ArcSetOpt arc_set_opt; ///< 设置焊接参数选项

    private:
     std::string m_weaveData; ///< 摆动参数名
     std::string m_trackData; ///< 电弧跟踪参数名
   };

   class XCORE_API WMoveCFCommand : public MoveCFCommand {
    public:
     /**
    * @param target 目标点
    * @param aux 辅助点
    * @param angle 执行角度, 单位弧度
    * @param speed 末端线速度, 单位mm/s
    * @param zone 转弯区, 单位mm
    * @param weaveData 摆动参数名称
    * @param trackData 电弧跟踪参数名称
    */
     WMoveCFCommand(const CartesianPosition &target, const CartesianPosition &aux, double angle, int speed = USE_DEFAULT, int zone = USE_DEFAULT, const std::string &weaveData = "", const std::string &trackData = "");

     /**
      * @brief 设置摆动参数
      * @param[in] weaveData 摆动参数名称
      * @param[out] ec 错误码
      */
     void setWeaveData(const std::string &weaveData, error_code &ec) noexcept;

     /**
      * @brief 获取摆动参数
      * @return 摆动参数名
      */
     std::string getWeaveData() const noexcept;

     /**
      * @brief 设置电弧跟踪参数
      * @param[in] weaveData 摆动参数名称
      * @param[out] ec 错误码
      */
     void setTrackData(const std::string &trackData, error_code &ec) noexcept;

     /**
      * @brief 获取电弧跟踪参数
      * @param[out] ec 错误码
      * @return 摆动参数名
      */
     std::string getTrackData() const noexcept;

     ArcSetOpt arc_set_opt;///< 设置焊接参数选项

    private:
     std::string m_weaveData;///< 摆动参数名
     std::string m_trackData;///< 电弧跟踪参数名
   };

   /**
    * @class WMoveLPendulumCommand
    * @brief 焊接指令 - 钟摆，摆动参数默认为空
    */
   class XCORE_API WMoveLPendulumCommand : public MoveLCommand
   {
   public:
       /**
        * brief  构造函数：针对arc块首条钟摆startAux不为NULL的情况
        * @param startAux 起点辅助点，
        * @param targetAux 目标辅助点
        * @param target 目标点
        * @param speed 运行速度
        * @param frequency 摆动频率, 范围[0.1, 5], 单位Hz
        * @param dwellTimeLeft 左边缘停留时间, 范围[0, 10000], 单位ms
        * @param dwellTimeRight 右边缘停留时间, 范围[0, 10000], 单位ms
        */
       WMoveLPendulumCommand(CartesianPosition startAux, CartesianPosition targetAux, CartesianPosition target, int speed = USE_DEFAULT, double frequency = 0.1, double dwellTimeLeft = 0.0, double dwellTimeRight = 0.0);

       /**
        * @brief 重载构造函数：针对arc块非首条钟摆startAux可为NULL的情况
        * @param startAux 起弧辅助点
        * @param targetAux 目标辅助点
        * @param target 目标点
        * @param speed 运行速度
        * @param frequency 摆动频率, 范围[0.1, 5], 单位Hz
        * @param dwellTimeLeft 左边缘停留时间, 范围[0, 10000], 单位ms
        * @param dwellTimeRight 右边缘停留时间, 范围[0, 10000], 单位ms
        */
       WMoveLPendulumCommand(std::nullptr_t startAux, CartesianPosition targetAux, CartesianPosition target, int speed = USE_DEFAULT, double frequency = 0.1, double dwellTimeLeft = 0.0, double dwellTimeRight = 0.0);

       bool enableStartAux;    ///< 标志位，识别是否使用起始辅助点
       CartesianPosition startAux;    ///< 起始辅助点位，非首条钟摆可为NULL
       CartesianPosition::Offset startAuxOffset; ///< 偏移选项
       CartesianPosition targetAux;    ///< 目标辅助点位
       CartesianPosition::Offset targetAuxOffset; ///< 偏移选项
       CartesianPosition::Offset targetOffset; ///< 偏移选项
       double frequency; ///< 摆动频率, 范围[0.1, 5], 单位Hz
       double dwellTimeLeft; ///< 左边缘停留时间, 范围[0, 10000], 单位ms
       double dwellTimeRight; ///< 右边缘停留时间, 范围[0, 10000], 单位ms
      
       ArcSetOpt arc_set_opt; ///< 设置焊接参数选项
   };

   /**
    * @class WeaveOnCommand
    * @brief 焊接指令 - 开始摆动
    */
   class XCORE_API WeaveOnCommand
   {
    public:
     /**
      * @param[in] weaveData 摆动参数名称
      */
     WeaveOnCommand(const std::string &weaveData = "default");

     /**
      * @brief 设置摆动参数
      * @param[in] weaveData 摆动参数名称
      * @param[out] ec 错误码
      */
     void setWeaveData(const std::string &weaveData, error_code &ec) noexcept;

     /**
      * @brief 获取摆动参数
      * @return 摆动参数名
      */
     std::string getWeaveData() const noexcept;

    private:
     std::string m_weaveData{"default"}; ///< 摆动参数名
   };

   /**
    * @class WeaveOffCommand
    * @brief 焊接指令 - 停止摆动
    */
   class XCORE_API WeaveOffCommand
   {
   };

   /**
    * @class LaserTrackOnCommand
    * @brief 焊接指令 - 开始激光跟踪
    */
   class XCORE_API LaserTrackOnCommand
   {
    public:
     /**
      * @param[in] handEyeData 手眼标定参数名称
      * @param[in] laserTrackData 激光跟踪参数名称
      */
     LaserTrackOnCommand(const std::string &handEyeData = "default", const std::string &laserTrackData = "default");

     /**
      * @brief 设置手眼标定参数名称
      * @param[in] handEyeData 手眼标定参数名称
      * @param[out] ec 错误码
      */
     void setHandEyeData(const std::string &handEyeData, error_code &ec) noexcept;

     /**
      * @brief 获取手眼标定参数名称
      * @return 手眼标定参数名
      */
     std::string getHandEyeData() const noexcept;

     /**
      * @brief 设置激光跟踪参数名称
      * @param[in] laserTrackData 激光跟踪参数名称
      * @param[out] ec 错误码
      */
     void setLaserTrackData(const std::string &laserTrackData, error_code &ec) noexcept;

     /**
      * @brief 获取激光跟踪参数名称
      * @return 激光跟踪参数名
      */
     std::string getLaserTrackData() const noexcept;

    private:
     std::string m_handEyeData{"default"};    ///< 手眼标定参数名称
     std::string m_laserTrackData{"default"}; ///< 激光跟踪参数名称
   };

   /**
    * @class LaserTrackOffCommand
    * @brief 焊接指令 - 停止激光跟踪
    */
   class XCORE_API LaserTrackOffCommand
   {
   };

   /**
    * @class LaserSearchCommand
    * @brief 焊接指令 - 激光寻位
    */
   class XCORE_API LaserSearchCommand
   {
    public:
     /**
      * @param[in] laserHandEyeData 手眼标定参数名称
      * @param[in] laserSearchData 激光寻位参数名称
      * @param[in] endPoint 激光寻位终点, 工具工件坐标系下的
      * @param[in] speed 末端线速度, 单位mm/s
      * @param[in] zone 转弯区大小, 单位mm
      */
     LaserSearchCommand(const std::string &laserHandEyeData, const std::string &laserSearchData, const CartesianPosition &endPoint, int speed = USE_DEFAULT,int zone = USE_DEFAULT);

    public:
     std::string laserHandEyeData; ///< 手眼标定参数名称
     std::string laserSearchData;  ///< 激光寻位参数名称
     CartesianPosition endPoint;   ///< 激光寻位终点, 工具工件坐标系下的
     int speed;                    ///< 末端线速度, 单位mm/s
     int zone;                     ///< 转弯区大小, 单位mm
   };

   /**
    * @brief 激光寻位，阻塞等待运动结束
    * @note 如果设置了超时时间，该函数会阻塞直到超时或者寻位结束
    * @param[in] cmd 激光寻位指令
    * @param[in] isMove 是否立即开始运动。false：只添加寻位指令，需要额外使用moveStart()执行；true：添加寻位指令并执行
    * @param[in] timeout 超时时间。0：不等待寻位结果直接退出，返回默认值；>0：等待寻位结果，超时返回默认值
    * @param[out] ec 错误码
    * @return <是否寻到，寻到的位姿>，寻到的位姿是基于工具工件坐标系的
    */
   std::tuple<bool, CartesianPosition> executeLaserSearch(ArcWelding::LaserSearchCommand cmd, bool isMove, std::chrono::steady_clock::duration timeout, error_code &ec) noexcept;

   /**
    * @brief 激光寻位 - 四点计算交点。只计算位置，姿态取points第一点的姿态
    * @param[in] points 寻到的4个点位，前两个是组成直线1，后两个组成直线2
    * @param[out] ec 错误码，一般是计算失败，计算失败的原因见SDK日志
    * @return 计算出的交点，无错误码时有效
    */
   CartesianPosition calcIntersection(const std::vector<CartesianPosition> &points, error_code &ec) noexcept;

   /**
    * @class SegOnCommand
    * @brief 焊接指令 - 开始间断焊
    */
   class XCORE_API SegOnCommand
   {
   public:
     /**
      * SegOnCommand
      * @param[in] segData 间断焊参数名
      */
     SegOnCommand(const std::string &segData = "default");

     std::string segData {"default"}; ///< 间断焊参数名
   };

   /**
    * @class SegOffCommand
    * @brief 焊接指令 - 停止间断焊
    */
   class XCORE_API SegOffCommand{};

   XCORESDK_DECLARE_IMPL
 };
}

#endif // ROKAEAPI_ARCWELDING_H_