class BhCruis:public Behavior {
public: BhCruis(const char* name):Behavior(name){ }; BhCruis(); void Run(); void Setup(); };
void BhCruis::Setup() { }
void BhCruis::Run() {
int bid = GetId();
GO_speed_left[bid] = 255; GO_speed_right[bid] = 255;
GT_beh_action[ACTION_TYPE_MOTOR][bid] = true; }
上面的代码很简单,就是让两个电机以同样的速度晕装,其他都不用考虑。对于某些行为,需要引入稍微复杂一些的处理,比如发现障碍物,首先要停下来,然后判断是应该往左还是往右,做出决定之后,再进行具体的动作。针对这种不能在一个时刻完成,要经过几个不同的状态才能处理完成的行为,可以用状态机来解决。下图是“逃离”行为的状态机:
对于行为实现自己的状态机,在行为实现的代码内部实现,而不影响其他行为。这种结构可以让每个行为子关心自己的实现方式,从而最大的降低软件复杂度,方便功能添加和修改。逃离行为状态机实现原型代码:
void BhEscape::Run(){
int bid = GetId(); // 状态机实现 switch(state){
case 0: // 前方距离过小
if(GI_distance[DISTANCE_FORWORD] < 30){
GO_speed_left[bid] = 0;
GO_speed_right[bid] = 0;
GT_beh_action[ACTION_TYPE_MOTOR][bid] = true;
timestart = millis();
state++; // 状态变化 }else{
GT_beh_action[ACTION_TYPE_MOTOR][bid] = false; } break;
case 1: // 观察左右距离
if(millis() - timestart > 1000){
GO_eyeAngle[bid] = 0;
GT_beh_action[ACTION_TYPE_HEAD][bid] = true;
timestart = millis();
state++;
}
case 2: // 观察左右距离
if(millis() - timestart > 1000){
GO_eyeAngle[bid] = 180;
GT_beh_action[ACTION_TYPE_HEAD][bid] = true;
timestart = millis();
state++; }
case 3: // 决定往哪边转弯
if(millis() - timestart > 1000){
GO_eyeAngle[bid] = Angle_Center_90;
GT_beh_action[ACTION_TYPE_HEAD][bid] = true;
if(GI_distance[DISTANCE_LEFT_1] > GI_distance[DISTANCE_RIGHT_1]){
// 左转
GO_speed_left[bid] = 0;
GO_speed_right[bid] = 255;
}else{ //右转
GO_speed_left[bid] = 255;
GO_speed_right[bid] = 0;
}
GT_beh_action[ACTION_TYPE_MOTOR][bid] = true; state = 0; Delay(2000); } default: break; } }
这种基于行为单元的实现方法比较类似生物的反射行为,完整的代码在下载专区进行下载。完成了基本的代码,下一部分需要构建机器人的机构和测试了。
结构和测试
实验机器人的结构就地取材,用了一个拼装玩具小车的零件,如下图: