用CruiseControl监视你的项目 -CruiseControl step by step(4)

CruiseControl持续集成实践
本文介绍了CruiseControl持续集成系统的使用方法,包括项目状态分类、Dashboard操作界面解析及JMX控制台使用等内容。

现在,我们已经为自己的项目建立了持续集成服务器。让我们来看一下CruiseControl正在对你说些什么。

一、项目的状态

首先CruiseControl把项目分成三类,Discontinued,Inactive,及Active。

如果一个项目是Discontinued,表示CruiseControl可以找到该项目的日志文件,但在配置文件(Config.xml)中并没有该文件。所以CruiseControl不会去构建它,但你可以看到这个项目过去构建的历史信息。如果想把这个项目从CruiseControl中删除,只有把该项目的日志目录删除才行。如果该项目名为"vcdstore",目录当该是${CruiseContor.Home}/logs/vcdstore。

如果一个项目是Inactive,表示CruiseControl在配置文件(Config.xml)中发现了该项目,但是没有发现关于这个项目的任何历史信息,即在CruiseControl的日志目录中还没有该项目的日志文件,或日志文件被人为删除了。CruiseControl会根据配置信息对这个项目进行检查新版本并进行构建。当第一次构建完成后,CruiseControl就会生成日志,这个项目状态就会转为Active了。

如果一个项目是Active,表示CruiseControl即可以找到该项目的日志文件,又在配置文件(Config.xml)中可以发现它。此时,这个项目可能是构建成功,也可能是构建失败,还可能是构建中。

二、Dashboard

你可以通过 http://localhost:8080/dashboard 访问Dashboard。

Dashboard主要有四个页面,它们分别是Dashboard,Builds,Build Details和Administatiorn。

(1) Dashboard

你可以在Dashboard上看到所有项目的状态, 红色方块表示该项目最近一次构建是失败的。 绿色方块表示该项目最近一次构建是成功的。灰色方块表示该项目可能是Inactive的,也可能是Discontinued。

当把鼠标放在小方块上时,会显示该项目的主要信息。点击小方块,会进入Build Details页面。

Dashboard page

(2) Builds

你可以在Builds页面上以列表的方式看到所有项目的状态,点击每个列表,可以进行Build Details页面。

如果你将ForceBuild配置为true,在列表右侧有一个按钮,你可以强迫该项目进行构建,而不必等到其下一次检查,也不必等到它有版本变化。


(3) Build Details

此页面会列出该项目某次构建的详细信息,包括与上次构建相比有哪些变化,测试结果是什么,详细的日志输出,如果构建成功的话,在配置文件(config.xml)中配置的Artifacts也会在名为Artifiacts的tab页上看到。

右侧的列表是该项目所有的构建列表,点击其中一个构建,你就可以得到该次构建的详细信息。


(4) Administration

该页面你可以看到About和Configuration两个子标签。

在About子标签中,你可以看到CruiseControl所用的环境信息,如CruiseControl的版本号、所用的操作系统和JDK版本等。


在Administration子标签中,你可以看到CruiseControl的Dashboard-config.xml文件内容。在该版本中,还不支持修改,也移除了"Add Project"按钮。


三、CruiseControl Reporting

你也可以通过链接http://localhost:8080/ 来访问CruiseControl的Old Reporting。


点击项目名称,可以看到详细内容。


四、CruiseControl JMX控制台

你也可以通过链接http://localhost:8000/来访问CruiseControl的JMX控制台。


在控制台上点击项目名称(如connectfour),可以修改项目配置,暂停/恢复项目构建等。


小贴士:

(1) 以上的链接均以不修改CruiseControl默认配置为基础。

(2) 后面的文章中,我们会介绍如何通过Build Grid来推展我们的CruiseControl构建能力。

 

#include <rei_robot_cruise/cruise.h> #include "oryxbot_cruise_ex/oryxbot_task.h" #include <geometry_msgs/Twist.h> // 实例化对象 ORYXTask oryxTask; geometry_msgs::Twist workStationAbovePose_; geometry_msgs::Twist boxAbovePose_; std::vector<geometry_msgs::Twist> boxPose_; std::vector<geometry_msgs::Twist> workStationPoses_; std::vector<int> boxState_(2,0); bool StartCallback0(){ return oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z); } bool chargeCallback(int value){ int taskStep = value; int taskState; std::vector<int> arIds; int placeTime = 0; ros::Rate loop(1); while(ros::ok()){ if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::PAUSE){ rei_cruise::RobotCruise::getInstance().SetCallBackFuncStep(taskStep); break; }else if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::STOP){ break; } taskState = rei_cruise::RobotCruise::getInstance().GetTaskState(); if(taskState == rei_cruise::TaskState::ACTIVE){ switch (taskStep) { case 0: if(oryxTask.ArAdjust(0)) taskStep = 1; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 1: if(oryxTask.RelativeMove(0.12,0,0,"odom")){ ros::Time start = ros::Time::now(); while (ros::Time::now() - start < ros::Duration(2.0) && ros::ok()) { if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::PAUSE) { rei_cruise::RobotCruise::getInstance().SetCallBackFuncStep(taskStep); return true; } else if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::STOP) { return true; } ros::Duration(0.1).sleep(); } taskStep = 2; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 2: if(oryxTask.RelativeMove(-0.12,0,0,"odom")){ return true; }else return false; break; } }else if(taskState == rei_cruise::TaskState::STOP){ break; } loop.sleep(); } return true; } bool StartCallback1(){ return oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z); } bool renwua_aplaceCallback(int value){ int taskStep = value; int taskState; std::vector<int> arIds; int placeTime = 0; ros::Rate loop(1); while(ros::ok()){ if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::PAUSE){ rei_cruise::RobotCruise::getInstance().SetCallBackFuncStep(taskStep); break; }else if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::STOP){ break; } taskState = rei_cruise::RobotCruise::getInstance().GetTaskState(); if(taskState == rei_cruise::TaskState::ACTIVE){ switch (taskStep) { case 0: if(oryxTask.ArAdjust(1)) taskStep = 1; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 1: if(oryxTask.RelativeMove(0.12,0,0,"odom")){ taskStep = 2; placeTime = 0; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 2: if(oryxTask.GotoPosition(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z)){ taskStep=3; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 3: if(oryxTask.GetArIDs(arIds)) taskStep=4; else if(placeTime>0) taskStep=5; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 4: if(oryxTask.PickPlace(4,70, -160, 10)){ taskStep=5; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 5: if(oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z)){ taskStep=6; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 6: if(oryxTask.RelativeMove(-0.12,0,0,"odom")){ return true; }else return false; break; } }else if(taskState == rei_cruise::TaskState::STOP){ break; } loop.sleep(); } return true; } bool StartCallback2(){ return oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z); } bool renwua_bplaceCallback(int value){ int taskStep = value; int taskState; std::vector<int> arIds; double p=3.141592653589793238462643383279502884197169399375105820974944923078164; int placeTime = 0; ros::Rate loop(1); while(ros::ok()){ if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::PAUSE){ rei_cruise::RobotCruise::getInstance().SetCallBackFuncStep(taskStep); break; }else if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::STOP){ break; } taskState = rei_cruise::RobotCruise::getInstance().GetTaskState(); if(taskState == rei_cruise::TaskState::ACTIVE){ switch (taskStep) { case 0: if(oryxTask.ArAdjust(1)) taskStep = 1; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 1: if(oryxTask.RelativeMove(0.12,0,0,"odom")){ taskStep = 2; placeTime = 0; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 2: if(oryxTask.GotoPosition(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z)){ taskStep=3; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 3: if(oryxTask.GetArIDs(arIds)) taskStep=4; else if(placeTime>0) taskStep=5; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 4: if(oryxTask.PickPlace(6,130, -163, 10)){ taskStep=5; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 5: if(oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z)){ taskStep=6; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 6: if(oryxTask.RelativeMove(-0.12,0,0,"odom")){ return true; }else return false; break; } }else if(taskState == rei_cruise::TaskState::STOP){ break; } loop.sleep(); } return true; } bool StartCallback3(){ return oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z); } bool renwub_aplaceCallback(int value){ int taskStep = value; int taskState; std::vector<int> arIds; int placeTime = 0; ros::Rate loop(1); while(ros::ok()){ if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::PAUSE){ rei_cruise::RobotCruise::getInstance().SetCallBackFuncStep(taskStep); break; }else if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::STOP){ break; } taskState = rei_cruise::RobotCruise::getInstance().GetTaskState(); if(taskState == rei_cruise::TaskState::ACTIVE){ switch (taskStep) { case 0: if(oryxTask.ArAdjust(1)) taskStep = 1; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 1: if(oryxTask.RelativeMove(0.12,0,0,"odom")){ taskStep = 2; placeTime = 0; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 2: if(oryxTask.GotoPosition(workStationAbovePose_.linear.x, workStationAbovePose_.linear.y, workStationAbovePose_.linear.z)){ taskStep=3; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 3: if(oryxTask.GetArIDs(arIds)) taskStep=4; else if(placeTime>0) taskStep=5; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 4: if(oryxTask.PickPlace(arIds[0], 105, 123,20)) { taskStep=5; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 5: if(oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z)){ taskStep=6; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 6: if(oryxTask.RelativeMove(-0.12,0,0,"odom")){ return true; }else return false; break; } }else if(taskState == rei_cruise::TaskState::STOP){ break; } loop.sleep(); } return true; } bool StartCallback4(){ return oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z); } bool renwub_bplaceCallback(int value){ int taskStep = value; int taskState; std::vector<int> arIds; int placeTime = 1; double p=3.141592653589793238462643383279502884197169399375105820974944; ros::Rate loop(1); while(ros::ok()){ if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::PAUSE){ rei_cruise::RobotCruise::getInstance().SetCallBackFuncStep(taskStep); break; }else if(rei_cruise::RobotCruise::getInstance().GetTaskState() == rei_cruise::STOP){ break; } taskState = rei_cruise::RobotCruise::getInstance().GetTaskState(); if(taskState == rei_cruise::TaskState::ACTIVE){ switch (taskStep) { case 0: if(oryxTask.ArAdjust(1)) taskStep = 1; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 1: if(oryxTask.RelativeMove(0.12,0,0,"odom")){ taskStep = 2; placeTime = 1; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 2: if(oryxTask.GotoPosition(workStationAbovePose_.linear.x+20, workStationAbovePose_.linear.y, workStationAbovePose_.linear.z)){ taskStep=3; } else rei_cruise::RobotCruise::getInstance().Pause(); break; case 3: if(oryxTask.GetArIDs(arIds)) taskStep=4; else if(placeTime>0) taskStep=5; else rei_cruise::RobotCruise::getInstance().Pause(); break; case 4: if(oryxTask.PickPlace(arIds[0], 105, 183,20)) { taskStep=5; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 5: if(oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, boxAbovePose_.linear.z)){ taskStep=6; }else rei_cruise::RobotCruise::getInstance().Pause(); break; case 6: if(oryxTask.RelativeMove(-0.12,0,0,"odom")){ return true; }else return false; break; } }else if(taskState == rei_cruise::TaskState::STOP){ break; } loop.sleep(); } return true; } int main(int argc, char** argv){ ros::init(argc, argv, "cruise_test_node"); ros::NodeHandle nh; //ros::Publisher Vel_c; // Vel_c = nh.advertise<geometry_msgs::Twist>("cmd_vel",10); // geometry_msgs::Twist vel_msg; // vel_msg.linear.x=0.4; // vel_msg.angular.z=1.0; if (!oryxTask.Init(nh)){ return 0; } // 仿真小车白色盒子观测位置 boxAbovePose_.linear.x = 105.0; boxAbovePose_.linear.y = 120.0; boxAbovePose_.linear.z = 85.0; boxAbovePose_.angular.z = 0.0; if(!oryxTask.ResetArm(boxAbovePose_.linear.x, boxAbovePose_.linear.y, 60, 0)){ return 0; } // 模拟加工台观测位置 workStationAbovePose_.linear.x = 70.0; workStationAbovePose_.linear.y = -160.0; workStationAbovePose_.linear.z = 80.0; workStationAbovePose_.angular.z = 0.0; //仿真小车两个盒子位置 geometry_msgs::Twist tmpPose; tmpPose.linear.x = 105; tmpPose.linear.y = 123; tmpPose.linear.z = 30; tmpPose.angular.z = 0.0; boxPose_.push_back(tmpPose); tmpPose.linear.x = 105; tmpPose.linear.y = 183; tmpPose.linear.z = 30; tmpPose.angular.z = 0.0; boxPose_.push_back(tmpPose); //模拟加工台的放置位置 tmpPose.linear.x = 65; tmpPose.linear.y = -160; tmpPose.linear.z = 30.0; tmpPose.angular.z = 0.0; workStationPoses_.push_back(tmpPose); tmpPose.linear.x = 125; tmpPose.linear.y = -160; tmpPose.linear.z = 30.0; tmpPose.angular.z = 0.0; workStationPoses_.push_back(tmpPose); rei_cruise::RobotCruise& cruise = rei_cruise::RobotCruise::getInstance(); if(!cruise.Init(nh)) return 0; cruise.AddStartCallBack(StartCallback1); if(cruise.AddCallBack("renwua_a_place", renwua_aplaceCallback)) { ROS_INFO("set callback renwua_aplaceCallback success"); } cruise.AddStartCallBack(StartCallback2); if(cruise.AddCallBack("renwua_b_place", renwua_bplaceCallback)) { ROS_INFO("set callback renwua_bplaceCallback success"); } cruise.AddStartCallBack(StartCallback3); if(cruise.AddCallBack("renwub_a_place", renwub_aplaceCallback)) { ROS_INFO("set callback WorkStationPickCallback success"); } cruise.AddStartCallBack(StartCallback4); if(cruise.AddCallBack("renwub_b_place", renwub_bplaceCallback)) { ROS_INFO("set callback WorkStationPickCallback success"); } if(cruise.AddCallBack("charge", chargeCallback)) { ROS_INFO("set callback WorkStationPickCallback success"); } cruise.AddStartCallBack(StartCallback0); cruise.RunNavTask(); return 0; }clear_old_goal: True #bool型,是否清除之前存储的目标点 goals_name: ["home","work5", "work2","work3","work1","work4","charge"] #string型,目标点列表,以","分隔 home: frame_id: map #string型,目标点基坐标 x: 0.00 y: 0.00 theta: 0.0 work5: frame_id: map #string型,目标点基坐标 x: 0.64 y: 1.15 theta: 0 work2: frame_id: map #string型,目标点基坐标 x: 2.16 y: 1.11 theta: 0 work3: frame_id: map #string型,目标点基坐标 x: 2.16 y: 0.12 theta: 0 work1: frame_id: map #string型,目标点基坐标 x: 2.16 y: 2.11 theta: -0.09 work4: frame_id: map #string型,目标点基坐标 x: 0.64 y: 2.15 theta: 0 charge: frame_id: map #string型,目标点基坐标 x: 0.35 y: 2.10 theta: 1.57 nav_order: ["work3","work2","home","work1","work5","charge","home"] #string型,任务顺序列表,以空格分隔 callback: ["renwua_a_place","renwua_b_place","delauft","renwub_b_place","renwub_a_place","charge","delauft"] #string型,对应任务顺序列表中每个任务点的回调任务,以空格分隔 loop_time: 1 #string型,任务循环次数。怎么修改代码可以利用pid二次定位在home点可以精准定位
06-29
#include "Motor.h" #include "tim.h" /* 步进电机控制参数 */ #define STEP_SEQ_SIZE 4 #define MAX_DUTY 100 // 最大占空比(百分比) uint8_t step_sequence[STEP_SEQ_SIZE][4] = { {1, 0, 1, 0}, // A+ B+ {0, 1, 1, 0}, // A- B+ {0, 1, 0, 1}, // A- B- {1, 0, 0, 1} // A+ B- }; volatile int8_t current_step = 0; //当前第几步 volatile uint8_t motor_direction = 0; // 0:停止, 1:正转, 2:反转 /* 梯形加减速参数 */ volatile MotorState motor_state = MOTOR_STOP; // 电机状态 /* 设置电机速度(PWM占空比) */ void Set_Motor_Speed(uint8_t speed_percent) { if(speed_percent > MAX_DUTY) speed_percent = MAX_DUTY; // 设置A相占空比 __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, speed_percent); // 设置B相占空比 __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, speed_percent); } /* 设置电机方向 */ void Set_Motor_Direction(uint8_t dir) { motor_direction = dir; } /* 执行步进序列 */ void Step_Motor(void) { if(motor_direction == 0) return; // 停止状态 // 根据方向更新步进序号 if(motor_direction == 1) { // 正转 current_step = (current_step + 1) % STEP_SEQ_SIZE; } else if(motor_direction == 2) { // 反转 current_step = (current_step - 1 + STEP_SEQ_SIZE) % STEP_SEQ_SIZE; } // 设置相位控制引脚 HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin, step_sequence[current_step][0] ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(IN2_GPIO_Port, IN2_Pin, step_sequence[current_step][1] ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(IN3_GPIO_Port, IN3_Pin, step_sequence[current_step][2] ? GPIO_PIN_SET : GPIO_PIN_RESET); HAL_GPIO_WritePin(IN4_GPIO_Port, IN4_Pin, step_sequence[current_step][3] ? GPIO_PIN_SET : GPIO_PIN_RESET); } /* 停止电机 */ void Stop_Motor(void) { Set_Motor_Direction(0); Set_Motor_Speed(0); HAL_GPIO_WritePin(IN1_GPIO_Port, IN1_Pin | IN2_Pin | IN3_Pin | IN4_Pin, GPIO_PIN_RESET); motor_state = MOTOR_STOP; } /* 梯形加减速算法 */ void Trapezoid_Control() { }现在帮我完成这个程序,实现按键按下,步进电机转动,带动输出轴上的滑片移动一段固定距离。电机速度控制采用梯形加减速算法,先加速后匀速然后减速。要求将梯形加减速算法封装成一个函数,写在motor.c里面,输入参数为移动距离、正/反转、最大速度(匀速运动时),程序采用Hal库编写,按键采用非阻塞式按下,按键按下后电机带动滑片往前移动一段距离,再按一次电机往后移动一段距离(归位)。
06-17
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值