virtual bool Run(RobotInfo ri, NavInfo ni, EventFlag evf, RobotCmd& cmd ){
		bool ret = true;

		switch (local_status_) {
		case P0:
			cmd = tec_.Calclate(ni.pos);
			if (tec_.isLastCtlPoints() && evf.is_SetEvent(Robot::EV_LIGHT_BLACK)) {
				// 最後の制御点列で黒を検知したら終了。
				Robot::Instance().Beep();
				local_status_ = P1;
				ret = true;
				tec_pid_.Init();
				timer_start (2000);
			}
			break;

		case P1:
			if (IsTimeup()) {
				Robot::Instance().Beep(Robot::B);
				local_status_ = P2;
				ret = true;
				timer_start (7000);
			} else {
				cmd = tec_pid_.Calclate(ri.light_sensor_val, 50, Technic::RIGHT);
				ret = true;
			}
			break;

		case P2:
			if (IsTimeup()) {
				ret = false; // 終了.
				Robot::Instance().Beep(Robot::A2);
			} else {
				cmd = tec_pid_.Calclate(ri.light_sensor_val, 100, Technic::RIGHT);
				ret = true;
			}
			break;

		default:
			ret = false; // 終了.
			break;
		}

		cmd.param3 = 0;
        return ret;
    }
Пример #2
0
    virtual bool Run(RobotInfo ri, NavInfo ni, EventFlag evf, RobotCmd& cmd)
	{
        bool ret = true;

		switch (local_status_) {
		case MISSION_START:		// 単純走行モード.
			// 走行計算.
			cmd = pid_trace_.Calclate(ri.light_sensor_val, speed_, edge_);
			cmd.param3 = tail_;
			// 終了条件:指定時間で終了.
			if (IsTimeup()) {
				Robot::Instance().Beep(Robot::C);
				local_status_ = DETECT_GRAY_ZONE;
			}
			break;

		case DETECT_GRAY_ZONE:	// グレーゾーン検知モード.
			// 走行計算.
			cmd = pid_trace_.Calclate(ri.light_sensor_val, speed_, edge_);
			cmd.param3 = tail_;
			// 終了条件:グレー検知で終了.
			if (evf.is_SetEvent(Robot::EVENT_MARKER)) {
				Robot::Instance().Beep(Robot::D);
				local_status_ = MISSION_NEXT;
			}
			break;

		case MISSION_NEXT:
			// G1前半ミッション終了.
			Robot::Instance().Beep(Robot::E);
			ret = false;
			TimerStart(1000);
			break;
		}

        return ret;
    }
    virtual bool Run(RobotInfo ri, NavInfo ni, EventFlag evf, RobotCmd& cmd ){

        bool stay_mission = true;
		
		switch (local_status_){
        case P_REACHING: //シーソーに近づく
            speed_ = 10;
            if( evf.is_SetEvent(Robot::EVENT_GYRO)){
                evf.Set(Robot::EVENT_GYRO, false);
                Robot::Instance().Beep();
                set_current_position(pos, ni);
				local_status_ = S_APPROACH_BACK;

                // 助走するために少し下がる
                tec_s_.Init(ri);
                tecType_ = TEC_S;
                speed_ = -30;
            }
            break;

        case S_APPROACH_BACK:
            if( get_distance(pos, ni) > 100*100){
                set_current_position(pos, ni);
                Robot::Instance().Beep();
                local_status_ = S_STAGING;

                // 一気に登る
                tec_s_.Init(ri);
                tecType_ = TEC_S;
                speed_ = 100;
            }
            break;

        case S_STAGING: // 一気にシーソーへ登る
            if( get_distance(pos, ni) > 180*180){
                set_current_position(pos, ni);
                Robot::Instance().Beep(Robot::B);
                local_status_ = P_RECOVER_ON_SEESAW;
                    
                // とりあえずシーソー上でラインに復帰
                tecType_ = TEC_P;
                tec_p_.Init();
                speed_ = 10;
            }
            break;

        case P_RECOVER_ON_SEESAW: // とりあえずシーソー上でラインに復帰
            if( get_distance(pos, ni) > 200*200 ){
                set_current_position(pos, ni);
                Robot::Instance().Beep();
                local_status_ = S_GET_OFF; //左にそれながらシーソーを降りる
                tec_s_.Init(ri);
                tecType_ = TEC_S;
                speed_ = 40;
            }
            break;

            case S_GET_OFF:
                if(get_distance(pos, ni) > 250*250){
                    Robot::Instance().Beep(Robot::B);
                    local_status_ = S_RECOVER_ON_GROUND;

                    // ラインに復帰を試みる
                    tec_s_.Init(ri);
                    tecType_ = TEC_S;
                    speed_ = 10;

                }
                break;

            case S_RECOVER_ON_GROUND:
                /* 終了条件 */
                if(evf.is_SetEvent(Robot::EVENT_LIGHT_BLACK)){
                    set_current_position(pos, ni);
                    local_status_ = P_FOR_NEXT_MISSION;
                    Robot::Instance().Beep(Robot::G);
                    tecType_ = TEC_P;
                    tec_p_.Init();
                    speed_ = 20;
                    TimerStart(10000);
                }
                break;

            case P_FOR_NEXT_MISSION: // 最後に安定するまでライントレースして完全復帰する
                /* ミッション終了の条件 */
                if(get_distance(pos, ni) > 200*200){
                    Robot::Instance().Beep(Robot::E);
                    stay_mission = false;                 
                }
                break;
                
            default:
                stay_mission = true;
                break;
        } // end of switch-case(local_status_)


		/* 走行計算 */
		if(tecType_ == TEC_S){
			cmd = tec_s_.Calclate(speed_,
                              ri.rot_encoderL_val,
                              ri.rot_encoderR_val
                              );
			if(local_status_ == S_GET_OFF){
				cmd.param2 =- 3; // 左側へ降りる
			}
			if(local_status_ == S_RECOVER_ON_GROUND){
				cmd.param2 =+ 3; // 右側のラインへ復帰する
			}

		}else if(tecType_ == TEC_P){
			cmd = tec_p_.Calclate(ri.light_sensor_val, speed_, edge_dir);
			// if(local_status_ == S_STAGING || local_status_ == P_RECOVER_ON_SEESAW){
			// 	cmd.param2 = (S16)((F32)cmd.param2 * 0.7);
			// }
		}else if(tecType_ == TEC_R){
			cmd = tec_r_.Calclate(speed_, rotate_, dir_);
		}else if(tecType_ == TEC_T){
            // しっぽの設定はcase内で設定するよ
		}else{}
        
        return stay_mission;
    }
	virtual bool Run(RobotInfo ri, NavInfo ni, EventFlag evf, RobotCmd& cmd ){
		
		bool ret = true;
		S32 diffR;
		S32 diffL;
		
		switch (local_status_) {

			// 流し走行中(階段衝突前)
			// do: PIDライントレース
			// exit: ジャイロ
			case STAIRS_PRE_IN:
				cmd = tec_pid_.Calclate(ri.light_sensor_val, (S16)(80), Technic::RIGHT);

				if(is_timeup()){
					Robot::Instance().Beep(Robot::A2);
					local_status_ = STAIRS_IN;
				}
				break;

			// 流し走行中(階段衝突前)
			// do: PIDライントレース
			// exit: ジャイロ
			case STAIRS_IN:
				cmd = tec_pid_.Calclate(ri.light_sensor_val, (S16)(speed_ * 0.2), Technic::RIGHT);
				cmd.param3 = 0;

				if(evf.is_SetEvent(Robot::EV_GYRO)){
					start_encoderR = ri.rot_encoderR_val;
					start_encoderL = ri.rot_encoderL_val;
					Robot::Instance().Beep(Robot::D);
					local_status_ = STAIRS_HIT_ONE;
				}
				break;

			// 片輪乗り上げ中
			// do: 旋回走行
			// exit: 340ms
			case STAIRS_HIT_ONE:
				cmd = tec_r_.Calclate(30, 100, Technic::LEFT);
				diffR = ri.rot_encoderR_val - start_encoderR;

				if(diffR > 80){//45:1, 50:2
					Robot::Instance().Beep(Robot::E);
					local_status_ = STAIRS_HIT_BOTH;
				}
				break;
			
			// もう片輪乗り上げ中
			// do: 旋回走行
			// exit: 480ms
			case STAIRS_HIT_BOTH:
				cmd = tec_r_.Calclate(30, 150, Technic::RIGHT);
				diffL = ri.rot_encoderL_val - start_encoderL;

				if(diffL > 80){//45:1, 50:2]]
					Robot::Instance().Beep(Robot::F);
					local_status_ = STAIRS_FLATTEN;
				}
				break;

			// 安定化中
			// do: 旋回走行
			// exit: 480ms
			case STAIRS_FLATTEN:
				diffR = ri.rot_encoderR_val - start_encoderR;
				diffL = ri.rot_encoderL_val - start_encoderL;

				if(diffR - diffL > 1){
					cmd = tec_r_.Calclate(5, 100, Technic::RIGHT);
				}else if(diffL - diffR > 1){
					cmd = tec_r_.Calclate(5, 100, Technic::LEFT);
				}else{
					cmd.param1 = 5;
					cmd.param2 = 0; 
					flatten_count++;
				}

				if(flatten_count > 20){
					Robot::Instance().Beep(Robot::B);
					local_status_ = STAIRS_FORWARD;
					timer_start(4000);
					tec_s_.Init(ri);
				}

				break;

			// ゆっくり前進
			case STAIRS_FORWARD:
				cmd = tec_s_.Calclate(10, ri.rot_encoderL_val, ri.rot_encoderR_val);

				if(is_timeup() && evf.is_SetEvent(Robot::EV_GYRO)){
					start_encoderR = ri.rot_encoderR_val;
					start_encoderL = ri.rot_encoderL_val;
					Robot::Instance().Beep(Robot::C);
					local_status_ = STAIRS_HIT_ONE2;
				}
				break;
			

			// 片輪乗り上げ中
			// do: 旋回走行
			case STAIRS_HIT_ONE2:
				cmd = tec_r_.Calclate(30, 100, Technic::RIGHT);
				diffL = ri.rot_encoderL_val - start_encoderL;


				if(diffL > 80){//45:1, 50:2
					Robot::Instance().Beep(Robot::E);
					local_status_ = STAIRS_HIT_BOTH2;
				}
				break;
			
			// もう片輪乗り上げ中
			// do: 旋回走行
			case STAIRS_HIT_BOTH2:
				cmd = tec_r_.Calclate(30, 150, Technic::LEFT);
				diffR = ri.rot_encoderR_val - start_encoderR;

				if(diffR > 80){//45:1, 50:2]]
					Robot::Instance().Beep(Robot::F);
					local_status_ = STAIRS_FLATTEN2;
					flatten_count = 0;
				}
				break;

			// 安定化中
			case STAIRS_FLATTEN2:
				diffR = ri.rot_encoderR_val - start_encoderR;
				diffL = ri.rot_encoderL_val - start_encoderL;

				if(diffR - diffL > 1){
					cmd = tec_r_.Calclate(5, 100, Technic::RIGHT);
				}else if(diffL - diffR > 1){
					cmd = tec_r_.Calclate(5, 100, Technic::LEFT);
				}else{
					cmd.param1 = 5;
					cmd.param2 = 0; 
					flatten_count++;
				}

				if(flatten_count > 20){
					Robot::Instance().Beep(Robot::B);
					local_status_ = STAIRS_FORWARD2;
					tec_s_.Init(ri);
					timer_start(4000);
				}

				break;

			// ゆっくり前進
			case STAIRS_FORWARD2:
				cmd = tec_s_.Calclate(10, ri.rot_encoderL_val, ri.rot_encoderR_val);
				
				if(is_timeup() && evf.is_SetEvent(Robot::EV_GYRO)){
					Robot::Instance().Beep(Robot::A);
					local_status_ = STAIRS_OUT;
					tec_pid_.Init();
					timer_start(1000);
				}
				break;

			// ライン復帰
			case STAIRS_OUT:
				cmd = tec_pid_.Calclate(ri.light_sensor_val, (S16)(speed_ * 0.2), Technic::RIGHT);
				
				if(is_timeup()){
					Robot::Instance().Beep(Robot::C);
					local_status_ = STAIRS_END;
				}
				break;

			
			default:
				ret = false;
				break;
		}
		
		
		return ret;
	}
    virtual bool Run(RobotInfo ri, NavInfo ni, EventFlag evf, RobotCmd& cmd ){

        bool ret = true;

		switch (local_status_) {
		case TIMER_RUN:			// タイムアップ待ち
			if (is_state_move_) {
				is_state_move_ = false;
				tec_pid_.Init();
				timer_start(2000);
			}
			cmd = tec_pid_.Calclate(ri.light_sensor_val, speed_, edge_);
			cmd.param3 = 0;
			if (is_timeup()) {
				is_state_move_ = true;
				local_status_ = UNTIL_MARKER;
				Robot::Instance().Beep(Robot::C);
			}
			break;

		case UNTIL_MARKER:		// マーカー検知待ち
			if (is_state_move_) {
				is_state_move_ = false;
				tec_pid_.Init();
			}
			cmd = tec_pid_.Calclate(ri.light_sensor_val, speed_, edge_);
			cmd.param3 = 0;
			if (evf.is_SetEvent(Robot::EV_MARKER)) {
				is_state_move_ = true;
				speed_ = 0;
				local_status_ = GARAGE_IN;
				Robot::Instance().Beep(Robot::D);
			}
			break;

		case GARAGE_IN:			// ガレージ入庫
			if (is_state_move_) {
				is_state_move_ = false;
				tec_s_.Init(ri);
				timer_start(1000);
			}
			speed_ = 15;
			cmd = tec_s_.Calclate(speed_, ri.rot_encoderL_val, ri.rot_encoderR_val);
			cmd.param3 = 100;			// しっぽ下ろす
			if(is_timeup()){
				is_state_move_ = true;
				local_status_ = STOP1;
				Robot::Instance().Beep(Robot::E);
			}
			break;

		case STOP1:				// ガレージ停車(少し後進)
			if (is_state_move_) {
				is_state_move_ = false;
				tec_s_.Init(ri);
				timer_start(500);
			}
			speed_ = -15;
			cmd = tec_s_.Calclate(speed_, ri.rot_encoderL_val, ri.rot_encoderR_val);
			cmd.param3 = 100;
			if(is_timeup()){
				is_state_move_ = true;
				local_status_ = STOP2;
				Robot::Instance().Beep(Robot::F);
			}
			break;

		case STOP2:				// ガレージ停車(完全停止)
			cmd.Mode = RobotCmd::DIRECT_MODE;
			cmd.param1 = 0;
			cmd.param2 = 0;
			cmd.param3 = 100;
			break;

		default:
			ret = false;
			break;
		}

        return ret;
    }
    virtual bool Run(RobotInfo ri, NavInfo ni, EventFlag evf, RobotCmd& cmd ){

        bool ret = true;
    	static int count = 0;
    	static  bool flag = false;
    	static S32 lmotor,rmotor;

		
        switch(local_status_){
            // スタート時はスピードを抑え目にして安定した走りだしをする
            case P_START:
            
                /* 走行計算 */
                cmd = pid_trace_.Calclate(ri.light_sensor_val, (S16)(speed_), edge_);
                cmd.param3 = 0;
                
                /* 終了条件 */
                if (IsTimeup()) {
                    Robot::Instance().Beep();
                    local_status_ = P_STRAIGHT_BEFORE;
                    TimerStop();
                }
                break;

            // 直線走行
            case P_STRAIGHT_BEFORE:
                /* 走行計算 */
                cmd = pid_trace_.Calclate(ri.light_sensor_val, (S16)(speed_), edge_);

                if(Robot::Instance().sonar_distance < 30 && flag == false){
                    count++;
                }else {
                    count = 0;
                }

                if(count > 3){
                    Robot::Instance().Beep();
                    count = 0;
                    flag = true;
                    TimerStart(800);
                }
                
                /* 終了条件*/
                if(IsTimeup()){
                    Robot::Instance().Beep();
                    local_status_ = P_STOP;
                    
                    /* 初期化 */
                    flag = false;
                    dist.x = ni.pos.X;
                    dist.y = ni.pos.Y;
                    dist.xy = (dist.x * dist.x) + (dist.y * dist.y);
                    TimerStart(1000);
                }
                break;

            // 停止状態
            case P_STOP:
                
                /* 走行計算 */
                cmd = pid_trace_.Calclate(ri.light_sensor_val, (S16)(0), edge_);
                cmd.param3 = 90;
                
                /* 終了条件 */
                if (IsTimeup()) {
                    Robot::Instance().Beep();
                    local_status_ = P_LOOKUP;
                    
                    /* 初期化 */
                    dist.x = ni.pos.X;
                    dist.y = ni.pos.Y;
                    dist.xy = (dist.x * dist.x) + (dist.y * dist.y);
                    TimerStart(100);
                    Robot::Instance().SetGyroOffset(Robot::Instance().GetGyroOffset() - 20);
                }
                break;

            // LOOKUP
            case P_LOOKUP:
            
                /* 走行計算 */ 
                cmd = pid_trace_.Calclate(ri.light_sensor_val, (S16)(0), edge_);
                cmd.param3 = 90;
                
                /* 終了条件 */
                if (IsTimeup()) {
                    Robot::Instance().Beep();
                    local_status_ = P_STOP_LOOKUP;
                    
                    /* 初期化 */
                    dist.x = ni.pos.X;
                    dist.y = ni.pos.Y;
                    dist.xy = (dist.x * dist.x) + (dist.y * dist.y);
                    TimerStart(100);
                }
                break;

            //斜め停止
            case P_STOP_LOOKUP:
                
                /* 走行計算 */
                static int temptail = 90;
                cmd.Mode = RobotCmd::DIRECT_MODE;
                cmd.param1 = 0;
                cmd.param2 = 0;
                cmd.param3 = temptail;
                
                if (IsTimeup()) {
                    temptail--;
                    TimerStart(100);
                }
                
                /* 終了条件 */
                if(temptail == 70){
                    local_status_ = P_STRAIGHT_LOOKUP;
                    
                    /* 初期化 */
                    temptail = 90;
                    TimerStart(1000);
                }
                break;

            // 斜め停止2
            case P_STOP_LOOKUP2:
                /* 走行計算 */
                cmd.Mode = RobotCmd::DIRECT_MODE;
                cmd.param1 = 0;
                cmd.param2 = 0;
                cmd.param3 = 70;
                
                /* 終了条件 */
                if (IsTimeup()) {
                    local_status_ = P_STRAIGHT_LOOKUP;
                    Robot::Instance().Beep();
                }
                break;

            // 直線走行(lookup)
            case P_STRAIGHT_LOOKUP:
                /* 走行計算 */
                cmd.Mode = RobotCmd::DIRECT_MODE;
                cmd.param1 = 37;
                cmd.param2 = 30;
                cmd.param3 = 68;
                
                /* 終了条件 */
                if(((ni.pos.X - dist.x) * (ni.pos.X - dist.x) +( ni.pos.Y - dist.y) * ( ni.pos.Y - dist.y)) >  DIST_LOOKUP){
                    Robot::Instance().Beep();
                    local_status_ = P_BACK;
                    
                    /* 初期化 */
                    Robot::Instance().GetMotorEncoder(lmotor,rmotor);
                    TimerStart(2000);
                }
                break;

            // BACK
            case P_BACK:
            
                /* 走行計算 */
                cmd.Mode = RobotCmd::DIRECT_MODE;
                cmd.param1 = -10;
                cmd.param2 = -10;
                cmd.param3 = 105;

                /* 終了条件 */
                S32 lmotor2,rmotor2;
                Robot::Instance().GetMotorEncoder(lmotor2,rmotor2);
                if( (lmotor - lmotor2 > LOOKUPENCODER) ||( rmotor - rmotor2 > LOOKUPENCODER)){
                    Robot::Instance().Beep();
                    local_status_ = P_STRAIGHT;
                    
                    /* 初期化 */
                    Robot::Instance().SetGyroOffset(Robot::Instance().GetGyroOffset() + 20);
                    Robot::Instance().ResetBalanceAPI();
                    Navigator::Instance().ResetEncoder();
                    TimerStart(5000);
                    speed_ = 20;
                    pid_trace_.Init();
                }
                break;

            // STAND UP
            case P_STANDUP:
            
                /* 走行計算 */
                cmd.Mode = RobotCmd::DIRECT_MODE;
                cmd.param1 = 0;
                cmd.param2 = 0;
                cmd.param3 = 108;
                
                /* 終了条件 */
                if (IsTimeup()) {
                    local_status_ = P_STRAIGHT;

                    /* 初期化 */ 
                    Robot::Instance().SetGyroOffset(Robot::Instance().GetGyroOffset() + 20);
                    Robot::Instance().ResetBalanceAPI();
                    Navigator::Instance().ResetEncoder();
                    speed_ = 10;
                    tec_r_.Init();
                }
                break;

            case P_STRAIGHT:
            
                /* 走行計算 */
                cmd = tec_r_.Calclate(speed_, -5, edge_);
                cmd.param3 = 0;

                /* 終了条件 */
                if( evf.is_SetEvent(Robot::EVENT_LIGHT_BLACK) ){
                    local_status_ = P_STRAIGHT2;
                    ret = false;
                    
                    /* 初期化 */
                    speed_ = 10;
                    TimerStart(3000);
                    pid_trace_.Init();
                }
                break;
            case P_STRAIGHT2:
            
                /* 走行計算 */
                cmd = pid_trace_.Calclate(ri.light_sensor_val, (S16)(speed_), edge_);
                cmd.param3 = 0;

                /* 終了条件 */
                if (IsTimeup()) {
                    ret = false;
                    
                    /* 初期化 */
                    speed_ = 50;
                    TimerStop();
                }
                break;

            default:
                ret = false;
		}

        return ret;

    }