예제 #1
0
//*****************************************************************************
//
//! Move robot a little bit (error +-500 pulses). Robot velocity is equal 0 after moving.
//! Make sure this function return true before calling it again.
//!
//! \param deltaLeft distance left motor will go
//! \param deltaRight distance right motor will go
//! \param velLeftMax max left velocity
//! \param velRightMax max right velocity
//!
//! \return true if done
//
//*****************************************************************************
static bool move(int deltaLeft,int deltaRight,int velLeftMax, int velRightMax)
{
	static int origLeft, origRight;
	static bool done = true;

	int currentLeft=qei_getPosLeft();
	int currentRight=qei_getPosRight();

	if (done)
	{
		done=false;
		origLeft=currentLeft;
		origRight=currentRight;
	}
	//bluetooth_print("move: %5d %5d\r\n",origLeft,currentLeft);
	if (abs(origLeft+deltaLeft-currentLeft)>500)
	{
		pid_posLeft.PID_Saturation = velLeftMax;
		speed_set(MOTOR_LEFT, pid_process(&pid_posLeft,origLeft+deltaLeft-currentLeft));
		pid_posRight.PID_Saturation = velRightMax;
		speed_set(MOTOR_RIGHT, pid_process(&pid_posRight,origRight+deltaRight-currentRight));
		done=false;
	}
	else
	{
		done = true;
		pid_reset(&pid_posLeft);
		pid_reset(&pid_posRight);
	}
#ifdef _DEBUG_MOVE
	bluetooth_print("move: %5d %5d %5d %5d\r\n",(int)left, (int)right,(int)pid_posLeft.u,(int)pid_posRight.u);
#endif

	return done;
}
예제 #2
0
void robot_cs_update(void* dummy)
{
  double vx_t,vy_t,omegaz_t;
  double vx_r,vy_r;
  double alpha;
  double _ca,_sa;

  hrobot_vector_t hvec;
	robot_cs_t *rcs = dummy;
 

  // if CS inactivated, just quit
  if(!rcs->active)
    return;

  // if CS was previously inactive, we need a little hack for quadramps
  if(rcs->reactivated)
  {
    int32_t consign;

    pid_reset(&pid_x);
    pid_reset(&pid_y);
    pid_reset(&pid_angle);

    consign = cs_get_consign(&csm_angle);
    qramp_angle.previous_var = 0;
    qramp_angle.previous_out = consign;
    qramp_angle.previous_in = consign;
       
    rcs->reactivated = 0;
  }

  // compute control system first level (x,y,a)
  cs_manage(&csm_x);
  cs_manage(&csm_y);
  cs_manage(&csm_angle);

  // transform output vector from table coords to robot coords
  vx_t     = cs_get_out(&csm_x);
  vy_t     = cs_get_out(&csm_y);
  omegaz_t = cs_get_out(&csm_angle);

  hposition_get(rcs->hpm, &hvec);

  alpha = -hvec.alpha;
 
  _ca = cos(alpha);
  _sa = sin(alpha);

  vx_r = vx_t*_ca - vy_t*_sa;
  vy_r = vx_t*_sa + vy_t*_ca;

  // set second level consigns
  hrobot_set_motors(rcs->hrs, vx_r, vy_r, omegaz_t);
                              
}
예제 #3
0
void charger_reset(CHARGER& charger, int pwm){
  charger.pwm=(double)pwm;
  analogWrite(P_PWM,pwm); 
  delay(TIMER_TICK);
  digitalWrite(P_SW, LOW);
  pid_reset(pid);
}
예제 #4
0
static void do_set_enabled(bool enabled)
{
	contrtemp.enabled = enabled;

	/* Reset the temp controller. */
	pid_reset(&contrtemp.pid);
	timer_set_now(&contrtemp.dt_timer);
	contrtemp_set_boost_mode(TEMPBOOST_NORMAL);
	/* Reset current controller to no-current. */
	contrcurr_set_setpoint(float_to_fixpt(CONTRCURR_NEGLIM));
}
예제 #5
0
int32 pid_set_target(uint8 nr, pid_type target)
{
    if (nr > PID_NR - 1) return -1;

    if (target < CRITICAL_SPEED * hall_get_res())
    {
        pid_reset(nr);
    }

    pid[nr].target = target * hall_get_res();
    return 0;
}
예제 #6
0
파일: beacon.c 프로젝트: onitake/aversive
void beacon_calibre_pos(void)
{
	sensorboard.flags &= ~DO_CS;

	/* init beacon pos */
	pwm_ng_set(BEACON_PWM, 100);

	/* find rising edge of the mirror*/
	wait_ms(100);
	while (sensor_get(BEACON_POS_SENSOR));
	wait_ms(100);
	while (!sensor_get(BEACON_POS_SENSOR));

	pwm_ng_set(BEACON_PWM, 0);


	beacon_reset_pos();
	pid_reset(&sensorboard.beacon.pid);
	encoders_spi_set_value_beacon(BEACON_ENCODER, BEACON_OFFSET_CALIBRE);

	cs_set_consign(&sensorboard.beacon.cs, 0);

	sensorboard.flags |= DO_CS;
}
예제 #7
0
파일: pid.c 프로젝트: 52osworld/4axis
/*************************************************

名称:calculate(float pitch, float roll, float yaw, u8 throttle, u8 rudder, u8 elevator, u8 aileron, float gx, float gy, float gz)
功能:系统pid运算
输入参数:
   	 float pitch   当前俯仰角度
	 float roll    当前倾斜角度
	 float yaw     当前偏航角度 
	 u8 throttle   油门给定值
	 u8 rudder     偏航给定值
	 u8 elevator   俯仰给定值
	 u8 aileron    倾斜给定值
	 float gx      x轴角速度
	 float gy      y轴角速度
	 float gz      z轴角速度
输出参数:电机控制量
返回值:  无
**************************************************/
void calculate(float pitch, float roll, float yaw, u8 throttle, u8 rudder, u8 elevator, u8 aileron, float gx, float gy, float gz)
{

  u16 thr = 0;
  s16 pitch_out = 0, roll_out = 0, yaw_out = 0;
  s16 m1 = 0, m2 = 0, m3 = 0, m4 = 0;

  if(elevator > 0)  // 后 
  {
    if(elevator >= 0x80)
	{
	  elevator -= 0x80;
	  pid_pitch.zero_err = elevator * 0.2;
	}
    else  // 前 
	{
	  pid_pitch.zero_err = -(elevator * 0.2);
	}	 
  }
  else 
  {
    pid_pitch.zero_err = 0;
  }


  if(aileron > 0)  // 右   
  {
    if(aileron >= 0x80)
	{
	  aileron -= 0x80;
	  pid_roll.zero_err = -(aileron * 0.2);
	}
    else  // 左  
	{
	  pid_roll.zero_err = aileron * 0.2;
	}	 
  }
  else 
  {
    pid_roll.zero_err = 0;
  }


  if(rudder > 0)  // 右偏   
  {
    if(rudder >= 0x80)
	{
	  rudder -= 0x80;
	  pid_yaw.zero_err = rudder * 20.0;
	}
    else  // 左偏  
	{
	  pid_yaw.zero_err = -rudder * 20.0;
	}	 
  }
  else 
  {  
	pid_yaw.zero_err = 0;
  }

  roll_out = (s16)pid_calculate(&pid_roll, roll, gx);
  pitch_out = (s16)pid_calculate(&pid_pitch, pitch, gy);
  yaw_out = (s16)pid_calculate(&pid_yaw, yaw, gz);

  if(throttle > 0)  //  油门
  {
    thr = throttle * 7.0;
    m1 = thr - pitch_out + roll_out + yaw_out;
    m2 = thr + pitch_out + roll_out - yaw_out;
    m3 = thr + pitch_out - roll_out + yaw_out;
    m4 = thr - pitch_out - roll_out - yaw_out;
  }
  else  
  {
	m1 = 0;
	m2 = 0;
	m3 = 0;
	m4 = 0;
	pid_reset();
  }

  motor_control(m1, m2, m3, m4);  
}
예제 #8
0
void yaw_ctrl_reset(void)
{
   pid_reset(&controller);
}
예제 #9
0
파일: main2.c 프로젝트: ohayak/tars_code
uint8_t findPosition(uint8_t type)
{
	disableSpinning();

	if(type == REDSTART)
	{
		asserv_set_vitesse_low(&asserv);

		trajectory_goto_d(&traj, END, -200);
		while(!trajectory_is_ended(&traj))
		{
			if(REPOSITIONING)
			{
				trajectory_reinit(&traj);
				asserv_stop(&asserv);
			}
		}
		trajectory_goto_d(&traj, END, 20 - DIST_CENTRE);//dist centre = 12.2
		while(!trajectory_is_ended(&traj));
		trajectory_goto_arel(&traj, END, -90.0);
		while(!trajectory_is_ended(&traj));
		trajectory_goto_d(&traj, END, -200);
		while(!trajectory_is_ended(&traj))
		{
			if(REPOSITIONING)
			{
				trajectory_reinit(&traj);
				asserv_stop(&asserv);
			}
		}


		trajectory_goto_d(&traj, END, 20 - DIST_CENTRE);
		while(!trajectory_is_ended(&traj));
			//asserv_set_distance()

		cli();
		printf("pos asserv a : %lu %lu \n",U_ASSERV_ANGLE,U_PM_ANGLE);

		position_set_xya_cm_deg(&pos,fxx_from_double(20.0),fxx_from_double(20.0), fxx_from_double(0.0));
		wait_ms(100);
		printf("pos x : %ld pos y %ld \n",pos.x,pos.y);
		printf("pos sum x : %lf pos y %lf \n",pos.sum_x,pos.sum_y);
		asserv_stop(&asserv);//attention bug bizare avant
		asserv_set_vitesse_fast(&asserv);

	}
	else if(type == YELLOWSTART)// team == YELLOW
	{			
		asserv_set_vitesse_low(&asserv);

		trajectory_goto_d(&traj, END, -200);
		while(!trajectory_is_ended(&traj))
		{
			if(REPOSITIONING)
			{
				trajectory_reinit(&traj);
				asserv_stop(&asserv);
			}
		}
		trajectory_goto_d(&traj, END, 20 - DIST_CENTRE);//dist centre = 12.2
		while(!trajectory_is_ended(&traj));
		trajectory_goto_arel(&traj, END, 90.0);
		while(!trajectory_is_ended(&traj));
		trajectory_goto_d(&traj, END, -200);
		while(!trajectory_is_ended(&traj))
		{
			if(REPOSITIONING)
			{
				trajectory_reinit(&traj);
				asserv_stop(&asserv);
			}
		}
		trajectory_goto_d(&traj, END, 20 - DIST_CENTRE);
		while(!trajectory_is_ended(&traj));
		cli();

		printf("pos asserv a : %lu %lu \n",U_ASSERV_ANGLE,U_PM_ANGLE);

		position_set_xya_cm_deg(&pos,fxx_from_double(20.0),fxx_from_double(280.0), fxx_from_double(0.0));
		asserv_stop(&asserv);

		asserv_set_vitesse_fast(&asserv);
	}
	else if(type == REDPAINT)
	{

		// asserv_set_vitesse_low(&asserv);
		// double eps = 0;
		// set_startCoor(position_get_coor_eps(&pos, &eps));
		// printf("start pos: %d eps %lf \n",position_get_coor_eps(&pos, &eps),eps);

		// set_goalCoor(G_LENGTH * 1 + 7);

		// if (eps > EPSILON)
		// {
		// 	go_to_node(fxx_to_double(position_get_y_cm(&pos)),fxx_to_double(position_get_x_cm(&pos)));
		// }    
		// while(!astarMv() && !actionIsFailed());
		// if(actionIsFailed())return DONE;

		asserv_set_vitesse_normal(&asserv);

		trajectory_goto_a(&traj, END, 90);
		trajectory_goto_d(&traj, END, -40);
		disableSpinning();
		enableSpinning();// a tester
		while(!trajectory_is_ended(&traj))
		{
			if(REPOSITIONING)
			{
				trajectory_reinit(&traj);
				asserv_stop(&asserv);
			}
		}
		enableSpinning();
		//if(actionIsFailed())return DONE;

		trajectory_goto_d(&traj, END, 20 - DIST_CENTRE);
		//while(!trajectory_is_ended(&traj));
		// if(actionIsFailed())return DONE;
		cli();

		printf("pos asserv a : %lu %lu \n",U_ASSERV_ANGLE,U_PM_ANGLE);

		position_set_xya_cm_deg(&pos,fxx_from_double(20.0),fxx_from_double(160.0), fxx_from_double(90.0));
		asserv_stop(&asserv);

		asserv_set_vitesse_normal(&asserv);
	}
	else if(type == YELLOWPAINT)
	{
		// double eps = 0;
		// set_startCoor(position_get_coor_eps(&pos, &eps));
		// printf("start pos: %d eps %lf \n",position_get_coor_eps(&pos, &eps),eps);

		// set_goalCoor(G_LENGTH * 1 + 8);

		// if (eps > EPSILON)
		// {
		// 	go_to_node(fxx_to_double(position_get_y_cm(&pos)),fxx_to_double(position_get_x_cm(&pos)));
		// }    


		// while(!astarMv() && !actionIsFailed());
		// if(actionIsFailed())return DONE;

		asserv_set_vitesse_normal(&asserv);
		trajectory_goto_a(&traj, END, -90);
		trajectory_goto_d(&traj, END, -40);
		disableSpinning();
		enableSpinning();// a tester
		while(!trajectory_is_ended(&traj))
		{
			if(REPOSITIONING)
			{
				trajectory_reinit(&traj);
				asserv_stop(&asserv);
			}
		}
		enableSpinning();
		//if(actionIsFailed())return DONE;
		trajectory_goto_d(&traj, END, 20 - DIST_CENTRE);
		while(!trajectory_is_ended(&traj));
		//if(actionIsFailed())return DONE;
		cli();

		printf("pos asserv a : %lu %lu \n",U_ASSERV_ANGLE,U_PM_ANGLE);

		position_set_xya_cm_deg(&pos,fxx_from_double(20.0),fxx_from_double(160.0), fxx_from_double(-90.0));
		asserv_stop(&asserv);
		asserv_set_vitesse_normal(&asserv);
	}
		//printf("pos asserv a : %lu %lu \n",U_ASSERV_ANGLE,U_PM_ANGLE);

	quadramp_reset(&asserv);
	control_reset(&asserv);
	pid_reset(&asserv);
	diff_reset(&asserv);
	printf("pos x : %ld pos y %ld \n",pos.x,pos.y);
	printf("pos sum x : %lf pos y %lf \n",pos.sum_x,pos.sum_y);
	sei();

	enableSpinning();

	return DONE;
}
예제 #10
0
void pid_Wallfollow_process(void)
{
	if (ControlFlag)
	{
		static int i;
		pid_Runtimeout(&pid_process_callback, ui32_msLoop);
		ControlFlag = false;

		leftError=(float)IR_get_calib_value(IR_CALIB_BASE_LEFT) - (float)IR_GetIrDetectorValue(1);
		rightError=(float)IR_get_calib_value(IR_CALIB_BASE_RIGHT) - (float)IR_GetIrDetectorValue(2);
		isWallLeft = IR_GetIrDetectorValue(1)<IR_get_calib_value(IR_CALIB_MAX_LEFT);
		isWallRight = IR_GetIrDetectorValue(2)<IR_get_calib_value(IR_CALIB_MAX_RIGHT);
		isWallFrontLeft = IR_GetIrDetectorValue(0)<IR_get_calib_value(IR_CALIB_MAX_FRONT_LEFT);
		isWallFrontRight = IR_GetIrDetectorValue(3)<IR_get_calib_value(IR_CALIB_MAX_FRONT_RIGHT);


		switch(eMove)
		{
		case FORWARD:
			switch (moveStage)
			{
			case 1:
				if (Forward())
					moveStage++;
				if (isWallFrontLeft| isWallFrontRight)
				{
					preMove=eMove;
					eMove=getMove(isWallLeft,isWallFrontLeft|isWallFrontRight,isWallRight);
				}
				break;
			case 2:
				posLeftTmp=qei_getPosLeft();
				moveStage++;
				i=1;
				avrSpeedTmp=avrSpeed;
			case 3://slow down
				forwardUpdate();
				if (!isWallLeft)
				{
					rqTurnLeft=true;
				}
				if (!isWallRight)
				{
					rqTurnRight=true;
				}
				if ((abs(qei_getPosLeft()-posLeftTmp)<5000)
						&& (!isWallFrontLeft) && (!isWallFrontRight))
				{
					if ((abs(qei_getPosLeft()-posLeftTmp)>i*500) && (avrSpeed>AVG_SPEED_FWD-40))
					{
						avrSpeed -= 10;
						i++;
					}
					if (isWallLeft|isWallRight)
						pid_wallfollow(leftError,rightError, avrSpeed,WALL_FOLLOW_AUTO);
					else
					{
						pid_reset(&pid_wall_left);
						pid_reset(&pid_wall_right);
						speed_set(MOTOR_RIGHT, avrSpeed);
						speed_set(MOTOR_LEFT, avrSpeed);
					}
				}
				else
				{
#ifdef TEST_FORWARD_MOVE
					speed_Enable_Hbridge(false);
#endif
					preMove=eMove;
					eMove=getMove(!rqTurnLeft,isWallFrontLeft|isWallFrontRight,!rqTurnRight);
					if (eMove==FORWARD)
						avrSpeed=AVG_SPEED_FWD;
					rqTurnLeft=false;
					rqTurnRight=false;
					moveStage=1;
				}
				break;
			}
			break;

		case TURN_LEFT:
			switch (moveStage)
			{
			case 1:
				if (preMove!=FORWARD)//after turning left or right
					//test
					// ____
					// |   |
					// | | |
					fwdPulse=6000;
				else if ((preMove==FORWARD) && (avrSpeed<AVG_SPEED_FWD_FAST))
					//after turning back
					//test
					// ___
					// |__   |
					//    |__|
					fwdPulse=5500;
				else//after moving forward
					//test
					// ___
					// ___  |
					//    | |
					//    |_|
					fwdPulse=4500;
				moveStage++;

			case 2:
				if (TurnLeft(fwdPulse,60,240,7800,1700+CELL_ENC))
				{
					moveStage++;
				}
				break;
			case 3:
				posLeftTmp=qei_getPosLeft();
				moveStage++;
			case 4:
				//go straight a little bit to check wall
				forwardUpdate();
				if (abs(qei_getPosLeft()-posLeftTmp)<2000)
				{
					if (abs(qei_getPosLeft()-posLeftTmp)>1500)
					{
						if (!isWallRight)
							rqTurnRight=1;
						if (!isWallLeft)
							rqTurnLeft=1;
					}
					avrSpeed=AVG_SPEED_FWD_SLOW;
					if (isWallLeft|isWallRight)
						pid_wallfollow(leftError,rightError, avrSpeed,WALL_FOLLOW_AUTO);
					else
					{
						pid_reset(&pid_wall_left);
						pid_reset(&pid_wall_right);
						speed_set(MOTOR_RIGHT, avrSpeed);//left motor is faster
						speed_set(MOTOR_LEFT, avrSpeed);
					}
				}
				else
				{
#ifdef TEST_TURNLEFT_MOVE3
					speed_Enable_Hbridge(false);
#endif
					//time to check front wall
					preMove=eMove;
					eMove=getMove(!rqTurnLeft,isWallFrontLeft|isWallFrontRight,!rqTurnRight);
					rqTurnLeft=false;
					rqTurnRight=false;
					moveStage=1;
					pid_reset(&pid_wall_left);
					pid_reset(&pid_wall_right);
				}
			}
			break;

		case TURN_RIGHT:
			switch (moveStage)
			{
			case 1:
				if (preMove!=FORWARD)//after turning left or right
					//test
					// ____
					// |   |
					// | | |
					fwdPulse=6000;
				else if ((preMove==FORWARD) && (avrSpeed<AVG_SPEED_FWD_FAST))
					//after turning back
					//test
					// 	  ____
					// |  ____
					// |__|
					fwdPulse=5500;
				else//after moving forward
					//test
					//   _____
					// | _____
					// | |
					// |_|
					fwdPulse=4500;
				moveStage++;
			case 2:
				if (TurnRight(fwdPulse,200,40,8000,1700+CELL_ENC))
				{
					moveStage++;
				}
				break;
			case 3:
				posLeftTmp=qei_getPosLeft();
				moveStage++;
			case 4:
				forwardUpdate();
				if (abs(qei_getPosLeft()-posLeftTmp)<1000)
				{
					if (abs(qei_getPosLeft()-posLeftTmp)>500)
					{
						if (!isWallRight)
							rqTurnRight=1;
						if (!isWallLeft)
							rqTurnLeft=1;
					}
					avrSpeed=AVG_SPEED_FWD_SLOW;
					if (isWallLeft|isWallRight)
						pid_wallfollow(leftError,rightError, avrSpeed,WALL_FOLLOW_AUTO);
					else
					{
						pid_reset(&pid_wall_left);
						pid_reset(&pid_wall_right);
						speed_set(MOTOR_RIGHT, avrSpeed);
						speed_set(MOTOR_LEFT, avrSpeed);
					}
				}
				else
				{
#ifdef TEST_TURNRIGHT_MOVE3
					speed_Enable_Hbridge(false);
#endif
					preMove=eMove;
					eMove=getMove(!rqTurnLeft,isWallFrontLeft|isWallFrontRight,!rqTurnRight);
					rqTurnLeft=false;
					rqTurnRight=false;
					moveStage=1;
					pid_reset(&pid_wall_left);
					pid_reset(&pid_wall_right);
				}
			}
			break;
		case TURN_BACK:
			switch (moveStage)
			{
			case 1:
				if (preMove==FORWARD)
					fwdPulse=8000;
				else
					fwdPulse=9000;
				moveStage++;
			case 2:
				if (TurnBack(fwdPulse,-140,60,8000,13000))
				{
					//rotate more if we still detect front wall: do it yourself ;D
					moveStage++;
				}
				break;
			case 3:
				if (move(-9000,-9000,AVG_SPEED_BWD,AVG_SPEED_BWD))
				{
#ifdef TEST_TURNBACK_BACKWARD
					speed_Enable_Hbridge(false);
#endif
					forwardUpdate();
					avrSpeed = AVG_SPEED_FWD_SLOW;
					preMove=eMove;
					eMove=FORWARD;
					moveStage = 1;
				}
			}



			break;
		}
	}
}
예제 #11
0
//*****************************************************************************
//
//! Control two motor to make robot turn back 180 degree.
//!
//! \param fwdPulse is the distance robot will go straight before turn right
//!, the robot will stand between the next cell of maze.
//! \param avrSpeedLeft is the speed of left motor.
//! \param avrSpeedRight is the speed of left motor.
//! \param NumPulse is the total pulse of two encoder after turn
//! \param resetEnc is the reset value for encoder after turning back
//! \return true if finish
//!			false if not
//
static bool TurnBack(int fwdPulse, int avrSpeedLeft,int avrSpeedRight,int turnPulse,
		int resetEnc)
{
	LED1_ON();LED2_ON();LED3_ON();
	switch (CtrlStep)
	{
	case 1:
	{
		posLeftTmp = qei_getPosLeft();
		avrSpeedTmp = avrSpeed;
		CtrlStep++;
	}
	case 2://go forward a litte bit
	{

		if (abs(qei_getPosLeft()-posLeftTmp)<fwdPulse)
		{
			avrSpeed = ((abs(fwdPulse + posLeftTmp - qei_getPosLeft()) / (fwdPulse / avrSpeedTmp)) / 2)
					+ (abs(avrSpeedLeft) + abs(avrSpeedRight)) / 2;
			if (isWallRight)
				pid_wallfollow(leftError,rightError,avrSpeed,WALL_FOLLOW_RIGHT);
			else if (isWallLeft)
				pid_wallfollow(leftError,rightError,avrSpeed,WALL_FOLLOW_LEFT);
			else
			{
				speed_set(MOTOR_RIGHT, avrSpeed);
				speed_set(MOTOR_LEFT, avrSpeed);
			}
		}
		else
		{
			pid_reset(&pid_wall_left);
			pid_reset(&pid_wall_right);
			forwardUpdate();
			CtrlStep++;
			avrSpeed = avrSpeedTmp;
		}
		break;
	}
	case 3:
		posLeftTmp=qei_getPosLeft();
		posRightTmp=qei_getPosRight();
		CtrlStep++;
	case 4://turing 90 degree
	{
#ifdef TEST_TURNBACK_FWD
		speed_Enable_Hbridge(false);
#endif
		if ((abs(qei_getPosLeft()-posLeftTmp)+abs(qei_getPosRight()-posRightTmp))<turnPulse)
		{
			speed_set(MOTOR_RIGHT, avrSpeedRight);
			speed_set(MOTOR_LEFT, avrSpeedLeft);
		}
		else
		{
			currentDir=(currentDir+3)%4;
			CtrlStep++;
		}
		break;
	}
	case 5:
		posLeftTmp=qei_getPosLeft();
		posRightTmp=qei_getPosRight();
		CtrlStep++;
	case 6://turning another 90 degree
	{
#ifdef TEST_TURNBACK_TURN1
		speed_Enable_Hbridge(false);
#endif

		if ((abs(qei_getPosLeft()-posLeftTmp)+abs(qei_getPosRight()-posRightTmp))<turnPulse)
		{
			speed_set(MOTOR_RIGHT, -avrSpeedLeft);
			speed_set(MOTOR_LEFT, -avrSpeedRight);
		}
		else
		{
#ifdef TEST_TURNBACK_TURN2
		speed_Enable_Hbridge(false);
#endif
			currentDir=(currentDir+3)%4;
			clearPosition();
			qei_setPosLeft(resetEnc);
			qei_setPosRight(resetEnc);
			forwardUpdate();
			CtrlStep=1;
			return true;
		}
		break;
	}
	}
	return false;
}
예제 #12
0
//*****************************************************************************
//
//! Control two motor to make robot turn left 90 degree
//!
//! \param fwdPulse is the distance robot will go straight before turn right
//!, the robot will stand between the next cell of maze.
//! \param avrSpeedLeft is the speed of left motor.
//! \param avrSpeedRight is the speed of right motor.
//! \param turnPulse is the total pulse of two encoder after turn
//! \param resetEnc is reset value for encoder after turning 90 degree, ignore this if you don't want to estimate position
//! \return true if finish
//!			false if not
//
//*****************************************************************************
static bool TurnLeft(int fwdPulse,int avrSpeedLeft,int avrSpeedRight,int turnPulse,
		int resetEnc)
{
	static int vt,vp;
	LED1_ON();LED2_OFF();LED3_OFF();
//	bluetooth_print("LS %d\r\n",CtrlStep);
	switch (CtrlStep)
	{
	case 1:
		posLeftTmp=qei_getPosLeft();
		CtrlStep++;
		avrSpeedTmp=avrSpeed;
	case 2://go straight
		if ((abs(qei_getPosLeft()-posLeftTmp)<fwdPulse) ||
				(isWallFrontLeft && isWallFrontRight &&
				(IR_GetIrDetectorValue(3)>IR_get_calib_value(IR_CALIB_BASE_FRONT_RIGHT))&&
				(IR_GetIrDetectorValue(0)>IR_get_calib_value(IR_CALIB_BASE_FRONT_LEFT))))

		{
			if (qei_getPosLeft()<fwdPulse+posLeftTmp)
				avrSpeed = ((abs(fwdPulse + posLeftTmp - qei_getPosLeft()) / (fwdPulse / avrSpeedTmp)) / 2)
					+ (abs(avrSpeedLeft) + abs(avrSpeedRight)) / 2;
			else
				avrSpeed = (abs(avrSpeedLeft) + abs(avrSpeedRight)) / 2;

			if (isWallRight)
				pid_wallfollow(leftError,rightError,avrSpeed,WALL_FOLLOW_RIGHT);
			else
			{
				speed_set(MOTOR_RIGHT, avrSpeed);
				speed_set(MOTOR_LEFT, avrSpeed);
			}
		}
		else
		{
#ifdef TEST_TURNLEFT_MOVE1
		speed_Enable_Hbridge(false);
#endif

			pid_reset(&pid_wall_right);
			pid_reset(&pid_wall_left);
			forwardUpdate();
			CtrlStep++;
			avrSpeed=avrSpeedTmp;
		}
		break;
	case 3:
		posLeftTmp=qei_getPosLeft();
		posRightTmp=qei_getPosRight();
		CtrlStep++;
		vp=1;
		vt=1;
	case 4://turn 90 degree

		if (abs(qei_getPosLeft()-posLeftTmp) + abs(qei_getPosRight()-posRightTmp) < turnPulse)

		{
			speed_set(MOTOR_RIGHT, avrSpeedRight);
			speed_set(MOTOR_LEFT, -avrSpeedLeft);
			if((abs(qei_getPosRight()-posRightTmp)>(turnPulse*0.8*vp/8)) && (vp<9))
			{
				if (avrSpeedRight>=24)
					avrSpeedRight-=24;
				vp++;

			}
			if((abs(qei_getPosLeft()-posLeftTmp)>(turnPulse*0.2*vt/8)) && (vt<9))
			{
				if (avrSpeedLeft>=4)
					avrSpeedLeft-=4;
				vt++;
			}
		}
		else
		{
#ifdef TEST_TURNLEFT_TURN
		speed_Enable_Hbridge(false);
#endif
			currentDir=(currentDir+3)%4;
			clearPosition();
			qei_setPosLeft(resetEnc);
			qei_setPosRight(resetEnc);
			forwardUpdate();
			CtrlStep=1;
			pid_reset(&pid_wall_left);
			pid_reset(&pid_wall_right);
			speed_set(MOTOR_LEFT, avrSpeed);
			speed_set(MOTOR_RIGHT, avrSpeed);
			return true;
		}
		break;
	}
	return false;

}
예제 #13
0
void u_speed_reset(void)
{
   pid_reset(&ctrl);
}
예제 #14
0
/**
 * @brief Wall follow controller
 */
static bool pid_wallfollow(float delta_IR_left, float delta_IR_right, float averageSpeed,
		WALL_FOLLOW_SELECT wall_follow_select)
{
	static float error, u, rightFirst=1;
	static WALL_FOLLOW_SELECT preSelect=WALL_FOLLOW_NONE;
	int32_t set_speed[2];

	if (preSelect!=WALL_FOLLOW_NONE)
		if (preSelect!=wall_follow_select)
		{
			if (preSelect==WALL_FOLLOW_RIGHT)
				pid_reset(&pid_wall_right);
			else if (preSelect==WALL_FOLLOW_LEFT)
				pid_reset(&pid_wall_left);
		}

	switch (wall_follow_select)
	{
	case WALL_FOLLOW_NONE:	//Do nothing
		return true;
	case WALL_FOLLOW_LEFT:
		{
			error = -delta_IR_left;
			u = pid_process(&pid_wall_left,error);
		}
		break;
	case WALL_FOLLOW_RIGHT:
		{
			error = delta_IR_right;
			u = pid_process(&pid_wall_right,error);
		}
		break;
	case WALL_FOLLOW_BOTH:
		{
			error = delta_IR_right - delta_IR_left;
			u = pid_process(&pid_wall_right,error);
		}
		break;
	case WALL_FOLLOW_AUTO:
		if (rightFirst)
		{
			if (isWallRight)
			{

				error = delta_IR_right;
				u = pid_process(&pid_wall_right,error);
			}
			else if (isWallLeft)
			{
				pid_reset(&pid_wall_right);
				error = -delta_IR_left;
				u = pid_process(&pid_wall_left,error);
				rightFirst=0;
			}
		}
		else
		{
			if (isWallLeft)
			{
				error = -delta_IR_left;
				u = pid_process(&pid_wall_left,error);
			}
			else if (isWallRight)
			{
				pid_reset(&pid_wall_left);
				error = delta_IR_right;
				u = pid_process(&pid_wall_right,error);
				rightFirst=1;
			}
		}
		break;
	default:
		return false;
	}

	preSelect = wall_follow_select;

	set_speed[0] = averageSpeed + (int32_t)(u / 2);
	set_speed[1] = averageSpeed - (int32_t)(u / 2);

	speed_set(MOTOR_RIGHT, set_speed[0]);
	speed_set(MOTOR_LEFT, set_speed[1]);

	return true;
}
예제 #15
0
// the ctbot class
void native_ctbot_motor_invoke(u08_t mref) {

  // JAVA: void setLeft(int val)
  if(mref == NATIVE_METHOD_setLeft) {
    nvm_int_t val = stack_pop_int();
    cli();
    pwm_motor_l=val;
    pid_mode &= ~PID_LEFT_ENABLED;
    sei();
  }

  // JAVA: void setRight(int val)
  else if(mref == NATIVE_METHOD_setRight) {
    nvm_int_t val = stack_pop_int();
    cli();
    pwm_motor_r=val;
    pid_mode &= ~PID_RIGHT_ENABLED;
    sei();
  }
  
  else if(mref == NATIVE_METHOD_setLeftSpeed) {
    nvm_int_t val = stack_pop_int();
    cli();
    pid_left_value=val;
    pid_mode |= PID_LEFT_ENABLED;
    sei();
  }

  // JAVA: void setRight(int val)
  else if(mref == NATIVE_METHOD_setRightSpeed) {
    nvm_int_t val = stack_pop_int();
    cli();
    pid_right_value=val;
    pid_mode |= PID_RIGHT_ENABLED;
    sei();
  }

  // JAVA: int getLeft()
  else if(mref == NATIVE_METHOD_getLeft) {
    nvm_int_t val = pwm_motor_l;
    stack_push(val);
  }

  // JAVA: int getRight()
  else if(mref == NATIVE_METHOD_getRight) {
    nvm_int_t val = pwm_motor_r;
    stack_push(val);
  }

  // JAVA: int getLeft()
  else if(mref == NATIVE_METHOD_getLeftSpeed) {
    nvm_int_t val = pwm_motor_l;
    stack_push(val);
  }

  // JAVA: int getRight()
  else if(mref == NATIVE_METHOD_getRightSpeed) {
    nvm_int_t val = pwm_motor_r;
    stack_push(val);
  }

  // JAVA: void stopt()
  else if(mref == NATIVE_METHOD_stop) {
    cli();
    pwm_motor_r = 0;
    pwm_motor_l = 0;
    pid_mode &= ~(PID_RIGHT_ENABLED|PID_LEFT_ENABLED);
    pid_reset();
    sei();
  }

}
예제 #16
0
void att_ctrl_reset(void)
{
   FOR_EACH(i, controllers)
      pid_reset(&controllers[i]);
}
예제 #17
0
void u_ctrl_reset(void)
{
   pid_reset(&ctrl);
}