这个 main
函数实现了一个程序的主逻辑,它包含以下几个主要功能:
-
根据输入参数选择运行模式:
- 当没有输入参数时,默认运行
track
模式,并将residenceColor
设置为brown
。 - 当有输入参数时,根据第一个参数选择不同的运行模式或颜色配置:
track
模式默认residenceColor
为null
。brown
模式设置residenceColor
为brown
。violet
模式设置residenceColor
为violet
。stop
模式停止。- 当输入参数不符合上述任何一种时,默认进入
track
模式并提示参数错误。
- 当没有输入参数时,默认运行
-
根据第二个输入参数设置
divergerColor
或者显示图像:red
设置divergerColor
为red
。green
设置divergerColor
为green
。showImage
开启UdpUtil
的start
方法以显示图像。
-
尝试打开摄像头:
- 循环尝试打开编号从0到3的摄像头,如果成功则打印成功信息并退出循环,否则在尝试到第4个摄像头失败时退出程序。
-
创建 LCM 发送对象并开启计时线程:
- 创建
lcmUtil
对象。 - 启动
mythread
线程。
- 创建
-
主循环逻辑:
- 如果摄像头断开则循环重新尝试打开摄像头。
- 捕获图像并进行处理。
- 处理完成后通过
LCM
发送指令。 - 打印状态。
- 根据
flag
决定是否显示或发送图像,并根据UdpUtil
接收到的信息选择颜色、设置颜色阈值或保存颜色阈值。 - 线程休眠20ms以降低CPU占用。
-
程序结束时释放摄像头资源:
下面是逐段解析:
1. 参数解析和模式选择
if(argc==1){
printf("using default parameter mode is track\n");
printf("mode is track\n");
printf("default residenceColor is red\n");
mythread.mode=track;
residenceColor="brown";//******
}
else if(argc>=2){
inputParameters1=argv[1];
if(inputParameters1=="track"){
printf("mode is track\n");
printf("default residenceColor is null\n");
mythread.mode=track;
}else if(inputParameters1=="brown"){
printf("mode is track\n");
printf("input residenceColor is brown\n");
mythread.mode=track;
residenceColor="brown";
}else if(inputParameters1=="violet"){
printf("mode is track\n");
printf("input residenceColor is violet\n");
mythread.mode=track;
residenceColor="violet";
}
else if(inputParameters1=="stop"){
printf("mode is stop\n");
mythread.mode=stop;
}else{
mythread.mode=track;
printf("parameters error\n");
printf("mode is track\n");
}
if(argc==3){
inputParameters2=argv[2];
if(inputParameters2=="red"){
printf("mode is track\n");
printf("input divergerColor is red\n");
mythread.mode=track;
divergerColor="red";
}
else if(inputParameters2=="green"){
printf("mode is track\n");
printf("input divergerColor is green\n");
mythread.mode=track;
divergerColor="green";
}
else if(inputParameters2=="showImage"){
printf("start to show image\n");
flag=true;
udpsocket.start();
}
}
}
2. 打开摄像头
for(int i=0;i<=3;i++){
cap.open(i);
if(!cap.isOpened())
{
printf("打开摄像头失败:number=%d\n",i);
if(i==3)
return 0;
}else {
printf("打开摄像头成功:number=%d\n",i);
break;
}
}
3. 创建 LCM 对象和开启线程
lcmUtil *lcmutil=new lcmUtil;
mythread.start();
QTime time;
4. 主循环逻辑
while(1){
if(cap.get(CAP_PROP_HUE)==-1){
while (1) {
QThread::msleep(100);
for(int i=0;i<=3;i++){
cap.open(i);
if(cap.isOpened()){
break;
}
}
if(cap.isOpened()){
break;
}
}
}
cap >> srcImage;
if( ! srcImage.empty()){
imageProcess(srcImage);
lcmutil->send(v_des,gait_type,step_height,stand_height,rpy_des);
logMode();
if(flag){
colorgroup.showPicture(srcImage,1);
colorgroup.start();
if(udpsocket.ifReceiveInfoFlag!=0){
switch (udpsocket.ifReceiveInfoFlag){
case 1:
std::cout<<"choose color and return this color threadhold"<<std::endl;
colorgroup.chooseColor(udpsocket.color);
colorgroup.sendColorThreadhold();
colorgroup.ifRunContinueFlag=true;
break;
case 2:
std::cout<<"set color threadhold"<<std::endl;
colorgroup.setColorThreadhold(udpsocket.colorThreadhold);
break;
case 3:
std::cout<<"save color threadhold"<<std::endl;
colorgroup.save();
break;
}
udpsocket.ifReceiveInfoFlag=0;
}
}
}
QThread::msleep(20);
}
5. 结束程序
printf("程序运行结束\n");
cap.release();
return 0;
总结,该程序通过解析输入参数决定运行模式,并通过 UDP 接收和摄像头捕获图像,处理图像后发送指令,此外根据需求可以显示图像。