void initialize_motors(engines_t * motors){
	nxt_motor_set_count(NXT_PORT_A, 1000);
    for(int i = 0; i < SAMP_NUM; i++){
    	motors->first.speeds[i] = 0;
    	motors->first.revolutions[i] = nxt_motor_get_count(NXT_PORT_A);
    	motors->first.times[i] = (long) ecrobot_get_systick_ms();
    }
    for(int j = 0; j < BUFFER_SIZE; j++){
    	motors->first.speed_ref[j] = 0;
    	motors->first.distance_ref[j] = 0;
    }
    
    nxt_motor_set_count(NXT_PORT_B, 1000);
    for(int i = 0; i < SAMP_NUM; i++){
    	motors->second.speeds[i] = 0;
    	motors->second.revolutions[i] = nxt_motor_get_count(NXT_PORT_B);
    	motors->second.times[i] = (long) ecrobot_get_systick_ms();
    }
    for(int j = 0; j < BUFFER_SIZE; j++){
    	motors->first.speed_ref[j] = 0;
    	motors->first.distance_ref[j] = 0;
    }
    
    nxt_motor_set_count(NXT_PORT_C, 1000);
    for(int i = 0; i < SAMP_NUM; i++){
    	motors->third.speeds[i] = 0;
    	motors->third.revolutions[i] = nxt_motor_get_count(NXT_PORT_C);
    	motors->third.times[i] = (long) ecrobot_get_systick_ms();
    }
    for(int j = 0; j < BUFFER_SIZE; j++){
    	motors->third.speed_ref[j] = 0;
    	motors->third.distance_ref[j] = 0;
    }
}
int Calibration_calibration(Calibration *this_Calibration){

	static U32	avg_cnt = 0;
	static U32	cal_start_time;	

	//gyro_offset
	while (1){
		if(PushButton_detect_push_button(&pushButton) == TRUE)break;
	}
	
		ecrobot_sound_tone(880, 512, 10);
		/* ジャイロセンサの値を計算するための開始時間をセットする */
		cal_start_time = ecrobot_get_systick_ms();

	while((ecrobot_get_systick_ms() - cal_start_time) < 1000U){
		/* ジャイロセンサの設定をする */
		this_Calibration->gyro += InclinationEncoder_get_inclination(&inclinationEncoder);
		avg_cnt++;
	}

		this_Calibration->gyro /= avg_cnt;
		ecrobot_sound_tone(440U, 500U, 10);

	systick_wait_ms(500);
	
	//black
	while(1){
		if(PushButton_detect_push_button(&pushButton) == TRUE){
			ecrobot_sound_tone(906, 512, 10);
			BrightnessEncoder_set_black(&brightnessEncoder,BrightnessEncoder_get_brightness(&brightnessEncoder));
			systick_wait_ms(500);
			break;
		}
	}

	//white
	while(1){
		if(PushButton_detect_push_button(&pushButton) == TRUE){
			ecrobot_sound_tone(906, 512, 10);
			BrightnessEncoder_set_white(&brightnessEncoder,BrightnessEncoder_get_brightness(&brightnessEncoder));
			systick_wait_ms(500);
			break;
		}
	}

	InclinationEncoder_set_gyro_offset(&inclinationEncoder ,this_Calibration->gyro);
	InclinationEncoder_set_initial_gyro_offset(&inclinationEncoder ,this_Calibration->gyro);

	while(1){
		if(PushButton_detect_push_button(&pushButton) == TRUE){
			systick_wait_ms(500);
			break;
		}
	}
	//キャリブレーションが終了したら1を返す
	return 1;
}
void updateMotors(engines_t * motors){
	motor_t *motor;
    motor_t *otherMotor;
	for(int m = 0; m < 2; m++){
		switch (m){
			case 0: motor = &(motors->first); otherMotor = &(motors->second); break;
			case 1: motor = &(motors->second); otherMotor = &(motors->first); break;
		}
		for (int i = SAMP_NUM; i > 0; i--){
			motor->revolutions[i] = motor->revolutions[i-1];
			motor->speeds[i] = motor->speeds[i-1];
		}
		motor->revolutions[0] = nxt_motor_get_count(motor->port);
		motor->times[0] = ecrobot_get_systick_ms();
		motor->speeds[0] = evaluate_speed(motor, motor->speeds[1]);
		
		if(motor->speed_control_type == NOT_USING)
			continue;
		
		if(motor->speed_control_type == PID_CONTROLLED){

			double distance = (((motor->revolutions[0] + otherMotor->revolutions[0])/2.0) * PI/180) * 0.028;

			if(abs(distance) >= motor->distance_ref[0]){
				for (int i = 0; i < BUFFER_SIZE - 1; i++){
					motor->speed_ref[i] = motor->speed_ref[i+1];
					motor->distance_ref[i] = motor->distance_ref[i+1];
					otherMotor->speed_ref[i] = otherMotor->speed_ref[i+1];
					otherMotor->distance_ref[i] = otherMotor->distance_ref[i+1];
				}
				motor->speed_ref[BUFFER_SIZE-1] = 0;
				motor->distance_ref[BUFFER_SIZE-1] = 0;
				otherMotor->speed_ref[BUFFER_SIZE-1] = 0;
				otherMotor->distance_ref[BUFFER_SIZE-1] = 0;
			}
			
			if(distance < motor->distance_ref[0]){
				double error = motor->speed_ref[0] - motor->speeds[0];
				double rotationError = rotationController(motors);

				if(m == 0) {
					error = error - rotationError/2;
					motor->powers[0] = controller(error);

				}
				if(m == 1) {
					error = error + rotationError/2;
					motor->powers[0] = controller2(error);
				}

			}
		}
		
		nxt_motor_set_speed(motor->port, motor->powers[0], 1);
	}
}
void RN_set_gyro_start()
{
	/* ジャイロセンサの設定を始める */
	if (ecrobot_get_touch_sensor(NXT_PORT_S4) == TRUE) {
		ecrobot_sound_tone(880, 512, 30);

		/* ジャイロセンサの値を計算するための開始時間をセットする */
		cal_start_time = ecrobot_get_systick_ms();
		setting_mode = RN_SETTINGMODE_GYRO;
	}
}
void RN_set_gyro()
{
	/* ジャイロセンサの設定をする */
	gyro_offset += (U32)ecrobot_get_gyro_sensor(NXT_PORT_S1);
	avg_cnt++;
	
	/* 1秒経過したら、ジャイロセンサのオフセット値の平均値を計算し、次の状態に遷移する。 */
	if ((ecrobot_get_systick_ms() - cal_start_time) >= 1000U) {
		gyro_offset /= avg_cnt;

		ecrobot_sound_tone(440U, 500U, 30U);

		setting_mode = RN_SETTINGMODE_GYRO_END;
	}
}
void updateMotors(engines_t * motors){
	motor_t *motor;
    motor_t *otherMotor;
	motor = &(motors->first); 
	otherMotor = &(motors->second);
	
	for (int i = SAMP_NUM; i > 0; i--){
		motor->revolutions[i] = motor->revolutions[i-1];
		motor->speeds[i] = motor->speeds[i-1];
	}
	motor->revolutions[0] = nxt_motor_get_count(motor->port);
	motor->times[0] = ecrobot_get_systick_ms();
	motor->speeds[0] = evaluate_speed(motor, motor->speeds[1]);
		
	if(motor->speed_control_type == NOT_USING)
		continue;
		
	if(motor->speed_control_type == PID_CONTROLLED){
		double error = motor->speed_ref[0] - motor->speeds[0];
		motor->powers[0] = controller(error);
	}
	
	nxt_motor_set_speed(motor->port, motor->powers[0], 1);
}
//  :3 Listen, here we will write the function that will decode only ONE order and will return some data, IF it's a sensors packet...
static void decode_bro_input (bro_fist_t * input_packet, engines_t * motors )
{
    U8 temp_port;
    
    output_packet->port = input_packet->port;
    output_packet->operation = input_packet->operation;
    
    switch (input_packet->operation) {
        case LIGHT_SENSOR:
            decode_bro_port (input_packet->port, &temp_port);
            input_packet->data = (float) ecrobot_get_light_sensor(temp_port);
            break;
            
        case TOUCH_SENSOR:
            decode_bro_port (input_packet->port, &temp_port);
            input_packet->data = (float) ecrobot_get_touch_sensor(temp_port);
            break;
            
        case SOUND_SENSOR:
            decode_bro_port (input_packet->port, &temp_port);
            input_packet->data = (float) ecrobot_get_sound_sensor(temp_port);
            break;
            
        case RADAR_SENSOR:
            decode_bro_port (input_packet->port, &temp_port);
            input_packet->data = (float) ecrobot_get_sonar_sensor(temp_port);
            break;
            
        case TACHO_COUNT:
            decode_bro_port (input_packet->port, &temp_port);
            input_packet->data = (float) nxt_motor_get_count(temp_port);
            break;
 
       case SET_POWER:
            decode_bro_port (input_packet->port, &temp_port);
            switch (temp_port) {
                case NXT_PORT_A:
                    motors->first.speed_control_type = RAW_POWER;
                    motors->first.powers[0] = input_packet->data;
					input_packet->data = (float) nxt_motor_get_count(temp_port);
					input_packet->time = (long) ecrobot_get_systick_ms();
                break;
                
                case NXT_PORT_B:
                    motors->second.speed_control_type = RAW_POWER;
                    motors->second.powers[0] = input_packet->data;
					input_packet->data = (float) nxt_motor_get_count(temp_port);
					input_packet->time = (long) ecrobot_get_systick_ms();
                break;
                
                case NXT_PORT_C:
                    motors->third.speed_control_type = RAW_POWER;
                    motors->third.powers[0] = input_packet->data;
					input_packet->data = (float) nxt_motor_get_count(temp_port);
					input_packet->time = (long) ecrobot_get_systick_ms();
                break;
            };
			
            break;
		case SET_SPEED:
            motors->first.speed_control_type = PID_CONTROLLED;
            motors->first.speed_ref = input_packet->data;
            break;
        default:
            //Nothing HERE
            break;
    };
}
Exemple #8
0
//*****************************************************************************
// TASK			: tsk0
// DESCRIPTION 	: 4msec periodical Task and controls NXTway-GS
//                INIT_MODE
//                ��
//                CAL_MODE
//                ��
//                CONTROL_MODE 
//*****************************************************************************
void tsk0(VP_INT exinf)
{
	static U32	gyro_offset;    /* gyro sensor offset value */
	static U32 avg_cnt;		    /* average count to calc gyro offset */
	static U32	cal_start_time;	/* calibration start time */
	static U8	bt_receive_buf[BT_RCV_BUF_SIZE]; /* Bluetooth receive buffer(32bytes) */
	SINT i;
	S8  cmd_forward, cmd_turn;
	S8	pwm_l, pwm_r;
  	
	switch(nxtway_gs_mode){
		case(INIT_MODE):
			gyro_offset = 0;
			avg_cnt = 0;
			for (i = 0; i < BT_RCV_BUF_SIZE; i++){
				bt_receive_buf[i] = 0;
			}
			balance_init(); /* NXTway-GS C API initialize function */
			nxt_motor_set_count(PORT_MOTOR_L, 0); /* reset left motor count */
			nxt_motor_set_count(PORT_MOTOR_R, 0); /* reset right motor count */
			cal_start_time = ecrobot_get_systick_ms();
			nxtway_gs_mode = CAL_MODE;
			break;
						
		case(CAL_MODE):
			gyro_offset += (U32)ecrobot_get_gyro_sensor(PORT_GYRO);
			avg_cnt++;
			if ((ecrobot_get_systick_ms() - cal_start_time) >= 1000U) {
				/* 1000msec later, start balancing */
				gyro_offset /= avg_cnt;
				ecrobot_sound_tone(440U, 500U, 30U); /* beep a tone */
				nxtway_gs_mode = CONTROL_MODE;
			}
			break;
						
		case(CONTROL_MODE):
			(void)ecrobot_read_bt_packet(bt_receive_buf, BT_RCV_BUF_SIZE);
			/* 
			 * R/C command from NXT GamePad
			 * buf[0]: -100(forward max.) to 100(backward max.)
			 * buf[1]: -100(turn left max.) to 100(turn right max.)
			 */
			cmd_forward = -(S8)bt_receive_buf[0]; /* reverse the direction */
			cmd_turn = (S8)bt_receive_buf[1];
			if (obstacle_flag == 1){
				/* make NXTway-GS move backward to avoid obstacle */
				cmd_forward = -100;
				cmd_turn = 0;
			}

			/* NXTway-GS C API balance control function (has to be invoked in 4msec period) */
			balance_control(
				(F32)cmd_forward,
				(F32)cmd_turn,
				(F32)ecrobot_get_gyro_sensor(PORT_GYRO),
				(F32)gyro_offset,
				(F32)nxt_motor_get_count(PORT_MOTOR_L),
				(F32)nxt_motor_get_count(PORT_MOTOR_R),
				(F32)ecrobot_get_battery_voltage(),
				&pwm_l,
				&pwm_r);
			nxt_motor_set_speed(PORT_MOTOR_L, pwm_l, 1);
			nxt_motor_set_speed(PORT_MOTOR_R, pwm_r, 1);

			ecrobot_bt_data_logger(cmd_forward, cmd_turn); /* Bluetooth data logger */
			break;
			
		default:
			/* unexpected mode */
			nxt_motor_set_speed(PORT_MOTOR_L, 0, 1);
			nxt_motor_set_speed(PORT_MOTOR_R, 0, 1);
			break;
	}

	ext_tsk(); /* terminates this task */
}