547 lines
19 KiB
C++
547 lines
19 KiB
C++
|
|
#include "ConfigCmdParser.h"
|
|||
|
|
#include "VrError.h"
|
|||
|
|
#include <iostream>
|
|||
|
|
#include <sstream>
|
|||
|
|
#include <chrono>
|
|||
|
|
#include <iomanip>
|
|||
|
|
#include <cstring>
|
|||
|
|
|
|||
|
|
ConfigCmdParser::ConfigCmdParser()
|
|||
|
|
: m_pShareMem(nullptr)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ConfigCmdParser::~ConfigCmdParser()
|
|||
|
|
{
|
|||
|
|
CleanupSharedMemory();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::ParseCommandLine(int argc, char* argv[], ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
if (argc < 2) {
|
|||
|
|
ShowHelp();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 1; i < argc; ++i) {
|
|||
|
|
std::string arg = argv[i];
|
|||
|
|
|
|||
|
|
if (arg == "-h" || arg == "--help") {
|
|||
|
|
ShowHelp();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (arg == "-v" || arg == "--version") {
|
|||
|
|
ShowVersion();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (arg == "-c" || arg == "--config") {
|
|||
|
|
if (i + 1 >= argc) {
|
|||
|
|
std::cerr << "错误: -c 参数需要指定配置项" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::string configType = argv[i + 1];
|
|||
|
|
|
|||
|
|
// 收集剩余的参数
|
|||
|
|
std::vector<std::string> configParams;
|
|||
|
|
for (int j = i + 2; j < argc; ++j) {
|
|||
|
|
configParams.push_back(argv[j]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 根据参数类型进行解析
|
|||
|
|
if (configType == "expose") {
|
|||
|
|
return ParseCameraExpose(configParams, configData);
|
|||
|
|
}
|
|||
|
|
else if (configType == "gain") {
|
|||
|
|
return ParseCameraGain(configParams, configData);
|
|||
|
|
}
|
|||
|
|
else if (configType == "framerate") {
|
|||
|
|
return ParseCameraFrameRate(configParams, configData);
|
|||
|
|
}
|
|||
|
|
else if (configType == "swing") {
|
|||
|
|
return ParseCameraSwing(configParams, configData);
|
|||
|
|
}
|
|||
|
|
else if (configType == "roi") {
|
|||
|
|
return ParseROISetting(configParams, configData);
|
|||
|
|
}
|
|||
|
|
else if (configType == "algo") {
|
|||
|
|
return ParseAlgoParam(configParams, configData);
|
|||
|
|
}
|
|||
|
|
else if (configType == "calib") {
|
|||
|
|
return ParseCalibParam(configParams, configData);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
std::cerr << "错误: 未知的配置参数类型: " << configType << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::cerr << "错误: 未找到有效的配置参数" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::SendConfigCommand(const ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
if (!InitializeSharedMemory()) {
|
|||
|
|
std::cerr << "错误: 初始化共享内存失败" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 准备共享数据
|
|||
|
|
ConfigCmdSharedData sharedData;
|
|||
|
|
sharedData.data = configData;
|
|||
|
|
sharedData.header.checksum = sharedData.CalculateChecksum();
|
|||
|
|
sharedData.header.hasNewData = true;
|
|||
|
|
|
|||
|
|
// 写入共享内存
|
|||
|
|
int ret = m_pShareMem->Lock(5000); // 5秒超时
|
|||
|
|
if (ret != SUCCESS) {
|
|||
|
|
std::cerr << "错误: 锁定共享内存失败, 错误码: " << ret << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ret = m_pShareMem->WriteData(0, &sharedData, sizeof(ConfigCmdSharedData));
|
|||
|
|
m_pShareMem->Unlock();
|
|||
|
|
|
|||
|
|
if (ret < 0) {
|
|||
|
|
std::cerr << "错误: 写入共享内存失败, 错误码: " << ret << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::cout << "配置命令发送成功" << std::endl;
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::ParseCameraExpose(const std::vector<std::string>& params, ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
// 支持格式:
|
|||
|
|
// expose 100 - 设置所有相机曝光时间为100微秒
|
|||
|
|
// expose 1 100 - 设置相机1曝光时间为100微秒
|
|||
|
|
|
|||
|
|
if (params.empty()) {
|
|||
|
|
std::cerr << "错误: expose 命令需要指定曝光时间" << std::endl;
|
|||
|
|
std::cerr << "用法: expose <曝光时间> 或 expose <相机索引> <曝光时间>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
configData.cmdType = CONFIG_CMD_CAMERA_EXPOSE;
|
|||
|
|
configData.cameraParam.cameraIndex = -1; // 默认所有相机
|
|||
|
|
|
|||
|
|
if (params.size() == 1) {
|
|||
|
|
// 格式: expose 100
|
|||
|
|
if (!IsNumber(params[0])) {
|
|||
|
|
std::cerr << "错误: 曝光时间必须是数字: " << params[0] << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
configData.cameraParam.exposeTime = std::stod(params[0]);
|
|||
|
|
}
|
|||
|
|
else if (params.size() == 2) {
|
|||
|
|
// 格式: expose 1 100
|
|||
|
|
if (!IsNumber(params[0]) || !IsNumber(params[1])) {
|
|||
|
|
std::cerr << "错误: 相机索引和曝光时间都必须是数字" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
configData.cameraParam.cameraIndex = std::stoi(params[0]);
|
|||
|
|
configData.cameraParam.exposeTime = std::stod(params[1]);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
std::cerr << "错误: expose 命令参数过多" << std::endl;
|
|||
|
|
std::cerr << "用法: expose <曝光时间> 或 expose <相机索引> <曝光时间>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 参数验证
|
|||
|
|
if (configData.cameraParam.exposeTime <= 0) {
|
|||
|
|
std::cerr << "错误: 曝光时间必须大于0" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置时间戳
|
|||
|
|
std::string timestamp = GetCurrentTimestamp();
|
|||
|
|
strncpy(configData.timestamp, timestamp.c_str(), sizeof(configData.timestamp) - 1);
|
|||
|
|
|
|||
|
|
std::cout << "解析相机曝光参数: 相机" << configData.cameraParam.cameraIndex
|
|||
|
|
<< ", 曝光时间: " << configData.cameraParam.exposeTime << "微秒" << std::endl;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::ParseCameraGain(const std::vector<std::string>& params, ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
// 支持格式:
|
|||
|
|
// gain 2.5 - 设置所有相机增益为2.5
|
|||
|
|
// gain 1 2.5 - 设置相机1增益为2.5
|
|||
|
|
|
|||
|
|
if (params.empty()) {
|
|||
|
|
std::cerr << "错误: gain 命令需要指定增益值" << std::endl;
|
|||
|
|
std::cerr << "用法: gain <增益值> 或 gain <相机索引> <增益值>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
configData.cmdType = CONFIG_CMD_CAMERA_GAIN;
|
|||
|
|
configData.cameraParam.cameraIndex = -1; // 默认所有相机
|
|||
|
|
|
|||
|
|
if (params.size() == 1) {
|
|||
|
|
// 格式: gain 2.5
|
|||
|
|
if (!IsNumber(params[0])) {
|
|||
|
|
std::cerr << "错误: 增益值必须是数字: " << params[0] << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
configData.cameraParam.gain = std::stod(params[0]);
|
|||
|
|
}
|
|||
|
|
else if (params.size() == 2) {
|
|||
|
|
// 格式: gain 1 2.5
|
|||
|
|
if (!IsNumber(params[0]) || !IsNumber(params[1])) {
|
|||
|
|
std::cerr << "错误: 相机索引和增益值都必须是数字" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
configData.cameraParam.cameraIndex = std::stoi(params[0]);
|
|||
|
|
configData.cameraParam.gain = std::stod(params[1]);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
std::cerr << "错误: gain 命令参数过多" << std::endl;
|
|||
|
|
std::cerr << "用法: gain <增益值> 或 gain <相机索引> <增益值>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 参数验证
|
|||
|
|
if (configData.cameraParam.gain <= 0) {
|
|||
|
|
std::cerr << "错误: 增益值必须大于0" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::string timestamp = GetCurrentTimestamp();
|
|||
|
|
strncpy(configData.timestamp, timestamp.c_str(), sizeof(configData.timestamp) - 1);
|
|||
|
|
|
|||
|
|
std::cout << "解析相机增益参数: 相机" << configData.cameraParam.cameraIndex
|
|||
|
|
<< ", 增益: " << configData.cameraParam.gain << std::endl;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::ParseAlgoParam(const std::vector<std::string>& params, ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
// 支持格式:
|
|||
|
|
// algo threshold 0.5 - 设置算法参数threshold为0.5
|
|||
|
|
|
|||
|
|
if (params.size() != 2) {
|
|||
|
|
std::cerr << "错误: algo 命令需要2个参数" << std::endl;
|
|||
|
|
std::cerr << "用法: algo <参数名> <参数值>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!IsNumber(params[1])) {
|
|||
|
|
std::cerr << "错误: 算法参数值必须是数字: " << params[1] << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
configData.cmdType = CONFIG_CMD_ALGO_PARAM;
|
|||
|
|
strncpy(configData.algoParam.paramName, params[0].c_str(), sizeof(configData.algoParam.paramName) - 1);
|
|||
|
|
configData.algoParam.paramValue = std::stod(params[1]);
|
|||
|
|
|
|||
|
|
std::string timestamp = GetCurrentTimestamp();
|
|||
|
|
strncpy(configData.timestamp, timestamp.c_str(), sizeof(configData.timestamp) - 1);
|
|||
|
|
|
|||
|
|
std::cout << "解析算法参数: " << configData.algoParam.paramName
|
|||
|
|
<< " = " << configData.algoParam.paramValue << std::endl;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::ParseCalibParam(const std::vector<std::string>& params, ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
// 简化实现,这里可以根据实际需求扩展
|
|||
|
|
// 支持格式:
|
|||
|
|
// calib <相机索引> - 触发指定相机的标定过程
|
|||
|
|
|
|||
|
|
if (params.size() != 1) {
|
|||
|
|
std::cerr << "错误: calib 命令需要1个参数" << std::endl;
|
|||
|
|
std::cerr << "用法: calib <相机索引>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!IsNumber(params[0])) {
|
|||
|
|
std::cerr << "错误: 相机索引必须是数字: " << params[0] << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
configData.cmdType = CONFIG_CMD_CALIB_PARAM;
|
|||
|
|
configData.calibParam.cameraIndex = std::stoi(params[0]);
|
|||
|
|
|
|||
|
|
std::string timestamp = GetCurrentTimestamp();
|
|||
|
|
strncpy(configData.timestamp, timestamp.c_str(), sizeof(configData.timestamp) - 1);
|
|||
|
|
|
|||
|
|
std::cout << "解析标定参数: 相机" << configData.calibParam.cameraIndex << std::endl;
|
|||
|
|
std::cerr << "警告: 标定参数配置功能尚未完全实现" << std::endl;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::ParseCameraFrameRate(const std::vector<std::string>& params, ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
// 支持格式:
|
|||
|
|
// framerate 30 - 设置所有相机帧率为30fps
|
|||
|
|
// framerate 1 30 - 设置相机1帧率为30fps
|
|||
|
|
|
|||
|
|
if (params.empty()) {
|
|||
|
|
std::cerr << "错误: framerate 命令需要指定帧率值" << std::endl;
|
|||
|
|
std::cerr << "用法: framerate <帧率> 或 framerate <相机索引> <帧率>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
configData.cmdType = CONFIG_CMD_CAMERA_FRAMERATE;
|
|||
|
|
configData.cameraParam.cameraIndex = -1; // 默认所有相机
|
|||
|
|
|
|||
|
|
if (params.size() == 1) {
|
|||
|
|
// 格式: framerate 30
|
|||
|
|
if (!IsNumber(params[0])) {
|
|||
|
|
std::cerr << "错误: 帧率值必须是数字: " << params[0] << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
configData.cameraParam.frameRate = std::stod(params[0]);
|
|||
|
|
}
|
|||
|
|
else if (params.size() == 2) {
|
|||
|
|
// 格式: framerate 1 30
|
|||
|
|
if (!IsNumber(params[0]) || !IsNumber(params[1])) {
|
|||
|
|
std::cerr << "错误: 相机索引和帧率值都必须是数字" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
configData.cameraParam.cameraIndex = std::stoi(params[0]);
|
|||
|
|
configData.cameraParam.frameRate = std::stod(params[1]);
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
std::cerr << "错误: framerate 命令参数过多" << std::endl;
|
|||
|
|
std::cerr << "用法: framerate <帧率> 或 framerate <相机索引> <帧率>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 参数验证
|
|||
|
|
if (configData.cameraParam.frameRate <= 0) {
|
|||
|
|
std::cerr << "错误: 帧率值必须大于0" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置时间戳
|
|||
|
|
std::string timestamp = GetCurrentTimestamp();
|
|||
|
|
strncpy(configData.timestamp, timestamp.c_str(), sizeof(configData.timestamp) - 1);
|
|||
|
|
|
|||
|
|
std::cout << "解析相机帧率参数: 相机" << configData.cameraParam.cameraIndex
|
|||
|
|
<< ", 帧率: " << configData.cameraParam.frameRate << "fps" << std::endl;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::ParseCameraSwing(const std::vector<std::string>& params, ConfigCmdData& configData)
|
|||
|
|
{
|
|||
|
|
// 支持格式:
|
|||
|
|
// swing 10 0 180 - 设置所有相机摆动:速度10,角度0-180度
|
|||
|
|
// swing 1 10 0 180 - 设置相机1摆动:速度10,角度0-180度
|
|||
|
|
|
|||
|
|
if (params.size() != 3 && params.size() != 4) {
|
|||
|
|
std::cerr << "错误: swing 命令需要3个或4个参数" << std::endl;
|
|||
|
|
std::cerr << "用法: swing <速度> <开始角度> <结束角度> 或 swing <相机索引> <速度> <开始角度> <结束角度>" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
configData.cmdType = CONFIG_CMD_CAMERA_SWING;
|
|||
|
|
configData.swingParam.cameraIndex = -1; // 默认所有相机
|
|||
|
|
|
|||
|
|
std::vector<std::string> swingValues;
|
|||
|
|
|
|||
|
|
if (params.size() == 3) {
|
|||
|
|
// 格式: swing 10 0 180
|
|||
|
|
swingValues = params;
|
|||
|
|
}
|
|||
|
|
else if (params.size() == 4) {
|
|||
|
|
// 格式: swing 1 10 0 180
|
|||
|
|
if (!IsNumber(params[0])) {
|
|||
|
|
std::cerr << "错误: 相机索引必须是数字: " << params[0] << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
configData.swingParam.cameraIndex = std::stoi(params[0]);
|
|||
|
|
swingValues = std::vector<std::string>(params.begin() + 1, params.end());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 验证所有摆动参数都是数字
|
|||
|
|
for (size_t i = 0; i < swingValues.size(); ++i) {
|
|||
|
|
if (!IsNumber(swingValues[i])) {
|
|||
|
|
std::cerr << "错误: 摆动参数必须是数字: " << swingValues[i] << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 解析摆动参数
|
|||
|
|
configData.swingParam.swingSpeed = std::stod(swingValues[0]);
|
|||
|
|
configData.swingParam.startAngle = std::stod(swingValues[1]);
|
|||
|
|
configData.swingParam.stopAngle = std::stod(swingValues[2]);
|
|||
|
|
|
|||
|
|
// 参数验证
|
|||
|
|
if (configData.swingParam.swingSpeed <= 0) {
|
|||
|
|
std::cerr << "错误: 摆动速度必须大于0" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (configData.swingParam.startAngle >= configData.swingParam.stopAngle) {
|
|||
|
|
std::cerr << "错误: 开始角度必须小于结束角度" << std::endl;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置时间戳
|
|||
|
|
std::string timestamp = GetCurrentTimestamp();
|
|||
|
|
strncpy(configData.timestamp, timestamp.c_str(), sizeof(configData.timestamp) - 1);
|
|||
|
|
|
|||
|
|
std::cout << "解析相机摆动参数: 相机" << configData.swingParam.cameraIndex
|
|||
|
|
<< ", 速度: " << configData.swingParam.swingSpeed
|
|||
|
|
<< ", 角度: " << configData.swingParam.startAngle
|
|||
|
|
<< "-" << configData.swingParam.stopAngle << std::endl;
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ConfigCmdParser::ShowHelp()
|
|||
|
|
{
|
|||
|
|
std::cout << "GrabBag 配置命令行工具" << std::endl;
|
|||
|
|
std::cout << "用法: grabbag [选项] -c <配置类型> <参数...>" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
std::cout << "选项:" << std::endl;
|
|||
|
|
std::cout << " -h, --help 显示帮助信息" << std::endl;
|
|||
|
|
std::cout << " -v, --version 显示版本信息" << std::endl;
|
|||
|
|
std::cout << " -c, --config 设置配置参数" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
std::cout << "配置参数格式:" << std::endl;
|
|||
|
|
std::cout << " 相机曝光:" << std::endl;
|
|||
|
|
std::cout << " grabbag -c expose <曝光时间> - 设置所有相机曝光时间(微秒)" << std::endl;
|
|||
|
|
std::cout << " grabbag -c expose <相机索引> <曝光时间> - 设置指定相机曝光时间" << std::endl;
|
|||
|
|
std::cout << " 示例: grabbag -c expose 100" << std::endl;
|
|||
|
|
std::cout << " grabbag -c expose 1 150" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
std::cout << " 相机增益:" << std::endl;
|
|||
|
|
std::cout << " grabbag -c gain <增益值> - 设置所有相机增益" << std::endl;
|
|||
|
|
std::cout << " grabbag -c gain <相机索引> <增益值> - 设置指定相机增益" << std::endl;
|
|||
|
|
std::cout << " 示例: grabbag -c gain 2.5" << std::endl;
|
|||
|
|
std::cout << " grabbag -c gain 1 3.0" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
std::cout << " 相机帧率:" << std::endl;
|
|||
|
|
std::cout << " grabbag -c framerate <帧率> - 设置所有相机帧率(fps)" << std::endl;
|
|||
|
|
std::cout << " grabbag -c framerate <相机索引> <帧率> - 设置指定相机帧率" << std::endl;
|
|||
|
|
std::cout << " 示例: grabbag -c framerate 30" << std::endl;
|
|||
|
|
std::cout << " grabbag -c framerate 1 25" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
std::cout << " 摆动参数:" << std::endl;
|
|||
|
|
std::cout << " grabbag -c swing <速度> <开始角度> <结束角度> - 设置所有相机摆动参数" << std::endl;
|
|||
|
|
std::cout << " grabbag -c swing <相机索引> <速度> <开始角度> <结束角度> - 设置指定相机摆动参数" << std::endl;
|
|||
|
|
std::cout << " 示例: grabbag -c swing 10 0 180" << std::endl;
|
|||
|
|
std::cout << " grabbag -c swing 1 15 -45 45" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
std::cout << " 算法参数:" << std::endl;
|
|||
|
|
std::cout << " grabbag -c algo <参数名> <值> - 设置算法参数" << std::endl;
|
|||
|
|
std::cout << " 示例: grabbag -c algo threshold 0.5" << std::endl;
|
|||
|
|
std::cout << " grabbag -c algo windowSize 10" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
std::cout << " 标定参数:" << std::endl;
|
|||
|
|
std::cout << " grabbag -c calib <相机索引> - 触发指定相机标定" << std::endl;
|
|||
|
|
std::cout << " 示例: grabbag -c calib 1" << std::endl;
|
|||
|
|
std::cout << std::endl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ConfigCmdParser::ShowVersion()
|
|||
|
|
{
|
|||
|
|
std::cout << "GrabBag 配置命令行工具 v1.0.0" << std::endl;
|
|||
|
|
std::cout << "版权所有 (C) 2024" << std::endl;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::InitializeSharedMemory()
|
|||
|
|
{
|
|||
|
|
if (m_pShareMem) {
|
|||
|
|
return true; // 已经初始化
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
m_pShareMem = CreateShareMemInstance();
|
|||
|
|
if (!m_pShareMem) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 尝试打开已存在的共享内存,如果不存在则创建
|
|||
|
|
int ret = m_pShareMem->CreateOrOpen(CONFIG_CMD_SHARED_MEM_NAME, CONFIG_CMD_SHARED_MEM_SIZE, false);
|
|||
|
|
if (ret != SUCCESS) {
|
|||
|
|
// 如果打开失败,尝试创建新的
|
|||
|
|
ret = m_pShareMem->CreateOrOpen(CONFIG_CMD_SHARED_MEM_NAME, CONFIG_CMD_SHARED_MEM_SIZE, true);
|
|||
|
|
if (ret != SUCCESS) {
|
|||
|
|
CleanupSharedMemory();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 映射内存
|
|||
|
|
void* mappedAddr = m_pShareMem->MapView();
|
|||
|
|
if (!mappedAddr) {
|
|||
|
|
CleanupSharedMemory();
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ConfigCmdParser::CleanupSharedMemory()
|
|||
|
|
{
|
|||
|
|
if (m_pShareMem) {
|
|||
|
|
m_pShareMem->UnmapView();
|
|||
|
|
m_pShareMem->Close();
|
|||
|
|
DestroyShareMemInstance(m_pShareMem);
|
|||
|
|
m_pShareMem = nullptr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::vector<std::string> ConfigCmdParser::SplitString(const std::string& str, char delimiter)
|
|||
|
|
{
|
|||
|
|
std::vector<std::string> result;
|
|||
|
|
std::stringstream ss(str);
|
|||
|
|
std::string item;
|
|||
|
|
|
|||
|
|
while (std::getline(ss, item, delimiter)) {
|
|||
|
|
result.push_back(item);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return result;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ConfigCmdParser::IsNumber(const std::string& str)
|
|||
|
|
{
|
|||
|
|
if (str.empty()) return false;
|
|||
|
|
|
|||
|
|
std::string::const_iterator it = str.begin();
|
|||
|
|
|
|||
|
|
// 允许负号
|
|||
|
|
if (*it == '-') ++it;
|
|||
|
|
|
|||
|
|
bool hasDigit = false;
|
|||
|
|
bool hasDot = false;
|
|||
|
|
|
|||
|
|
while (it != str.end()) {
|
|||
|
|
if (std::isdigit(*it)) {
|
|||
|
|
hasDigit = true;
|
|||
|
|
}
|
|||
|
|
else if (*it == '.' && !hasDot) {
|
|||
|
|
hasDot = true;
|
|||
|
|
}
|
|||
|
|
else {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
++it;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return hasDigit;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
std::string ConfigCmdParser::GetCurrentTimestamp()
|
|||
|
|
{
|
|||
|
|
auto now = std::chrono::system_clock::now();
|
|||
|
|
auto time_t = std::chrono::system_clock::to_time_t(now);
|
|||
|
|
|
|||
|
|
std::stringstream ss;
|
|||
|
|
ss << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S");
|
|||
|
|
return ss.str();
|
|||
|
|
}
|