예제 #1
0
int main(void)
{
  int i;
  int led = 0;
  unsigned long count = 0;
  //  unsigned long baud = 57600;
  unsigned long baud = 1000000;
  int ret;
  volatile float imuAngle[3];

  // Variables to keep track for reading servos
  int nRead=0, idRead=0;
  uint8_t *ctableByte;
  int serialWait = 0;
  
  // Dynamixel packets and counters for input/output
  DynamixelPacket *pktReadData, *pktStatus;
  DynamixelPacket pktSerialInput, pktRs485Input;

  init();
  uart0_printf("\r\nStarting %s\r\n", CONTROLLER_NAME);
  uart0_printf("Switching serial to %lu baud...\r\n", baud);
  _delay_ms(100);
  uart0_setbaud(baud);
  uart0_printf("\r\nRunning serial at %lu baud\r\n", baud);
  _delay_ms(100);

  // Set Dynamixel return delay
  rs485_putstrn("\xFF\xFF\xFE\x04\x03\x05\x00\xF5", 8);

  while (1) {
    count++;

    if (count % 1000 == 0) {
      // Toggle MON and Dynamixel Leds
      if (led) {
	led = 0;
	sbi(PORTC, PORTC4);
	rs485_putstrn("\xFF\xFF\xFE\x04\x03\x19\x00\xE1", 8);
      }
      else {
	led = 1;
	cbi(PORTC, PORTC4);
	rs485_putstrn("\xFF\xFF\xFE\x04\x03\x19\x01\xE0", 8);
      }
      _delay_us(100);
    }


    if (uart0_recv(&pktSerialInput)) {
      // RxD LED on
      cbi(PORTC, PORTC1);

      if (pktSerialInput.id == controlTable.id) {
	switch (pktSerialInput.instruction) {
	case INST_WRITE:
	  for (i = 1; i < pktSerialInput.length-2; i++) {
	    controlTablePtr[pktSerialInput.parameter[0]+i-1] =
	      pktSerialInput.parameter[i];
	  }
	  // Status packet
	  pktStatus = dynamixel_status(controlTable.id,
					 0, NULL, 0);
	  break;
	case INST_READ:	    
	  pktStatus = dynamixel_status(controlTable.id, 0,
				       (uchar *)controlTablePtr+pktSerialInput.parameter[0],
				       pktSerialInput.parameter[1]);
	  break;
	case INST_PING:
	  pktStatus = dynamixel_status(controlTable.id,
				       0, NULL, 0);
	  break;
	default:
	  // Unknown command
	  pktStatus = dynamixel_status(controlTable.id,
				       1, NULL, 0);
	  break;
	}
	uart0_send(pktStatus);
      }

      else {
	// Forward packet to RS485
	rs485_send(&pktSerialInput);
	if (pktSerialInput.id != DYNAMIXEL_BROADCAST_ID) {
	  serialWait = 1;
	}
      }
      // RxD LED off
      sbi(PORTC, PORTC1);
    } // if (uart0_recv())

    if (!serialWait) {
      // TxD LED on
      cbi(PORTC, PORTC2);

      // Query servo for data in round robin fashion:
      if (++nRead >= controlTable.nServo) nRead = 0;
      idRead = controlTable.idMap[nRead];
      pktReadData = dynamixel_instruction_read_data(idRead,
						    controlTable.addrRead,
						    controlTable.lenRead);
      rs485_send(pktReadData);
      // TxD LED off
      sbi(PORTC, PORTC2);
    } // if (!serialWait)

    while (rs485_recv_timeout(&pktRs485Input, 300)) {
      // Check if status packet contains requested read data
      if (serialWait) {
	// Forward packet to uart0
	uart0_send(&pktRs485Input);
      }
      else if ((pktRs485Input.id == idRead) &&
	       (pktRs485Input.instruction == 0) &&
	       (pktRs485Input.length == controlTable.lenRead+2)) {
	// Packet is correct return, flash EDIT Led
	cbi(PORTC, PORTC3);
	ctableByte = controlTable.dataRead + nRead*(controlTable.lenRead+1);
	*ctableByte++ = idRead;
	for (i=0; i<controlTable.lenRead; i++) {
	  *ctableByte++ = pktRs485Input.parameter[i];
	}
	sbi(PORTC, PORTC3);
      }
    } // while (rs485_recv())

    // Timeout waiting for serial response
    if (serialWait) {
      if (++serialWait > 3) serialWait = 0;
    }
    
    
     //check to see if we got full set of adc values
    //if the data is ready, it will be copied to the provided pointer
    cli();   //disable interrupts to prevent race conditions while copying, 
             //since the interrupt-based ADC cycle will write asynchronously
    ret = adc_get_data(controlTable.imuAcc);
    sei();   //re-enable interrupts
    
    /*
    if (ret > 0) 
    	ProcessImuReadings(controlTable.imuAcc,controlTable.imuAngle);
    */
    /*
    if (ret > 0) {
    ProcessImuReadings(controlTable.imuAcc,controlTable.imuAngle);
    
    for (i = 0; i<3;i++)
    	controlTable.imuAngle2[i]=  32768 + 1024* controlTable.imuAngle[i] ;
    }*/
    
    
    if (ret > 0) {
    ProcessImuReadings(controlTable.imuAcc,imuAngle);
    
    for (i = 0; i<3;i++)
    	controlTable.imuAngle[i]=  32768 + (uint16_t) 1024* imuAngle[i] ;
    }
    
    
    if (PINB & _BV(PB4)) {
		     //if pin high, the button is not pressed
		  controlTable.button = 0;
		  LED_ESTOP_PORT    &= ~(_BV(LED_ESTOP_PIN));
  	}
  	else {
		  //if pin is low, the button is pressed
		  controlTable.button = 1;
		  LED_ESTOP_PORT    |= _BV(LED_ESTOP_PIN);
  	}

  } // while (1)

  return 0;
}
예제 #2
0
int main(void)
{
  int16_t len;
  uint8_t * buf;
  int c;
  int imuRet;
  int ret;
  uint8_t ledState=0;

  uint8_t * servo1PacketOut        = NULL;
  DynamixelPacket * servo1PacketIn = NULL;
  uint8_t servo1PacketOutSize      = 0;
  float servo1Angle;
  uint32_t servo1Time;
  uint32_t newEstopTime;
  
  estopState = MMC_ESTOP_STATE_RUN;
  LED_ESTOP_ON;
  
  estopPublishTimer  = GlobalTimerGetTime();
  estopTimeout       = GlobalTimerGetTime();
  
  DynamixelPacketInit(&hostPacketIn);
  DynamixelPacketInit(&busPacketIn);
  DynamixelPacketInit(&xbeePacketIn);

  if (LoadAndSetEepromParams() != 0)
  {
    while(1)
    {
      //TODO: send the error packet
      _delay_ms(100);
    }
  }

  init();

  //Servo1SetMode(SERVO_CONTROLLER_MODE_FB_ONLY);
  //Servo1SetMode(SERVO_CONTROLLER_MODE_SERVO);
  
  while(1)
  {
    //receive packet from host
    len=HostReceivePacket(&hostPacketIn);
    if (len>0)
      HostPacketHandler(&hostPacketIn);

    if (mode == MMC_MC_MODE_CONFIG)
      continue;


//--------------------------------------------------------------------
//                      Estop Stuff
//--------------------------------------------------------------------

    //check the state of the estop input
    if (ESTOP_PORT & _BV(ESTOP_PIN))   //input high means disabled
    {
      estopState = MMC_ESTOP_STATE_DISABLE;
      DisableVehicle();
    }
    
    //see if we need to send out estop status
    newEstopTime = GlobalTimerGetTime();
    if (newEstopTime > (estopPublishTimer+62500))   //1.0 seconds
    {
      estopPublishCntr++;
      HostSendPacket(MMC_ESTOP_DEVICE_ID,MMC_ESTOP_STATE,
                     (uint8_t*)&estopState,1);
                     
                     
      if ((estopPublishCntr % ESTOP_PUBLISH_MOD) == 0)
      {
        estopStateDataOut[0] = ptableR.id;
        estopStateDataOut[1] = estopState;
        XbeeSendPacket(MMC_ESTOP_DEVICE_ID,MMC_ESTOP_STATE,
                         estopStateDataOut,2);
      }
                   
      estopPublishTimer = newEstopTime;
      
      switch (estopState)
      {
        case MMC_ESTOP_STATE_RUN:
          LED_ESTOP_ON;
          LED_ERROR_OFF;
          break;
        case MMC_ESTOP_STATE_FREEZE:
          LED_ESTOP_OFF;
          LED_ERROR_TOGGLE;
          break;
        case MMC_ESTOP_STATE_DISABLE:
          DisableVehicle();
          break;
        default:
          break;
      }
    }
    
    if (newEstopTime > (estopTimeout + 625000))     //10 seconds
    {
      estopState = MMC_ESTOP_STATE_FREEZE;
    }
     

//--------------------------------------------------------------------
//                        RS-485 Bus
//--------------------------------------------------------------------

    //receive packet from RS485 bus
    servo1PacketIn = NULL;
    len=BusReceivePacket(&busPacketIn);
    if (len>0)
    {
      if (DynamixelPacketGetId(&busPacketIn) == MMC_DYNAMIXEL0_DEVICE_ID)
        servo1PacketIn = &busPacketIn;
      
      BusPacketHandler(&busPacketIn);
    }


//--------------------------------------------------------------------
//                      Servo Controller
//--------------------------------------------------------------------
    
    Servo1UpdateTime(GlobalTimerGetTime());
    Servo1Update(servo1PacketIn,&servo1PacketOut,&servo1PacketOutSize);
    
    if (servo1PacketOut && (servo1PacketOutSize > 0) && (estopState == MMC_ESTOP_STATE_RUN) )
    {
      memcpy(servo1PacketOutBuf,servo1PacketOut,servo1PacketOutSize);
      servo1PacketOutBufSize = servo1PacketOutSize;
    
      needToSendServo1Packet = 1;
    }


//--------------------------------------------------------------------
//                              Xbee
//--------------------------------------------------------------------

    len = XbeeReceivePacket(&xbeePacketIn);
    if (len > 0)
      XbeePacketHandler(&xbeePacketIn);
    
    
//--------------------------------------------------------------------
//                              GPS
//--------------------------------------------------------------------    
    //receive a line from gps
    len=GpsReceiveLine(&buf);
    if (len>0)
      GpsPacketHandler(buf,len);
      
      
      
//--------------------------------------------------------------------
//                              ADC
//--------------------------------------------------------------------

    cli();
    len = adc_get_data(adcVals);
    sei();    

    if (len > 0)
    {
      adcCntr++;
      imuRet = ProcessImuReadings(adcVals,rpy,wrpy);
      if (imuRet == 0) //will return 0 if updated, 1 if not yet updated
      {
        //send stuff out
        memcpy(imuOutVals,  &rpy[0], sizeof(float));
        memcpy(imuOutVals+1,&rpy[1], sizeof(float));
        memcpy(imuOutVals+2,&rpy[2], sizeof(float));
        memcpy(imuOutVals+3,&wrpy[0],sizeof(float));
        memcpy(imuOutVals+4,&wrpy[1],sizeof(float));
        memcpy(imuOutVals+5,&wrpy[2],sizeof(float));
    
        HostSendPacket(MMC_IMU_DEVICE_ID,MMC_IMU_ROT, 
                  (uint8_t*)imuOutVals,6*sizeof(float));
      }
      if (imuRet == 1 || sendImuRaw == 1)    //send out raw values if calibration is not finished
      {
        imuPacket[0] = adcCntr;
        memcpy(&(imuPacket[1]),adcVals,NUM_ADC_CHANNELS*sizeof(uint16_t));
        HostSendPacket(MMC_IMU_DEVICE_ID,MMC_IMU_RAW,
		       (uint8_t*)imuPacket,(NUM_ADC_CHANNELS+1)*sizeof(uint16_t));
      }
      
      
      if (estopState == MMC_ESTOP_STATE_RUN)  //flicker leds when in run mode
      {
        if (adcCntr % 4 == 0)
          DDRL = 0xFF;
        else
          DDRL = 0x00;
      }
      else 
        DDRL = 0xFF;
      

      //switch colors when in run mode
      if (adcCntr % 20 == 0)
      {
        ledState++;
        
        if (ledState == 8)
          ledState = 0;
        
        if (estopState == MMC_ESTOP_STATE_RUN)
        {
          switch (ledState)
          {
            case 0:
              PORTL = _BV(PL3);
              break;
            case 1:
              PORTL = _BV(PL4);
              break;
            case 2:
              PORTL = _BV(PL5);
              break;
            default:
              PORTL = 0;
              break;
          
          }
        }
        else 
          PORTL = _BV(PL3); //paused
      }

      if (adcCntr % 100 == 0)
      {
        voltageBatt = adcVals[6]/1024.0*2.56*(11.0);
        HostSendPacket(MMC_MAIN_CONTROLLER_DEVICE_ID,MMC_MC_VOLTAGE_BATT,
	                     (uint8_t*)(&voltageBatt),sizeof(float));

        if (voltageBatt < 21.0)
        {
          cli();  BUZZER_ON; sei();
        }
        else
        {
          cli(); BUZZER_OFF; sei();
        }
      }
    }


//--------------------------------------------------------------------
//                       RS485 Bus Handling
//--------------------------------------------------------------------

    if ( (needToSendServo1Packet == 1) && (rs485Blocked == 0))
    {
      SetBusBlocked();
      BusSendRawData(servo1PacketOutBuf,servo1PacketOutBufSize);
      needToSendServo1Packet = 0;
      TCNT1 = 12500/4;
    }

    if ( (needToRequestFb == 1) && (rs485Blocked == 0) )
    {
      SetBusBlocked();
      BusSendRawData(encoderRequestRawPacket,encoderRequestRawPacketSize);
      needToRequestFb = 0;
    }  
 }

  

  return 0;
}