该示例演示了如何通过 API 接口操作参数组,执行新增、切换、删除等操作。
如何在Visual Studio、QT、CLion中使用示例工程请参考示例工程使用说明。
// std
#include <iostream>
// alson
#include <alson/classic_client.h>
// 客户端事件监听器
class SimpleClientEventListener : public ALSON::BaseClientEventListener {
public:
void onDisconnectedByException() override {
// 当通信异常断开时,该函数会被调用。这里打印一条消息作为演示。
// 在实际的工程应用中应该及时向用户反馈,待异常解决后执行重连逻辑。
std::cout << "********************* client exception *******************" << std::endl;
}
};
// 设备事件监听器
class SimpleDeviceEventListener : public ALSON::ClassicDeviceEventListener {
public:
void onDeviceException(uint64_t code, const std::string& message) override {
// 当硬件出现异常时,该函数会被调用。这里打印一条消息作为演示。
// 硬件异常包括相机断开连接、串口断开连接等。
// 在实际的工程应用中应该及时向用户反馈,待异常解决后执行重连逻辑。
std::cout << "********************* device exception *******************" << std::endl;
}
};
int main(int argc, char** argv) {
try {
// 开启客户端日志,需要指定日志配置文件。
ALSON::Client::initLog("../../../LogConfig-Client.yaml");
// 检测所有服务端(即可用的设备),并获取其中第一个服务端的信息
std::vector<ALSON::ServerInfo> serverInfoList = ALSON::Client::discovery();
if (serverInfoList.empty()) {
std::cerr << "can not find any server or device" << std::endl;
return -1;
}
ALSON::ServerInfo serverInfo = serverInfoList.front();
// 构造客户端并建立通信连接
ALSON::Client client;
client.connect(serverInfo.getServerNetworkCardInfo().getIp(), serverInfo.getServerNetworkCardInfo().getBindPort());
std::cout << "is connected: " << client.isConnected() << std::endl;
// 心跳时间通常设置为 2000ms 至 3000ms。在开发调试过程中,可适当设置大些。
// 如果心跳时间很大,那么当通信意外断开时,客户端和服务端都需要经历很长的时间才能感知到。
// 在此期间,客户端将阻塞您的进程,服务端不能被新的客户端连接。
client.setHeartbeatTimeout(3000);
// 注册客户端事件监听器
ALSON::BaseClientEventListenerPtr clientEventListener = std::make_shared<SimpleClientEventListener>();
client.setClientEventListener(clientEventListener);
// 创建设备控制器对象
ALSON::ClassicDeviceController deviceController = client.createDeviceController<ALSON::ClassicDeviceController>();
// 注册设备事件监听器
ALSON::ClassicDeviceEventListenerPtr classicDeviceEventListener = std::make_shared<SimpleDeviceEventListener>();
deviceController.setDeviceEventListener(classicDeviceEventListener);
// 打开设备。注意无论设备是否关闭,在调用 DeviceController 中其他接口之前都必须调用 open 接口。
deviceController.open();
// 获取参数组管理器
ALSON::DeviceParameterManager parameterManager = client.createDeviceParameterManager();
// 设置多语言,CN(中文)、EN(英文)、JP(日文)、KR(韩文),默认是 CN(中文)。
parameterManager.setLanguageType("CN");
// 获取当前使用的语言类型
std::string languageType = parameterManager.getLanguageType();
std::cout << "languageType: " << languageType << std::endl;
std::cout << "====== Init ======" << std::endl;
std::cout << "current parameter group id: " << parameterManager.getCurrent().id << std::endl;
// 获取全部参数组的 ID,其中第一个 ID 是默认参数组的 ID。
// 注意:calibration 是保留参数组,请不要操作。
std::vector<std::string> allIds = parameterManager.getAllIds();
for (int i = 0; i < allIds.size(); i++) {
std::cout << "allIds[ " << i << " ]: " << allIds[i] << std::endl;
}
std::string defaultId = allIds[0];
std::cout << "====== Add foo ======" << std::endl;
// 从当前参数组克隆一个 ID 为 foo 的完全一样的参数组,这是新增参数组的主要手段。
parameterManager.cloneCurrent("foo");
std::cout << "After clone, current parameter group id: " << parameterManager.getCurrent().id << std::endl;
// 切换到刚刚克隆出来的参数组,切换参数组的同时,会对当前参数组执行保存操作。
parameterManager.switchCurrent("foo");
std::cout << "After switch, current parameter group id: " << parameterManager.getCurrent().id << std::endl;
// 获取全部参数组的 ID,其中第一个 ID 是默认参数组的 ID。
// 注意:calibration 是保留参数组,请不要操作。
allIds = parameterManager.getAllIds();
for (int i = 0; i < allIds.size(); i++) {
std::cout << "allIds[ " << i << " ]: " << allIds[i] << std::endl;
}
std::cout << "====== Set foo as default ======" << std::endl;
// 将当前参数组设置为默认参数组
parameterManager.setDefault();
// 获取全部参数组的 ID,其中第一个 ID 是默认参数组的 ID。
// 注意:calibration 是保留参数组,请不要操作。
allIds = parameterManager.getAllIds();
for (int i = 0; i < allIds.size(); i++) {
std::cout << "allIds[ " << i << " ]: " << allIds[i] << std::endl;
}
std::cout << "====== Reset default ======" << std::endl;
// 切换到最初的默认参数组,并将其重新设置为默认参数组。
// 注意:loadCurrent 接口在切换参数组的时候,不会对参数组执行保存操作。
parameterManager.loadCurrent(defaultId);
std::cout << "After load, current parameter group id: " << parameterManager.getCurrent().id << std::endl;
parameterManager.setDefault();
parameterManager.setDefault();
// 获取全部参数组的 ID,其中第一个 ID 是默认参数组的 ID。
// 注意:calibration 是保留参数组,请不要操作。
allIds = parameterManager.getAllIds();
for (int i = 0; i < allIds.size(); i++) {
std::cout << "allIds[ " << i << " ]: " << allIds[i] << std::endl;
}
std::cout << "====== Delete foo ======" << std::endl;
// 切换到 foo 参数组。
parameterManager.switchCurrent("foo");
std::cout << "After switch, current parameter group id: " << parameterManager.getCurrent().id << std::endl;
// 删除 foo 参数组,并切换到默认参数组。
parameterManager.deleteCurrentAndSwitchToDefault();
std::cout << "After delete, current parameter group id: " << parameterManager.getCurrent().id << std::endl;
// 获取全部参数组的 ID,其中第一个 ID 是默认参数组的 ID。
// 注意:calibration 是保留参数组,请不要操作。
allIds = parameterManager.getAllIds();
for (int i = 0; i < allIds.size(); i++) {
std::cout << "allIds[ " << i << " ]: " << allIds[i] << std::endl;
}
std::cout << "====== Add and delete bar ======" << std::endl;
std::cout << "Before clone and switch, current parameter group id: " << parameterManager.getCurrent().id << std::endl;
// 克隆一个 ID 为 bar 的参数组,并切换到这个参数组。
parameterManager.cloneAndSwitchCurrent("bar");
std::cout << "After clone and switch, current parameter group id: " << parameterManager.getCurrent().id << std::endl;
// 获取全部参数组的 ID,其中第一个 ID 是默认参数组的 ID。
// 注意:calibration 是保留参数组,请不要操作。
allIds = parameterManager.getAllIds();
for (int i = 0; i < allIds.size(); i++) {
std::cout << "allIds[ " << i << " ]: " << allIds[i] << std::endl;
}
// 删除 bar 参数组,并切换到默认参数组。
parameterManager.deleteCurrentAndSwitchToDefault();
// 关闭设备。注意:close 接口一般情况下不需要调用,如果该接口被调用,下次调用 open 接口的时候就会比较耗时。
deviceController.close();
// 如果不再需要连接服务端,请及时调用 disconnect 断开连接。
client.disconnect();
}
catch (ALSON::CommonException& cause) {
// API 中的所有接口都有可能抛出异常,请按照这种方式进行捕获。否则异常发生时可能会导致程序崩溃。
std::cerr << cause.getStackTrace() << std::endl;
return -1;
}
return 0;
}