void tgCPGCableControl::onStep(tgSpringCableActuator& subject, double dt)
{
    assert(&subject == m_PID->getControllable());
    
    m_controlTime += dt;
	m_totalTime += dt;

    if (m_controlTime >= m_controlStep)
    {
        if (usePID)
        {
            m_commandedTension = motorControl().control(*m_PID, dt, controlLength(), getCPGValue());
        }
        else
        {
            tgBasicActuator* basicAct =  tgCast::cast<tgSpringCableActuator, tgBasicActuator>(&subject);
            m_commandedTension = motorControl().control(*basicAct, dt, controlLength(), getCPGValue());
        }
        m_controlTime = 0;
    }
    else
    {
		const double currentTension = subject.getTension();
        if(usePID)
        {
            m_PID->control(dt, m_commandedTension, currentTension);
        }
        else
        {
            tgBasicActuator* basicAct =  tgCast::cast<tgSpringCableActuator, tgBasicActuator>(&subject);
            basicAct->moveMotors(dt);
        }
	}
}
示例#2
0
//reset the position of all the motors
void resetMotors(unsigned int & serialPort)
{
#ifdef ENABLE_MOTORS
  motorControl(serialPort, 'G', 0);
  motorControl(serialPort, 'T', 0);
  motorControl(serialPort, 'B', 0);
#endif

#ifdef ENABLE_STEERING
  Move_Motor_Abs(STEERING_CENTER);
#endif
}
示例#3
0
/*static*/
void controlUpdate(union sigval v)
{
#if 0	//用于示波器观测定时器
	if(count)
    {
        count = 0;
        gpioWrite(PIN_SIG, 1);
    }
    else
    {
        count = 1;
        gpioWrite(PIN_SIG, 0);
    }
#endif
#if 1
	imuUpdate();
	//printImuData();

	pidControl();


	motorControl();

	joystickControl();
#endif
	//control2();
}
示例#4
0
int main()
{
    int i;
    init(0);
    // connect camera to the screen
    open_screen_stream();
    // set all didgital outputs to +5V
    for (i = 0; i < 8; i++)
    {
      // set all digital channels as outputs
      select_IO(i,0);
      write_digital(i,1);
    }
    while(1)
    {
      motorControl(line());
     }

   // terminate hardware
    close_screen_stream();
    set_motor(1,0);
    set_motor(2,0);

    return 0;


}
示例#5
0
// controls motor PWM values based on current and target position using a proportional controller (triggered by interrupt)
// total duration = 439us, therefore max freq = 2kHz. We use 200Hz (5ms), where 0.5ms = motor control, 4.5ms = program runtime
void fingerPosCtrl(void)
{
    static int fingerCounter = 0;	// counts through attached _fingers

    signed int motorSpeed = 0;			// used to calculate the motor speed as a vector (±255)
    float m;							// the proportional gradient
    signed int vectorise = 1;			// changes the sign '±' of the value
    int proportionalOffset = 150;
    signed int motorStopOffset = 20;


    if(_TotalFingerCount > 0)			// if _fingers are attached
    {
        // count through each finger at each function call
        if(fingerCounter < (_TotalFingerCount - 1))
            fingerCounter++;
        else
            fingerCounter = 0;


        // read position
        _fingers[fingerCounter].CurrPos = analogRead(_fingers[fingerCounter].Pin.sns);			// 424us

        // 	invert finger direction if enabled
        if(_fingers[fingerCounter].invert)
            _fingers[fingerCounter].CurrPos = 1023 - _fingers[fingerCounter].CurrPos;

        // calc positional error
        _fingers[fingerCounter].CurrErr = (signed int) (_fingers[fingerCounter].TargPos - _fingers[fingerCounter].CurrPos);

        // speed/position line gradient
        m = (float) (((float) _fingers[fingerCounter].TargSpeed)/((float) proportionalOffset));

        // change the ± sign on the motorSpeed depending on required direction
        if(_fingers[fingerCounter].CurrErr>=0)
            vectorise = -1;

        // constrain speed
        if(abs(_fingers[fingerCounter].CurrErr) < motorStopOffset)
            motorSpeed = 0;              // motor dead zone
        else if(_fingers[fingerCounter].CurrErr > (signed int)(proportionalOffset + motorStopOffset))
            motorSpeed = _fingers[fingerCounter].TargSpeed;        // set to max speed speed depending on direction
        else if(_fingers[fingerCounter].CurrErr < -(signed int)(proportionalOffset + motorStopOffset))
            motorSpeed = -_fingers[fingerCounter].TargSpeed;      // set to max speed speed depending on direction
        else if(abs(_fingers[fingerCounter].CurrErr) <= (proportionalOffset + motorStopOffset))
            motorSpeed = (m * (_fingers[fingerCounter].CurrErr + (motorStopOffset * vectorise))) - (_fingers[fingerCounter].MinSpeed * vectorise); // proportional control

        // constrain speed to limits
        motorSpeed = constrain(motorSpeed,-((signed int)_fingers[fingerCounter].MaxSpeed) ,(signed int)_fingers[fingerCounter].MaxSpeed);

        // if motor disabled, set speed to 0
        if(!_fingers[fingerCounter].motorEn)
            motorSpeed = 0;

        // send speed to motors
        motorControl(fingerCounter, motorSpeed);				// 15us
    }
}
示例#6
0
void motorStatus(motor_t status)
{
    if(0 == status)
    {
        motorControl(0,0);
    }
    else
    {
        if(status > 0)
        {
            motorControl((abs(status)+5)*10, 0);
        }
        else
        {
            motorControl(0, (abs(status)+5)*10);
        }
    }  
}
void tgCPGCableControl::updateTensionSetpoint(double newTension)
{
    if (newTension >= 0.0)
    {
        motorControl().setOffsetTension(newTension);
    }
    else
    {
        throw std::runtime_error("Tension setpoint is less than zero!");
    }
}
/*
	Motor Thread
	Handles the roll and pitch motors. It has three states, Follow, Goto Angle and Stop.
	Follow = simple updates the motor's angles to the values in the global struct.
	Goto = moves the motors to the specified angle over a specified time received from transmitter
	Stop =  simply stops the motors
*/
void motor_thread(void const *argument) {
  struct Values *values = (struct Values*)argument;
  char string[5]= {0};
  uint32_t mscount=0;

	while(1){
		//Follow Mode
		if(values->follow == 1){
			osMutexWait(measureUpdate, osWaitForever);
			motorControl(values->pitch, values->roll, global_pitch, global_roll);
			osMutexRelease(measureUpdate);    
		}
		//Goto Angle Mode
		if(values->follow == 0){
            osSignalWait(0x02, osWaitForever);
            osMutexWait(measureUpdate, osWaitForever);
            measurements.roll += values->rollIncrement;
            measurements.pitch += values->pitchIncrement;
            motorControl(measurements.pitch,measurements.roll, global_pitch, global_roll);
            ++mscount;
            //Check to see if we reached the desired time
            if (mscount >= values->time) {
                osTimerStop(timerid_motor); //stop timer
                mscount=0; //reset count
                // Delay 
                osDelay(1000);
                // Move back to follow mode
                measurements.follow = 1;
        }
        osMutexRelease(measureUpdate);
        }
    //Stop Mode
    if(values->follow == 3){
      osDelay(1000);
    }
		osDelay(MOTOR_DELAY);
	}
}
void tgCPGActuatorControl::onStep(tgSpringCableActuator& subject, double dt)
{
    m_controlTime += dt;
    m_totalTime += dt;
    /// @todo this fails if its attached to multiple controllers!
    /// is there a way to track _global_ time at this level

    // Workaround until we implement PID
    tgBasicActuator& m_sca = *(tgCast::cast<tgSpringCableActuator, tgBasicActuator>(subject));

    if (m_controlTime >= m_controlStep)
    {

        m_commandedTension = motorControl().control(m_sca, m_controlTime, controlLength(), getCPGValue());

        m_controlTime = 0;
    }
    else
    {
        m_sca.moveMotors(dt);
    }
}
int main(int argc, char **argv)
{
	/**
	* The ros::init() function needs to see argc and argv so that it can perform
	* any ROS arguments and name remapping that were provided at the command line.
	* For programmatic remappings you can use a different version of init() which takes
	* remappings directly, but for most command-line programs, passing argc and argv is
	* the easiest way to do it.  The third argument to init() is the name of the node.
	*
	* You must call one of the versions of ros::init() before using any other
	* part of the ROS system.
	*/
	ros::init(argc, argv, "pwm_controller");
	ros::NodeHandle n("/pwm_controller");;
	
    n.param("right_p", controlPR, 0.7);
    n.param("left_p", controlPL, 0.7);
    n.param("right_i", controlIR, 0.001);
    n.param("left_i", controlIL, 0.001);
    n.param("right_d", controlDR, 0.0);
    n.param("left_d", controlDL, 0.0);
	
	ros::Publisher pwm_pub = n.advertise<ras_arduino_msgs::PWM>("/arduino/pwm", 1000);
	ros::Subscriber twist_sub = n.subscribe<geometry_msgs::Twist>("/cmd_vel", 1000, updateTwist);
	ros::Subscriber encoder_sub = n.subscribe<ras_arduino_msgs::Encoders>("/arduino/encoders", 1000, updateEncoders);
	ros::Rate loop_rate(controlRate);

	while (ros::ok())
    {

        pwm_pub.publish(motorControl()); //
		ros::spinOnce(); // Run the callbacks.
		loop_rate.sleep();
	}


	return 0;
}
示例#11
0
void servoSet(int setPt)
{
	// setPt = Angle of Incidence in 10ths of degrees

	//char hysteresis = 40;
	int servoSpeed;

	// Convert angle*10 to a value between 25-93
	int  tmpSetPt = setPt/4;
	if (tmpSetPt >  34) tmpSetPt= 34;
	if (tmpSetPt < -34) tmpSetPt=-34;
	tmpSetPt += 59;

	servoSpeed = (ADCH-tmpSetPt)*20;

	if (servoSpeed > 255) servoSpeed= 255;
	if (servoSpeed < -255) servoSpeed=-255;
	//if (servoSpeed > -60 && servoSpeed < 60) servoSpeed = 0;
	//if (servoSpeed > hysteresis) { servoSpeed=255; hysteresis = 10; }
	//else if (servoSpeed < -hysteresis) { servoSpeed=-255; hysteresis = 10; }
	//else { servoSpeed=0; hysteresis = 100; }

	motorControl(servoSpeed);
}
示例#12
0
                         /* is set to 'yes' (#pragma interrupt saveall is generated before the ISR)      */
void TI1_OnInterrupt(void)
{
  oneMsCounter++;
  
  //------------------------------------------- 
    g_nspeedControPeriod ++;
  	speedControlOutput();
  //___________________________________________
  
  //-------------------------------------------
  
    g_nDirectionControlPeriod ++;
  	DirectionControlOutput();
  //___________________________________________
  
  if(oneMsCounter == 1)            
  {
     if(AD_Flag)    updataSensor();  		       //读取ADC的值
  }
//--------------------------------------------------  
  else if(oneMsCounter == 2)       
  {
    AngleCalculate();              //计算角度
  	AngleControl();                //角度的PD值控制  	 
  	motorControl();                //电机输出控制		
  }
//-----------------------------------------------  
  else if(oneMsCounter == 3)       
  {  
    g_nSpeedControlCount++;
    oneHundredMsCounter++;
    
    if(g_nSpeedControlCount >= SPEED_CONTROL_COUNT)
    {
      speedControl();               //速度控制
      g_nSpeedControlCount=0;
      g_nspeedControPeriod=0;	
    }
    
    if(standFlag){
        if(oneHundredMsCounter == 100)         
        {
          if(CAR_SPEED_SET < speedNeed3)
              CAR_SPEED_SET += 10;
          else
          {
              CAR_SPEED_SET = speedNeed3;
              speedStarEndFlag = 1;
          }   
          oneHundredMsCounter = 0;         
        }
    }
    else
    {
        CAR_SPEED_SET = 0;
        oneHundredMsCounter = 0;
        speedStarEndFlag = 0;
    }
  }
//--------------------------------------------------  
  else if(oneMsCounter == 4)       
  {
      g_nDirectionControlCount ++;
      DianciCalculate();
      DirectionVoltageSigma();
      if(g_nDirectionControlCount >= DIRECTION_CONTROL_COUNT) {
          DirectionControl();
          g_nDirectionControlCount = 0;
          g_nDirectionControlPeriod = 0;
      }  	  
  }
//-------------------------------------------------  
  else if(oneMsCounter >= 5)
  {
  	oneMsCounter = 0; 
  	GetMotorPulse();
  	UartFlag = 1;
  }
}
int main(int argc, char *argv[]) 
{
    MotorController motorControl(argc, argv);
}
示例#14
0
文件: bud.c 项目: trevhoot/BestBuds
int16_t main(void) {
	init_clock();
	init_timer();
	init_pin();
	init_oc();
	init_ui();

	InitUSB();							  // initialize the USB registers and serial interface engine
	while (USB_USWSTAT!=CONFIG_STATE) {	 // while the peripheral is not configured...
		ServiceUSB();					   // ...service USB requests
	}

	// Configure Interrupts on the pic
	IEC1bits.CNIE = 1;
	CNEN1bits.CN2IE = 1;
	IFS1bits.CNIF = 0;

	IEC0bits.OC1IE = 1;
	IFS0bits.OC1IF = 0;
	timer_enableInterrupt(&timer1);
	timer_lower(&timer1);
	timer_enableInterrupt(&timer2);
	timer_lower(&timer2);
	timer_enableInterrupt(&timer4);
	timer_lower(&timer4);
	timer_enableInterrupt(&timer5);
	timer_lower(&timer5);



	// Configure Pins
	inPin0 = &A[0];	
	pin_analogIn(inPin0);
	inPin1 = &A[1];	
	pin_analogIn(inPin1);
	inPin2 = &A[2];	
	pin_analogIn(inPin2);
	inPin3 = &A[3];	
	pin_analogIn(inPin3);
	inPin4 = &A[4];	
	pin_analogIn(inPin4);

	irPin = &A[5];	
	pin_analogIn(irPin);

	outPin = &D[6];
	pin_digitalOut(outPin);
	oc_pwm(&oc1, outPin, NULL, 10, (uint16_t)(0));		// write to D2 with a 10Hz PWM signal
	pin_write(outPin, 10000);	//duty doesn't matter, really. 

	redPin = &D[7];
	pin_digitalOut(redPin);
	oc_pwm(&oc2, redPin, NULL, 100, (uint16_t)(0));	
	greenPin = &D[10];
	pin_digitalOut(greenPin);
	oc_pwm(&oc3, greenPin, NULL, 100, (uint16_t)(0));	
	bluePin = &D[8];
	pin_digitalOut(bluePin);
	oc_pwm(&oc4, bluePin, NULL, 100, (uint16_t)(0));	

	pingPin = &D[4];
	pin_digitalOut(pingPin);
	oc_pwm(&oc5, pingPin, &timer3, 40000, 0);
	receivePin = &D[12];
	pin_digitalIn(receivePin);

	// Motor controller pins
	dirPin = &D[0];
	pin_digitalOut(dirPin);
	nSleepPin = &D[3];
	pin_digitalOut(nSleepPin);
	pin_write(nSleepPin, 1);
	stepPin = &D[2];
	pin_digitalOut(stepPin);

	testPin = &D[13];
	pin_digitalOut(testPin);

	timer_setFreq(&timer1, 100);


	while (1) {
		ServiceUSB(); // service any pending USB requests


		
		irVoltage = pin_read(irPin);
		if (irVoltage < 40000){
			dist = 32768;
		}
		if (irVoltage >= 40000){
			dist = 32900;
		}


		if (dist != stepCount) {
			changeFlag += 1;
		} else {
			changeFlag = 0;
		}

		if (changeFlag >= 3){
			changeFlag = 0;
			motorControl(dist);
		}


		if (touching0 == 10){
			greenTarget = 40000;
			redTarget = 60000;
			blueTarget = 0;
			if (currentPetal == 0){
				greenTarget = 0;
				redTarget = 0;
				blueTarget = 0;
			}
			currentPetal == 0;
		}
		if (touching1 == 11){
			greenTarget = 20000;
			redTarget = 20000;
			blueTarget = 20000;
			if (currentPetal == 1){
				greenTarget = 0;
				redTarget = 0;
				blueTarget = 0;
			}
			currentPetal == 1;
		}
		if (touching2 == 12){
			greenTarget = 0;
			redTarget = 60000;
			blueTarget = 40000;
			if (currentPetal == 2){
				greenTarget = 0;
				redTarget = 0;
				blueTarget = 0;
			}
			currentPetal == 2;
		}
		if (touching3 == 13){
			greenTarget = 0;
			redTarget = 60000;
			blueTarget = 0;
			if (currentPetal == 3){
				greenTarget = 0;
				redTarget = 0;
				blueTarget = 0;
			}
			currentPetal == 3;
			
		}
		if (touching4 == 14){
			greenTarget = 60000;
			redTarget = 0;
			blueTarget = 0;
			if (currentPetal == 4){
				greenTarget = 0;
				redTarget = 0;
				blueTarget = 0;
			}
			currentPetal == 4;

		}
		if (greenDuty < greenTarget) {
			greenChange = 1;
		} else if (greenDuty > greenTarget) {
			greenChange = -1;
		} else {
			greenChange = 0;
			onTarget += 1;
		}
		if (redDuty < redTarget) {
			redChange = 1;
		} else if (redDuty > redTarget) {
			redChange = -1;
		} else {
			redChange = 0;
			onTarget += 1;
		}
		if (blueDuty < blueTarget) {
			blueChange = 1;
		} else if (blueDuty > blueTarget) {
			blueChange = -1;
		} else {
			blueChange = 0;
			onTarget += 1;
		}
		greenDuty += greenChange;
		redDuty += redChange;
		blueDuty += blueChange;
		pin_write(greenPin, greenDuty);
		pin_write(redPin, redDuty);
		pin_write(bluePin, blueDuty);


		/*
		// fade on when touched
		if (touching0 == 10){
			if (greenOn == 0){
				greenChange = 1;
			}
			if (greenOn == 1){
				greenChange = -1;
			}
			redChange = -1;
			blueChange = -1;
		}
		if (touching1 == 11){
			if (redOn == 1){
				redChange = -1;
			}
			if (redOn == 0){
				redChange = 1;
			}
			blueChange = -1;
			greenChange = -1;
		}
		if (touching2 == 12){
			if (blueOn == 1){
				blueChange = -1;
			}
			if (blueOn == 0){
				blueChange = 1;
			}
			greenChange = -1;
			redChange = -1;
		}
		greenDuty = greenDuty + greenChange;
		if (greenDuty == MAX_INT){
			greenDuty = MAX_INT -1;
			greenOn = 1;
			greenChange = 0;
		}
		if (greenDuty == 0){
			greenDuty = 1;
			greenOn = 0;
			greenChange = 0;
		}
		redDuty = redDuty + redChange;
		if (redDuty == MAX_INT){
			redDuty = MAX_INT - 1;
			redOn = 1;
			redChange = 0;
		}
		if (redDuty == 0){
			redDuty = 1;
			redOn = 0;
			redChange = 0;
		}
		blueDuty = blueDuty + blueChange;
		if (blueDuty == MAX_INT){
			blueDuty = MAX_INT - 1;
			blueOn = 1;
			blueChange = 0;
		}
		if (blueDuty == 0){
			blueDuty = 1;
			blueOn = 0;
			blueChange = 0;
		}
		pin_write(greenPin, greenDuty);
		pin_write(redPin, redDuty);
		pin_write(bluePin, blueDuty);
		*/

		/*
		if (iteration > 10000) {
			ping();
			iteration = 0;
		}
		iteration += 1;
		*/
	}
}
示例#15
0
//*MAIN*//
int main(int argc, char * argv[])
{
  bool active = true; //flag that controls main loop
  int value;          //value of received message
  char messageType;

  unsigned int  serialPort;

  char * serialAddr = "/dev/ser1";

  TCP tcpConnection;
  unsigned int clientSocket;

  //Initialization
  //Parse the arguments
  switch (argc)
  {
    case 2:
      serialAddr = argv[1];
      break;
  }

  if ( argc >= 2 )
  {
    if ( initSerial(serialPort, serialAddr) == false )
    {
      std::cout << "Serial port initialization failure.\n";
      return 0;
    }
    if ( initMotors() == false )
    {
      std::cout << "Motor initialization failure.\n";
      return 0;
    }
  }

  if ( initTCP(tcpConnection, clientSocket) == false )
  {
    std::cout << "TCPIP initialization failure.\n";
    return 0;
  }

  while (active)
  {
    tcpConnection.receiveData(  clientSocket,
                                (char *) &messageType,
                                sizeof( messageType ));

    if(tcpConnection.receiveData( clientSocket,
                                  (char *) &value,
                                  sizeof( value )) == DATA_ERROR)
    {
      active = false;
      std::cout << "Client Disconnected!" << std::endl;
    }

#ifdef DEBUG
    debugprint(messageType, value);
#endif

    if(messageType == 'X')
      active = false;

    else if (active == true)
    {

#ifdef ENABLE_STEERING
      if (messageType == 'S')
        Move_Motor_Abs(value);
      else
#endif
        motorControl(serialPort, messageType, value);
        //watch out for this!
    }
  }
  std::cout << "Resetting motors..." << std::endl;
  resetMotors(serialPort);

#ifdef ENABLE_STEERING
  Close_Maxon_Motor_Driver();
#endif

  tcpConnection.closeSocket(clientSocket);

  std::cout << "Terminating..." << std::endl;
  return 0;
}
示例#16
0
/*
	Main Receive Thread. It reads from the wireless  and checks the control part of the packet to determine
	what kind of data we are receiving. There are three types PACKET_CTRL1_BEGIN, PACKET_CTRL1_PR, PACKET_CTRL1_RECORD_BEGIN.
	PACKET_CTRL1_BEGIN = Receiving a desired Roll and Pitch Angle that the board should travel to over some time
	PACKET_CTRL1_PR = simply update the current pitch and roll angle for the board to follow. i.e. real time angle following
	PACKET_CTRL1_RECORD_BEGIN = indicate that we are receiving a sequence of angles that the board will follow.
	
*/
void receive_thread(void const *argument) {
  uint8_t status = CC2500_CommandProbe(CC2500_READBIT, CC2500_SRX);
  printf("Moved to RX (%x) \n",status);
  //osDelay(500);
  
  ring_buffer_t dist_filter; 
  int size = DIST_FILTER_SIZE; 
  int dist_buffer[size];
  init_buffer(&dist_filter,dist_buffer,size);  
    
  float f1, f2, value; 
  uint16_t control;
  uint8_t ctrl = 0;
  uint8_t ctrl2 = 0;
  while (1) { 
    control = receive_pitchroll(&f1, &f2, &ctrl2);
		
		//Check to see what kind of Packet we have received
    if (control == PACKET_CTRL1_BEGIN) {
      while (ctrl != PACKET_CTRL1_END) {
        receive_keypad(&ctrl, &value);
				//update our global values from the recieved data
        switch(ctrl) {
            case PACKET_CTRL1_PITCH: 
              measurements.pitchIncrement = value; 
              break;
            case PACKET_CTRL1_ROLL: 
              measurements.rollIncrement = value; 
              break;
            case PACKET_CTRL1_TIME: 
              measurements.time = value; 
              break;
        } 
      } 
      //printf("EX MOVE pitchIncrement = %f, rollIncrement = %f, time = %f \n",measurements.pitchIncrement,measurements.rollIncrement,measurements.time);
      //Turn off Motor Follow Mode
			measurements.follow = 0;
			//Start OS Timer for Motor 
      osTimerStart(timerid_motor,100);
			//Wait till follow flag has been reset
      while (!measurements.follow) {
        osDelay(500);
      }  
      ctrl = 0; // reset control
    }
		//Update Pitch and Roll angles for motor to follow
    else if (control == PACKET_CTRL1_PR) {

      measurements.pitch = f1;
      measurements.roll = f2;
      //Return the signal strength of the wireless receiver. 
      float f = filter_point(get_signal_strength(), &dist_filter);
      showSignalStrength(f); //updates the LEDs  
      //printf("READ: Pitch = %f (%f) Roll = %f (%f)  Control1 = %x  Pkt_index = %i Power = %f \n",f1,global_pitch,f2,global_roll,control,ctrl2,f);
    }
	//Begin playing Recorded Sequence	
	else if (control == PACKET_CTRL1_RECORD_BEGIN) {
	  float pitchBuffer[256];
	  float rollBuffer[256];
    float time_interval = f1;
		//start receiving the sequence and store in the buffers	
	  receive_record_sequence(pitchBuffer,rollBuffer,&time_interval);
	  //printf("RECV: Record Sequence: \n");
      int i;

      measurements.follow = 3; // Stop Motors Following
      
      //printf("Motors moving sequence, timedelay = %f \n",time_interval); 
      i = 0;
      uint8_t j;
      float f1, f2; 
      float pitchInc, rollInc; 
			//Playing back the Angle Sequence
      while (i < 256) {
        j = 0;
        pitchInc = (pitchBuffer[i+1] - pitchBuffer[i]) / 10;
        rollInc = (rollBuffer[i+1] - rollBuffer[i]) / 10;
        f1 = pitchBuffer[i];
        f2 = rollBuffer[i];
				//Linear Interpolation of the Data as we received only 1/10th the actual sequence
				//so we fill in the blanks using the average of two consequetive angles in the sequence.
        while (j < 10) {
            f1 += pitchInc; 
            f2 += rollInc;
            motorControl(f1, f2, global_pitch, global_roll);
            printf("Motors moving to angle: index = %i  Pitch = %f  Roll = %f \n",i,pitchBuffer[i],rollBuffer[i]); 
            j++;
						osDelay(10);//Delay of 100 so the Loop runs at 100Hz, the rate of which the accelerometer reads.
        }
        //osDelay((int)time_interval);
        i++;
      }
      
      osDelay(1000);
      measurements.follow = 1; // Stop following
		}	
			
  }
}