/** @file  type_def.h
 *  \~chinese @brief 数据类型的定义 \~english @brief enum type definitions
 */
#ifndef AUBO_SDK_TYPE_DEF_H
#define AUBO_SDK_TYPE_DEF_H

#include <stddef.h>
#include <array>
#include <vector>
#include <memory>
#include <functional>
#include <iostream>
#include <string>

#ifdef _MSC_VER
#pragma execution_character_set("utf-8")
#endif

// clang-format off

namespace arcs {
namespace common_interface {

/// Cartesion degree of freedom, 6 for x,y,z,rx,ry,rz
#define CARTESIAN_DOF 6
#define SAFETY_PARAM_SELECT_NUM 2 ///< \~chinese 正常 + 缩减 \~english normal + reduced
#define SAFETY_PLANES_NUM 8 ///< \~chinese 安全平面的数量 \~english Number of safety planes
#define SAFETY_CUBIC_NUM 10 ///< \~chinese 安全立方体的数量 \~english Number of safety cubes
#define TOOL_CONFIGURATION_NUM 3 ///< \~chinese 工具配置数量 \~english Number of tool configurations

using Vector3d = std::array<double, 3>;
using Vector4d = std::array<double, 4>;
using Vector3f = std::array<float, 3>;
using Vector4f = std::array<float, 4>;
using Vector6f = std::array<float, 6>;

struct RobotSafetyParameterRange
{
    RobotSafetyParameterRange()
    {
        for (int i = 0; i < SAFETY_PARAM_SELECT_NUM; i++) {
            params[i].power = 0.;
            params[i].momentum = 0.;
            params[i].stop_time = 0.;
            params[i].stop_distance = 0.;
            params[i].reduced_entry_time = 0.;
            params[i].reduced_entry_distance = 0.;
            params[i].tcp_speed = 0.;
            params[i].elbow_speed = 0.;
            params[i].tcp_force = 0.;
            params[i].elbow_force = 0.;
            std::fill(params[i].qmin.begin(), params[i].qmin.end(), 0.);
            std::fill(params[i].qmax.begin(), params[i].qmax.end(), 0.);
            std::fill(params[i].qdmax.begin(), params[i].qdmax.end(), 0.);
            std::fill(params[i].joint_torque.begin(),
                      params[i].joint_torque.end(), 0.);
            params[i].tool_orientation.fill(0.);
            params[i].tool_deviation = 0.;
            for (int j = 0; j < SAFETY_PLANES_NUM; j++) {
                params[i].planes[j].fill(0.);
                params[i].restrict_elbow[j] = 0;
            }
        }
        for (int i = 0; i < SAFETY_PLANES_NUM; i++) {
            trigger_planes[i].plane.fill(0.);
            trigger_planes[i].restrict_elbow = 0;
        }
        for (int i = 0; i < SAFETY_CUBIC_NUM; i++) {
            cubic[i].orig.fill(0.);
            cubic[i].size.fill(0.);
            cubic[i].restrict_elbow = 0;
        }
        for (int i = 0; i < TOOL_CONFIGURATION_NUM; i++) {
            tools[i].fill(0.);
        }

        tool_inclination = 0.;
        tool_azimuth = 0.;
        std::fill(safety_home.begin(), safety_home.end(), 0.);

        safety_input_emergency_stop = 0;
        safety_input_safeguard_stop = 0;
        safety_input_safeguard_reset = 0;
        safety_input_auto_safeguard_stop = 0;
        safety_input_auto_safeguard_reset = 0;
        safety_input_three_position_switch = 0;
        safety_input_operational_mode = 0;
        safety_input_reduced_mode = 0;
        safety_input_handguide = 0;

        safety_output_emergency_stop = 0;
        safety_output_not_emergency_stop = 0;
        safety_output_robot_moving = 0;
        safety_output_robot_steady = 0;
        safety_output_reduced_mode = 0;
        safety_output_not_reduced_mode = 0;
        safety_output_safe_home = 0;
        safety_output_robot_not_stopping = 0;
        safety_output_safetyguard_stop = 0;

        tp_3pe_for_handguide = 1;
        allow_manual_high_speed = 0;
    }

    uint32_t crc32{ 0 };

    /// \~chinese 最多可以保存2套参数, 默认使用第 0 套参数 \~english At most 2
    /// sets of parameters can be saved, default is the 0th set
    struct
    {
        float power; ///< \~chinese 关节力矩与关节角速度的乘积之和 \~english sum of joint torques times joint angular speeds
        float momentum; ///< \~chinese 机器人动量限制 \~english robot momentum limit
        float stop_time; ///< \~chinese 停机时间 ms \~english stop time in milliseconds
        float stop_distance; ///< \~chinese 停机距离 m \~english stop distance in meters
        float reduced_entry_time; ///< \~chinese 进入缩减模式的最大时间 \~english maximum time to enter reduced mode
        float reduced_entry_distance; ///< \~chinese 进入缩减模式的最大距离(可由安全平面触发) \~english maximum distance to enter reduced mode (can be triggered by safety planes)
        float tcp_speed;
        float elbow_speed;
        float tcp_force;
        float elbow_force;
        std::vector<float> qmin;
        std::vector<float> qmax;
        std::vector<float> qdmax;
        std::vector<float> joint_torque;
        Vector3f tool_orientation; ///<
        float tool_deviation;
        Vector4f planes[SAFETY_PLANES_NUM]; /// x,y,z,displacement
        int restrict_elbow[SAFETY_PLANES_NUM];
    } params[SAFETY_PARAM_SELECT_NUM];

    /// \~chinese 8个触发平面 \~english 8 trigger planes
    struct
    {
        Vector4f plane; /// x,y,z,displacement
        int restrict_elbow;
    } trigger_planes[SAFETY_PLANES_NUM];

    struct
    {
        Vector6f orig; ///< \~chinese 立方块的原点 (x,y,z,rx,ry,rz) \~english origin of the cubic (x,y,z,rx,ry,rz)
        Vector3f size; ///< \~chinese 立方块的尺寸 (x,y,z) \~english size of the cubic (x,y,z)
        int restrict_elbow;
    } cubic[SAFETY_CUBIC_NUM]; ///< \~chinese 10个安全空间 \~english 10 safety spaces

    /// \~chinese 3个工具 \~english 3 tools
    Vector4f tools[TOOL_CONFIGURATION_NUM]; /// x,y,z,radius

    float tool_inclination{
        0.
    };                        ///< \~chinese 倾角 \~english inclination angle
    float tool_azimuth{ 0. }; ///< \~chinese 方位角 \~english azimuth angle
    std::vector<float> safety_home;

    /// \~chinese 可配置IO的输入输出安全功能配置 \~english Configurable IO input
    /// and output safety functions
    uint32_t safety_input_emergency_stop;
    uint32_t safety_input_safeguard_stop;
    uint32_t safety_input_safeguard_reset;
    uint32_t safety_input_auto_safeguard_stop;
    uint32_t safety_input_auto_safeguard_reset;
    uint32_t safety_input_three_position_switch;
    uint32_t safety_input_operational_mode;
    uint32_t safety_input_reduced_mode;
    uint32_t safety_input_handguide;

    uint32_t safety_output_emergency_stop;
    uint32_t safety_output_not_emergency_stop;
    uint32_t safety_output_robot_moving;
    uint32_t safety_output_robot_steady;
    uint32_t safety_output_reduced_mode;
    uint32_t safety_output_not_reduced_mode;
    uint32_t safety_output_safe_home;
    uint32_t safety_output_robot_not_stopping;
    uint32_t safety_output_safetyguard_stop;

    int tp_3pe_for_handguide; ///< \~chinese 是否将示教器三档位开关作为拖动功能开关 \~english Whether to use the three-position switch of the teach pendant as a hand guiding function switch
    int allow_manual_high_speed; ///< \~chinese 手动模式下允许高速运行 /~english Allow high-speed operation in manual mode
};

inline std::ostream &operator<<(std::ostream &os,
                                const RobotSafetyParameterRange &vd)
{
    // os << (int)vd;
    return os;
}

struct WObjectData
{
    /// \~chinese 是否为外部工具 \~english Whether it is an external tool
    bool remote_tool{ false };

    /// \~chinese 工件坐标系耦合的 \~english Coupled with the workpiece
    /// coordinate system
    std::string attach_frame{ "" };

    /// \~english User coordinate system. \~chinese 用户坐标系
    /// \~chinese 如果 robhold 为 false, 那 uframe 的数值是基于 world \~english
    /// If robhold is false, the values of uframe are based on world.
    /// \~chinese 否则，uframe 的数值是基于 flange \~english Otherwise, the
    /// values of uframe are based on flange.
    std::vector<double> user_coord{ std::vector<double>(6, 0) };

    /// \~chinese 工件坐标系，基于 uframe \~english tool coordinate system,
    /// based on uframe
    std::vector<double> obj_coord{ std::vector<double>(6, 0) };
};

inline std::ostream &operator<<(std::ostream &os, WObjectData p)
{
    return os;
}


struct VibrationRecalibrationParameter{
    double mass;    // 负载质量
    std::vector<double> cog;    // 负载质心
    std::vector<double> inertia;    // 负载惯量
    std::vector<std::vector<double>> points; // 路点，关节角
    std::vector<std::vector<double>> stiff_section; // 关节刚度数据
    std::vector<std::vector<double>> stiff_param; // 关节刚度数据
};

inline std::ostream &operator<<(std::ostream &os, const VibrationRecalibrationParameter p)
{
    return os;
}

/// \~chinese 接口函数返回值定义 \~english Error codes definition
///
/// \~chinese 整数为警告，负数为错误，0为没有错误也没有警告 \~english whole
/// number is warning, negative number is error, 0 is no error and no warning
#define ENUM_AuboErrorCodes_DECLARES                                           \
    ENUM_ITEM(AUBO_OK, 0, "Success")                                           \
    ENUM_ITEM(AUBO_BAD_STATE, 1, "State error")                                \
    ENUM_ITEM(AUBO_QUEUE_FULL, 2, "Planning queue full")                       \
    ENUM_ITEM(AUBO_BUSY, 3, "The previous command is executing")               \
    ENUM_ITEM(AUBO_TIMEOUT, 4, "Timeout")                                      \
    ENUM_ITEM(AUBO_INVL_ARGUMENT, 5, "Invalid parameters")                     \
    ENUM_ITEM(AUBO_NOT_IMPLETEMENT, 6, "Interface not implemented")            \
    ENUM_ITEM(AUBO_NO_ACCESS, 7, "Cannot access")                              \
    ENUM_ITEM(AUBO_CONN_REFUSED, 8, "Connection refused")                      \
    ENUM_ITEM(AUBO_CONN_RESET, 9, "Connection is reset")                       \
    ENUM_ITEM(AUBO_INPROGRESS, 10, "Execution in progress")                    \
    ENUM_ITEM(AUBO_EIO, 11, "Input/Output error")                              \
    ENUM_ITEM(AUBO_NOBUFFS, 12, "")                                            \
    ENUM_ITEM(AUBO_REQUEST_IGNORE, 13, "Request was ignored")                  \
    ENUM_ITEM(AUBO_ALGORITHM_PLAN_FAILED, 14,                                  \
              "Motion planning algorithm error")                               \
    ENUM_ITEM(AUBO_VERSION_INCOMPAT, 15, "Interface version unmatch")          \
    ENUM_ITEM(AUBO_DIMENSION_ERR, 16,                                          \
              "Input parameter dimension is incorrect")                        \
    ENUM_ITEM(AUBO_SINGULAR_ERR, 17, "Input configuration may be singular")    \
    ENUM_ITEM(AUBO_POS_BOUND_ERR, 18,                                          \
              "Input position boundary exceeds the limit range")               \
    ENUM_ITEM(AUBO_INIT_POS_ERR, 19, "Initial position input is unreasonable") \
    ENUM_ITEM(AUBO_ELP_SETTING_ERR, 20, "Envelope body setting error")         \
    ENUM_ITEM(AUBO_TRAJ_GEN_FAIL, 21, "Trajectory generation failed")          \
    ENUM_ITEM(AUBO_TRAJ_SELF_COLLISION, 22, "Trajectory self collision")       \
    ENUM_ITEM(                                                                 \
        AUBO_IK_NO_CONVERGE, 23,                                               \
        "Inverse kinematics computation did not converge; computation failed") \
    ENUM_ITEM(AUBO_IK_OUT_OF_RANGE, 24,                                        \
              "Inverse kinematics result out of robot range")                  \
    ENUM_ITEM(AUBO_IK_CONFIG_DISMATCH, 25,                                     \
              "Inverse kinematics input configuration contains errors")        \
    ENUM_ITEM(AUBO_IK_JACOBIAN_FAILED, 26,                                     \
              "The calculation of the inverse Jacobian matrix failed")         \
    ENUM_ITEM(AUBO_IK_NO_SOLU, 27,                                             \
              "The target point has solutions, but it has exceeded the joint " \
              "limit conditions")                                              \
    ENUM_ITEM(AUBO_IK_UNKOWN_ERROR, 28, "Inverse kinematics unkown error")     \
    ENUM_ITEM(AUBO_MOVE_IGNORED_SERVOMODE, 29,                                 \
              "Robot is in servo mode where movement is disabled")             \
    ENUM_ITEM(AUBO_MOVE_INVALID_SPEED_VALUE, 30,                        \
              "Movement speed must be a valid positive value (cannot be zero or negative)") \
    ENUM_ITEM(AUBO_MOVE_INVALID_ACCELERATION_VALUE, 31,                 \
              "Movement acceleration must be a valid positive value (cannot be zero or negative)") \
    ENUM_ITEM(AUBO_INVALID_FILE_PATH, 32,                 \
              "Please verify the file path. It appears to be invalid.") \
    ENUM_ITEM(AUBO_INST_QUEUED, 100, "Instruction pused into queue succeed")   \
    ENUM_ITEM(AUBO_INTERNAL_ERR, 101, "Internal error caused by alg .etc.")    \
    ENUM_ITEM(AUBO_BADSTATE_THREAD_DETACHED, 200,                               \
              "Bad state: Operation not allowed on detached thread")          \
    ENUM_ITEM(AUBO_BADSTATE_THREAD_KILLED, 201,                              \
              "Bad state: Operation not allowed on killed thread")            \
    ENUM_ITEM(AUBO_BADSTATE_TASK_NOT_FOUND, 202,                             \
              "Bad state: Specified task id does not exist in the task queue")\
    ENUM_ITEM(AUBO_BADSTATE_RTM_NOT_STARTED, 203,                            \
              "Bad state: RuntimeMachine has not been started yet")           \
    ENUM_ITEM(AUBO_BADSTATE_RTM_NOT_STOPPED, 204,                            \
              "Bad state: RuntimeMachine must be in Stopped state for this operation") \
    ENUM_ITEM(AUBO_BADSTATE_RTM_NOT_PAUSED, 205,                             \
              "Bad state: RuntimeMachine must be in Paused state for this operation") \
    ENUM_ITEM(AUBO_BADSTATE_RTM_ABORTING, 206, "Bad state: RuntimeMachine is in aborting state") \
    ENUM_ITEM(AUBO_BADSTATE_PSTOP, 207, "Bad state: Operation blocked by protective stop") \
    ENUM_ITEM(AUBO_BADSTATE_ROBOT_ESTOP, 208, "Bad state: Robot emergency stop triggered") \
    ENUM_ITEM(AUBO_BADSTATE_SYSTEM_ESTOP, 209, "Bad state: System emergency stop triggered") \
    ENUM_ITEM(AUBO_BADSTATE_INVALID_ROBOT_MODE, 210,                         \
              "Bad state: Robot is not in required operation mode")           \
    ENUM_ITEM(AUBO_BADSTATE_INVALID_SAFETY_MODE, 211,                        \
              "Bad state: Robot is not in required safety mode")              \
    ENUM_ITEM(AUBO_BADSTATE_ROBOT_NOT_RUNNING, 212,                          \
              "Bad state: Robot must be in Running mode for this operation")  \
    ENUM_ITEM(AUBO_BADSTATE_ROBOT_NOT_POWERED_OFF, 213,                      \
              "Bad state: Robot must be in PowerOff mode for this operation") \
    ENUM_ITEM(AUBO_BADSTATE_SERIAL_OPEN_FAILED, 214, "Bad state: Failed to open serial device") \
    ENUM_ITEM(AUBO_BADSTATE_SERIAL_NOT_A_TERMINAL, 215,                       \
              "Bad state: Specified device is not a terminal")                \
    ENUM_ITEM(AUBO_BADSTATE_SERIAL_CONFIG_FAILED, 216,                        \
              "Bad state: Failed to configure serial port parameters")        \
    ENUM_ITEM(AUBO_BADSTATE_KINEMATICS_COMPENSATE_FAILED, 217,                \
              "Bad state: Failed to set kinematics compensation parameters")  \
    ENUM_ITEM(AUBO_BADSTATE_ROBOT_NOT_STEADY, 218, "Bad state: Robot is not in steady state") \
    ENUM_ITEM(AUBO_BADSTATE_FREE_DRIVE_ACTIVE, 219, "Bad state: Free-drive mode is active") \
    ENUM_ITEM(AUBO_BADSTATE_FORCE_CTRL_ACTIVE, 220, "Bad state: Force control mode is active") \
    ENUM_ITEM(AUBO_BADSTATE_SIMULATION_MODE_ACTIVE, 221,                      \
              "Bad state: Operation not allowed in simulation mode")          \
    ENUM_ITEM(AUBO_BADSTATE_MB_ERROR, 222, "Bad state: Modbus signal has error") \
    ENUM_ITEM(AUBO_BADSTATE_MB_TIMEOUT, 223, "Bad state: Modbus signal timeout") \
    ENUM_ITEM(AUBO_ERR_UNKOWN, 99999, "Unkown error occurred.")

/**
 * The RuntimeState enum
 *
 */
#define ENUM_RuntimeState_DECLARES                           \
    ENUM_ITEM(Running, 0, "正在运行中")                        \
    ENUM_ITEM(Retracting, 1, "倒退")                          \
    ENUM_ITEM(Pausing, 2, "暂停中")                           \
    ENUM_ITEM(Paused, 3, "暂停状态")                          \
    ENUM_ITEM(Stepping, 4, "单步执行中")                       \
    ENUM_ITEM(Stopping, 5, "受控停止中(保持原有轨迹)")           \
    ENUM_ITEM(Stopped, 6, "已停止")                           \
    ENUM_ITEM(Aborting, 7, "停止(最大速度关节运动停机)")

/**
 * \chinese
 * @brief The RobotModeType enum
 *
 * 硬件强相关
 * \endchinese
 *
 * \english
 * @brief The RobotModeType enum
 *
 * Hardware related
 * \endenglish
 */
#define ENUM_RobotModeType_DECLARES                                                                     \
    ENUM_ITEM(NoController, -1,          "提供给示教器使用的, 如果aubo_control进程崩溃则会显示为NoController") \
    ENUM_ITEM(Disconnected, 0,           "没有连接到机械臂本体(控制器与接口板断开连接或是 EtherCAT 等总线断开)")  \
    ENUM_ITEM(ConfirmSafety, 1,          "正在进行安全配置, 断电状态下进行")                                  \
    ENUM_ITEM(Booting, 2,                "机械臂本体正在上电初始化")                                         \
    ENUM_ITEM(PowerOff, 3,               "机械臂本体处于断电状态")                                           \
    ENUM_ITEM(PowerOn, 4,                "机械臂本体上电成功, 刹车暂未松开(抱死), 关节初始状态未获取")            \
    ENUM_ITEM(Idle, 5,                   "机械臂上电成功, 刹车暂未松开(抱死), 电机不通电, 关节初始状态获取完成")    \
    ENUM_ITEM(BrakeReleasing, 6,         "机械臂上电成功, 刹车正在松开")                                      \
    ENUM_ITEM(BackDrive, 7,              "反向驱动：刹车松开, 电机不通电")                                    \
    ENUM_ITEM(Running, 8,                "机械臂刹车松开, 运行模式, 控制权由硬件移交给软件")                     \
    ENUM_ITEM(Maintaince, 9,             "维护模式: 包括固件升级、参数写入等")                                 \
    ENUM_ITEM(Error, 10,                 "")                                                              \
    ENUM_ITEM(PowerOffing, 11,           "机械臂本体处于断电过程中")

#define ENUM_SafetyModeType_DECLARES                           \
    ENUM_ITEM(Undefined, 0,          "安全状态待定")             \
    ENUM_ITEM(Normal, 1,             "正常运行模式")             \
    ENUM_ITEM(ReducedMode, 2,        "缩减运行模式")             \
    ENUM_ITEM(Recovery, 3,           "启动时如果在安全限制之外, 机器人将进入recovery模式") \
    ENUM_ITEM(Violation, 4,          "超出安全限制（根据安全配置, 例如速度超限等）") \
    ENUM_ITEM(ProtectiveStop, 5,     "软件触发的停机（保持轨迹, 不抱闸, 不断电）") \
    ENUM_ITEM(SafeguardStop, 6,      "IO触发的防护停机（不保持轨迹, 抱闸, 不断电）") \
    ENUM_ITEM(SystemEmergencyStop,7, "系统急停：急停信号由外部输入(可配置输入), 不对外输出急停信号") \
    ENUM_ITEM(RobotEmergencyStop, 8, "机器人急停：控制柜急停输入或者示教器急停按键触发, 对外输出急停信号") \
    ENUM_ITEM(Fault, 9,              "机械臂硬件故障或者系统故障")
    //ValidateJointId

/**
 * \chinese
 * 根据ISO 10218-1:2011(E) 5.7节
 * Automatic: In automatic mode, the robot shall execute the task programme and
 * the safeguarding measures shall be functioning. Automatic operation shall be
 * prevented if any stop condition is detected. Switching from this mode shall
 * result in a stop.
 * \endchinese
 * \english
 * Based on ISO 10218-1:2011(E) Section 5.7
 * Automatic: In automatic mode, the robot shall execute the task programme and
 * the safeguarding measures shall be functioning. Automatic operation shall be
 * prevented if any stop condition is detected. Switching from this mode shall
 * result in a stop.
 * \endenglish
 */
#define ENUM_OperationalModeType_DECLARES                                                \
    ENUM_ITEM(Disabled, 0, "禁用模式: 不使用 Operational Mode")                              \
    ENUM_ITEM(Automatic, 1, "自动模式: 机器人正常工作模式, 运行速度不会被限制 (auto mode: robot normal operation, speed will not be limited)")            \
    ENUM_ITEM(Manual, 2, "手动模式: 机器人编程示教模式(T1), 机器人运行速度将会被限制或者机器人程序校验模式(T2) (manual mode: robot programming teaching mode (T1), robot running speed will be limited or robot program verification mode (T2)") \

/**
 * \~chinese 机器人的控制模式, 最终的控制对象 \~english Robot control mode, the final control object
 */
#define ENUM_RobotControlModeType_DECLARES                 \
    ENUM_ITEM(Unknown, 0,   "未知的控制模式 (unknown control mode)")                \
    ENUM_ITEM(Position, 1,  "位置控制  movej (position control)")              \
    ENUM_ITEM(Speed, 2,     "速度控制  speedj/speedl (speed control)")      \
    ENUM_ITEM(Servo, 3,     "位置控制  servoj (position control)")             \
    ENUM_ITEM(Freedrive, 4, "拖动示教  freedrive_mode")     \
    ENUM_ITEM(Force, 5,     "末端力控  force_mode")         \
    ENUM_ITEM(Torque, 6,    "关节力矩控制 (joint torque control)")                  \
    ENUM_ITEM(Collision, 7,    "碰撞模式 (collision mode)") \

#define ENUM_JointServoModeType_DECLARES                  \
    ENUM_ITEM(Unknown, -1, "未知")                         \
    ENUM_ITEM(Open, 0, "开环模式 (open loop mode)")                          \
    ENUM_ITEM(Current, 1, "电流伺服模式 (current servo mode)")                    \
    ENUM_ITEM(Velocity, 2, "速度伺服模式 (speed servo mode)")                   \
    ENUM_ITEM(Position, 3, "位置伺服模式 (position servo mode)")                   \
    ENUM_ITEM(Torque, 4, "力矩伺服模式 (torque servo mode)") \

#define ENUM_JointStateType_DECLARES                             \
    ENUM_ITEM(Poweroff, 0, "节点未连接到接口板或者已经断电 (node not conected to interface board or already powered off)")          \
    ENUM_ITEM(Idle, 2,        "节点空闲 (node idle)")                         \
    ENUM_ITEM(Fault, 3,       "节点错误, 节点停止伺服运动, 刹车抱死 (node error, node stopped servo move, brake engaged)") \
    ENUM_ITEM(Running, 4,     "节点伺服 (node servo)")                         \
    ENUM_ITEM(Bootload, 5,     "节点bootloader状态, 暂停一切通讯 (node bootloader state, pause all communication)") \

#define ENUM_StandardInputAction_DECLARES                        \
    ENUM_ITEM(Default, 0,  "无触发")                              \
    ENUM_ITEM(Handguide, 1, "拖动示教，高电平触发")                 \
    ENUM_ITEM(GoHome, 2, "运动到工程初始位姿，高电平触发")            \
    ENUM_ITEM(StartProgram, 3, "开始工程，上升沿触发")              \
    ENUM_ITEM(StopProgram, 4, "停止工程，上升沿触发")               \
    ENUM_ITEM(PauseProgram, 5, "暂停工程，上升沿触发")              \
    ENUM_ITEM(PopupDismiss, 6, "消除弹窗，上升沿触发")              \
    ENUM_ITEM(PowerOn, 7, "机器人上电/松刹车，上升沿触发")           \
    ENUM_ITEM(PowerOff, 8, "机器人抱死刹车/断电，上升沿触发")         \
    ENUM_ITEM(ResumeProgram, 9, "恢复工程，上升沿触发")             \
    ENUM_ITEM(SlowDown1, 10, "机器人减速触发1，高电平触发")          \
    ENUM_ITEM(SlowDown2, 11, "机器人减速触发2，高电平触发")          \
    ENUM_ITEM(SafeStop, 12, "安全停止，高电平触发")                 \
    ENUM_ITEM(RunningGuard, 13, "信号，高电平有效")                \
    ENUM_ITEM(MoveToFirstPoint, 14, "运动到工程初始位姿，高电平触发") \
    ENUM_ITEM(xSlowDown1, 15, "机器人减速触发1，低电平触发")         \
    ENUM_ITEM(xSlowDown2, 16, "机器人减速触发2，低电平触发")         \
    ENUM_ITEM(ConveyorTrack, 17, "传送带1检测到物品触发，高电平触发")  \
    ENUM_ITEM(xConveyorTrack, 18, "传送带1检测到物品触发，低电平触发") \
    ENUM_ITEM(UnlockProtectiveStop, 19, "解除保护性停止，上升沿触发") \
    ENUM_ITEM(ArbitraryResumeProgram , 20, "恢复工程，不检查当前位置和暂停点之间的距离，上升沿触发")

#define ENUM_StandardOutputRunState_DECLARES             \
    ENUM_ITEM(None, 0,     "标准输出状态未定义")            \
    ENUM_ITEM(StopLow, 1, "低电平指示工程停止")             \
    ENUM_ITEM(StopHigh, 2, "高电平指示机器人停止")          \
    ENUM_ITEM(RunningHigh, 3,  "指示工程正在运行")         \
    ENUM_ITEM(PausedHigh, 4,  "指示工程已经暂停")          \
    ENUM_ITEM(AtHome, 5, "高电平指示机器人正在拖动")         \
    ENUM_ITEM(Handguiding, 6, "高电平指示机器人正在拖动")    \
    ENUM_ITEM(PowerOn, 7, "高电平指示机器人已经上电")           \
    ENUM_ITEM(RobotEmergencyStop, 8, "高电平指示机器人急停按下") \
    ENUM_ITEM(SystemEmergencyStop, 9, "高电平指示外部输入系统急停按下") \
    ENUM_ITEM(InternalEmergencyStop, 8, "高电平指示机器人急停按下") \
    ENUM_ITEM(ExternalEmergencyStop, 9, "高电平指示外部输入系统急停按下") \
    ENUM_ITEM(SystemError, 10, "系统错误，包括故障、超限、急停、安全停止、防护停止 ") \
    ENUM_ITEM(NotSystemError, 11, "无系统错误，包括普通模式、缩减模式和恢复模式 ") \
    ENUM_ITEM(RobotOperable, 12, "机器人可操作，机器人上电且松刹车了 ") \
    ENUM_ITEM(OperationalMode, 13, "高电平指示自动模式，低电平指示手动模式") \
    ENUM_ITEM(SafeguardStop, 14, "高电平指示处于安全停止状态") \
    ENUM_ITEM(ProtectiveStop, 15, "高电平指示处于防护停止状态") \
    ENUM_ITEM(ProgramAborted, 16, "高电平指示工程意外停止") \
    ENUM_ITEM(WaypointArrived, 17, "高电平指示机器人到达路点")

#define ENUM_SafetyInputAction_DECLARES                        \
    ENUM_ITEM(Unassigned, 0, "安全输入未分配动作")                \
    ENUM_ITEM(EmergencyStop, 1, "安全输入触发急停")               \
    ENUM_ITEM(SafeguardStop, 2, "安全输入触发防护停止, 边沿触发")   \
    ENUM_ITEM(SafeguardReset, 3, "安全输入触发防护重置, 边沿触发")  \
    ENUM_ITEM(ThreePositionSwitch, 4, "3档位使能开关")           \
    ENUM_ITEM(OperationalMode, 5, "切换自动模式和手动模式")        \
    ENUM_ITEM(HandGuide, 6, "拖动示教")              \
    ENUM_ITEM(ReducedMode, 7, "安全参数切换1(缩减模式)，序号越低优先级越高，三路输出都无效时，选用第0组安全参数")         \
    ENUM_ITEM(AutomaticModeSafeguardStop, 8, "自动模式下防护停机输入(需要配置三档位使能设备)") \
    ENUM_ITEM(AutomaticModeSafeguardReset, 9, "自动模式下上升沿触发防护重置(需要配置三档位使能设备)")

#define ENUM_SafetyOutputRunState_DECLARES                         \
    ENUM_ITEM(Unassigned, 0, "安全输出未定义")                       \
    ENUM_ITEM(SystemEmergencyStop, 1, "输出高当有机器人急停输入或者急停按键被按下")         \
    ENUM_ITEM(NotSystemEmergencyStop, 2, "输出低当有机器人急停输入或者急停按键被按下")      \
    ENUM_ITEM(RobotMoving, 3, "输出高当有关节运动速度超过 0.1rad/s")                     \
    ENUM_ITEM(RobotNotMoving, 4, "输出高当所有的关节运动速度不超过 0.1rad/s")             \
    ENUM_ITEM(ReducedMode, 5, "输出高当机器人处于缩减模式")                       \
    ENUM_ITEM(NotReducedMode, 6, "输出高当机器人不处于缩减模式")                   \
    ENUM_ITEM(SafeHome, 7, "输出高当机器人已经处于安全Home位姿")                    \
    ENUM_ITEM(RobotNotStopping, 8, "输出低当机器人正在急停或者安全停止中")

#define ENUM_PayloadIdentifyMoveAxis_DECLARES      \
    ENUM_ITEM(Joint_2_6, 0,"第2和6关节运动")         \
    ENUM_ITEM(Joint_3_6, 1,"第3和6关节运动")         \
    ENUM_ITEM(Joint_4_6, 2,"第4和6关节运动")         \
    ENUM_ITEM(Joint_4_5_6, 3,"第4、5、6关节运动")    \

#define ENUM_EnvelopingShape_DECLARES \
    ENUM_ITEM(Cube, 1,"立方体") \
    ENUM_ITEM(Column, 2,"柱状体") \
    ENUM_ITEM(Stl, 3,"以STL文件的形式描述负载碰撞集合体")

#define ENUM_TaskFrameType_DECLARES                           \
    ENUM_ITEM(NONE, 0,"")        \
    ENUM_ITEM(POINT_FORCE, 1, "力控坐标系发生变换, 使得力控参考坐标系的y轴沿着机器人TCP指向力控所选特征的原点, x和z轴取决于所选特征的原始方向" \
                              "力控坐标系发生变换, 使得力控参考坐标系的y轴沿着机器人TCP指向力控所选特征的原点, x和z轴取决于所选特征的原始方向" \
                              "机器人TCP与所选特征的起点之间的距离至少为10mm" \
                              "优先选择X轴, 为所选特征的X轴在力控坐标系Y轴垂直平面上的投影, 如果所选特征的X轴与力控坐标系的Y轴平行, " \
                              "通过类似方法确定力控坐标系Z轴, Y-X或者Y-Z轴确定之后, 通过右手法则确定剩下的轴") \
    ENUM_ITEM(FRAME_FORCE, 2,"力控坐标系不发生变换 SIMPLE_FORC") \
    ENUM_ITEM(MOTION_FORCE, 3,"力控坐标系发生变换, 使得力控参考坐标系的x轴为机器人TCP速度在所选特征x-y平面上的投影y轴将垂直于机械臂运动, 并在所选特征的x-y平面内")\
    ENUM_ITEM(TOOL_FORCE, 4,"以工具末端坐标系作为力控参考坐标系")

#ifdef ERROR
#undef ERROR
#endif

#define ENUM_TraceLevel_DECLARES  \
    ENUM_ITEM(FATAL, 0, "") \
    ENUM_ITEM(ERROR, 1, "") \
    ENUM_ITEM(WARNING, 2, "") \
    ENUM_ITEM(INFO, 3, "") \
    ENUM_ITEM(DEBUG, 4, "")

#define ENUM_AxisModeType_DECLARES  \
    ENUM_ITEM(NoController, -1, "提供给示教器使用的, 如果aubo_control进程崩溃则会显示为NoController") \
    ENUM_ITEM(Disconnected, 0, "未连接") \
    ENUM_ITEM(PowerOff, 1, "断电") \
    ENUM_ITEM(BrakeReleasing, 2, "刹车松开中") \
    ENUM_ITEM(Idle, 3, "空闲") \
    ENUM_ITEM(Running, 4, "运行中") \
    ENUM_ITEM(Fault, 5, "错误状态")

#define ENUM_HandleStateType_DECLARES  \
    ENUM_ITEM(Disconnected, 0, "未连接") \
    ENUM_ITEM(Init, 1, "初始化中") \
    ENUM_ITEM(Connected, 2, "已连接") \
    ENUM_ITEM(Lock, 3, "锁定") \
    ENUM_ITEM(Fault, 4, "错误状态") \

#define ENUM_HandleModeType_DECLARES  \
    ENUM_ITEM(None, 0, "不支持手柄") \
    ENUM_ITEM(Default, 1, "S等系列默认手柄") \
    ENUM_ITEM(MultiFuncG1, 2, "G系列第一代多功能手柄") \

#define ENUM_SafeguedStopType_DECLARES  \
    ENUM_ITEM(None, 0, "无安全停止") \
    ENUM_ITEM(SafeguedStopIOInput, 1, "安全停止(IO输入)") \
    ENUM_ITEM(SafeguedStop3PE, 2, "安全停止(三态开关)") \
    ENUM_ITEM(SafeguedStopOperational, 3, "安全停止(操作模式)")

#define ENUM_RobotEmergencyStopType_DECLARES  \
    ENUM_ITEM(RobotEmergencyStopNone, 0, "无紧急停止") \
    ENUM_ITEM(RobotEmergencyStopControlBox, 1, "紧急停止(控制柜急停)") \
    ENUM_ITEM(RobotEmergencyStopTeachPendant, 2, "紧急停止(示教器急停)") \
    ENUM_ITEM(RobotEmergencyStopHandle, 3, "紧急停止(手柄急停)") \
    ENUM_ITEM(RobotEmergencyStopEI, 4, "紧急停止(固定IO急停)")

#define ENUM_RobotIOType_DECLARES \
    ENUM_ITEM(IONone, 0, "无IO") \
    ENUM_ITEM(StandardDigitalOutput, 1, "标准数字输出IO") \
    ENUM_ITEM(ToolDigitalOutput, 2, "工具端数字输出IO") \
    ENUM_ITEM(ConfigurableDigitalOutput, 3, "可配置数字输出IO") \
    ENUM_ITEM(StandardDigitalInput, 4, "标准数字输入IO") \
    ENUM_ITEM(ToolDigitalInput, 5, "工具端数字输入IO") \
    ENUM_ITEM(ConfigurableDigitalInput, 6, "可配置数字输入IO") \
    ENUM_ITEM(StandardAnalogOutput, 7, "标准模拟输出IO") \
    ENUM_ITEM(ToolAnalogOutput, 8, "工具端模拟输出IO") \
    ENUM_ITEM(StandardAnalogInput, 9, "标准模拟输入IO") \
    ENUM_ITEM(ToolAnalogInput, 10, "工具端模拟输入IO")

#define ENUM_ITEM(c, n, ...) c = n,
enum AuboErrorCodes : int
{
    ENUM_AuboErrorCodes_DECLARES
};

enum class RuntimeState : int
{
    ENUM_RuntimeState_DECLARES
};

enum class RobotModeType : int
{
    ENUM_RobotModeType_DECLARES
};

enum class AxisModeType : int
{
    ENUM_AxisModeType_DECLARES
};

enum class HandleStateType : int
{
    ENUM_HandleStateType_DECLARES
};

enum class HandleModeType : int
{
    ENUM_HandleModeType_DECLARES
};

/**
 * \~chinese 安全状态: \~english Safety Mode
 *
 */
enum class SafetyModeType : int
{
    ENUM_SafetyModeType_DECLARES
};

/**
 * \~chinese 操作模式 \~english Operational Mode
 */
enum class OperationalModeType : int
{
    ENUM_OperationalModeType_DECLARES
};

/**
 * \~chinese 机器人控制模式 \~english Robot Control Mode
 */
enum class RobotControlModeType : int
{
    ENUM_RobotControlModeType_DECLARES
};

/**
 * \~chinese 关节伺服模式 \~english Joint Servo Mode
 */
enum class JointServoModeType : int
{
    ENUM_JointServoModeType_DECLARES
};

/**
 * \~chinese 关节状态 \~english Joint State
 */
enum class JointStateType : int
{
    ENUM_JointStateType_DECLARES
};

/**
 * \~chinese 标准输出运行状态 \~english Standard Output Run State
 */
enum class StandardOutputRunState : int
{
    ENUM_StandardOutputRunState_DECLARES
};

/**
 * @brief The StandardInputAction enum
 */
enum class StandardInputAction : int
{
    ENUM_StandardInputAction_DECLARES
};

enum class SafetyInputAction : int
{
    ENUM_SafetyInputAction_DECLARES
};

enum class SafetyOutputRunState : int
{
    ENUM_SafetyOutputRunState_DECLARES
};

enum TaskFrameType
{
    ENUM_TaskFrameType_DECLARES
};

enum EnvelopingShape : int
{
    ENUM_EnvelopingShape_DECLARES
};

enum PayloadIdentifyMoveAxis : int
{
    ENUM_PayloadIdentifyMoveAxis_DECLARES
};

enum TraceLevel
{
    ENUM_TraceLevel_DECLARES
};

enum SafeguedStopType : int
{
    ENUM_SafeguedStopType_DECLARES
};

enum RobotEmergencyStopType : int
{
    ENUM_RobotEmergencyStopType_DECLARES
};

enum RobotIOType : int
{
    ENUM_RobotIOType_DECLARES
};
#undef ENUM_ITEM

#define DECL_TO_STRING_FUNC(ENUM)                             \
    inline std::string toString(ENUM v)                       \
    {                                                         \
        using T = ENUM;                                       \
        std::string name = #ENUM ".";                         \
        ENUM_##ENUM##_DECLARES                                \
                                                              \
            return #ENUM ".Unkown";                           \
    }                                                         \
    inline std::ostream &operator<<(std::ostream &os, ENUM v) \
    {                                                         \
        os << toString(v);                                    \
        return os;                                            \
    }

#define ENUM_ITEM(c, n, ...) \
    if (v == T::c) {         \
        return name + #c;    \
    }

DECL_TO_STRING_FUNC(RuntimeState)
DECL_TO_STRING_FUNC(RobotModeType)
DECL_TO_STRING_FUNC(AxisModeType)
DECL_TO_STRING_FUNC(SafetyModeType)
DECL_TO_STRING_FUNC(OperationalModeType)
DECL_TO_STRING_FUNC(RobotControlModeType)
DECL_TO_STRING_FUNC(JointServoModeType)
DECL_TO_STRING_FUNC(JointStateType)
DECL_TO_STRING_FUNC(StandardInputAction)
DECL_TO_STRING_FUNC(StandardOutputRunState)
DECL_TO_STRING_FUNC(SafetyInputAction)
DECL_TO_STRING_FUNC(SafetyOutputRunState)
DECL_TO_STRING_FUNC(TaskFrameType)
DECL_TO_STRING_FUNC(TraceLevel)
DECL_TO_STRING_FUNC(HandleModeType)
DECL_TO_STRING_FUNC(HandleStateType)
DECL_TO_STRING_FUNC(RobotIOType)

#undef ENUM_ITEM

enum class ForceControlState
{
    Stopped,
    Starting,
    Stropping,
    Running
};

enum class RefFrameType
{
    None, ///
    Tool, ///< \~chinese 工具坐标系 \~english Tool coordinate system
    Path, ///< \~chinese 轨迹坐标系 \~english Trajectory coordinate system
    Base  ///< \~chinese 基坐标系 \~english Base coordinate system
};

/// \~chinese 圆周运动参数定义 \~english Circular motion parameters definition
struct CircleParameters
{
    std::vector<double> pose_via; ///< \~chinese 圆周运动途中点的位姿 \~english Pose of the intermediate point in circular motion
    std::vector<double> pose_to; ///< \~chinese 圆周运动结束点的位姿 \~english Pose of the end point in circular motion
    double a; ///< \~chinese 加速度, 单位: m/s^2 \~english Acceleration, unit: m/s^2
    double v; ///< \~chinese 速度，单位: m/s \~english Speed, unit: m/s
    double blend_radius; ///< \~chinese 交融半径,单位: m \~english Blending radius, unit: m
    double duration; ///< \~chinese 运行时间，单位: s \~english Running time, unit: s
    double helix;
    double spiral;
    double direction;
    int loop_times; ///< \~chinese 暂不支持 \~english Currently not supported
};

inline std::ostream &operator<<(std::ostream &os, CircleParameters p)
{
    return os;
}

struct SpiralParameters
{
    std::vector<double> frame; ///< \~chinese 参考点，螺旋线的中心点和参考坐标系 \~english Reference point, the center point of the spiral and the reference coordinate system
    int plane; ///< \~chinese 参考平面选择 0-XY 1-YZ 2-ZX \~english Reference plane selection 0-XY 1-YZ 2-ZX
    double angle; ///< \~chinese 转动的角度，如果为正数，机器人逆时针旋转 \~english The angle of rotation, if positive, the robot rotates counterclockwise
    double spiral; ///< \~chinese 正数外扩 \~english Positive outward
    double helix;  ///< \~chinese 正数上升 \~english Positive upward
};

inline std::ostream &operator<<(std::ostream &os, SpiralParameters p)
{
    return os;
}

struct Enveloping
{
    EnvelopingShape shape; // \~chinese 包络体形状 \~english Enveloping shape
    std::vector<double> ep_args; // \~chinese 包络体组合，shape为None或Stl时无需对ep_args赋值; \~english Enveloping combination, when shape is None or Stl, no need to assign value to ep_args.
                 // \~chinese shape为Cube时ep_args有9个元素，分别为xmin,xmax,ymin,ymax,zmin,zmax,rx,ry,rz; \~english When shape is Cube, ep_args has 9 elements, which are xmin, xmax, ymin, ymax, zmin, zmax, rx, ry, rz;
                 // \~chinese shape为Column时ep_args有5个元素，分别为radius,height,rx,ry,rz; \~english When shape is Column, ep_args has 5 elements, which are radius, height, rx, ry, rz;
    std::string stl_path; // \~chinese stl的路径(绝对路径)，stl文件需为二进制文件, \~english Path of the stl file (absolute path), the stl file must be a binary file, \~chinese shape设置为Stl时，此项生效 \~english When shape is set to Stl, this item takes effect
};

inline std::ostream &operator<<(std::ostream &os, Enveloping p)
{
    return os;
}

/// \~chinese 用于负载辨识的轨迹配置 \~english Trajectory configuration for
/// payload identification
struct TrajConfig
{
    std::vector<Enveloping> envelopings; // \~chinese 包络体组合 \~english Enveloping combination
    PayloadIdentifyMoveAxis move_axis; // \~chinese 运动的轴(ID), 下标从0开始 \~english Axis of movement (ID), index starts from 0
    std::vector<double> init_joint; // \~chinese 关节初始位置 \~english Initial joint positions
    std::vector<double> upper_joint_bound; // \~chinese 运动轴上限 \~english Upper joint limits
    std::vector<double> lower_joint_bound; // \~chinese 运动轴下限 \~english Lower joint limits
    std::vector<double> max_velocity; // \~chinese 关节运动的最大速度，默认值为　3.0 \~english Maximum joint velocities, default value is 3.0
    std::vector<double> max_acceleration; // \~chinese 关节运动的最大加速度，默认值为　5.0 \~english Maximum joint accelerations, default value is 5.0
};

inline std::ostream &operator<<(std::ostream &os, TrajConfig p)
{
    return os;
}

// result with error code
using ResultWithErrno = std::tuple<std::vector<double>, int>;
using ResultWithErrno1 = std::tuple<std::vector<std::vector<double>>, int>;
using ResultWithErrno2 = std::tuple<std::vector<std::string>, int>;
using ResultWithErrno3 = std::tuple<int, int>;

// mass, cog, aom, inertia
using Payload = std::tuple<double, std::vector<double>, std::vector<double>,
                           std::vector<double>>;

// force_offset, com, mass, angle
using ForceSensorCalibResult =
    std::tuple<std::vector<double>, std::vector<double>, double,
               std::vector<double>>;

// force_offset, com, mass, angle error
using ForceSensorCalibResultWithError =
    std::tuple<std::vector<double>, std::vector<double>, double,
               std::vector<double>, double>;

// \~chinese 动力学模型m,d,k \~english Dynamics model m, d, k
using DynamicsModel =
    std::tuple<std::vector<double>, std::vector<double>, std::vector<double>>;

// double xmin;
// double xmax;
// double ymin;
// double ymax;
// double zmin;
// double zmax;
using Box = std::vector<double>;

// double xcbottom;
// double ycbottom;
// double zcbottom;
// double height;
// double radius;
using Cylinder = std::vector<double>;

// double xc;
// double yc;
// double radius;
using Sphere = std::vector<double>;

struct RobotMsg
{
    uint64_t timestamp; ///< \~chinese 时间戳，即系统时间 \~english Timestamp,
                        ///< i.e., system time
    TraceLevel level; ///< \~chinese 日志等级 \~english Log level
    int code;         ///< \~chinese 错误码 \~english Error code
    std::string
        source; ///< \~chinese 发送消息的机器人别名 alias \~english Alias of the
                ///< robot sending the message
                ///< \~chinese 可在 /root/arcs_ws/config/aubo_control.conf
                ///< \~english Can be found in
                ///< /root/arcs_ws/config/aubo_control.conf
                ///< \~chinese 配置文件中查到机器人的alias \~english The robot's
                ///< alias can be found in the configuration file
                ///< /root/arcs_ws/config/aubo_control.conf
    std::vector<std::string> args; ///< \~chinese 机器人参数 \~english Robot parameters
};
using RobotMsgVector = std::vector<RobotMsg>;

struct GripperStatus
{
    std::string name;
    bool is_connected;
    bool is_enabled;
    double position;
    double velocity;
    double force;
    double angle;
    double r_velocity;
    double torque;
    bool object_detection;
    bool motion_state;
    double voltage;
    double temperature;
    int status_code;
};
using GripperStatusVector = std::vector<GripperStatus>;

/// \~chinese RTDE菜单 \~english RTDE menu
struct RtdeRecipe
{
    bool to_server;   ///< \~chinese 输入/输出 \~english Input/Output
    int chanel;       ///< \~chinese 通道 \~english Channel
    double frequency; ///< \~chinese 更新频率 \~english Update frequency
    int trigger; ///< \~chinese 触发方式(该功能暂未实现): 0 - 周期; 1 - 变化
                 ///< \~english Trigger method (this feature is not yet
                 ///< implemented): 0 - Periodic; 1 - Change
    std::vector<std::string> segments; ///< \~chinese 字段列表 \~english segment list
};

/// \~chinese 干涉区配置: 轴对齐长方体 + 余量 + 本区独立 IO(standard DI/DO)。
/// \~english WorldZone zone config: axis-aligned box + margins + per-zone IO.
struct WorldZone
{
    /// \~chinese 区域唯一标识 \~english Unique zone id
    int id{ 0 };
    /// \~chinese 是否启用 \~english Whether enabled
    bool enabled{ false };
    /// \~chinese false=腔内危险(外扩), true=腔外危险(内缩)
    /// \~english false=inside is danger (expand), true=outside is danger (shrink)
    bool outside{ false };
    /// \~chinese 体对角顶点 [x,y,z], 基坐标系, m \~english diagonal vertex
    std::array<double, 3> base_vertex{ { 0, 0, 0 } };
    /// \~chinese 体对角的另一顶点 \~english opposite diagonal vertex
    std::array<double, 3> opposite_vertex{ { 0, 0, 0 } };
    /// \~chinese 工艺余量, m \~english process margin
    double margin{ 0.0 };
    /// \~chinese 工具包络半径, m \~english tool envelope radius
    double tool_radius{ 0.0 };
    /// \~chinese 制动距离余量, m; 启用时必 >0 \~english brake margin, must >0 when enabled
    double brake_margin{ 0.0 };
    /// \~chinese 本区占用输出 standard DO 序号, -1=不绑 \~english per-zone occupancy DO index
    int occupied_do_index{ -1 };
    /// \~chinese 占用极性 \~english occupancy polarity
    bool occupied_active_high{ true };
    /// \~chinese 本区允许输入 standard DI 序号, -1=不绑(恒许可) \~english per-zone permit DI index
    int permit_di_index{ -1 };
    /// \~chinese 允许极性 \~english permit polarity
    bool permit_active_high{ true };

    bool operator==(const WorldZone &o) const
    {
        return id == o.id && enabled == o.enabled && outside == o.outside &&
               base_vertex == o.base_vertex &&
               opposite_vertex == o.opposite_vertex && margin == o.margin &&
               tool_radius == o.tool_radius && brake_margin == o.brake_margin &&
               occupied_do_index == o.occupied_do_index &&
               occupied_active_high == o.occupied_active_high &&
               permit_di_index == o.permit_di_index &&
               permit_active_high == o.permit_active_high;
    }
};

inline std::ostream &operator<<(std::ostream &os, const WorldZone &zone)
{
    (void)zone;
    return os;
}

/// \~chinese 干涉区只读运行状态(聚合)。
/// \~english WorldZone zone read-only runtime state (aggregated).
struct WorldZoneState
{
    /// \~chinese TCP 在任一区内 \~english TCP in any zone
    bool any_occupied{ false };
    /// \~chinese 是否正因干涉区保持 \~english holding due to world zone
    bool holding{ false };
    /// \~chinese 任一区 need_area && !permit \~english any zone blocking
    bool blocking{ false };
    /// \~chinese 导致保持/阻塞的区 id(各区 permit 独立, 看此表定位) \~english blocking zone ids
    std::vector<int> blocking_ids;

    bool operator==(const WorldZoneState &o) const
    {
        return any_occupied == o.any_occupied && holding == o.holding &&
               blocking == o.blocking && blocking_ids == o.blocking_ids;
    }
};

inline std::ostream &operator<<(std::ostream &os, const WorldZoneState &state)
{
    (void)state;
    return os;
}

/// \~chinese 异常类型 \~english Error type
enum error_type
{
    parse_error = -32700,     ///< \~chinese 解析错误 \~english Parse error
    invalid_request = -32600, ///< \~chinese 无效请求 \~english Invalid request
    method_not_found = -32601, ///< \~chinese 方法未找到 \~english Method not found
    invalid_params = -32602, ///< \~chinese 无效参数 \~english Invalid parameters
    internal_error = -32603, ///< \~chinese 内部错误 \~english Internal error
    server_error = -32500, ///< \~chinese 服务器错误 \~english Server error
    invalid = -32400      ///< \~chinese 无效 \~english Invalid
};

/// \~chinese 异常码 \~english Exception code
enum ExceptionCode
{
    EC_DISCONNECTED = -1, ///< \~chinese 断开连接 \~english Disconnected
    EC_NOT_LOGINED = -2,  ///< \~chinese 未登录 \~english Not logged in
    EC_INVAL_SOCKET = -3, ///< \~chinese 无效套接字 \~english Invalid socket
    EC_REQUEST_BUSY = -4, ///< \~chinese 请求繁忙 \~english Request busy
    EC_SEND_FAILED = -5,  ///< \~chinese 发送失败 \~english Send failed
    EC_RECV_TIMEOUT = -6, ///< \~chinese 接收超时 \~english Receive timeout
    EC_RECV_ERROR = -7,   ///< \~chinese 接收错误 \~english Receive error
    EC_PARSE_ERROR = -8,  ///< \~chinese 解析错误 \~english Parse error
    EC_INVALID_REQUEST = -9, ///< \~chinese 无效请求 \~english Invalid request
    EC_METHOD_NOT_FOUND = -10, ///< \~chinese 方法未找到 \~english Method not found
    EC_INVALID_PARAMS = -11, ///< \~chinese 无效参数 \~english Invalid parameters
    EC_INTERNAL_ERROR = -12, ///< \~chinese 内部错误 \~english Internal error
    EC_SERVER_ERROR = -13, ///< \~chinese 服务器错误 \~english Server error
    EC_INVALID = -14       ///< \~chinese 无效 \~english Invalid
};

/// \~chinese 自定义异常类 AuboException \~english Custom exception class
/// AuboException
class AuboException : public std::exception
{
public:
    AuboException(int code, const std::string &prefix,
                  const std::string &message) noexcept
        : code_(code), message_(prefix + "-" + message)
    {
    }

    AuboException(int code, const std::string &message) noexcept
        : code_(code), message_(message)
    {
    }

    error_type type() const
    {
        if (code_ >= -32603 && code_ <= -32600) {
            return static_cast<error_type>(code_);
        } else if (code_ >= -32099 && code_ <= -32000) {
            return server_error;
        } else if (code_ == -32700) {
            return parse_error;
        }
        return invalid;
    }

    int code() const { return code_; }
    const char *what() const noexcept override { return message_.c_str(); }

private:
    int code_;            ///< \~chinese 异常码 \~english Exception code
    std::string message_; ///< \~chinese 异常消息 \~chinese Exception message
};

inline const char *returnValue2Str(int retval)
{
    static const char *retval_str[] = {
#define ENUM_ITEM(n, v, s) s,
        ENUM_AuboErrorCodes_DECLARES
#undef ENUM_ITEM
    };

    enum arcs_index
    {
#define ENUM_ITEM(n, v, s) n##_INDEX,
        ENUM_AuboErrorCodes_DECLARES
#undef ENUM_ITEM
    };

    int index = -1;

#define ENUM_ITEM(n, v, s) \
    if (abs(retval) == v)  \
        index = n##_INDEX;
    ENUM_AuboErrorCodes_DECLARES
#undef ENUM_ITEM

        if (index == -1)
    {
        index = AUBO_ERR_UNKOWN_INDEX;
    }

    return retval_str[(unsigned)index];
}

} // namespace common_interface
} // namespace arcs
#endif

// clang-format on

#if defined ENABLE_JSON_TYPES
#include "bindings/jsonrpc/json_types.h"
#endif
