#ifndef AGVC_INTERFACE_H
#define AGVC_INTERFACE_H

#include <memory>
#include "agvc_interface/type.h"

#define INTERFACE_VERSION_MAJOR 0
#define INTERFACE_VERSION_MINOR 4
#define INTERFACE_VERSION_PATCH 0
#define INTERFACE_VERSION       (INTERFACE_VERSION_MAJOR * 1000000 + INTERFACE_VERSION_MINOR * 1000 + INTERFACE_VERSION_PATCH)

/**
 * @defgroup Map Map(地图模块)
 * @brief AGVC自定义地图的创建、切换、删除、数据读写等核心功能
 */

/**
 * @defgroup Station Station(站点模块)
 * @brief AGVC地图站点的增删改查、充电站点自动识别等功能
 */

/**
 * @defgroup Path Path(路径模块)
 * @brief AGVC地图路径的生成、修改、删除、查询等功能
 */

/**
 * @defgroup Navigation Navigation(导航模块)
 * @brief AGVC运动控制、导航任务下发、重定位、模式切换等功能
 */

/**
 * @defgroup Charging Charging(充电模块)
 * @brief AGVC自动充电、强制上下桩、电量检测等充电相关功能
 */

/**
 * @defgroup AgvInfo AgvInfo(AGV信息模块)
 * @brief AGVC状态、位姿、日志、错误码等信息查询功能
 */

/**
 * @defgroup System System(系统模块)
 * @brief AGVC系统配置、控制权、软件升级、固件更新等系统级功能
 */

namespace agvc_interface {

class AgvcInterface
{
public:
    AgvcInterface();
    virtual ~AgvcInterface();

    /**
     * @ingroup System
     * @brief 设置agv系统时间
     * @param[in] stamp   时间戳，YYYY-MM-DDTHH:mm:ss.ssZ
     * (e.g.“2017-04-15T11:40:03.12Z”)
     */
    int setSystemClock(const std::string &stamp);

    /**
     * @ingroup AgvInfo
     * @attention rtde推送
     * @brief 查询当前agv信息
     * @return agv详细信息
     */
    AgvDetails getAgvDetails();

    /**
     * @ingroup AgvInfo
     * @attention rtde推送
     * @brief 查询当前agv运行信息
     * @return agv运行信息
     */
    RunningInfo getRunningInfo();

    /**
     * @ingroup AgvInfo
     * @attention rtde推送
     * @brief 查询agv当前位姿
     * @return 当前位姿
     */
    Pose2d getAgvCurrentPose();

    /**
     * @ingroup AgvInfo
     * @attention rtde推送
     * @brief 查询当前激光点云数据
     * @return 二维激光点坐标
     */
    std::vector<Point2d> getLaserPointCloud();

    /**
     * @ingroup System
     * @brief 查询异步接口的运行情况，不代表异步接口本身的运行结果
     * @note  异步接口：saveMap, switchMap, changeRunningMode, relocation, sendBase64PngMapToAgv
     * @note  异步接口：getGridMapAllInfo, setGridMapAllInfo, sendGridMapToAgv, getGridMapFromAgv
     * @note  异步接口：getPngMapAllInfo, setPngMapAllInfo, getBase64PngMapFromAgv, previewPngMapFromAgv
     * @note  异步接口：autoAlignRailway
     * @note  客户端与agv断联后，调用该接口获取异步接口运行情况
     * @note 返回值的每个字段中均有header，其中header.id表示下发异步任务时的id号
     * @return NONE：   异步接口未运行
     *         RUNNING：异步接口运行中
     *         FINISH： 异步接口运行结束
     */
    AsyncInterfaceResultStatus getAsyncInterfaceResultStatus();

    /**
     * @ingroup Station
     * @brief 查询当前地图的所有站点信息
     * @return 当前地图的所有站点信息
     */
    std::vector<StationMark> getAllStations();

    /**
     * @ingroup Station
     * @brief 查询指定地图的所有站点信息
     * @param[in] map_header 指定地图header(命令id,名称,时间,地图id)
     * @return 指定地图的所有站点信息
     */
    std::vector<StationMark> getAllStationsOfTargetMap(const Header &map_header);

    /**
     * @ingroup Station
     * @brief 添加/修改一个站点
     * @param[in] station 待添加/修改的站点信息
     * @return 10100000：添加/修改站点成功
     *             else：添加/修改站点失败 
     */
    int addStation(const StationMark &station);

    /**
     * @ingroup Station
     * @brief 添加/修改多个站点
     * @param[in] stations 待添加的站点
     * @return 10100000：添加/修改站点成功
     *             else：添加/修改站点失败
     */
    int addStations(const std::vector<StationMark> &stations);

    /**
     * @ingroup Station
     * @brief 通过自动识别充电桩位姿来添加充电站点
     * @since 0.7.0
     * @param[in] station_header 待添加/修改的充电站点信息(站点id，名称，时间，地图id)
     * @param[in] dis_station_board 充电站点与充电桩之间的距离(充电站点位于AGV中心)，单位：m，范围[1.0~2.0]
     * @return 10100000：添加充电站点成功
     *             else：添加充电站点失败
     */
    int addCPStationUseChargingBoard(const Header &station_header, const double &dis_station_board = 1.5);

    /**
     * @ingroup Station
     * @brief 删除指定站点（会删除与该站点相关的路径）
     * @param[in] station_header 待删除站点信息(站点id,名称,时间,地图id)
     * @return 10100000：删除站点成功
     *             else：删除站点失败
     */
    int deleteStation(const Header &station_header);

    /**
     * @ingroup Station
     * @brief 删除多个站点（会删除与站点相关的路径）
     * @param[in] stations_header 待删除站点信息(站点id,名称,时间,地图id)
     * @return 10100000：删除站点成功
     *             else：删除站点失败
     */
    int deleteStations(const std::vector<Header> &stations_header);

    /**
     * @ingroup Path
     * @brief 查询当前地图的所有路径信息
     * @return 当前地图的所有路径信息
     */
    std::vector<PathStation> getAllPaths();

    /**
     * @ingroup Path
     * @brief 查询指定地图的所有路径信息
     * @param[in] map_header 指定地图header(命令id,名称,时间,地图id)
     * @return 指定地图的所有路径信息
     */
    std::vector<PathStation> getAllPathsOfTargetMap(const Header &map_header);

    /**
     * @ingroup Path
     * @brief 查询agv当前正在跟踪的路径信息
     * @return 当前正在跟踪的路径信息
     */
    PathStation getCurrentPath();

    /**
     * @ingroup Path
     * @brief 生成/修改一条路径
     * @param[in] path_station 待生成/修改的路径信息
     * @return 10100000：修改/生成路径成功
     *             else：修改/生成路径失败
     */
    int generatePath(const PathStation &path_station);

    /**
     * @ingroup Path
     * @brief 生成/修改多条路径
     * @param[in] paths_station 待生成/修改的路径信息
     * @return 10100000：修改/生成路径成功
     *             else：修改/生成路径失败
     */
    int generatePaths(const std::vector<PathStation> &paths_station);

    /**
     * @ingroup Path
     * @brief 删除一条路径
     * @param[in] path_header 待删除路径信息(路径id,名称,时间,地图id)
     * @return 10100000：删除路径成功
     *             else：删除路径失败
     */
    int deletePath(const Header &path_header);

    /**
     * @ingroup Path
     * @brief 删除多条路径
     * @param[in] paths_header 待删除路径信息(路径id,名称,时间,地图id)
     * @return 10100000：删除路径成功
     *             else：删除路径失败
     */
    int deletePaths(const std::vector<Header> &paths_header);

    /**
     * @ingroup Map
     * @brief 获取agv所有地图的信息头
     * @return 所有地图的信息头(命令id,名称,时间,地图id)
     */
    std::vector<Header> getMapList();

    /**
     * @ingroup Map
     * @brief 查询当前agv地图的信息头
     * @return 当前地图的信息头(命令id,名称,时间,地图id)
     */
    Header getCurrentMapHeader();

    /**
     * @ingroup Map
     * @brief 获取指定栅格地图信息
     * @param[in] map_header 指定地图的信息头(本次异步命令id,名称,时间,地图id)
     * @note map_id为"current_map"时，可特指为当前地图
     * @return 指定栅格地图信息
     */
    OccupancyGridMap getGridMapFromAgv(const Header &map_header);

    /**
     * @ingroup Map
     * @attention 1.异步接口
     * @brief 获取Base64编码的png地图信息
     * @param[in] map_header 指定地图的信息头(本次异步命令id,名称,时间,地图id)
     * @note map_id为"current_map"时，可特指为当前地图
     * @return Base64编码的png地图信息
     */
    Base64PngMap getBase64PngMapFromAgv(const Header &map_header);

    /**
     * @ingroup Map
     * @attention 1.异步接口
     * @brief 获取预览图，可指定预览图的长和宽
     * @param[in] map_header 指定地图的信息头(本次异步命令id,名称,时间,地图id)
     * @param[in] image_width_px 地图的宽度(像素)，默认值为0 返回缩略图数据为空
     * @param[in] image_height_px 地图的高度(像素)，默认值为0 返回缩略图数据为空
     * @note map_id为"current_map"时，可特指为当前地图
     * @return Base64编码的png缩略图
     */
    Base64PngMap previewPngMapFromAgv(const Header &map_header, const int &image_width_px = 0, const int &image_height_px = 0);

    /**
     * @ingroup Map
     * @attention 1.异步接口
     * @brief 将栅格地图信息发送给agv
     * @param[in] map 栅格地图信息
     * @return 10100000：发送地图成功
     *         10100201：发送地图中
     *             else：发送地图失败
     */
    int sendGridMapToAgv(const OccupancyGridMap &map);

    /**
     * @ingroup Map
     * @attention 1.异步接口
     * @brief 将Base64编码的Png地图发送给agv
     * @param[in] map Base64编码的Png地图
     * @return 10100000：发送地图成功
     *         10100201：发送地图中
     *             else：发送地图失败
     */
    int sendBase64PngMapToAgv(const Base64PngMap &map);

    /**
     * @ingroup Map
     * @attention 1.异步接口; 2.控制权限制
     * @brief 建图完成后,调用该接口保存地图
     * @param[in] map_header 地图信息头(本次异步命令id,名称,时间,地图id)
     * @return 10100000：保存地图成功
     *         10100201：异步接口运行中
     *         10120202：无控制权
     *             else：保存地图失败
     */
    int saveMap(const Header &map_header);

    /**
     * @ingroup Map
     * @attention 1.异步接口; 2.控制权限制
     * @brief 切换指定地图
     * @param[in] map_header 指定地图的信息头(本次异步命令id,名称,时间,地图id)
     * @return 10100000：切换地图成功
     *         10100201：异步接口运行中
     *         10120202：无控制权
     *             else：切换地图失败
     */
    int switchMap(const Header &map_header);

    /**
     * @ingroup Map
     * @brief 删除一张指定地图
     * @param[in] map_header 指定地图的信息头(命令id,名称,时间,地图id)
     * @return 10100000：删除地图成功
     *             else：删除地图失败 
     */
    int deleteMap(const Header &map_header);

    /**
     * @ingroup Map
     * @brief 删除多张指定地图
     * @param[in] map_headers 多个指定地图的信息头(命令id,名称,时间,地图id)
     * @return 10100000：删除地图成功
     *             else：删除地图失败 
     */
    int deleteMaps(const std::vector<Header> &map_headers);

    /**
     * @ingroup Map
     * @brief 查询当前地图的虚拟区域
     * @return 当前地图的虚拟区域信息
     */
    std::vector<MapVirtualArea> getAllMapVirtualArea();

    /**
     * @ingroup Map
     * @brief 查询目标地图的虚拟区域
     * @param[in] map_header 指定地图header(命令id,名称,时间,地图id)
     * @return 指定地图的所有虚拟区域
     */
    std::vector<MapVirtualArea> getAllMapVirtualAreaOfTargetMap(const Header &map_header);

    /**
     * @ingroup Map
     * @brief 添加/修改一个虚拟区域
     * @param[in] map_virtual_area 待添加/修改的虚拟区域信息
     * @return 10100000：添加/修改虚拟区域成功
     *             else：添加/修改虚拟区域失败
     */
    int addMapVirtualArea(const MapVirtualArea &map_virtual_area);

    /**
     * @ingroup Map
     * @brief 添加/修改多个虚拟区域
     * @param[in] map_virtual_areas 待添加的虚拟区域信息
     * @return 10100000：添加/修改虚拟区域成功
     *             else：添加/修改虚拟区域失败
     */
    int addMapVirtualAreas(const std::vector<MapVirtualArea> &map_virtual_areas);

    /**
     * @ingroup Map
     * @brief 删除指定虚拟区域
     * @param[in] virtual_area_header
     * 指定虚拟区域信息头(命令id，虚拟区域名称，时间，所在地图id)
     * @return 10100000：删除虚拟区域成功
     *             else：删除虚拟区域失败
     */
    int deleteMapVirtualArea(const Header &virtual_area_header);

    /**
     * @ingroup Map
     * @brief 删除多个指定虚拟区域
     * @param[in] virtual_areas_header
     * 指定虚拟区域信息头(命令id，虚拟区域名称，时间，所在地图id)
     * @return 10100000：删除虚拟区域成功
     *             else：删除虚拟区域失败
     */
    int deleteMapVirtualAreas(const std::vector<Header> &virtual_areas_header);

    /**
     * @ingroup Map
     * @attention 1.异步接口
     * @brief 获取指定地图的栅格地图数据、路径、站点、虚拟区信息
     * @param[in] map_header 指定地图信息头(本次异步命令id，地图名称，时间，地图id)
     * @note map_id为"current_map"时，可特指为当前地图
     * @return 栅格地图上的全部信息
     */
    MapAllInfo getGridMapAllInfo(const Header &map_header);

    /**
     * @ingroup Map
     * @attention 1.异步接口
     * @brief 获取指定地图的Base64地图数据、路径、站点、虚拟区信息
     * @param[in] map_header 指定地图信息头(本次异步命令id，地图名称，时间，地图id)
     * @note map_id为"current_map"时，可特指为当前地图
     * @return base64地图上的全部信息
     */
    MapAllInfo getPngMapAllInfo(const Header &map_header);

    /**
     * @ingroup Map
     * @attention 1.异步接口; 2.控制权限制
     * @brief 设置栅格地图、路径、站点、虚拟区信息
     * @param[in] map_all_info 栅格地图上的全部信息
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @note 请保证数据下发的可行性(agv不会对数据进行校验)
     * @return 10100000：上传全部地图信息成功
     *         10100201：异步接口运行中
     *         10120202：无控制权
     *             else：上传全部地图信息失败
     */
    int setGridMapAllInfo(const MapAllInfo &map_all_info,
                          const Header &command_header = { "99999", "99999", 1, "99999" });

    /**
     * @ingroup Map
     * @attention 1.异步接口; 2.控制权限制
     * @brief 设置Base64格式地图、路径、站点、虚拟区信息
     * @param[in] map_all_info Base64格式地图上的全部信息
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @note 请保证数据下发的可行性(agv不会对数据进行校验)
     * @return 10100000：上传全部地图信息成功
     *         10100201：异步接口运行中
     *         10120202：无控制权
     *             else：上传全部地图信息失败
     */
    int setPngMapAllInfo(const MapAllInfo &map_all_info,
                         const Header &command_header = { "99999", "99999", 1, "99999" });

    /**
     * @ingroup Map
     * @brief 删除指定地图的全部信息(地图数据、站点、路径、虚拟区信息)
     * @param[in] map_header 指定地图信息头(命令id，地图名称，时间，地图id)
     * @return 10100000：删除成功
     *             else：删除失败
     */
    int deleteMapAllInfo(const Header &map_header);

    /**
     * @ingroup System
     * @attention 异步接口
     * @brief 获取当前扫描到的WiFi列表
     * @return {RUNNING} 异步接口运行中
     *         {} 为空-未扫描到WIFI
     *         {SSID} 不为空-扫描到的WIFI名称列表
     */
    std::vector<std::string> getWifiList();

    /**
     * @ingroup System
     * @brief 连接到指定WiFi(自动切换到WiFi模式)
     * @note 必须在有线连接时调用,且执行时间较长
     * @param[in] ssid WiFi名称
     * @param[in] password WiFi密码
     * @return 10100000：连接WiFi成功
     *             else：连接WiFi失败
     */
    int connectWifi(const std::string &ssid, const std::string &password);

    /**
     * @ingroup System
     * @brief 开启热点(自动切换到热点模式)
     * @note 必须在有线连接时调用,且执行时间较长
     * @param[in] password 热点密码,
     * 如果为空使用"administrator"为默认密码；ssid默认为SN码
     * @return 10100000：启用热点成功
     *             else：启用热点失败
     */
    int enableHotspot(const std::string &password);

    /**
     * @ingroup System
     * @brief 获取本机所有IP地址
     * @return 本机所有IP地址
     */
    std::vector<IpAddressInfo> getIpAddressList();

    /**
     * @ingroup Navigation
     * @attention 1.异步接口; 2.控制权限制
     * @brief: 切换agv模式
     * @param[in] running_mode 打算切换的模式:导航模式、建图模式;
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @return 10100000：换模式成功
     *         10100201：异步接口运行中
     *         10120202：无控制权
     *             else：切换模式失败
     */
    int changeRunningMode(const RunningMode &running_mode,
                          const Header &command_header = { "99999", "99999", 1, "99999" });

    /**
     * @ingroup Navigation
     * @attention 控制权限制
     * @brief 控制agv运动
     * @param[in] speed 速度信息
     * @return 10100000：向agv下发速度成功
     *         10120202：没有控制权
     *             else：向agv下发速度失败
     */
    int setControlSpeed(const Speed &speed);

    /**
     * @ingroup Navigation
     * @attention 控制权限制
     * @brief 向agv发送导航任务
     * @param[in] target 目标位置信息与导航参数信息
     * @return 10100000：设置导航任务成功
     *         10120202：没有控制权
     *             else：设置导航任务失败
     */
    int setNavGoal(const NavGoalType &target);

    /**
     * @ingroup AgvInfo
     * @attention rtde推送
     * @brief 获取当前导航信息
     * @return 当前导航信息
     */
    NavInfo getNavInfo();

    /**
     * @ingroup Navigation
     * @attention 控制权限制
     * @brief 暂停agv速度
     * @return 10100000：暂停成功
     *         10120202：没有控制权
     *             else：暂停失败
     */
    int pauseAgvSpeed();

    /**
     * @ingroup Navigation
     * @attention 控制权限制
     * @brief 暂停后，恢复agv速度
     * @return 10100000：恢复成功
     *         10120202：没有控制权
     *             else：恢复失败
     */
    int resumeAgvSpeed();

    /**
     * @ingroup Navigation
     * @attention 控制权限制
     * @brief 取消导航任务
     * @return 10100000：取消导航任务成功
     *         10120202：没有控制权
     *             else：取消导航任务失败
     */
    int cancelNavigation();

    /**
     * @ingroup Navigation
     * @attention 1.异步接口; 2.控制权限制
     * @brief agv重定位
     * @param[in] init_pose agv当前参考位姿
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @return 10100000：重定位成功
     *         10100201：异步接口运行中
     *         10120202：无控制权
     *             else：重定位失败
     */
    int relocation(const Pose2d &init_pose, const Header &command_header = { "99999", "99999", 1, "99999" });

    /**
     * @ingroup System
     * @brief 获取agv控制器的参数文件
     * @return std::string 当前agv控制器中的参数信息
     */
    std::string getAgvControllerParametersFile();

    /**
     * @ingroup System
     * @attention 控制权限制
     * @brief 设置agv控制器的参数文件
     * @note 不要高频调用，调用频率低于1Hz；此接口会默认执行刷新参数功能
     * @param[in] agv_parameters agv控制器的参数信息
     * @return 10100000：设置参数成功
     *             else：设置参数失败
     */
    int setAgvControllerParametersFile(const std::string &agv_parameters);

    /**
     * @ingroup System
     * @attention 控制权限制
     * @brief 修改agv控制器的参数文件后，让agv各节点刷新参数
     * @note 不要高频调用，调用频率低于1Hz
     * @return 10100000：接口执行成功
     *             else：接口执行失败
     */
    int refreshAgvControllerParametersFile();

    /**
     * @ingroup System
     * @attention 控制权限制
     * @brief 将agv控制器的参数文件恢复出厂设置
     * @note 不要高频调用，调用频率低于1Hz
     * @return 10100000：接口执行成功
     *             else：接口执行失败
     */
    int resetAgvControllerParametersFile();

    /**
     * @ingroup Charging
     * @attention 控制权限制
     * @brief 检测当前电量，电量低将自动上桩充电
     * @deprecated 自 0.7.0 起废弃，请使用新的 sendAutoChargingCommand(const AutoChargingCommand&) 接口。
     * @note 充电完成后，根据配置文件中的参数auto_leave_board，决定是否自动下桩并行驶到指定站点或等待区
     *       在配置文件中设置电量低阈值[low_battery_threshold]或电量高阈值[high_battery_threshold]
     * @param[in] check_power_header
     * 本次命令的id，本次命令的name，当前时间，地图id
     * @param[in] nav_board_charge_station_id 行驶到指定的充电站点进行上桩充电；
     *                                        如果不设置该参数，行驶到最近的充电站点进行上桩充电
     * @return 10100000：接口调用成功，AGV开始执行充电命令
     *         10120202：无控制权
     *             else：接口调用失败
     */
    [[deprecated("Since 0.7.0: use sendAutoChargingCommand(const AutoChargingCommand&) instead.")]]
    int checkPowerAndAutoCharge(const Header &check_power_header               = { "99999", "99999", 99999, "99999" },
                                const std::string &nav_board_charge_station_id = "99999");

    /**
     * @ingroup Charging
     * @brief 设置自动下桩时的目标站点
     * @deprecated 自 0.7.0 起废弃，请使用新的 sendAutoChargingCommand(const AutoChargingCommand&) 接口。
     * @param[in] leave_board_target_station_header 自动下桩的站点的header信息
     * @return 10100000：设置自动下桩站点成功
     *             else：设置自动下桩站点失败
     */
    [[deprecated("Since 0.7.0: use sendAutoChargingCommand(const AutoChargingCommand&) instead.")]]
    int setLeaveBoardTargetStation(const Header &leave_board_target_station_header);

    /**
     * @ingroup Charging
     * @brief 获取自动下桩时的目标站点
     * @deprecated 自 0.7.0 起废弃，请使用新的 getNavInfo() 接口。
     * @return Header 自动下桩时的目标站点Header信息
     */
    [[deprecated("Since 0.7.0: use getNavInfo() instead.")]]
    Header getLeaveBoardTargetStation();

    /**
     * @ingroup Charging
     * @attention 控制权限制
     * @brief 强制上桩充电
     * @deprecated 自 0.7.0 起废弃，请使用新的 sendAutoChargingCommand(const AutoChargingCommand&) 接口。
     * @param[in] forced_charge_header 本次命令的id，本次命令的name，当前时间，地图id
     * @param[in] nav_board_charge_station_id 行驶到指定的充电站点进行上桩充电；
     *                                        如果不设置该参数，行驶到最近的充电站点进行上桩充电
     * @return 10100000：接口调用成功，AGV开始上桩充电
     *         10120202：无控制权
     *             else：接口调用失败
     */
    [[deprecated("Since 0.7.0: use sendAutoChargingCommand(const AutoChargingCommand&) instead.")]]
    int forcedAgvToChargingBoard(const Header &forced_charge_header             = { "99999", "99999", 99999, "99999" },
                                 const std::string &nav_board_charge_station_id = "99999");

    /**
     * @ingroup Charging
     * @attention 控制权限制
     * @brief 强制下桩
     * @deprecated 自 0.7.0 起废弃，请使用新的 sendAutoChargingCommand(const AutoChargingCommand&) 接口。
     * @param[in] forced_leave_header
     * 本次命令的id，本次命令的name，当前时间，地图id
     * @param[in] leave_board_target_station_id 下桩前往的站点；
     *                                          如果不设置该参数，则下桩到充电站点
     * @return 10100000：接口调用成功，AGV开始下桩
     *         10120202：无控制权
     *             else：接口调用失败
     */
    [[deprecated("Since 0.7.0: use sendAutoChargingCommand(const AutoChargingCommand&) instead.")]]
    int forcedAgvLeaveChargingBoard(const Header &forced_leave_header = { "99999", "99999", 99999, "99999" },
                                    const std::string &leave_board_target_station_id = "99999");

    /**
     * @ingroup Charging
     * @attention 控制权限制
     * @brief 下发自动充电命令
     * @since 0.7.0
     * @param[in] auto_charging_command 自动充电命令
     * @return 10100000：接口调用成功，AGV开始执行充电命令
     *         10120202：无控制权
     *             else：接口调用失败
     */
    int sendAutoChargingCommand(const AutoChargingCommand &auto_charging_command);

    /**
     * @ingroup AgvInfo
     * @brief 获取agv运行中的日志信息
     * @return agv运行中的日志信息
     */
    std::string getAgvLogMessage();

    /**
     * @ingroup System
     * @brief agv软件升级
     * @param[in] upgrade_pack_path 升级包路径，例如"/root/agvc_release-0.1.1+398d1f7-Linux_x86_64.tar.gz"
     * @return 10100000：目标版本升级成功
     *         10100201：正在升级中
     *             else：升级失败
     */
    int updateSoftware(const std::string &upgrade_pack_path);

    /**
     * @ingroup System
     * @brief 获取agv软件版本列表
     * @return 软件版本列表集合 {0.3.2+3b807d1-Linux_x86_64,0.6.3-patch.3+b8c6aa4-Linux_x86_64}
     */
    std::vector<std::string> getSoftwareVersionList();

    /**
     * @ingroup System
     * @brief 切换agv软件版本
     * @param[in] software_version 软件版本 "0.3.2+3b807d1-Linux_x86_64"
     * @return 10100000：软件版本切换成功
     *             else：软件版本切换失败
     */
    int switchSoftwareVersion(const std::string &software_version);

    /**
     * @ingroup System
     * @brief 卸载agv软件版本
     * @param[in] software_version 软件版本 "0.3.2+3b807d1-Linux_x86_64"
     * @return 10100000：软件版本卸载成功
     *             else：软件版本卸载失败
     */
    int uninstallSoftware(const std::string &software_version);

    /**
     * @ingroup System
     * @brief agv固件更新
     * @param[in] update_firmware 配置要更新固件的模块、固件存储路径
     * @return 10100000：下发固件更新信息成功
     *             else：固件正在更新中
     */
    int updateFirmware(const FirmwareUpdateParam &update_firmware);

    /**
     * @ingroup System
     * @brief 获取固件更新过程信息
     * @return
     * 固件更新步骤信息（步骤信息为failed代表更新失败），更新进度（进度信息为1.0代表更新成功）
     */
    FirmwareUpdateProcessInfo getUpdateFirmwareProcess();

    /**
     * @ingroup System
     * @brief 开始采集数据
     * @note LASER_ODOM标定采集数据量要求大于1000组，具体数据量可以在配置文件中修改
     * @param[in] type 标定类型
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @return 10100000：接口调用成功
     *         10120202：无控制权
     *             else：接口调用失败
     */
    int startCollectCalibrationData(const CalibrationType &type,
                                    const Header &command_header = { "99999", "99999", 1, "99999" });

    /**
     * @ingroup System
     * @brief 取消采集数据
     * @param[in] type 标定类型
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @return 10100000：接口调用成功
     *         10120202：无控制权
     *             else：接口调用失败
     */
    int cancelCollectCalibrationData(const CalibrationType &type,
                                     const Header &command_header = { "99999", "99999", 1, "99999" });

    /**
     * @ingroup System
     * @brief 开始标定
     * @param[in] type 标定类型
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @return 10100000：接口调用成功
     *         10120202：无控制权
     *             else：接口调用失败
     */
    int startCalibration(const CalibrationType &type, const Header &command_header = { "99999", "99999", 1, "99999" });

    /**
     * @ingroup System
     * @brief 获取标定信息
     * @param[in] type 标定类型
     * @return 标定信息
     */
    CalibrationProcessInfo getCalibrationProcessInfo(const CalibrationType &type);

    /**
     * @ingroup System
     * @brief 重启agv
     * @return 10100000：重启指令执行成功
     *             else：重启指令执行失败
     */
    int restartAgv();

    /**
     * @ingroup System
     * @brief 设置agv的名称
     * @param[in] agv_name 设置的agv名称
     * @return 10100000：设置名称成功
     *             else：设置名称失败
     */
    int setAgvName(const std::string &agv_name);

    /**
     * @ingroup System
     * @brief 控制权设置
     * @note 1.该接口设置成功后才能正常使用控制权相关接口
     *       2.控制权设置前需要先释放他人的控制权:releasePriority
     *       3.web端抢占优先权： name="web"
     * @param[in] name 登陆RPC注册时的用户名
     * @param[in] ip   IP地址
     * @return 10100000：设置控制权成功
     *             else：设置控制权失败
     */
    int setPriority(const std::string &name, const std::string &ip = "");

    /**
     * @ingroup System
     * @brief 释放控制权
     * @return 10100000：释放控制权成功
     *             else：释放控制权失败
     */
    int releasePriority();

    /**
     * @ingroup System
     * @brief 暂停脚本
     * @return 10100000：脚本暂停成功
     *             else：脚本暂停失败
     */
    int scriptPaused();

    /**
     * @ingroup System
     * @brief 脚本恢复
     * @return 10100000：脚本恢复成功
     *             else：脚本恢复失败
     */
    int scriptResume();

    /**
     * @ingroup System
     * @brief 脚本停止权
     * @return 10100000：脚本停止成功
     *             else：脚本停止失败
     */
    int scriptStop();

    /**
     * @ingroup AgvInfo
     * @brief 获取脚本运行状态
     * @return 脚本运行状态
     */
    ScriptRuntimeState getScriptStatus();

    /**
     * @ingroup System
     * @brief 设置脚本运行状态
     * @return 10100000：设置脚本运行状态成功
     *             else：设置脚本运行状态失败
     */
    int setScriptStatus(ScriptRuntimeState status);

    /**
     * @ingroup AgvInfo
     * @brief 错误码查询
     * @param[in] error_code 错误码
     * @return 错误码含义
     *         为空-错误码未知
     *
     */
    std::string errorCodeDecoder(const int &error_code);

    /**
     * @ingroup AgvInfo
     * @brief 获取当前的错误码
     * @return 错误码集合
     */
    std::vector<Header> getCurrentErrorCodes();

    /**
     * @ingroup AgvInfo
     * @brief 寻找agv，自动播放语音并特殊灯光闪烁
     * @return 10100000: 寻找指令下发成功
     *             else: 下发指令失败
     */
    int soundLightPrompt();

    /**
     * @ingroup AgvInfo
     * @brief agv行进方向是否有障碍物
     * @param[in] detect_distance 检测距离 默认为1.0m
     * @return true: 行进方向存在障碍物
     *        false: 行进方向无障碍物
     */
    bool isObstacleAhead(const double &detect_distance = 1.0);

    /**
     * @ingroup AgvInfo
     * @brief 获取指定检测距离范围内的最近站点信息
     * @param[in] detect_distance 检测距离 默认为1.0m
     * @return 最近站点信息, id为NONE代表检测距离内无站点
     */
    StationMark getNearestStation(const double &detect_distance = 1.0);

    /**
     * @ingroup System
     * @attention 1.异步接口; 2.控制权限制
     * @brief 自动对接轨道并上轨
     * @param[in] command_header id字段代表下发本次命令的id；其他字段无特殊含义
     * @return 10100000：自动上轨成功
     *         10100201：正在上轨中
     *         10120202：无控制权
     *             else：上轨失败
     */
    int autoAlignRailway(const Header &command_header = { "99999", "99999", 1, "99999" });

    /** \cond */
protected:
    void *d_;
    /** \endcond */
};

using AgvcInterfacePtr = std::shared_ptr<AgvcInterface>;

} // namespace agvc_interface

#define AgvcInterface_DECLARES                                                                               \
    _FUNC(AgvcInterface, 1, setSystemClock, stamp)                                                           \
    _FUNC(AgvcInterface, 0, getAgvDetails)                                                                   \
    _FUNC(AgvcInterface, 0, getRunningInfo)                                                                  \
    _FUNC(AgvcInterface, 0, getAgvCurrentPose)                                                               \
    _FUNC(AgvcInterface, 0, getAsyncInterfaceResultStatus)                                                   \
    _FUNC(AgvcInterface, 0, getLaserPointCloud)                                                              \
    _FUNC(AgvcInterface, 0, getAllStations)                                                                  \
    _FUNC(AgvcInterface, 1, getAllStationsOfTargetMap, map_header)                                           \
    _FUNC(AgvcInterface, 1, addStation, station)                                                             \
    _FUNC(AgvcInterface, 1, addStations, stations)                                                           \
    _FUNC(AgvcInterface, 2, addCPStationUseChargingBoard, station_header, dis_station_post)                  \
    _FUNC(AgvcInterface, 1, deleteStation, station_header)                                                   \
    _FUNC(AgvcInterface, 1, deleteStations, stations_header)                                                 \
    _FUNC(AgvcInterface, 0, getAllPaths)                                                                     \
    _FUNC(AgvcInterface, 1, getAllPathsOfTargetMap, map_header)                                              \
    _FUNC(AgvcInterface, 0, getCurrentPath)                                                                  \
    _FUNC(AgvcInterface, 1, generatePath, path_station)                                                      \
    _FUNC(AgvcInterface, 1, generatePaths, paths_station)                                                    \
    _FUNC(AgvcInterface, 1, deletePath, path_header)                                                         \
    _FUNC(AgvcInterface, 1, deletePaths, paths_header)                                                       \
    _FUNC(AgvcInterface, 0, getMapList)                                                                      \
    _FUNC(AgvcInterface, 0, getCurrentMapHeader)                                                             \
    _FUNC(AgvcInterface, 1, getGridMapFromAgv, map_header)                                                   \
    _FUNC(AgvcInterface, 1, getBase64PngMapFromAgv, map_header)                                              \
    _FUNC(AgvcInterface, 3, previewPngMapFromAgv, map_header, image_width_px, image_height_px)               \
    _FUNC(AgvcInterface, 1, sendGridMapToAgv, map)                                                           \
    _FUNC(AgvcInterface, 1, sendBase64PngMapToAgv, map)                                                      \
    _FUNC(AgvcInterface, 1, saveMap, map_header)                                                             \
    _FUNC(AgvcInterface, 1, switchMap, map_header)                                                           \
    _FUNC(AgvcInterface, 1, deleteMap, map_header)                                                           \
    _FUNC(AgvcInterface, 1, deleteMaps, map_headers)                                                         \
    _FUNC(AgvcInterface, 0, getAllMapVirtualArea)                                                            \
    _FUNC(AgvcInterface, 1, getAllMapVirtualAreaOfTargetMap, map_header)                                     \
    _FUNC(AgvcInterface, 1, addMapVirtualArea, map_virtual_area)                                             \
    _FUNC(AgvcInterface, 1, addMapVirtualAreas, map_virtual_areas)                                           \
    _FUNC(AgvcInterface, 1, deleteMapVirtualArea, virtual_area_header)                                       \
    _FUNC(AgvcInterface, 1, deleteMapVirtualAreas, virtual_areas_header)                                     \
    _FUNC(AgvcInterface, 1, getGridMapAllInfo, map_header)                                                   \
    _FUNC(AgvcInterface, 1, getPngMapAllInfo, map_header)                                                    \
    _FUNC(AgvcInterface, 2, setGridMapAllInfo, map_all_info, command_header)                                 \
    _FUNC(AgvcInterface, 2, setPngMapAllInfo, map_all_info, command_header)                                  \
    _FUNC(AgvcInterface, 1, deleteMapAllInfo, map_header)                                                    \
    _FUNC(AgvcInterface, 0, getWifiList)                                                                     \
    _FUNC(AgvcInterface, 2, connectWifi, ssid, password)                                                     \
    _FUNC(AgvcInterface, 1, enableHotspot, password)                                                         \
    _FUNC(AgvcInterface, 0, getIpAddressList)                                                                \
    _FUNC(AgvcInterface, 2, changeRunningMode, running_mode, command_header)                                 \
    _FUNC(AgvcInterface, 1, setControlSpeed, speed)                                                          \
    _FUNC(AgvcInterface, 1, setNavGoal, target)                                                              \
    _FUNC(AgvcInterface, 0, getNavInfo)                                                                      \
    _FUNC(AgvcInterface, 0, pauseAgvSpeed)                                                                   \
    _FUNC(AgvcInterface, 0, resumeAgvSpeed)                                                                  \
    _FUNC(AgvcInterface, 0, cancelNavigation)                                                                \
    _FUNC(AgvcInterface, 2, relocation, init_pose, command_header)                                           \
    _FUNC(AgvcInterface, 0, getAgvControllerParametersFile)                                                  \
    _FUNC(AgvcInterface, 1, setAgvControllerParametersFile, agv_parameters)                                  \
    _FUNC(AgvcInterface, 0, refreshAgvControllerParametersFile)                                              \
    _FUNC(AgvcInterface, 0, resetAgvControllerParametersFile)                                                \
    _FUNC(AgvcInterface, 2, checkPowerAndAutoCharge, check_power_header, nav_board_charge_station_id)        \
    _FUNC(AgvcInterface, 1, setLeaveBoardTargetStation, leave_board_target_station_header)                   \
    _FUNC(AgvcInterface, 0, getLeaveBoardTargetStation)                                                      \
    _FUNC(AgvcInterface, 2, forcedAgvToChargingBoard, forced_charge_header, nav_board_charge_station_id)     \
    _FUNC(AgvcInterface, 2, forcedAgvLeaveChargingBoard, forced_leave_header, leave_board_target_station_id) \
    _FUNC(AgvcInterface, 1, sendAutoChargingCommand, auto_charging_command)                                  \
    _FUNC(AgvcInterface, 0, getAgvLogMessage)                                                                \
    _FUNC(AgvcInterface, 1, updateSoftware, upgrade_pack_path)                                               \
    _FUNC(AgvcInterface, 0, getSoftwareVersionList)                                                          \
    _FUNC(AgvcInterface, 1, switchSoftwareVersion, software_version)                                         \
    _FUNC(AgvcInterface, 1, uninstallSoftware, software_version)                                             \
    _FUNC(AgvcInterface, 1, updateFirmware, update_firmware)                                                 \
    _FUNC(AgvcInterface, 0, getUpdateFirmwareProcess)                                                        \
    _FUNC(AgvcInterface, 2, startCollectCalibrationData, type, command_header)                               \
    _FUNC(AgvcInterface, 2, cancelCollectCalibrationData, type, command_header)                              \
    _FUNC(AgvcInterface, 2, startCalibration, type, command_header)                                          \
    _FUNC(AgvcInterface, 1, getCalibrationProcessInfo, type)                                                 \
    _FUNC(AgvcInterface, 0, restartAgv)                                                                      \
    _FUNC(AgvcInterface, 1, setAgvName, agv_name)                                                            \
    _FUNC(AgvcInterface, 2, setPriority, name, ip)                                                           \
    _FUNC(AgvcInterface, 0, releasePriority)                                                                 \
    _FUNC(AgvcInterface, 0, scriptPaused)                                                                    \
    _FUNC(AgvcInterface, 0, scriptResume)                                                                    \
    _FUNC(AgvcInterface, 0, scriptStop)                                                                      \
    _FUNC(AgvcInterface, 0, getScriptStatus)                                                                 \
    _FUNC(AgvcInterface, 1, setScriptStatus, status)                                                         \
    _FUNC(AgvcInterface, 1, errorCodeDecoder, error_code)                                                    \
    _FUNC(AgvcInterface, 0, getCurrentErrorCodes)                                                            \
    _FUNC(AgvcInterface, 0, soundLightPrompt)                                                                \
    _FUNC(AgvcInterface, 1, isObstacleAhead, detect_distance)                                                \
    _FUNC(AgvcInterface, 1, getNearestStation, detect_distance)                                              \
    _FUNC(AgvcInterface, 1, autoAlignRailway, command_header)                 
#endif // AGVC_INTERFACE_H
