Пример #1
0
void turn(int target, int speed) {
  GYRO.calibrate(10);
  
  float zero = gyro(4);
  float value;
  
  MOTORS.setMotorSpeed(speed, -speed);
  
  do {
    value = abs(zero - gyro(4));
  } while (value < target);

  MOTORS.setMotorSpeed(0, 0);
}
Пример #2
0
/**
 * @example     L3G_Demo.cpp
 *
 * Read the gyrometer data and print it to the terminal
 *
 * @include PropWare_L3G/CMakeLists.txt
 */
int main () {
    int16_t       gyroValues[3];
    PropWare::SPI *spi = PropWare::SPI::get_instance();
    PropWare::L3G gyro(spi, CS);

    gyro.start();
    gyro.set_dps(PropWare::L3G::DPS_500);

    // Though this functional call is not necessary (default value is 0), I
    // want to bring attention to this function. It will determine whether the
    // l3g_read* functions will always explicitly set the SPI modes before
    // each call, or assume that the SPI driver is still running in the proper
    // configuration
    gyro.always_set_spi_mode(1);

    while (1) {
        gyro.read_all(gyroValues);
        //pwOut << "Gyro vals DPS... X: " << gyro.convert_to_dps(gyroValues[PropWare::L3G::X])
        //        << "\tY: " << gyro.convert_to_dps(gyroValues[PropWare::L3G::Y])
        //        << "\tZ: " << gyro.convert_to_dps(gyroValues[PropWare::L3G::Z]) << '\n';

        pwOut << "Gyro vals DPS... X: " << gyroValues[PropWare::L3G::X]
                << "\tY: " << gyroValues[PropWare::L3G::Y]
                << "\tZ: " << gyroValues[PropWare::L3G::Z] << '\n';

        waitcnt(50*MILLISECOND + CNT);
    }

    return 0;
}
void ViSensorInterface::ImuCallback(boost::shared_ptr<visensor::ViImuMsg> imu_ptr) {
  if (imu_ptr->imu_id != visensor::SensorId::IMU0)
    return;
  uint32_t timeNSec = imu_ptr->timestamp;
  Eigen::Vector3d gyro(imu_ptr->gyro[0], imu_ptr->gyro[1], imu_ptr->gyro[2]);
  Eigen::Vector3d acc(imu_ptr->acc[0], imu_ptr->acc[1], imu_ptr->acc[2]);
  std::cout << "IMU Accelerometer data: " << acc[0] << "\t "<< acc[1] << "\t"<< acc[2] << "\t" << std::endl;
	//Do stuff with IMU...
}
Пример #4
0
int main(int argc, char *argv[])
{
    if (strcmp(argv[1], "mag")==0)
        return mag(argc, argv);
    if (strcmp(argv[1], "gyro")==0)
        return gyro(argc, argv);
    if (strcmp(argv[1], "acc")==0)
        return acc(argc, argv);
    printf("Usage: %s [mag|gyro|acc] <cmd>\r\n");
    return 1;
}
/*
  process any 
 */
bool AP_InertialSensor_MPU6000::update( void )
{    
#if !MPU6000_FAST_SAMPLING
    if (_sum_count < _sample_count) {
        // we don't have enough samples yet
        return false;
    }
#endif

    // we have a full set of samples
    uint16_t num_samples;
    Vector3f accel, gyro;

    hal.scheduler->suspend_timer_procs();
#if MPU6000_FAST_SAMPLING
    gyro = _gyro_filtered;
    accel = _accel_filtered;
    num_samples = 1;
#else
    gyro(_gyro_sum.x, _gyro_sum.y, _gyro_sum.z);
    accel(_accel_sum.x, _accel_sum.y, _accel_sum.z);
    num_samples = _sum_count;
    _accel_sum.zero();
    _gyro_sum.zero();
#endif
    _sum_count = 0;
    hal.scheduler->resume_timer_procs();

    gyro *= _gyro_scale / num_samples;
    _rotate_and_offset_gyro(_gyro_instance, gyro);

    accel *= MPU6000_ACCEL_SCALE_1G / num_samples;
    _rotate_and_offset_accel(_accel_instance, accel);

    if (_last_filter_hz != _imu.get_filter()) {
        if (_spi_sem->take(10)) {
            _spi->set_bus_speed(AP_HAL::SPIDeviceDriver::SPI_SPEED_LOW);
            _set_filter_register(_imu.get_filter());
            _spi->set_bus_speed(AP_HAL::SPIDeviceDriver::SPI_SPEED_HIGH);
            _spi_sem->give();
        }
    }

    return true;
}
Пример #6
0
bool DummyInterface::readJointStates()
{
	// Save the current ROS time
	ros::Time now = ros::Time::now();

	// Set the feedback positions with some delay and some noise
	std::vector<double> cmds = (m_addDelay() ? m_dataBuf.front() : m_dataBuf.back());
	for(size_t i = 0; i < m_model->numJoints(); ++i)
	{
		const boost::shared_ptr<DummyJoint>& joint = boost::reinterpret_pointer_cast<DummyJoint>(m_model->joint(i));

		double noisyCmd = cmds[i];
		if(m_noiseEnable())
			noisyCmd += (drand48() - 0.5) * m_noiseMagnitude();

		if(joint->velocityMode())
		{
			joint->feedback.pos += noisyCmd * m_model->timerDuration();
			joint->feedback.pos = angles::normalize_angle(joint->feedback.pos);
		}
		else
			joint->feedback.pos = noisyCmd;

		joint->feedback.stamp = now;
	}

	// Calculate the fake orientation of the robot (nominal values taken from RobotModel constructor)
	Eigen::Quaterniond fakeQuat = rot_conv::QuatFromFused(m_fakeAttFusedY(), m_fakeAttFusedX());
	Eigen::Vector3d gyro(m_fakeIMUGyroX(), m_fakeIMUGyroY(), m_fakeIMUGyroZ());
	Eigen::Vector3d acc(m_fakeIMUAccX(), m_fakeIMUAccY(), m_fakeIMUAccZ());
	Eigen::Vector3d mag(m_fakeIMUMagX(), m_fakeIMUMagY(), m_fakeIMUMagZ());

	// Write dummy values into the RobotModel
	m_model->setRobotOrientation(fakeQuat);
	m_model->setAccelerationVector(acc);
	m_model->setMagneticFieldVector(mag);
	m_model->setRobotAngularVelocity(gyro);
	m_model->setTemperature(35.0);

	// Return success
	return true;
}
Пример #7
0
void Application::updateNetwork(){
	struct servo_packet pkt; 
	if(sock.recv(&pkt, sizeof(pkt), 0) == sizeof(pkt)){
		printf("servo: %d %d %d %d\n", pkt.servo[0], pkt.servo[1], pkt.servo[2], pkt.servo[3]); 
		for(unsigned c = 0; c < 8; c++){
			activeQuad->setServo(c, pkt.servo[c]); 
		}
	
	struct state_packet state; 
	memset(&state, 0, sizeof(state)); 

	// create a 3d world to ned frame rotation
	glm::quat r1(sin(glm::radians(90.0 / 2)), 0, 0, cos(glm::radians(90.0 / 2))); 
	glm::quat r2(0, sin(glm::radians(90.0 / 2)), 0, cos(glm::radians(90.0 / 2))); 
	glm::quat r2ef = r1 * r2; 
	
	glm::vec3 gyro(0, 0, 0); 

	if(!paused)
		gyro = activeQuad->getGyro(); 
	
	glm::vec3 accel = -activeQuad->getAccel(); 

	state.gyro[0] = -gyro.z; state.gyro[1] = gyro.x; state.gyro[2] = -gyro.y; 
	state.accel[0] = accel.x; state.accel[1] = accel.y; state.accel[2] = accel.z; 
	//state.accel[0] = (mRCPitch - 1000.0) / 100.0; 
	//state.accel[1] = (mRCRoll - 1000.0) / 100.0; 
	//state.accel[2] = (mRCThrottle - 1000.0) / 100.0; 
	state.rcin[0] = (mRCPitch - 1000.0) / 1000.0; 
	state.rcin[1] = (mRCRoll - 1000.0) / 1000.0; 
	state.rcin[2] = (mRCThrottle - 1000.0) / 1000.0; 
	state.rcin[3] = (mRCYaw - 1000.0) / 1000.0; 
	printf("sending: acc(%f %f %f) gyr(%f %f %f) rc(%f %f %f %f)\n", 
		state.accel[0], state.accel[1], state.accel[2],
		gyro.x, gyro.y, gyro.z,
		state.rcin[0], state.rcin[1], state.rcin[2], state.rcin[3]); 
	sock.sendto(&state, sizeof(state), "127.0.0.1", 9003); 

	}
}
Пример #8
0
void AP_InertialSensor_QURT::accumulate(void) 
{
    const float ACCEL_SCALE_1G = GRAVITY_MSS / 2048.0;
    const float GYRO_SCALE = 0.0174532 / 16.4;

    struct mpu9x50_data data;
    
    while (buf.pop(data)) {
        Vector3f accel(data.accel_raw[0]*ACCEL_SCALE_1G,
                       data.accel_raw[1]*ACCEL_SCALE_1G,
                       data.accel_raw[2]*ACCEL_SCALE_1G);
        Vector3f gyro(data.gyro_raw[0]*GYRO_SCALE,
                      data.gyro_raw[1]*GYRO_SCALE,
                      data.gyro_raw[2]*GYRO_SCALE);

        _rotate_and_correct_accel(accel_instance, accel);
        _rotate_and_correct_gyro(gyro_instance, gyro);
    
        _notify_new_gyro_raw_sample(gyro_instance, gyro, data.timestamp);
        _notify_new_accel_raw_sample(accel_instance, accel, data.timestamp);
    }
}
Пример #9
0
static void sensors_debug() {
    static int divider = 0;
    if (divider++ == 20) {
        divider = 0;
        float heading = g_compass.calculate_heading(g_ahrs.get_dcm_matrix());

        hal.console->printf("ahrs: roll %4.1f pitch %4.1f "
                            "yaw %4.1f hdg %.1f\r\n",
                            ToDeg(g_ahrs.roll), ToDeg(g_ahrs.pitch),
                            ToDeg(g_ahrs.yaw),
                            g_compass.use_for_yaw() ? ToDeg(heading):0.0f);

        Vector3f accel(g_ins.get_accel());
        Vector3f gyro(g_ins.get_gyro());
        hal.console->printf("mpu6000: accel %.2f %.2f %.2f "
                            "gyro %.2f %.2f %.2f\r\n",
                            accel.x, accel.y, accel.z,
                            gyro.x, gyro.y, gyro.z);

        hal.console->printf("compass: heading %.2f deg\r\n",
                            ToDeg(g_compass.calculate_heading(0, 0)));
    }
}
Пример #10
0
int main(int argc, char* argv[])
{
	signal(SIGINT, sigproc);
#ifndef WIN32
	signal(SIGQUIT, sigproc);
#endif

	bool noHelmet = false;
	if((argc > 1) && (argv[1] == std::string("-n"))) noHelmet = true;

    UdpTransmitSocket transmitSocket( IpEndpointName( ADDRESS, PORT ) );
    
    char buffer[OUTPUT_BUFFER_SIZE];
	
	emokit_device* d;
	
	d = emokit_create();
	printf("Current epoc devices connected: %d\n", emokit_get_count(d, EMOKIT_VID, EMOKIT_PID));
	if(emokit_open(d, EMOKIT_VID, EMOKIT_PID, 0) != 0 && !noHelmet)
	{
		printf("CANNOT CONNECT\n");
		return 1;
	} else if(noHelmet) {
		std::cout << "Sending random data" << std::endl;
	}
	
	if (!noHelmet) {
		while(true)
		{
			if(emokit_read_data(d) > 0)
			{
				emokit_get_next_frame(d);
				struct emokit_frame frame = d->current_frame;
				
				std::cout << "\r\33[2K" << "gyroX: " << (int)frame.gyroX
					<< "; gyroY: " << (int)frame.gyroY
					<< "; F3: " << frame.F3
					<< "; FC6: " << frame.FC6
					<< "; battery: " << (int)d->battery << "%";
				
				flush(std::cout);
				
				osc::OutboundPacketStream channels( buffer, OUTPUT_BUFFER_SIZE );
				osc::OutboundPacketStream gyro( buffer, OUTPUT_BUFFER_SIZE );
				osc::OutboundPacketStream info( buffer, OUTPUT_BUFFER_SIZE );
				
				channels << osc::BeginMessage( "/emokit/channels" )
					<< frame.F3 << frame.FC6 << frame.P7 << frame.T8 << frame.F7 << frame.F8 << frame.T7 << frame.P8 << frame.AF4 << frame.F4 << frame.AF3 << frame.O2 << frame.O1 << frame.FC5 << osc::EndMessage;
				transmitSocket.Send( channels.Data(), channels.Size() );
				
				gyro << osc::BeginMessage( "/emokit/gyro" ) 
					<< (int)frame.gyroX << (int)frame.gyroY << osc::EndMessage;
				transmitSocket.Send( gyro.Data(), gyro.Size() );
				
				info << osc::BeginMessage( "/emokit/info" )
					<< (int)d->battery;
					for (int i = 0; i<14 ; i++) info << (int)d->contact_quality[i];
					info << osc::EndMessage;
				transmitSocket.Send( info.Data(), info.Size() );
			}
		}
	} else {
		while (true) {
			usleep(FREQ);
			
			osc::OutboundPacketStream channels( buffer, OUTPUT_BUFFER_SIZE );
			osc::OutboundPacketStream gyro( buffer, OUTPUT_BUFFER_SIZE );
			osc::OutboundPacketStream info( buffer, OUTPUT_BUFFER_SIZE );
			
			channels << osc::BeginMessage( "/emokit/channels" );
			for (int i=0 ; i < 14 ; i++) channels << rand() % 10000;
			channels << osc::EndMessage;
			transmitSocket.Send( channels.Data(), channels.Size() );
			
			gyro << osc::BeginMessage( "/emokit/gyro" ) 
				<< rand() % 100 << rand() % 100 << osc::EndMessage;
			transmitSocket.Send( gyro.Data(), gyro.Size() );
			
			info << osc::BeginMessage( "/emokit/info" )
				<< rand() % 100;
				for (int i = 0; i<14 ; i++) info << rand() % 50;
				info << osc::EndMessage;
			transmitSocket.Send( info.Data(), info.Size() );
		}
	}

	emokit_close(d);
	emokit_delete(d);
	return 0;

}
void main_task(void *args)
{
  vTaskSetApplicationTaskTag(xTaskGetIdleTaskHandle(), (pdTASK_HOOK_CODE)1);
  vTaskSetApplicationTaskTag(NULL, (pdTASK_HOOK_CODE)2);

  led_init();

  hal.init(0, NULL);
  hal.console->printf("AP_HAL Sensor Test\r\n");
  hal.scheduler->register_timer_failsafe(failsafe, 1000);

  hal.console->printf("init AP_InertialSensor: ");
  g_ins.init(AP_InertialSensor::COLD_START, INS_SAMPLE_RATE, flash_leds);
  g_ins.init_accel(flash_leds);
  hal.console->println();
  led_set(0, false);
  hal.console->printf("done\r\n");

  hal.console->printf("init AP_Compass: "******"done\r\n");

  hal.console->printf("init AP_Baro: ");
  g_baro.init();
  g_baro.calibrate();
  hal.console->printf("done\r\n");

  hal.console->printf("init AP_AHRS: ");
  g_ahrs.init();
  g_ahrs.set_compass(&g_compass);
  g_ahrs.set_barometer(&g_baro);
  hal.console->printf("done\r\n");

  portTickType last_print = 0;
  portTickType last_compass = 0;
  portTickType last_wake = 0;
  float heading = 0.0f;

  last_wake = xTaskGetTickCount();

  for (;;) {
    // Delay to run this loop at 100Hz.
    vTaskDelayUntil(&last_wake, 10);

    portTickType now = xTaskGetTickCount();

    if (last_compass == 0 || now - last_compass > 100) {
      last_compass = now;
      g_compass.read();
      g_baro.read();
      heading = g_compass.calculate_heading(g_ahrs.get_dcm_matrix());
    }

    g_ahrs.update();

    if (last_print == 0 || now - last_print > 100) {
      last_print = now;

      hal.console->write("\r\n");
      hal.console->printf("ahrs:    roll %4.1f  pitch %4.1f  yaw %4.1f hdg %.1f\r\n",
                          ToDeg(g_ahrs.roll), ToDeg(g_ahrs.pitch),
                          ToDeg(g_ahrs.yaw),
                          g_compass.use_for_yaw() ? ToDeg(heading) : 0.0f);

      Vector3f accel(g_ins.get_accel());
      Vector3f gyro(g_ins.get_gyro());
      hal.console->printf("mpu6000: accel %.2f %.2f %.2f  "
                          "gyro %.2f %.2f %.2f\r\n",
                          accel.x, accel.y, accel.z,
                          gyro.x, gyro.y, gyro.z);

      hal.console->printf("compass: heading %.2f deg\r\n",
                          ToDeg(g_compass.calculate_heading(0, 0)));
      g_compass.null_offsets();

      if (hal.rcin->valid()) {
        uint16_t ppm[PPM_MAX_CHANNELS];
        size_t count;

        count = hal.rcin->read(ppm, PPM_MAX_CHANNELS);

        hal.console->write("ppm:     ");
        for (size_t i = 0; i < count; ++i)
          hal.console->printf("%u ", ppm[i]);
        hal.console->write("\r\n");
      }
    }
  }
}
int main(int argc, char **argv)
{
  Aria::init();
  ArRobot robot;
  ArServerBase server;

  ArArgumentParser parser(&argc, argv);
  ArSimpleConnector simpleConnector(&parser);
  ArServerSimpleOpener simpleOpener(&parser);


  // parse the command line... fail and print the help if the parsing fails
  // or if help was requested
  parser.loadDefaultArguments();
  if (!simpleConnector.parseArgs() || !simpleOpener.parseArgs() || 
      !parser.checkHelpAndWarnUnparsed())
  {    
    simpleConnector.logOptions();
    simpleOpener.logOptions();
    exit(1);
  }

  // Set up where we'll look for files such as config file, user/password file,
  // etc.
  char fileDir[1024];
  ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(), 
			 "ArNetworking/examples");

  // first open the server up
  if (!simpleOpener.open(&server, fileDir, 240))
  {
    if (simpleOpener.wasUserFileBad())
      printf("Error: Bad user/password/permissions file.\n");
    else
      printf("Error: Could not open server port. Use -help to see options.\n");
    exit(1);
  }


  // Devices
  ArAnalogGyro gyro(&robot);

  ArSonarDevice sonarDev;
  robot.addRangeDevice(&sonarDev);

  ArIRs irs;
  robot.addRangeDevice(&irs);

  ArBumpers bumpers;
  robot.addRangeDevice(&bumpers);

  ArSick sick(361, 180);
  robot.addRangeDevice(&sick);  
  

  ArServerInfoRobot serverInfoRobot(&server, &robot);
  ArServerInfoSensor serverInfoSensor(&server, &robot);

  // This is the service that provides drawing data to the client.
  ArServerInfoDrawings drawings(&server);

  // Convenience function that sets up drawings for all the robot's current
  // range devices (using default shape and color info)
  drawings.addRobotsRangeDevices(&robot);

  // Add our custom drawings
  drawings.addDrawing(
      //                shape:      color:               size:   layer:
      new ArDrawingData("polyLine", ArColor(255, 0, 0),  2,      49),
      "exampleDrawing_Home", 
      new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleHomeDrawingNetCallback)
  );
  drawings.addDrawing(                                    
      new ArDrawingData("polyDots", ArColor(0, 255, 0), 250, 48),
      "exampleDrawing_Dots", 
      new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleDotsDrawingNetCallback)
  );
  drawings.addDrawing(
      new ArDrawingData("polySegments", ArColor(0, 0, 0), 4, 52),
      "exampleDrawing_XMarksTheSpot", 
      new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleXDrawingNetCallback)
  );
  drawings.addDrawing(
      new ArDrawingData("polyArrows", ArColor(255, 0, 255), 500, 100),
      "exampleDrawing_Arrows", 
      new ArGlobalFunctor2<ArServerClient*, ArNetPacket*>(&exampleArrowsDrawingNetCallback)
  );

  // modes for moving the robot
  ArServerModeStop modeStop(&server, &robot);
  ArServerModeDrive modeDrive(&server, &robot);
  ArServerModeRatioDrive modeRatioDrive(&server, &robot);
  ArServerModeWander modeWander(&server, &robot);
  modeStop.addAsDefaultMode();
  modeStop.activate();

  

  // Connect to the robot.
  if (!simpleConnector.connectRobot(&robot))
  {
    printf("Error: Could not connect to robot... exiting\n");
    Aria::shutdown();
    return 1;
  }

  // set up the laser before handing it to the laser mode
  simpleConnector.setupLaser(&sick);

  robot.enableMotors();

  // start the robot cycle running in a background thread
  robot.runAsync(true);

  // start the laser processing cycle in a background thread
  sick.runAsync();

  // connect the laser if it was requested
  if (!simpleConnector.connectLaser(&sick))
  {
    printf("Error: Could not connect to laser... exiting\n");
    Aria::shutdown();
    return 1;
  }

  // log whatever we wanted to before the runAsync
  simpleOpener.checkAndLog();

  // run the server thread in the background
  server.runAsync();

  printf("Server is now running...\n");


  // Add a key handler mostly that windows can exit by pressing
  // escape, note that the key handler prevents you from running this program
  // in the background on Linux.
  ArKeyHandler *keyHandler;
  if ((keyHandler = Aria::getKeyHandler()) == NULL)
  {
    keyHandler = new ArKeyHandler;
    Aria::setKeyHandler(keyHandler);
    robot.lock();
    robot.attachKeyHandler(keyHandler);
    robot.unlock();
    printf("To exit, press escape.\n");
  }

  robot.waitForRunExit();
 

  Aria::shutdown();
  exit(0);  
}
int __cdecl _tmain (int argc, char** argv)
{

	//------------ I N I C I O   M A I N    D E L   P R O G R A M A   D E L    R O B O T-----------//

	  //inicializaion de variables
	  Aria::init();
	  ArArgumentParser parser(&argc, argv);
	  parser.loadDefaultArguments();
	  ArSimpleConnector simpleConnector(&parser);
	  ArRobot robot;
	  ArSonarDevice sonar;
	  ArAnalogGyro gyro(&robot);
	  robot.addRangeDevice(&sonar);
	  ActionGos go(500, 350);	  
	  robot.addAction(&go, 48);
	  ActionTurns turn(400, 110);
	  robot.addAction(&turn, 49);
	  ActionTurns turn2(400, 110);
	  robot.addAction(&turn2, 49);

	  // presionar tecla escape para salir del programa
	  ArKeyHandler keyHandler;
	  Aria::setKeyHandler(&keyHandler);
	  robot.attachKeyHandler(&keyHandler);
	  printf("Presionar ESC para salir\n");

	  // uso de sonares para evitar colisiones con las paredes u 
	  // obstaculos grandes, mayores a 8cm de alto
	  ArActionLimiterForwards limiterAction("limitador velocidad cerca", 300, 600, 250);
	  ArActionLimiterForwards limiterFarAction("limitador velocidad lejos", 300, 1100, 400);
	  ArActionLimiterTableSensor tableLimiterAction;
	  robot.addAction(&tableLimiterAction, 100);
	  robot.addAction(&limiterAction, 95);
	  robot.addAction(&limiterFarAction, 90);


	  // Inicializon la funcion de goto
	  ArActionGoto gotoPoseAction("goto");
	  robot.addAction(&gotoPoseAction, 50);
	  
	  // Finaliza el goto si es que no hace nada
	  ArActionStop stopAction("stop");
	  robot.addAction(&stopAction, 40);

	  // Parser del CLI
	  if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
	  {    
		Aria::logOptions();
		exit(1);
	  }
	  
	  // Conexion del robot
	  if (!simpleConnector.connectRobot(&robot))
	  {
		printf("Could not connect to robot... exiting\n");
		Aria::exit(1);
	  }
	  robot.runAsync(true);

	  // enciende motores, apaga sonidos
	  robot.enableMotors();
	  robot.comInt(ArCommands::SOUNDTOG, 0);

	  // Imprimo algunos datos del robot como posicion velocidad y bateria
		robot.lock();
		ArLog::log(ArLog::Normal, "Posicion=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Bateria=%.2fV",
			robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getBatteryVoltage());
		robot.unlock();

	  const int duration = 100000; //msec
	  ArLog::log(ArLog::Normal, "Completados los puntos en %d segundos", duration/1000);

	  // ============================ INICIO CONFIG COM =================================//
	    CSerial serial;
		LONG    lLastError = ERROR_SUCCESS;

		// Trata de abrir el com seleccionado
		lLastError = serial.Open(_T("COM3"),0,0,false);
		if (lLastError != ERROR_SUCCESS)
			return ::ShowError(serial.GetLastError(), _T("Imposible abrir el COM"));

		// Inicia el puerto serial (9600,8N1)
		lLastError = serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
		if (lLastError != ERROR_SUCCESS)
			return ::ShowError(serial.GetLastError(), _T("Imposible setear la config del COM"));

		// Register only for the receive event
		lLastError = serial.SetMask(CSerial::EEventBreak |
									CSerial::EEventCTS   |
									CSerial::EEventDSR   |
									CSerial::EEventError |
									CSerial::EEventRing  |
									CSerial::EEventRLSD  |
									CSerial::EEventRecv);
		if (lLastError != ERROR_SUCCESS)
			return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port event mask"));

		// Use 'non-blocking' reads, because we don't know how many bytes
		// will be received. This is normally the most convenient mode
		// (and also the default mode for reading data).
		lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);
		if (lLastError != ERROR_SUCCESS)
			return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port read timeout."));
		// ============================ FIN CONFIG COM =================================//

	  bool first = true;
	  int goalNum = 0;
	  int color = 3;
	  ArTime start;
	  start.setToNow();
	  while (Aria::getRunning()) 
	  {
		robot.lock();

		// inicia el primer punto 
		if (first || gotoPoseAction.haveAchievedGoal())
		{
		  first = false;
		  
		  goalNum++; //cambia de 0 a 1 el contador
		  printf("El contador esta en: --> %d <---\n",goalNum);
		  if (goalNum > 20)
			goalNum = 1;

		  //comienza la secuencia de puntos
		  if (goalNum == 1)
		  {
			gotoPoseAction.setGoal(ArPose(1150, 0));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			// Imprimo algunos datos del robot como posicion velocidad y bateria
			robot.lock();
			ArLog::log(ArLog::Normal, "Posicion=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Bateria=%.2fV",
				robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getBatteryVoltage());
			robot.unlock();
			// Create the sound queue.
			ArSoundsQueue soundQueue;
			// Run the sound queue in a new thread
			soundQueue.runAsync();
			std::vector<const char*> filenames;
			filenames.push_back("sound-r2a.wav");
			soundQueue.play(filenames[0]);
		  }
		  else if (goalNum == 2)
		  {
			  printf("Gira 90 grados izquierda\n");
			  robot.unlock();
			  turn.myActivate = 1;
			  turn.myDirection = 1;
			  turn.activate();
			  ArUtil::sleep(1000);
			  turn.deactivate();
			  turn.myActivate = 0;
			  turn.myDirection = 0;
			  robot.lock();
		  }
		  else if (goalNum == 3)
		  {
			gotoPoseAction.setGoal(ArPose(1150, 2670));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			// Imprimo algunos datos del robot como posicion velocidad y bateria
			robot.lock();
			ArLog::log(ArLog::Normal, "Posicion=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Bateria=%.2fV",
				robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getBatteryVoltage());
			robot.unlock();
		  }
		  else if (goalNum == 4)
		  {
			  printf("Gira 90 grados izquierda\n");
			  robot.unlock();
			  turn2.myActivate = 1;
			  turn2.myDirection = 1;
			  turn2.activate();
			  ArUtil::sleep(1000);
			  turn2.deactivate();
			  turn2.myActivate = 0;
			  turn2.myDirection = 0;
			  robot.lock();
		  }
		  else if (goalNum == 5)
		  {
			gotoPoseAction.setGoal(ArPose(650, 2670));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
		  }
		  else if (goalNum == 6)
		  {
			  printf("Gira 90 grados izquierda\n");
			  robot.unlock();
			  turn2.myActivate = 1;
			  turn2.myDirection = 1;
			  turn2.activate();
			  ArUtil::sleep(1000);
			  turn2.deactivate();
			  turn2.myActivate = 0;
			  turn2.myDirection = 0;
			  robot.lock();
		  }
		  else if (goalNum == 7)
		  {
			gotoPoseAction.setGoal(ArPose(650, 0));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
		  }
		  else if (goalNum == 8)
		  {
			gotoPoseAction.setGoal(ArPose(1800,1199));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
		  }
		  else if (goalNum == 9)
		  {
			gotoPoseAction.setGoal(ArPose(2600, 1199));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
		  }
		  else if (goalNum == 10)
		  {
			  if (color == 1)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 850));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
			  if (color == 2)
			  {
				gotoPoseAction.setGoal(ArPose(3500, 1199));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY()); 
			  }
			  if (color == 3)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 1550));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
		  }
		  else if (goalNum == 11)
		  {
			  if (color == 1)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 613));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
			  if (color == 2)
			  {
				  printf("Gira 180 grados derecha\n");
				  robot.unlock();
				  turn2.myActivate = 1;
				  turn2.myDirection = 2;
				  turn2.activate();
				  ArUtil::sleep(2000);
				  turn2.deactivate();
				  turn2.myActivate = 0;
				  turn2.myDirection = 0;
				  robot.lock();
				  goalNum = 19;
			  }
			  if (color == 3)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 1785));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
		  }
		  else if (goalNum == 12)
		  {
			  if (color == 1)
			  {
				gotoPoseAction.setGoal(ArPose(3300, 413));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
			  if (color == 3)
			  {
				gotoPoseAction.setGoal(ArPose(3300, 1985));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
		  }
		  else if (goalNum == 13)
		  {
			  if (color == 1)
			  {
				gotoPoseAction.setGoal(ArPose(3500, 413));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
			  if (color == 3)
			  {
				gotoPoseAction.setGoal(ArPose(3500, 1985));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
		  }
		  else if (goalNum == 14)
		  {
			  robot.unlock();
			  //Valor para el while
			  bool fContinue = true;
				// <<<<<<------------- 1 Parte Secuencia: BAJA BRAZO ------------->>>>>> //
				lLastError = serial.Write("b");
				if (lLastError != ERROR_SUCCESS)
					return ::ShowError(serial.GetLastError(), _T("Unable to send data"));

				//-------------------------E S C U C H A   C O M ----------------------------//
				do
				{
					// Wait for an event
					lLastError = serial.WaitEvent();
					if (lLastError != ERROR_SUCCESS)
						return ::ShowError(serial.GetLastError(), _T("Unable to wait for a COM-port event."));

					// Save event
					const CSerial::EEvent eEvent = serial.GetEventType();

					// Handle break event
					if (eEvent & CSerial::EEventBreak)
					{
						printf("\n### BREAK received ###\n");
					}

					// Handle CTS event
					if (eEvent & CSerial::EEventCTS)
					{
						printf("\n### Clear to send %s ###\n", serial.GetCTS()?"on":"off");
					}

					// Handle DSR event
					if (eEvent & CSerial::EEventDSR)
					{
						printf("\n### Data set ready %s ###\n", serial.GetDSR()?"on":"off");
					}

					// Handle error event
					if (eEvent & CSerial::EEventError)
					{
						printf("\n### ERROR: ");
						switch (serial.GetError())
						{
						case CSerial::EErrorBreak:		printf("Break condition");			break;
						case CSerial::EErrorFrame:		printf("Framing error");			break;
						case CSerial::EErrorIOE:		printf("IO device error");			break;
						case CSerial::EErrorMode:		printf("Unsupported mode");			break;
						case CSerial::EErrorOverrun:	printf("Buffer overrun");			break;
						case CSerial::EErrorRxOver:		printf("Input buffer overflow");	break;
						case CSerial::EErrorParity:		printf("Input parity error");		break;
						case CSerial::EErrorTxFull:		printf("Output buffer full");		break;
						default:						printf("Unknown");					break;
						}
						printf(" ###\n");
					}

					// Handle ring event
					if (eEvent & CSerial::EEventRing)
					{
						printf("\n### RING ###\n");
					}

					// Handle RLSD/CD event
					if (eEvent & CSerial::EEventRLSD)
					{
						printf("\n### RLSD/CD %s ###\n", serial.GetRLSD()?"on":"off");
					}

					// Handle data receive event
					if (eEvent & CSerial::EEventRecv)
					{
						// Read data, until there is nothing left
						DWORD dwBytesRead = 0;
						char szBuffer[101];
						do
						{
							// Lee datos del Puerto COM
							lLastError = serial.Read(szBuffer,sizeof(szBuffer)-1,&dwBytesRead);
							if (lLastError != ERROR_SUCCESS)
								return ::ShowError(serial.GetLastError(), _T("Unable to read from COM-port."));

							if (dwBytesRead > 0)
							{
								//Preseteo color
								int color = 0;
								// Finaliza el dato, asi que sea una string valida
								szBuffer[dwBytesRead] = '\0';
								// Display the data
								printf("%s", szBuffer);

								// <<<<<<----------- 2 Parte Secuencia: CIERRA GRIPPER ----------->>>>>> //
								if (strchr(szBuffer,76))
								{
									lLastError = serial.Write("c");
									if (lLastError != ERROR_SUCCESS)
										return ::ShowError(serial.GetLastError(), _T("Unable to send data"));
								}
								
								// <<<<<<------------- 3 Parte Secuencia: SUBE BRAZO ------------->>>>>> //
								if (strchr(szBuffer,117))
								{
									lLastError = serial.Write("s");
									if (lLastError != ERROR_SUCCESS)
										return ::ShowError(serial.GetLastError(), _T("Unable to send data"));
								}

								// <<<<<<------------- 4 Parte Secuencia: COLOR ------------->>>>>> //
								if (strchr(szBuffer,72))
								{
									lLastError = serial.Write("C");
									if (lLastError != ERROR_SUCCESS)
										return ::ShowError(serial.GetLastError(), _T("Unable to send data"));
								}

								// <<<<<<---------- 5.1 Parte Secuencia: COLOR ROJO---------->>>>>> //
								if (strchr(szBuffer,82))
								{
									color = 1;
									//salir del bucle
									fContinue = false;
								}

								// <<<<<<---------- 5.2 Parte Secuencia: COLOR AZUL ---------->>>>>> //
								if (strchr(szBuffer,66))
								{
									color = 2;
									//salir del bucle
									fContinue = false;
								}

								// <<<<<<---------- 5.3 Parte Secuencia: COLOR VERDE ---------->>>>>> //
								if (strchr(szBuffer,71))
								{
									color = 3;
									//salir del bucle
									fContinue = false;
								}
							}
						}
						while (dwBytesRead == sizeof(szBuffer)-1);
					}
				}
				while (fContinue);
				// Close the port again
				serial.Close();
				robot.lock();
		  }
		  else if (goalNum == 15)
		  {
			  printf("Gira 180 grados derecha\n");
			  robot.unlock();
			  turn2.myActivate = 1;
			  turn2.myDirection = 2;
			  turn2.activate();
			  ArUtil::sleep(2000);
			  turn2.deactivate();
			  turn2.myActivate = 0;
			  turn2.myDirection = 0;
			  robot.lock();
		  }
		  else if (goalNum == 16)
		  {
			  if (color == 1)
			  {
				gotoPoseAction.setGoal(ArPose(3300, 413));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
			  if (color == 3)
			  {
				gotoPoseAction.setGoal(ArPose(3300, 1985));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
		  }
		  else if (goalNum == 17)
		  {
			  if (color == 1)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 603));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
			  if (color == 3)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 1795));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
		  }
		  else if (goalNum == 18)
		  {
			  if (color == 1)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 860));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
			  if (color == 3)
			  {
				gotoPoseAction.setGoal(ArPose(2800, 1540));
				ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
				gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
			  }
		  }
		  else if (goalNum == 19)
		  {
			gotoPoseAction.setGoal(ArPose(2600, 1199));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
		  }
		  else if (goalNum == 20)
		  {
			gotoPoseAction.setGoal(ArPose(1800, 1199));
			ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f", 
			gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
		  }
		}

		if(start.mSecSince() >= duration) {
		  ArLog::log(ArLog::Normal, "No puede llegar al punto, y la aplicacion saldra en %d", duration/1000);
		  gotoPoseAction.cancelGoal();
		  robot.unlock();
		  ArUtil::sleep(3000);
		  break;
		}
	    
		robot.unlock();
		ArUtil::sleep(10);
	  }

	  // Robot desconectado al terminal el sleep
	  Aria::shutdown();

	//------------ F I N   M A I N    D E L   P R O G R A M A   D E L    R O B O T-----------//
    
    return 0;
}
Пример #14
0
void main_task(void *pvParameters)
{
	(void) pvParameters;

	vTaskDelay(500 / portTICK_RATE_MS);

	SPIMaster spi5(SPI5, SPI_BAUDRATEPRESCALER_32, 0x2000, {
				{MEMS_SPI_SCK_PIN,  GPIO_MODE_AF_PP, GPIO_PULLDOWN, GPIO_SPEED_MEDIUM, GPIO_AF5_SPI5},
				{MEMS_SPI_MISO_PIN, GPIO_MODE_AF_PP, GPIO_PULLDOWN, GPIO_SPEED_MEDIUM, GPIO_AF5_SPI5},
				{MEMS_SPI_MOSI_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL,   GPIO_SPEED_MEDIUM, GPIO_AF5_SPI5},
			}, {
				{GYRO_CS_PIN,  GPIO_MODE_OUTPUT_PP, GPIO_PULLUP, GPIO_SPEED_MEDIUM, 0},
				{ACCEL_CS_PIN, GPIO_MODE_OUTPUT_PP, GPIO_PULLUP, GPIO_SPEED_MEDIUM, 0},
			});

	SPIMaster spi2(SPI2, SPI_BAUDRATEPRESCALER_32, 0x2000, {
					{EXT_MEMS_SPI_SCK_PIN,  GPIO_MODE_AF_PP, GPIO_PULLDOWN, GPIO_SPEED_MEDIUM, GPIO_AF5_SPI2},
					{EXT_MEMS_SPI_MISO_PIN, GPIO_MODE_AF_PP, GPIO_PULLDOWN, GPIO_SPEED_MEDIUM, GPIO_AF5_SPI2},
					{EXT_MEMS_SPI_MOSI_PIN, GPIO_MODE_AF_PP, GPIO_NOPULL,   GPIO_SPEED_MEDIUM, GPIO_AF5_SPI2},
				}, {
					{EXT_GYRO_CS_PIN,  GPIO_MODE_OUTPUT_PP, GPIO_PULLUP, GPIO_SPEED_MEDIUM, 0},
					{LPS25HB_PRESSURE_CS_PIN,  GPIO_MODE_OUTPUT_PP, GPIO_PULLUP, GPIO_SPEED_MEDIUM, 0},
					{BMP280_PRESSURE_CS_PIN,  GPIO_MODE_OUTPUT_PP, GPIO_PULLUP, GPIO_SPEED_MEDIUM, 0},
				});

	L3GD20 gyro(spi5, 0);
	LPS25HB lps25hb(spi2, 1);
	BMP280 bmp2(spi2, 2);
	LSM303D accel(spi5, 1);
	uint8_t gyro_wtm = 5;
	uint8_t acc_wtm = 8;
	TimeStamp console_update_time;
	TimeStamp sample_dt;
	TimeStamp led_toggle_ts;
	FlightControl flight_ctl;
	static bool print_to_console = false;
	LowPassFilter<Vector3f, float> gyro_lpf({0.5});
	LowPassFilter<Vector3f, float> acc_lpf_alt({0.9});
	LowPassFilter<Vector3f, float> acc_lpf_att({0.990});
	LowPassFilter<float, float> pressure_lpf({0.6});
	attitudetracker att;

	/*
	 * Apply the boot configuration from flash memory.
	 */
	dronestate_boot_config(*drone_state);

	L3GD20Reader gyro_reader(gyro, GYRO_INT2_PIN, gyro_align);
	LSM303Reader acc_reader(accel, ACC_INT2_PIN, acc_align);

	UartRpcServer rpcserver(*drone_state, configdata, acc_reader.mag_calibrator_);

	bmp2.set_oversamp_pressure(BMP280_OVERSAMP_16X);
	bmp2.set_work_mode(BMP280_ULTRA_HIGH_RESOLUTION_MODE);
	bmp2.set_filter(BMP280_FILTER_COEFF_OFF);

	Bmp280Reader bmp_reader(bmp2);

	HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 1, 1);
	HAL_NVIC_EnableIRQ (DMA1_Stream6_IRQn);
	HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 1, 0);
	HAL_NVIC_EnableIRQ (DMA1_Stream5_IRQn);

#ifndef ENABLE_UART_TASK
	uart2.uart_dmarx_start();
#endif

	printf("Priority Group: %lu\n", NVIC_GetPriorityGrouping());
	printf("SysTick_IRQn priority: %lu\n", NVIC_GetPriority(SysTick_IRQn) << __NVIC_PRIO_BITS);
	printf("configKERNEL_INTERRUPT_PRIORITY: %d\n", configKERNEL_INTERRUPT_PRIORITY);
	printf("configMAX_SYSCALL_INTERRUPT_PRIORITY: %d\n", configMAX_SYSCALL_INTERRUPT_PRIORITY);
	printf("LPS25HB Device id: %d\n", lps25hb.Get_DeviceID());
	vTaskDelay(500 / portTICK_RATE_MS);

	gyro_reader.init(gyro_wtm);
	gyro_reader.enable_int2(false);

	vTaskDelay(500 / portTICK_RATE_MS);

	acc_reader.init(acc_wtm);
	acc_reader.enable_int2(false);
	acc_reader.mag_calibrator_.set_bias(drone_state->mag_bias_);
	acc_reader.mag_calibrator_.set_scale_factor(drone_state->mag_scale_factor_);
	vTaskDelay(500 / portTICK_RATE_MS);

	printf("Calibrating...");

	gyro_reader.enable_int2(true);
	gyro_reader.calculate_static_bias_filtered(2400);
	printf(" Done!\n");
	flight_ctl.start_receiver();

	printf("Entering main loop...\n");
	gyro_reader.enable_int2(true);

	sample_dt.time_stamp();
	lps25hb.Set_FifoMode(LPS25HB_FIFO_STREAM_MODE);
	lps25hb.Set_FifoModeUse(LPS25HB_ENABLE);
	lps25hb.Set_Odr(LPS25HB_ODR_25HZ);
	lps25hb.Set_Bdu(LPS25HB_BDU_NO_UPDATE);
	LPS25HB_FIFOTypeDef_st fifo_config;
	memset(&fifo_config, 0, sizeof(fifo_config));
	lps25hb.Get_FifoConfig(&fifo_config);

#ifdef USE_LPS25HB
	float base_pressure = lps25hb.Get_PressureHpa();
	for (int i = 0; i < 100; i++) {
		while (lps25hb.Get_FifoStatus().FIFO_EMPTY)
			vTaskDelay(50 / portTICK_RATE_MS);
		base_pressure = pressure_lpf.do_filter(lps25hb.Get_PressureHpa());
	}
#endif

	bmp_reader.calibrate();

	// Infinite loop
	PerfCounter idle_time;
	while (1) {
		drone_state->iteration_++;
		if (drone_state->iteration_ % 120 == 0) {
			led1.toggle();
		}


		if (drone_state->iteration_ % 4 == 0) {
#ifdef USE_LPS25HB
			drone_state->temperature_ = lps25hb.Get_TemperatureCelsius();
			while (!lps25hb.Get_FifoStatus().FIFO_EMPTY) {
				drone_state->pressure_hpa_ = pressure_lpf.do_filter(lps25hb.Get_PressureHpa());
				float alt = (powf(base_pressure/drone_state->pressure_hpa_, 0.1902f) - 1.0f) * ((lps25hb.Get_TemperatureCelsius()) + 273.15f)/0.0065;
				drone_state->altitude_ = Distance::from_meters(alt);
			}
#else
			bmp_reader.pressure_filter_.set_alpha(drone_state->altitude_lpf_);
			drone_state->altitude_ = bmp_reader.get_altitude(true);
			drone_state->pressure_hpa_ = bmp_reader.get_pressure().hpa();
			drone_state->temperature_ = bmp_reader.get_temperature(false).celsius();
#endif
		}

		idle_time.begin_measure();
		gyro_reader.wait_for_data();
		idle_time.end_measure();
		drone_state->dt_ = sample_dt.elapsed();
		sample_dt.time_stamp();

		if (drone_state->base_throttle_ > 0.1)
			att.accelerometer_correction_speed(drone_state->accelerometer_correction_speed_);
		else
			att.accelerometer_correction_speed(3.0f);
		att.gyro_drift_pid(drone_state->gyro_drift_kp_, drone_state->gyro_drift_ki_, drone_state->gyro_drift_kd_);
		att.gyro_drift_leak_rate(drone_state->gyro_drift_leak_rate_);

		size_t fifosize = gyro_reader.size();
		for (size_t i = 0; i < fifosize; i++)
			   drone_state->gyro_raw_ = gyro_lpf.do_filter(gyro_reader.read_sample());
		if (drone_state->gyro_raw_.length_squared() > 0 && drone_state->dt_.microseconds() > 0) {
			   drone_state->gyro_ = (drone_state->gyro_raw_ - gyro_reader.bias()) * drone_state->gyro_factor_;
			   att.track_gyroscope(DEG2RAD(drone_state->gyro_) * 1.0f, drone_state->dt_.seconds_float());
		}

		fifosize = acc_reader.size();
		for (size_t i = 0; i < fifosize; i++) {
			Vector3f acc_sample = acc_reader.read_sample_acc();
			acc_lpf_att.do_filter(acc_sample);
			acc_lpf_alt.do_filter(acc_sample);
		}
		drone_state->accel_raw_ = acc_lpf_att.output();
		drone_state->accel_alt_ = acc_lpf_alt.output();
		drone_state->accel_ = (drone_state->accel_raw_ - drone_state->accelerometer_adjustment_).normalize();

#define ALLOW_ACCELEROMETER_OFF
#ifdef ALLOW_ACCELEROMETER_OFF
		if (drone_state->track_accelerometer_) {
			att.track_accelerometer(drone_state->accel_, drone_state->dt_.seconds_float());
		}
#else
		att.track_accelerometer(drone_state->accel_, drone_state->dt_.seconds_float());
#endif

#define REALTIME_DATA 0
#if REALTIME_DATA
		std::cout << drone_state->gyro_.transpose() << drone_state->accel_.transpose() << drone_state->pid_torque_.transpose();
		std::cout << drone_state->dt_.seconds_float() << std::endl;
#endif

		drone_state->mag_raw_ = acc_reader.read_sample_mag();
		drone_state->mag_ = drone_state->mag_raw_.normalize();
		if (drone_state->track_magnetometer_) {
			att.track_magnetometer(drone_state->mag_, drone_state->dt_.seconds_float());
		}

		drone_state->attitude_ = att.get_attitude();
		drone_state->gyro_drift_error_ = RAD2DEG(att.get_drift_error());

		flight_ctl.update_state(*drone_state);
		flight_ctl.send_throttle_to_motors();

		if (print_to_console && console_update_time.elapsed() > TimeSpan::from_milliseconds(300)) {

			Vector3f drift_err = att.get_drift_error();
			console_update_time.time_stamp();
			printf("Gyro      : %5.3f %5.3f %5.3f\n", drone_state->gyro_.at(0), drone_state->gyro_.at(1), drone_state->gyro_.at(2));
			printf("Drift Err : %5.3f %5.3f %5.3f\n", RAD2DEG(drift_err.at(0)), RAD2DEG(drift_err.at(1)), RAD2DEG(drift_err.at(2)));
			printf("Gyro Raw  : %5.3f %5.3f %5.3f\n", drone_state->gyro_raw_.at(0), drone_state->gyro_raw_.at(1), drone_state->gyro_raw_.at(2));
			printf("Accel     : %5.3f %5.3f %5.3f\n", drone_state->accel_.at(0), drone_state->accel_.at(1), drone_state->accel_.at(2));
			printf("Mag       : %5.3f %5.3f %5.3f\n", drone_state->mag_.at(0), drone_state->mag_.at(1), drone_state->mag_.at(2));
			printf("dT        : %lu uSec\n", (uint32_t)drone_state->dt_.microseconds());
			printf("Q         : %5.3f %5.3f %5.3f %5.3f\n\n", drone_state->attitude_.w, drone_state->attitude_.x, drone_state->attitude_.y,
					drone_state->attitude_.z);
#if 1
			printf("Motors    : %1.2f %1.2f %1.2f %1.2f\n", drone_state->motors_[0], drone_state->motors_[1],
								drone_state->motors_[2], drone_state->motors_[3]);
			printf("Throttle  : %1.2f\n", drone_state->base_throttle_);
		    printf("Armed     : %d\n", drone_state->motors_armed_);
			printf("Altitude  : %4.2f m\n", drone_state->altitude_.meters());
			printf("GPS       : Lon: %3.4f Lat: %3.4f Sat %lu Alt: %4.2f m\n",
					drone_state->longitude_.degrees(), drone_state->latitude_.degrees(),
					drone_state->satellite_count_, drone_state->gps_altitude_.meters());
			printf("Battery   : %2.1f V, %2.0f%%\n", drone_state->battery_voltage_.volts(), drone_state->battery_percentage_);
#endif
		}

#if 0
		if (led_toggle_ts.elapsed() > TimeSpan::from_seconds(1)) {
			led_toggle_ts.time_stamp();
			led0.toggle();
		}
#endif

#ifndef ENABLE_UART_TASK
		rpcserver.jsonrpc_request_handler(&uart2);
#endif
	}
}
int main(int argc, char **argv)
{
  // Initialize Aria and Arnl global information
  Aria::init();
  Arnl::init();


  // The robot object
  ArRobot robot;

  // Parse the command line arguments.
  ArArgumentParser parser(&argc, argv);

  // Set up our simpleConnector, to connect to the robot and laser
  //ArSimpleConnector simpleConnector(&parser);
  ArRobotConnector robotConnector(&parser, &robot);

  // Connect to the robot
  if (!robotConnector.connectRobot())
  {
    ArLog::log(ArLog::Normal, "Error: Could not connect to robot... exiting");
    Aria::exit(3);
  }



  // Set up where we'll look for files. Arnl::init() set Aria's default
  // directory to Arnl's default directory; addDirectories() appends this
  // "examples" directory.
  char fileDir[1024];
  ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(), 
			 "examples");
  
  
  // To direct log messages to a file, or to change the log level, use these  calls:
  //ArLog::init(ArLog::File, ArLog::Normal, "log.txt", true, true);
  //ArLog::init(ArLog::File, ArLog::Verbose);
 
  // Add a section to the configuration to change ArLog parameters
  ArLog::addToConfig(Aria::getConfig());

  // set up a gyro (if the robot is older and its firmware does not
  // automatically incorporate gyro corrections, then this object will do it)
  ArAnalogGyro gyro(&robot);

  // Our networking server
  ArServerBase server;
  

  // Set up our simpleOpener, used to set up the networking server
  ArServerSimpleOpener simpleOpener(&parser);

  // the laser connector
  ArLaserConnector laserConnector(&parser, &robot, &robotConnector);

  // Tell the laser connector to always connect the first laser since
  // this program always requires a laser.
  parser.addDefaultArgument("-connectLaser");
  
  // Load default arguments for this computer (from /etc/Aria.args, environment
  // variables, and other places)
  parser.loadDefaultArguments();

  // Parse arguments 
  if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
  {
    logOptions(argv[0]);
    Aria::exit(1);
  }
  

  // This causes Aria::exit(9) to be called if the robot unexpectedly
  // disconnects
  ArGlobalFunctor1<int> shutdownFunctor(&Aria::exit, 9);
  robot.addDisconnectOnErrorCB(&shutdownFunctor);


  // Create an ArSonarDevice object (ArRangeDevice subclass) and 
  // connect it to the robot.
  ArSonarDevice sonarDev;
  robot.addRangeDevice(&sonarDev);



  // This object will allow robot's movement parameters to be changed through
  // a Robot Configuration section in the ArConfig global configuration facility.
  ArRobotConfig robotConfig(&robot);

  // Include gyro configuration options in the robot configuration section.
  robotConfig.addAnalogGyro(&gyro);

  // Start the robot thread.
  robot.runAsync(true);
  

  // connect the laser(s) if it was requested, this adds them to the
  // robot too, and starts them running in their own threads
  if (!laserConnector.connectLasers())
  {
    ArLog::log(ArLog::Normal, "Could not connect to all lasers... exiting\n");
    Aria::exit(2);
  }

  // find the laser we should use for localization and/or mapping,
  // which will be the first laser
  robot.lock();
  ArLaser *firstLaser = robot.findLaser(1);
  if (firstLaser == NULL || !firstLaser->isConnected())
  {
    ArLog::log(ArLog::Normal, "Did not have laser 1 or it is not connected, cannot start localization and/or mapping... exiting");
    Aria::exit(2);
  }
  robot.unlock();


    /* Create and set up map object */
  
  // Set up the map object, this will look for files in the examples
  // directory (unless the file name starts with a /, \, or .
  // You can take out the 'fileDir' argument to look in the program's current directory
  // instead.
  // When a configuration file is loaded into ArConfig later, if it specifies a
  // map file, then that file will be loaded as the map.
  ArMap map(fileDir);
  // set it up to ignore empty file names (otherwise if a configuration omits
  // the map file, the whole configuration change will fail)
  map.setIgnoreEmptyFileName(true);
  // ignore the case, so that if someone is using MobileEyes or
  // MobilePlanner from Windows and changes the case on a map name,
  // it will still work.
  map.setIgnoreCase(true);

    
    /* Create localization and path planning threads */


  ArPathPlanningTask pathTask(&robot, &sonarDev, &map);



  ArLog::log(ArLog::Normal, "Creating laser localization task");
  // Laser Monte-Carlo Localization
  ArLocalizationTask locTask(&robot, firstLaser, &map);



  // Set some options on each laser that the laser connector 
  // connected to.
  std::map<int, ArLaser *>::iterator laserIt;
  for (laserIt = robot.getLaserMap()->begin();
       laserIt != robot.getLaserMap()->end();
       laserIt++)
  {
    int laserNum = (*laserIt).first;
    ArLaser *laser = (*laserIt).second;

    // Skip lasers that aren't connected
    if(!laser->isConnected())
      continue;

    // add the disconnectOnError CB to shut things down if the laser
    // connection is lost
    laser->addDisconnectOnErrorCB(&shutdownFunctor);
    // set the number of cumulative readings the laser will take
    laser->setCumulativeBufferSize(200);
    // add the lasers to the path planning task
    pathTask.addRangeDevice(laser, ArPathPlanningTask::BOTH);
    // set the cumulative clean offset (so that they don't all fire at once)
    laser->setCumulativeCleanOffset(laserNum * 100);
    // reset the cumulative clean time (to make the new offset take effect)
    laser->resetLastCumulativeCleanTime();

    // Add the packet count to the Aria info strings (It will be included in
    // MobileEyes custom details so you can monitor whether the laser data is
    // being received correctly)
    std::string laserPacketCountName;
    laserPacketCountName = laser->getName();
    laserPacketCountName += " Packet Count";
    Aria::getInfoGroup()->addStringInt(
	    laserPacketCountName.c_str(), 10, 
	    new ArRetFunctorC<int, ArLaser>(laser, 
					 &ArLaser::getReadingCount));
  }


  // Used for optional multirobot features (see below) (TODO move to multirobot
  // example?)
  ArClientSwitchManager clientSwitch(&server, &parser);




    /* Start the server */

  // Open the networking server
  if (!simpleOpener.open(&server, fileDir, 240))
  {
    ArLog::log(ArLog::Normal, "Error: Could not open server.");
    exit(2);
  }



    /* Create various services that provide network access to clients (such as
     * MobileEyes), as well as add various additional features to ARNL */


  // ARNL can optionally get information about the positions of other robots from a
  // "central server" (see central server example program), if command
  // line options specifying the address of the central server was given.
  // If there is no central server, then the address of each other robot
  // can instead be given in the configuration, and the multirobot systems
  // will connect to each robot (or "peer") individually.

        // TODO move this to multirobot example?


  bool usingCentralServer = false;
  if(clientSwitch.getCentralServerHostName() != NULL)
    usingCentralServer = true;

  // if we're using the central server then we want to create the
  // multiRobot central classes
  if (usingCentralServer)
  {
    // Make the handler for multi robot information (this sends the
    // information to the central server)
    //ArServerHandlerMultiRobot *handlerMultiRobot = 
    new ArServerHandlerMultiRobot(&server, &robot, 
						      &pathTask,
						      &locTask, &map);
    
    // Normally each robot, and the central server, must all have
    // the same map name for the central server to share robot
    // information.  (i.e. they are operating in the same space).
    // This changes the map name that ArServerHandlerMutliRobot 
    // reports to the central server, in case you want this individual
    // robot to load a different map file name, but still report 
    // the common map file to the central server.
    //handlerMultiRobot->overrideMapName("central.map");

    // the range device that gets the multi robot information from
    // the central server and presents it as virtual range readings
    // to ARNL
    ArMultiRobotRangeDevice *multiRobotRangeDevice = new ArMultiRobotRangeDevice(&server);
    
    robot.addRangeDevice(multiRobotRangeDevice);
    pathTask.addRangeDevice(multiRobotRangeDevice, 
			    ArPathPlanningTask::BOTH);
    
    // Set up options for drawing multirobot information in MobileEyes.
    multiRobotRangeDevice->setCurrentDrawingData(
	    new ArDrawingData("polyDots", ArColor(125, 125, 0),
			      100, 73, 1000), true);
    multiRobotRangeDevice->setCumulativeDrawingData(
	    new ArDrawingData("polyDots", ArColor(125, 0, 125),
			      100, 72, 1000), true);

    // This sets up the localization to use the known poses of other robots
    // for its localization in cases where numerous robots crowd out the map.
    locTask.setMultiRobotCallback(multiRobotRangeDevice->getOtherRobotsCB());
  }
  // if we're not using a central server then create the multirobot peer classes
  else
  {
    // set the path planning so it uses the explicit collision range for how far its planning
    pathTask.setUseCollisionRangeForPlanningFlag(true);
    // make our thing that gathers information from the other servers
    ArServerHandlerMultiRobotPeer *multiRobotPeer = NULL;
    ArMultiRobotPeerRangeDevice *multiRobotPeerRangeDevice = NULL;
    multiRobotPeerRangeDevice = new ArMultiRobotPeerRangeDevice(&map);
    // make our thing that sends information to the other servers
    multiRobotPeer = new ArServerHandlerMultiRobotPeer(&server, &robot, 
						     &pathTask, &locTask);
    // hook the two together so they both know what priority this robot is
    multiRobotPeer->setNewPrecedenceCallback(
	    multiRobotPeerRangeDevice->getSetPrecedenceCallback());
    // hook the two together so they both know what priority this
    // robot's fingerprint is
    multiRobotPeer->setNewFingerprintCallback(
	    multiRobotPeerRangeDevice->getSetFingerprintCallback());
    // hook the two together so that the range device can call on the
    // server handler to change its fingerprint
    multiRobotPeerRangeDevice->setChangeFingerprintCB(
	    multiRobotPeer->getChangeFingerprintCB());
    // then add the robot to the places it needs to be
    robot.addRangeDevice(multiRobotPeerRangeDevice);
    pathTask.addRangeDevice(multiRobotPeerRangeDevice, 
			    ArPathPlanningTask::BOTH);

    // Set the range device so that we can see the information its using
    // to avoid, you can comment these out in order to not see them
    multiRobotPeerRangeDevice->setCurrentDrawingData(
	    new ArDrawingData("polyDots", ArColor(125, 125, 0),
			      100, 72, 1000), true);
    multiRobotPeerRangeDevice->setCumulativeDrawingData(
	    new ArDrawingData("polyDots", ArColor(125, 0, 125),
			      100, 72, 1000), true);
    // This sets up the localization to use the known poses of other robots
    // for its localization in cases where numerous robots crowd out the map.
    locTask.setMultiRobotCallback(
	    multiRobotPeerRangeDevice->getOtherRobotsCB());
  }




  /* Add additional range devices to the robot and path planning task (so it
     avoids obstacles detected by these devices) */
  
  // Add IR range device to robot and path planning task (so it avoids obstacles
  // detected by this device)
  robot.lock();
  ArIRs irs;
  robot.addRangeDevice(&irs);
  pathTask.addRangeDevice(&irs, ArPathPlanningTask::CURRENT);

  // Add bumpers range device to robot and path planning task (so it avoids obstacles
  // detected by this device)
  ArBumpers bumpers;
  robot.addRangeDevice(&bumpers);
  pathTask.addRangeDevice(&bumpers, ArPathPlanningTask::CURRENT);

  // Add range device which uses forbidden regions given in the map to give virtual
  // range device readings to ARNL.  (so it avoids obstacles
  // detected by this device)
  ArForbiddenRangeDevice forbidden(&map);
  robot.addRangeDevice(&forbidden);
  pathTask.addRangeDevice(&forbidden, ArPathPlanningTask::CURRENT);

  robot.unlock();


  // Action to slow down robot when localization score drops but not lost.
  ArActionSlowDownWhenNotCertain actionSlowDown(&locTask);
  pathTask.getPathPlanActionGroup()->addAction(&actionSlowDown, 140);

  // Action to stop the robot when localization is "lost" (score too low)
  ArActionLost actionLostPath(&locTask, &pathTask);
  pathTask.getPathPlanActionGroup()->addAction(&actionLostPath, 150);

  // Arnl uses this object when it must replan its path because its
  // path is completely blocked.  It will use an older history of sensor
  // readings to replan this new path.  This should not be used with SONARNL
  // since sonar readings are not accurate enough and may prevent the robot
  // from planning through space that is actually clear.
  ArGlobalReplanningRangeDevice replanDev(&pathTask);

  
  // Service to provide drawings of data in the map display :
  ArServerInfoDrawings drawings(&server);
  drawings.addRobotsRangeDevices(&robot);
  drawings.addRangeDevice(&replanDev);

  /* Draw a box around the local path planning area use this 
    (You can enable this particular drawing from custom commands 
    which is set up down below in ArServerInfoPath) */
  ArDrawingData drawingDataP("polyLine", ArColor(200,200,200), 1, 75);
  ArFunctor2C<ArPathPlanningTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorP(&pathTask, &ArPathPlanningTask::drawSearchRectangle);
  drawings.addDrawing(&drawingDataP, "Local Plan Area", &drawingFunctorP); 

  /* Show the sample points used by MCL */
  ArDrawingData drawingDataL("polyDots", ArColor(0,255,0), 100, 75);
  ArFunctor2C<ArLocalizationTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorL(&locTask, &ArLocalizationTask::drawRangePoints);
  drawings.addDrawing(&drawingDataL, "Localization Points", &drawingFunctorL);


  // "Custom" commands. You can add your own custom commands here, they will
  // be available in MobileEyes' custom commands (enable in the toolbar or
  // access through Robot Tools)
  ArServerHandlerCommands commands(&server);


  // These provide various kinds of information to the client:
  ArServerInfoRobot serverInfoRobot(&server, &robot);
  ArServerInfoSensor serverInfoSensor(&server, &robot);
  ArServerInfoPath serverInfoPath(&server, &robot, &pathTask);
  serverInfoPath.addSearchRectangleDrawing(&drawings);
  serverInfoPath.addControlCommands(&commands);

  // Provides localization info and allows the client (MobileEyes) to relocalize at a given
  // pose:
  ArServerInfoLocalization serverInfoLocalization(&server, &robot, &locTask);
  ArServerHandlerLocalization serverLocHandler(&server, &robot, &locTask);

  // If you're using MobileSim, ArServerHandlerLocalization sends it a command
  // to move the robot's true pose if you manually do a localization through 
  // MobileEyes.  To disable that behavior, use this constructor call instead:
  // ArServerHandlerLocalization serverLocHandler(&server, &robot, true, false);
  // The fifth argument determines whether to send the command to MobileSim.

  // Provide the map to the client (and related controls):
  ArServerHandlerMap serverMap(&server, &map);

  // These objects add some simple (custom) commands to 'commands' for testing and debugging:
  ArServerSimpleComUC uCCommands(&commands, &robot);                   // Send any command to the microcontroller
  ArServerSimpleComMovementLogging loggingCommands(&commands, &robot); // configure logging
  ArServerSimpleComLogRobotConfig configCommands(&commands, &robot);   // trigger logging of the robot config parameters
//  ArServerSimpleServerCommands serverCommands(&commands, &server);     // monitor networking behavior (track packets sent etc.)


  // service that allows the client to monitor the communication link status
  // between the robot and the client.
  //
  ArServerHandlerCommMonitor handlerCommMonitor(&server);



  // service that allows client to change configuration parameters in ArConfig 
  ArServerHandlerConfig handlerConfig(&server, Aria::getConfig(),
				      Arnl::getTypicalDefaultParamFileName(),
				      Aria::getDirectory());



  /* Set up the possible modes for remote control from a client such as
   * MobileEyes:
   */

  // Mode To go to a goal or other specific point:
  ArServerModeGoto modeGoto(&server, &robot, &pathTask, &map,
			    locTask.getRobotHome(),
			    locTask.getRobotHomeCallback());


  // Mode To stop and remain stopped:
  ArServerModeStop modeStop(&server, &robot);

  // Cause the sonar to turn off automatically
  // when the robot is stopped, and turn it back on when commands to move
  // are sent. (Note, if using SONARNL to localize, then don't do this
  // since localization may get lost)
  ArSonarAutoDisabler sonarAutoDisabler(&robot);

  // Teleoperation modes To drive by keyboard, joystick, etc:
  ArServerModeRatioDrive modeRatioDrive(&server, &robot);  
//  ArServerModeDrive modeDrive(&server, &robot);            // Older mode for compatability



  // Prevent normal teleoperation driving if localization is lost using
  // a high-priority action, which enables itself when the particular mode is
  // active.
  // (You have to enter unsafe drive mode to drive when lost.)
  ArActionLost actionLostRatioDrive(&locTask, &pathTask, &modeRatioDrive);
  modeRatioDrive.getActionGroup()->addAction(&actionLostRatioDrive, 110);

  // Add drive mode section to the configuration, and also some custom (simple) commands:
  modeRatioDrive.addToConfig(Aria::getConfig(), "Teleop settings");
  modeRatioDrive.addControlCommands(&commands);

  // Wander mode (also prevent wandering if lost):
  ArServerModeWander modeWander(&server, &robot);
  ArActionLost actionLostWander(&locTask, &pathTask, &modeWander);
  modeWander.getActionGroup()->addAction(&actionLostWander, 110);


  // This provides a small table of interesting information for the client
  // to display to the operator. You can add your own callbacks to show any
  // data you want.
  ArServerInfoStrings stringInfo(&server);
  Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor());
  
  // Provide a set of informational data (turn on in MobileEyes with
  // View->Custom Details)

  Aria::getInfoGroup()->addStringInt(
	  "Motor Packet Count", 10, 
	  new ArConstRetFunctorC<int, ArRobot>(&robot, 
					       &ArRobot::getMotorPacCount));

  Aria::getInfoGroup()->addStringDouble(
	  "Laser Localization Score", 8, 
	  new ArRetFunctorC<double, ArLocalizationTask>(
		  &locTask, &ArLocalizationTask::getLocalizationScore),
	  "%.03f");
  Aria::getInfoGroup()->addStringInt(
	  "Laser Loc Num Samples", 8, 
	  new ArRetFunctorC<int, ArLocalizationTask>(
		  &locTask, &ArLocalizationTask::getCurrentNumSamples),
	  "%4d");


  // Display gyro status if gyro is enabled and is being handled by the firmware (gyro types 2, 3, or 4).
  // (If the firmware detects an error communicating with the gyro or IMU it
  // returns a flag, and stops using it.)
  // (This gyro type parameter, and fault flag, are only in ARCOS, not Seekur firmware)
  if(robot.getOrigRobotConfig() && robot.getOrigRobotConfig()->getGyroType() > 1)
  {
    Aria::getInfoGroup()->addStringString(
          "Gyro/IMU Status", 10,
          new ArGlobalRetFunctor1<const char*, ArRobot*>(&getGyroStatusString, &robot)
      );
  }


  // Setup the dock if there is a docking system on board.
  ArServerModeDock *modeDock = NULL;
  modeDock = ArServerModeDock::createDock(&server, &robot, &locTask, 
					  &pathTask);
  if (modeDock != NULL)
  {
    modeDock->checkDock();
    modeDock->addAsDefaultMode();
    modeDock->addToConfig(Aria::getConfig());
    modeDock->addControlCommands(&commands);
  }



  // Make Stop mode the default (If current mode deactivates without entering
  // a new mode, then Stop Mode will be selected)
  modeStop.addAsDefaultMode();
    // TODO move up near where stop mode is created?





  /* Services that allow the client to initiate scanning with the laser to
     create maps in Mapper3 (So not possible with SONARNL): */

  ArServerHandlerMapping handlerMapping(&server, &robot, firstLaser, 
					fileDir, "", true);

  // make laser localization stop while mapping
  handlerMapping.addMappingStartCallback(
	  new ArFunctor1C<ArLocalizationTask, bool>
	  (&locTask, &ArLocalizationTask::setIdleFlag, true));

  // and then make it start again when we're doine
  handlerMapping.addMappingEndCallback(
	  new ArFunctor1C<ArLocalizationTask, bool>
	  (&locTask, &ArLocalizationTask::setIdleFlag, false));


  // Make it so our "lost" actions don't stop us while mapping
  handlerMapping.addMappingStartCallback(actionLostPath.getDisableCB());
  handlerMapping.addMappingStartCallback(actionLostRatioDrive.getDisableCB());
  handlerMapping.addMappingStartCallback(actionLostWander.getDisableCB());

  // And then let them make us stop as usual when done mapping
  handlerMapping.addMappingEndCallback(actionLostPath.getEnableCB());
  handlerMapping.addMappingEndCallback(actionLostRatioDrive.getEnableCB());
  handlerMapping.addMappingEndCallback(actionLostWander.getEnableCB());

  // don't let forbidden lines show up as obstacles while mapping
  // (they'll just interfere with driving while mapping, and localization is off anyway)
  handlerMapping.addMappingStartCallback(forbidden.getDisableCB());

  // let forbidden lines show up as obstacles again as usual after mapping
  handlerMapping.addMappingEndCallback(forbidden.getEnableCB());


  /*
  // If we are on a simulator, move the robot back to its starting position,
  // and reset its odometry.
  // This will allow localizeRobotAtHomeBlocking() below will (probably) work (it
  // tries current odometry (which will be 0,0,0) and all the map
  // home points.
  // (Ignored by a real robot)
  //robot.com(ArCommands::SIM_RESET);
  */


  // create a pose storage class, this will let the program keep track
  // of where the robot is between runs...  after we try and restore
  // from this file it will start saving the robot's pose into the
  // file
  ArPoseStorage poseStorage(&robot);
  /// if we could restore the pose from then set the sim there (this
  /// won't do anything to the real robot)... if we couldn't restore
  /// the pose then just reset the position of the robot (which again
  /// won't do anything to the real robot)
  if (poseStorage.restorePose("robotPose"))
    serverLocHandler.setSimPose(robot.getPose());
  else
    robot.com(ArCommands::SIM_RESET);



  /* File transfer services: */
  
#ifdef WIN32
  // Not implemented for Windows yet.
  ArLog::log(ArLog::Normal, "Note, file upload/download services are not implemented for Windows; not enabling them.");
#else
  // This block will allow you to set up where you get and put files
  // to/from, just comment them out if you don't want this to happen
  // /*
  ArServerFileLister fileLister(&server, fileDir);
  ArServerFileToClient fileToClient(&server, fileDir);
  ArServerFileFromClient fileFromClient(&server, fileDir, "/tmp");
  ArServerDeleteFileOnServer deleteFileOnServer(&server, fileDir);
  // */
#endif

    /* Video image streaming, and camera controls (Requires SAVserver or ACTS) */

  // Forward any video if either ACTS or SAV server are running.
  // You can find out more about SAV and ACTS on our website
  // http://robots.activmedia.com. ACTS is for color tracking and is
  // a seperate product. SAV just does software A/V transmitting and is
  // free to all our customers. Just run ACTS or SAV server before you
  // start this program and this class here will forward video from the
  // server to the client.
  ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070);
  
  // make a camera to use in case we have video. the camera collection collects
  // multiple ptz cameras 
  ArPTZ *camera = NULL;
  ArServerHandlerCamera *handlerCamera = NULL;
  ArCameraCollection *cameraCollection = NULL;

  // if we have video then set up a camera 
  if (videoForwarder.isForwardingVideo())
  {

    cameraCollection = new ArCameraCollection();
    cameraCollection->addCamera("Cam1", "PTZ", "Camera", "PTZ");

    videoForwarder.setCameraName("Cam1");
    videoForwarder.addToCameraCollection(*cameraCollection);

    camera = new ArVCC4(&robot); //,	invertedCamera, ArVCC4::COMM_UNKNOWN, true, true);
    // To use an RVision SEE camera instead:
    // camera = new ArRVisionPTZ(&robot);
    camera->init();

    handlerCamera = new ArServerHandlerCamera("Cam1", 
		                                           &server, 
					                                     &robot,
					                                     camera, 
					                                     cameraCollection);

    pathTask.addGoalFinishedCB(
	    new ArFunctorC<ArServerHandlerCamera>(
		    handlerCamera, 
		    &ArServerHandlerCamera::cameraModeLookAtGoalClearGoal));
  }

  // After all of the cameras / videos have been created and added to the collection,
  // then start the collection server.
  //
  if (cameraCollection != NULL) {
    new ArServerHandlerCameraCollection(&server, cameraCollection);
  }




    /* Load configuration values, map, and begin! */

  
  // When parsing the configuration file, also look at the program's command line options 
  // from the command-line argument parser as well as the configuration file.
  // (So you can use any argument on the command line, namely -map.) 
  Aria::getConfig()->useArgumentParser(&parser);
  puts("xxx");puts("aaa"); fflush(stdout);
  // Read in parameter files.
  ArLog::log(ArLog::Normal, "Loading config file %s into ArConfig (base directory %s)...", Arnl::getTypicalParamFileName(), Aria::getConfig()->getBaseDirectory());
  if (!Aria::getConfig()->parseFile(Arnl::getTypicalParamFileName()))
  {
    ArLog::log(ArLog::Normal, "Trouble loading configuration file, exiting");
    Aria::exit(5);
  }

  // Warn about unknown params.
  if (!simpleOpener.checkAndLog() || !parser.checkHelpAndWarnUnparsed())
  {
    logOptions(argv[0]);
    Aria::exit(6);
  }

  // Warn if there is no map
  if (map.getFileName() == NULL || strlen(map.getFileName()) <= 0)
  {
    ArLog::log(ArLog::Normal, "");
    ArLog::log(ArLog::Normal, "### No map file is set up, you can make a map with the following procedure");
    ArLog::log(ArLog::Normal, "   0) You can find this information in README.txt or docs/Mapping.txt");
    ArLog::log(ArLog::Normal, "   1) Connect to this server with MobileEyes");
    ArLog::log(ArLog::Normal, "   2) Go to Tools->Map Creation->Start Scan");
    ArLog::log(ArLog::Normal, "   3) Give the map a name and hit okay");
    ArLog::log(ArLog::Normal, "   4) Drive the robot around your space (see docs/Mapping.txt");
    ArLog::log(ArLog::Normal, "   5) Go to Tools->Map Creation->Stop Scan");
    ArLog::log(ArLog::Normal, "   6) Start up Mapper3");
    ArLog::log(ArLog::Normal, "   7) Go to File->Open on Robot");
    ArLog::log(ArLog::Normal, "   8) Select the .2d you created");
    ArLog::log(ArLog::Normal, "   9) Create a .map");
    ArLog::log(ArLog::Normal, "  10) Go to File->Save on Robot");
    ArLog::log(ArLog::Normal, "  11) In MobileEyes, go to Tools->Robot Config");
    ArLog::log(ArLog::Normal, "  12) Choose the Files section");
    ArLog::log(ArLog::Normal, "  13) Enter the path and name of your new .map file for the value of the Map parameter.");
    ArLog::log(ArLog::Normal, "  14) Press OK and your new map should become the map used");
    ArLog::log(ArLog::Normal, "");    
  }

  // Print a log message notifying user of the directory for map files
  ArLog::log(ArLog::Normal, "");
  ArLog::log(ArLog::Normal, 
	     "Directory for maps and file serving: %s", fileDir);
  
  ArLog::log(ArLog::Normal, "See the ARNL README.txt for more information");
  ArLog::log(ArLog::Normal, "");

  // Do an initial localization of the robot. It tries all the home points
  // in the map, as well as the robot's current odometric position, as possible
  // places the robot is likely to be at startup.   If successful, it will
  // also save the position it found to be the best localized position as the
  // "Home" position, which can be obtained from the localization task (and is
  // used by the "Go to home" network request).
  locTask.localizeRobotAtHomeBlocking();
  
  // Let the client switch manager (for multirobot) spin off into its own thread
  // TODO move to multirobot example?
  clientSwitch.runAsync();

  // Start the networking server's thread
  server.runAsync();


  // Add a key handler so that you can exit by pressing
  // escape. Note that this key handler, however, prevents this program from
  // running in the background (e.g. as a system daemon or run from 
  // the shell with "&") -- it will lock up trying to read the keys; 
  // remove this if you wish to be able to run this program in the background.
  ArKeyHandler *keyHandler;
  if ((keyHandler = Aria::getKeyHandler()) == NULL)
  {
    keyHandler = new ArKeyHandler;
    Aria::setKeyHandler(keyHandler);
    robot.lock();
    robot.attachKeyHandler(keyHandler);
    robot.unlock();
    puts("Server running. To exit, press escape.");
  }


 	
   ArnlASyncTaskExample asyncTaskExample(&pathTask, &robot, &modeGoto, &parser);



  // Enable the motors and wait until the robot exits (disconnection, etc.) or this program is
  // canceled.
  robot.enableMotors();
  robot.waitForRunExit();
  Aria::exit(0);
}
Пример #16
0
int main(int argc, const char * argv[]) {
    
    
    std::ofstream to_log(to_log_file_path.c_str());
    std::ofstream to_rpy(rpy_file_path.c_str());
    std::ofstream gps_out(gps_out_path.c_str());
    std::ofstream gps_filter_out(gps_filter_out_path.c_str());
    std::ofstream mag_out(mag_out_path.c_str());
    
    try {
        
    // Declaring objects used for inertial navigation
        ACCELEROMETER acc(acc_file_path, Captor::COLD_START);
        GYRO gyro(gyro_file_path, Captor::COLD_START);
        MAGNETOMETER mag(mag_file_path, Captor::COLD_START);
        GPS gps(gps_file_path,GPS::UBLOX);
        GPS_Filter gps_filter(&gps);
        EKF ekf(&gps_filter,&acc,&gyro,&mag);
        
    
    
    
    // Getting offset and gain for accelerometer, gyroscope and magnetometer. Getting GPS HOME field.
    // This routine will warn you if one of the offset couldn't be updated
        int ret = acc.initOffsets();
        if (ret != 1) std::cout << "Couldn't get acc offsets !" << std::endl;
        else std::cout << "Acc offsets updated" << std::endl;
        ret = acc.initGain();
        if (ret != 1) std::cout << "Couldn't get acc gain !" << std::endl;
        else std::cout << "Acc gain updated" << std::endl;
        
        // Advanced calibration for acc (offset and gain)
#ifdef ADCALIBRATION
        ret = acc.performAdvancedAccCalibration();
        if (ret !=1) std::cout << "Couldn't perform acc advanced calibration method" << std::endl;
        else {
            std::cout << "Acc advanced calibration performed" << std::endl;
            acc.correct_GN();
        }
#endif
        
        ret = gyro.initOffsets();
        if (ret != 1) std::cout << "Couldn't get gyro offsets !" << std::endl;
        else std::cout << "Gyro offsets updated" << std::endl;
        ret = gyro.initGain();
        if (ret != 1) std::cout << "Couldn't get gyro gain !" << std::endl;
        else std::cout << "Gyro gain updated" << std::endl;
        
        ret = mag.initOffsets();
        if (ret != 1) std::cout << "Couldn't get magnetometer offsets !" << std::endl;
        else std::cout << "Mag offsets updated" << std::endl;
        
        ret = gps.setHome();
        if (ret != 1) std::cout << "Couldn't get HOME !" << std::endl;
        else std::cout << "HOME updated" << std::endl;
        
        
        
    // Reading lines
        // We create the buffer for the sensor's output values
        Eigen::Vector3f acc_vector_buffer;
        Eigen::Vector3f gyro_vector_buffer;
        Eigen::Vector3d gps_buffer_vector;
        Eigen::Vector3d gps_position_vector;
        
       // We update and correct the magnetometer
        mag._init_earth_even_magnetic_field();
        mag.update_correct();
        // We initialize the state vector giving the initial heading
        ekf.init_state_vector(mag.getHeading());
        //ekf.init_state_vector();
        to_rpy << TODEG*(ekf.toRPY(ekf.get_state_vector())).transpose() << std::endl;           // Storing operation
        
        
        
        while (!acc.line_end && !gyro.line_end){
            
            // Reading from inertial captors and correcting the outputs
            acc.getOutput(&acc_vector_buffer);
            acc.correctOutput(&acc_vector_buffer, ekf.getDCM());
            gyro.getOutput(&gyro_vector_buffer);
            gyro.correctOutput(&gyro_vector_buffer);
            // Updating and correcting magnetometer
            mag.update_correct();
            // Updating GPS and storing into the &gps_buffer_vector
            gps.update(&gps_buffer_vector);
            
            
        
            // Predicting the state vector
            // Extended Kalman Filter according step is the prediction step. We first build the Jacobian matrix linearized around the current state and we then multiply the currrent state vector by such a matrix
            ekf.build_jacobian_matrix(&acc_vector_buffer, &gyro_vector_buffer);
            ekf.predict();
            
            to_rpy << TODEG*(ekf.getRPY()).transpose() << std::endl;                            // Storing operation for data exploitation
            to_log << ekf.get_state_vector().transpose() << std::endl;                          // Storing operation for data exploitation
            //mag_out << TODEG*mag.getHeading() << std::endl;                                   // Storing operation for data exploitation
            mag_out << TODEG*mag.getHeading((ekf.getRPY())(1),(ekf.getRPY())(0)) << std::endl;  // Storing operation for data exploitation

            
    

            
            // Checking inf a new gps data is availaible
            if (gps.isAvailable()){
                // If yes, we first update the GPS filter
                gps.calculatePositionFromHome(&gps_buffer_vector);
                gps_out << gps.getActualPosition().transpose() << std::endl;
                gps.actualizeInternDatas(&gps_buffer_vector);
                gps_filter.predict();
                gps_filter.updateFilter();
                gps_filter_out << gps_filter.getState().transpose() << std::endl;               // Storing operation for data exploitation
                // And we then correct the EKF filter by correcting in order position, speed and quaternion attitude vector
                //ekf.correct();
                //gps_filter.updateSpeedEKF(ekf.getCurrentSpeed());
            }
            
        }

    }
    catch (std::exception const& e)
    { std::cout << e.what() <<  " file " << std::endl; }
    
    

    
    return 0;
}
Пример #17
0
//******************************************************************************
void SHSensors::handleUpdate()
{
const float fToC = 9.0 / 5.0;
const float fOffset = 32;

    //*** read all data ***
    while ( imu_->IMURead() )
    {
        //*** get IMU data ***
        RTIMU_DATA imuData = imu_->getIMUData();

        //*** pressure / temperature ***
        if ( ((enabled_ & IMU_PRESSURE) || (enabled_ & IMU_TEMP)) && pressure_ )
        {
            pressure_->pressureRead( imuData );

            if ( enabled_ & IMU_PRESSURE )
            {
                //*** pressure in hPa ***
                emit pressure( imuData.pressure, RTMath::convertPressureToHeight(imuData.pressure) );
            }

            if ( enabled_ & IMU_TEMP )
            {
                //*** temp celsius, fahrenheit ***
                emit temperature( imuData.temperature,
                                  imuData.temperature * fToC + fOffset );
            }
        }

        //*** humidity ***
        if ( (enabled_ & IMU_HUMIDITY) && humidity_ )
        {
            humidity_->humidityRead( imuData );

            //*** relative humidity ***
            emit humidity( imuData.humidity );
        }

        //*** gyroscope ***
        if ( enabled_ & IMU_GYRO )
        {
            //*** gyroscope in degrees per second ***
            emit gyro( imuData.gyro.x() * RTMATH_RAD_TO_DEGREE,
                       imuData.gyro.y() * RTMATH_RAD_TO_DEGREE,
                       imuData.gyro.z() * RTMATH_RAD_TO_DEGREE );
        }

        //*** accelerometer ***
        if ( enabled_ & IMU_ACCEL )
        {
            //*** acceleration in g's ***'
            emit accel( imuData.accel.x(), imuData.accel.y(),
                        imuData.accel.z(), imuData.accel.length() );
        }

        //*** compass ***
        if ( enabled_ & IMU_COMPASS )
        {
            //*** compas (magnetometer) in uT ***
            emit compass( imuData.compass.x(), imuData.compass.y(),
                          imuData.compass.z(), imuData.compass.length() );
        }

        //*** always emit fusion data - degrees ***
        float fusionX = imuData.fusionPose.x() * RTMATH_RAD_TO_DEGREE;
        float fusionY = imuData.fusionPose.y() * RTMATH_RAD_TO_DEGREE;
        float fusionZ = imuData.fusionPose.z() * RTMATH_RAD_TO_DEGREE;
        emit fusionPose( fusionX, fusionY, fusionZ );
    }

}
Пример #18
0
int main(int argc, char **argv)
{
    Aria::init();
    //ArLog::init(ArLog::StdOut, ArLog::Verbose);
    // robot
    ArRobot robot;
    /// our server
    ArServerBase server;

    // set up our parser
    ArArgumentParser parser(&argc, argv);
    // set up our simple connector
    ArSimpleConnector simpleConnector(&parser);

    // set up a gyro
    ArAnalogGyro gyro(&robot);

    // load the default arguments
    parser.loadDefaultArguments();

    // parse the command line... fail and print the help if the parsing fails
    // or if the help was requested
    if (!simpleConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed())
    {
        simpleConnector.logOptions();
        exit(1);
    }

    if (!server.loadUserInfo("userServerTest.userInfo"))
    {
        printf("Could not load user info, exiting\n");
        exit(1);
    }

    server.logUsers();

    // first open the server up
    if (!server.open(7272))
    {
        printf("Could not open server port\n");
        exit(1);
    }

    // sonar, must be added to the robot
    ArSonarDevice sonarDev;
    // add the sonar to the robot
    robot.addRangeDevice(&sonarDev);

    ArIRs irs;
    robot.addRangeDevice(&irs);

    ArBumpers bumpers;
    robot.addRangeDevice(&bumpers);

    // a laser in case one is used
    ArSick sick(361, 180);
    // add the laser to the robot
    robot.addRangeDevice(&sick);




    // attach stuff to the server
    ArServerInfoRobot serverInfoRobot(&server, &robot);
    ArServerInfoSensor serverInfoSensor(&server, &robot);
    ArServerInfoDrawings drawings(&server);
    drawings.addRobotsRangeDevices(&robot);

    // ways of moving the robot
    ArServerModeStop modeStop(&server, &robot);
    ArServerModeDrive modeDrive(&server, &robot);
    ArServerModeRatioDrive modeRatioDrive(&server, &robot);
    ArServerModeWander modeWander(&server, &robot);
    modeStop.addAsDefaultMode();
    modeStop.activate();

    // set up the simple commands
    ArServerHandlerCommands commands(&server);
    // add the commands for the microcontroller
    ArServerSimpleComUC uCCommands(&commands, &robot);
    // add the commands for logging
    ArServerSimpleComMovementLogging loggingCommands(&commands, &robot);
    // add the commands for the gyro
    ArServerSimpleComGyro gyroCommands(&commands, &robot, &gyro);

    // add the commands to enable and disable safe driving to the simple commands
    modeDrive.addControlCommands(&commands);

    // Forward any video if we have some to forward.. this will forward
    // from SAV or ACTS, you can find both on our website
    // http://robots.activmedia.com, ACTS is for color tracking and is
    // charged for but SAV just does software A/V transmitting and is
    // free to all our customers... just run ACTS or SAV before you
    // start this program and this class here will forward video from it
    // to MobileEyes
    ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070);

    // make a camera to use in case we have video
    ArPTZ *camera = NULL;
    ArServerHandlerCamera *handlerCamera = NULL;
    // if we have video then set up a camera
    if (videoForwarder.isForwardingVideo())
    {
        bool invertedCamera = false;
        camera = new ArVCC4(&robot,	invertedCamera,
                            ArVCC4::COMM_UNKNOWN, true, true);
        camera->init();
        handlerCamera = new ArServerHandlerCamera(&server, &robot, camera);
    }

    server.logCommandGroups();
    server.logCommandGroupsToFile("userServerTest.commandGroups");

    // now let it spin off in its own thread
    server.runAsync();

    // set up the robot for connecting
    if (!simpleConnector.connectRobot(&robot))
    {
        printf("Could not connect to robot... exiting\n");
        Aria::shutdown();
        return 1;
    }

    // set up the laser before handing it to the laser mode
    simpleConnector.setupLaser(&sick);

    robot.enableMotors();
    // start the robot running, true so that if we lose connection the run stops
    robot.runAsync(true);

    sick.runAsync();

    // connect the laser if it was requested
    if (!simpleConnector.connectLaser(&sick))
    {
        printf("Could not connect to laser... exiting\n");
        Aria::shutdown();
        return 1;
    }

    robot.waitForRunExit();
    // now exit
    Aria::shutdown();
    exit(0);
}
Пример #19
0
int main(int argc, char** argv)
{
  // Initialize some global data
  Aria::init();

  // If you want ArLog to print "Verbose" level messages uncomment this:
  //ArLog::init(ArLog::StdOut, ArLog::Verbose);

  // This object parses program options from the command line
  ArArgumentParser parser(&argc, argv);

  // Load some default values for command line arguments from /etc/Aria.args
  // (Linux) or the ARIAARGS environment variable.
  parser.loadDefaultArguments();

  // Central object that is an interface to the robot and its integrated
  // devices, and which manages control of the robot by the rest of the program.
  ArRobot robot;

  // Object that connects to the robot or simulator using program options
  ArRobotConnector robotConnector(&parser, &robot);

  // If the robot has an Analog Gyro, this object will activate it, and 
  // if the robot does not automatically use the gyro to correct heading,
  // this object reads data from it and corrects the pose in ArRobot
  ArAnalogGyro gyro(&robot);

  // Connect to the robot, get some initial data from it such as type and name,
  // and then load parameter files for this robot.
  if (!robotConnector.connectRobot())
  {
    // Error connecting:
    // if the user gave the -help argumentp, then just print out what happened,
    // and continue so options can be displayed later.
    if (!parser.checkHelpAndWarnUnparsed())
    {
      ArLog::log(ArLog::Terse, "Could not connect to robot, will not have parameter file so options displayed later may not include everything");
    }
    // otherwise abort
    else
    {
      ArLog::log(ArLog::Terse, "Error, could not connect to robot.");
      Aria::logOptions();
      Aria::exit(1);
    }
  }

  // Connector for laser rangefinders
  ArLaserConnector laserConnector(&parser, &robot, &robotConnector);

  // Connector for compasses
  ArCompassConnector compassConnector(&parser);

  // Parse the command line options. Fail and print the help message if the parsing fails
  // or if the help was requested with the -help option
  if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
  {    
    Aria::logOptions();
    exit(1);
  }

  // Used to access and process sonar range data
  ArSonarDevice sonarDev;
  
  // Used to perform actions when keyboard keys are pressed
  ArKeyHandler keyHandler;
  Aria::setKeyHandler(&keyHandler);

  // ArRobot contains an exit action for the Escape key. It also 
  // stores a pointer to the keyhandler so that other parts of the program can
  // use the same keyhandler.
  robot.attachKeyHandler(&keyHandler);
  printf("You may press escape to exit\n");

  // Attach sonarDev to the robot so it gets data from it.
  robot.addRangeDevice(&sonarDev);

  
  // Start the robot task loop running in a new background thread. The 'true' argument means if it loses
  // connection the task loop stops and the thread exits.
  robot.runAsync(true);

  // Connect to the laser(s) if lasers were configured in this robot's parameter
  // file or on the command line, and run laser processing thread if applicable
  // for that laser class.  (For the purposes of this demo, add all
  // possible lasers to ArRobot's list rather than just the ones that were
  // specified with the connectLaser option (so when you enter laser mode, you
  // can then interactively choose which laser to use from the list which will
  // show both connected and unconnected lasers.)
  if (!laserConnector.connectLasers(false, false, true))
  {
    printf("Could not connect to lasers... exiting\n");
    Aria::exit(2);
  }

  // Create and connect to the compass if the robot has one.
  ArTCM2 *compass = compassConnector.create(&robot);
  if(compass && !compass->blockingConnect()) {
    compass = NULL;
  }
  
  // Sleep for a second so some messages from the initial responses
  // from robots and cameras and such can catch up
  ArUtil::sleep(1000);

  // We need to lock the robot since we'll be setting up these modes
  // while the robot task loop thread is already running, and they 
  // need to access some shared data in ArRobot.
  robot.lock();

  // now add all the modes for this demo
  // these classes are defined in ArModes.cpp in ARIA's source code.
  ArModeLaser laser(&robot, "laser", 'l', 'L');
  ArModeTeleop teleop(&robot, "teleop", 't', 'T');
  ArModeUnguardedTeleop unguardedTeleop(&robot, "unguarded teleop", 'u', 'U');
  ArModeWander wander(&robot, "wander", 'w', 'W');
  ArModeGripper gripper(&robot, "gripper", 'g', 'G');
  ArModeCamera camera(&robot, "camera", 'c', 'C');
  ArModeSonar sonar(&robot, "sonar", 's', 'S');
  ArModeBumps bumps(&robot, "bumps", 'b', 'B');
  ArModePosition position(&robot, "position", 'p', 'P', &gyro);
  ArModeIO io(&robot, "io", 'i', 'I');
  ArModeActs actsMode(&robot, "acts", 'a', 'A');
  ArModeCommand command(&robot, "command", 'd', 'D');
  ArModeTCM2 tcm2(&robot, "tcm2", 'm', 'M', compass);


  // activate the default mode
  teleop.activate();

  // turn on the motors
  robot.comInt(ArCommands::ENABLE, 1);

  robot.unlock();
  
  // Block execution of the main thread here and wait for the robot's task loop
  // thread to exit (e.g. by robot disconnecting, escape key pressed, or OS
  // signal)
  robot.waitForRunExit();

  Aria::exit(0);


}
int main(int argc, char **argv)
{
  // Initialize Aria and Arnl global information
  Aria::init();
  Arnl::init();

  // You can change default ArLog options in this call, but the settings in the parameter file
  // (arnl.p) which is loaded below (Aria::getConfig()->parseFile())  will override the options.
  //ArLog::init(ArLog::File, ArLog::Normal, "log.txt", true, true);

  // Used to parse the command line arguments.
  ArArgumentParser parser(&argc, argv);
  
  // Load default arguments for this computer (from /etc/Aria.args, environment
  // variables, and other places)
  parser.loadDefaultArguments();

#ifdef ARNL_LASER
  // Tell the laser connector to always connect the first laser since
  // this program always requires a laser.
  parser.addDefaultArgument("-connectLaser");
#endif

  


  // The robot object
  ArRobot robot;

  // handle messages from robot controller firmware and log the contents
  robot.addPacketHandler(new ArGlobalRetFunctor1<bool, ArRobotPacket*>(&handleDebugMessage));

  // This object is used to connect to the robot, which can be configured via
  // command line arguments.
  ArRobotConnector robotConnector(&parser, &robot);

  // Connect to the robot
  if (!robotConnector.connectRobot())
  {
    ArLog::log(ArLog::Normal, "Error: Could not connect to robot... exiting");
    Aria::exit(3);
  }



  // Set up where we'll look for files. Arnl::init() set Aria's default
  // directory to Arnl's default directory; addDirectories() appends this
  // "examples" directory.
  char fileDir[1024];
  ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(), 
			 "examples");
  
  
  // To direct log messages to a file, or to change the log level, use these  calls:
  //ArLog::init(ArLog::File, ArLog::Normal, "log.txt", true, true);
  //ArLog::init(ArLog::File, ArLog::Verbose);
 
  // Add a section to the configuration to change ArLog parameters
  ArLog::addToConfig(Aria::getConfig());

  // set up a gyro (if the robot is older and its firmware does not
  // automatically incorporate gyro corrections, then this object will do it)
  ArAnalogGyro gyro(&robot);

  // Our networking server
  ArServerBase server;
  
#ifdef ARNL_GPSLOC
  // GPS connector.
  ArGPSConnector gpsConnector(&parser);
#endif

  // Set up our simpleOpener, used to set up the networking server
  ArServerSimpleOpener simpleOpener(&parser);

#ifdef ARNL_LASER
  // the laser connector
  ArLaserConnector laserConnector(&parser, &robot, &robotConnector);
#endif

  // used to connect to camera PTZ control
  ArPTZConnector ptzConnector(&parser, &robot);

#ifdef ARNL_MULTIROBOT
  // Used to connect to a "central server" which can be used as a proxy 
  // for multiple robot servers, and as a way for them to also communicate with
  // each other.  (objects implementing some of these inter-robot communication
  // features are created below).  
  // NOTE: If the central server is running on the same host as robot server(s),
  // then you must use the -serverPort argument to instruct these robot-control
  // server(s) to use different ports than the default 7272, since the central
  // server will use that port.
  ArClientSwitchManager clientSwitch(&server, &parser);
#endif
  
  // Load default arguments for this computer (from /etc/Aria.args, environment
  // variables, and other places)
  parser.loadDefaultArguments();

  // Parse arguments 
  if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
  {
    logOptions(argv[0]);
    Aria::exit(1);
  }
  

  // This causes Aria::exit(9) to be called if the robot unexpectedly
  // disconnects
  ArGlobalFunctor1<int> shutdownFunctor(&Aria::exit, 9);
  robot.addDisconnectOnErrorCB(&shutdownFunctor);


  // Create an ArSonarDevice object (ArRangeDevice subclass) and 
  // connect it to the robot.
  ArSonarDevice sonarDev;
  robot.addRangeDevice(&sonarDev);



  // This object will allow robot's movement parameters to be changed through
  // a Robot Configuration section in the ArConfig global configuration facility.
  ArRobotConfig robotConfig(&robot);

  // Include gyro configuration options in the robot configuration section.
  robotConfig.addAnalogGyro(&gyro);

  // Start the robot thread.
  robot.runAsync(true);

#ifdef ARNL_GPSLOC
  // On the Seekur, power to the GPS receiver is switched on by this command.
  // (A third argument of 0 would turn it off). On other robots this command is
  // ignored. If this fails, you may need to reset the port with ARIA demo or 
  // seekurPower program (turn port off then on again).  If the port is already
  // on, it will have no effect on the GPS (it will remain powered.)
  // Do this now before connecting to lasers to give it plenty of time to power
  // on, initialize, and find a good position before GPS localization begins.
  ArLog::log(ArLog::Normal, "Turning on GPS power... (Seekur/Seekur Jr. power port 6)");
  robot.com2Bytes(116, 6, 1);
#endif
  
#ifdef ARNL_LASER

  // connect the laser(s) if it was requested, this adds them to the
  // robot too, and starts them running in their own threads
  ArLog::log(ArLog::Normal, "Connecting to laser(s) configured in parameters...");
  if (!laserConnector.connectLasers())
  {
    ArLog::log(ArLog::Normal, "Error: Could not connect to laser(s). Exiting.");
    Aria::exit(2);
  }
  ArLog::log(ArLog::Normal, "Done connecting to laser(s).");
#endif

#if defined(ARNL_LASERLOC) || defined(ARNL_MAPPING)
  // find the laser we should use for localization and/or mapping,
  // which will be the first laser
  robot.lock();
  ArLaser *firstLaser = robot.findLaser(1);
  if (firstLaser == NULL || !firstLaser->isConnected())
  {
    ArLog::log(ArLog::Normal, "Did not have laser 1 or it is not connected, cannot start localization and/or mapping... exiting");
    Aria::exit(2);
  }
  robot.unlock();
#endif  


    /* Create and set up map object */
  
  // Set up the map object, this will look for files in the examples
  // directory (unless the file name starts with a /, \, or .
  // You can take out the 'fileDir' argument to look in the program's current directory
  // instead.
  // When a configuration file is loaded into ArConfig later, if it specifies a
  // map file, then that file will be loaded as the map.
  ArMap map(fileDir);
  // set it up to ignore empty file names (otherwise if a configuration omits
  // the map file, the whole configuration change will fail)
  map.setIgnoreEmptyFileName(true);
  // ignore the case, so that if someone is using MobileEyes or
  // MobilePlanner from Windows and changes the case on a map name,
  // it will still work.
  map.setIgnoreCase(true);

    
    /* Create localization threads */

#ifdef ARNL_MULTILOC
  ArLocalizationManager locManager(&robot, &map);
#define LOCTASK locManager
#endif


#ifdef ARNL_LASERLOC
  ArLog::log(ArLog::Normal, "Creating laser localization task");
  // Laser Monte-Carlo Localization
  ArLocalizationTask locTask(&robot, firstLaser, &map);
#ifdef ARNL_MULTILOC
  locManager.addLocalizationTask(&locTask);
#else
#define LOCTASK locTask
#endif
#endif
  

#ifdef ARNL_SONARLOC
  ArLog::log(ArLog::Normal, "Creating sonar localization task");
  ArSonarLocalizationTask locTask(&robot, &sonarDev, &map);
#ifdef ARNL_MULTILOC
  locManager.addLocalizationTask(&locTask);
#else
#define LOCTASK locTask
#endif
#endif

#ifndef ARNL_GPSLOC
  // A callback function, which is called if localization fails
  ArGlobalFunctor1<int> locFailedCB(&locFailed);
  locTask.setFailedCallBack(&locFailedCB); //, &locTask);
#endif

#ifdef ARNL_GPSLOC
  ArLog::log(ArLog::Normal, "Connecting to GPS...");

  // Connect to GPS
  ArGPS *gps = gpsConnector.createGPS(&robot);
  if(!gps || !gps->connect())
  {
    ArLog::log(ArLog::Terse, "Error connecting to GPS device."
      "Try -gpsType, -gpsPort, and/or -gpsBaud command-line arguments."
      "Use -help for help. Exiting.");
    Aria::exit(5);
  }

  // set up GPS localization task
  ArLog::log(ArLog::Normal, "Creating GPS localization task");
  ArGPSLocalizationTask gpsLocTask(&robot, gps, &map);
#ifdef ARNL_MULTILOC
  locManager.addLocalizationTask(&gpsLocTask);
#else
#define LOCTASK gpsLocTask
#endif
#endif

#ifdef ARNL_LASER
  // Set some options  and callbacks on each laser that the laser connector 
  // connected to.
  std::map<int, ArLaser *>::iterator laserIt;
  for (laserIt = robot.getLaserMap()->begin();
       laserIt != robot.getLaserMap()->end();
       laserIt++)
  {
    int laserNum = (*laserIt).first;
    ArLaser *laser = (*laserIt).second;

    // Skip lasers that aren't connected
    if(!laser->isConnected())
      continue;

    // add the disconnectOnError CB to shut things down if the laser
    // connection is lost
    laser->addDisconnectOnErrorCB(&shutdownFunctor);
    // set the number of cumulative readings the laser will take
    laser->setCumulativeBufferSize(200);
    // set the cumulative clean offset (so that they don't all fire at once)
    laser->setCumulativeCleanOffset(laserNum * 100);
    // reset the cumulative clean time (to make the new offset take effect)
    laser->resetLastCumulativeCleanTime();

    // Add the packet count to the Aria info strings (It will be included in
    // MobileEyes custom details so you can monitor whether the laser data is
    // being received correctly)
    std::string laserPacketCountName;
    laserPacketCountName = laser->getName();
    laserPacketCountName += " Packet Count";
    Aria::getInfoGroup()->addStringInt(
	    laserPacketCountName.c_str(), 10, 
	    new ArRetFunctorC<int, ArLaser>(laser, 
					 &ArLaser::getReadingCount));
  }
#endif





    /* Start the server */

  // Open the networking server
  if (!simpleOpener.open(&server, fileDir, 240))
  {
    ArLog::log(ArLog::Normal, "Error: Could not open server.");
    exit(2);
  }



    /* Create various services that provide network access to clients (such as
     * MobileEyes), as well as add various additional features to ARNL */


  robot.unlock();



  
  // Service to provide drawings of data in the map display :
  ArServerInfoDrawings drawings(&server);
  drawings.addRobotsRangeDevices(&robot);

#ifdef ARNL_LASERLOC
  /* Show the sample points used by MCL */
  ArDrawingData drawingDataL("polyDots", ArColor(0,255,0), 100, 75);
  ArFunctor2C<ArLocalizationTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorL(&locTask, &ArLocalizationTask::drawRangePoints);
  drawings.addDrawing(&drawingDataL, "Localization Points", &drawingFunctorL);
#endif

#ifdef ARNL_GPSLOC
  /* Show the positions calculated by GPS localization */

  ArDrawingData drawingDataG("polyDots", ArColor(100,100,255), 130, 61);
  ArFunctor2C<ArGPSLocalizationTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorG(&gpsLocTask, &ArGPSLocalizationTask::drawGPSPoints);
  drawings.addDrawing(&drawingDataG, "GPS Points", &drawingFunctorG);

  ArDrawingData drawingDataG2("polyDots", ArColor(255,100,100), 100, 62);
  ArFunctor2C<ArGPSLocalizationTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorG2(&gpsLocTask, &ArGPSLocalizationTask::drawKalmanPoints);
  drawings.addDrawing(&drawingDataG2, "Kalman Points", &drawingFunctorG2);

  ArDrawingData drawingDataG3("polyDots", ArColor(100,255,100), 70, 63);
  ArFunctor2C<ArGPSLocalizationTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorG3(&gpsLocTask, &ArGPSLocalizationTask::drawOdoPoints);
  drawings.addDrawing(&drawingDataG3, "Odom. Points", &drawingFunctorG3);

  ArDrawingData drawingDataG4("polyDots", ArColor(255,50,50), 100, 75);
  ArFunctor2C<ArGPSLocalizationTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorG4(&gpsLocTask, &ArGPSLocalizationTask::drawKalmanRangePoints);
  drawings.addDrawing(&drawingDataG4, "KalRange Points", &drawingFunctorG4);

  ArDrawingData drawingDataG5("polySegments", ArColor(100,0,255), 1, 78);
  ArFunctor2C<ArGPSLocalizationTask, ArServerClient *, ArNetPacket *> 
    drawingFunctorG5(&gpsLocTask, &ArGPSLocalizationTask::drawKalmanVariance);
  drawings.addDrawing(&drawingDataG5, "VarGPS", &drawingFunctorG5);
#endif

  // "Custom" commands. You can add your own custom commands here, they will
  // be available in MobileEyes' custom commands (enable in the toolbar or
  // access through Robot Tools)
  ArServerHandlerCommands commands(&server);


  // These provide various kinds of information to the client:
  ArServerInfoRobot serverInfoRobot(&server, &robot);
  ArServerInfoSensor serverInfoSensor(&server, &robot);

  // Provides localization info and allows the client (MobileEyes) to relocalize at a given
  // pose:
  ArServerInfoLocalization serverInfoLocalization(&server, &robot, &LOCTASK);
  ArServerHandlerLocalization serverLocHandler(&server, &robot, &LOCTASK);

  // If you're using MobileSim, ArServerHandlerLocalization sends it a command
  // to move the robot's true pose if you manually do a localization through 
  // MobileEyes.  To disable that behavior, use this constructor call instead:
  // ArServerHandlerLocalization serverLocHandler(&server, &robot, true, false);
  // The fifth argument determines whether to send the command to MobileSim.

  // Provide the map to the client (and related controls):
  ArServerHandlerMap serverMap(&server, &map);

  // These objects add some simple (custom) commands to 'commands' for testing and debugging:
  ArServerSimpleComUC uCCommands(&commands, &robot);                   // Send any command to the microcontroller
  ArServerSimpleComMovementLogging loggingCommands(&commands, &robot); // configure logging
  ArServerSimpleComLogRobotConfig configCommands(&commands, &robot);   // trigger logging of the robot config parameters
//  ArServerSimpleServerCommands serverCommands(&commands, &server);     // monitor networking behavior (track packets sent etc.)


  // service that allows the client to monitor the communication link status
  // between the robot and the client.
  //
  ArServerHandlerCommMonitor handlerCommMonitor(&server);



  // service that allows client to change configuration parameters in ArConfig 
  ArServerHandlerConfig handlerConfig(&server, Aria::getConfig(),
				      Arnl::getTypicalDefaultParamFileName(),
				      Aria::getDirectory());


  // This service causes the client to show simple dialog boxes
  ArServerHandlerPopup popupServer(&server);




  /* Set up the possible modes for remote control from a client such as
   * MobileEyes:
   */

  // Mode To stop and remain stopped:
  ArServerModeStop modeStop(&server, &robot);

#ifndef ARNL_SONARLOC
  // Cause the sonar to turn off automatically
  // when the robot is stopped, and turn it back on when commands to move
  // are sent. (Note, if using SONARNL to localize, then don't do this
  // since localization may get lost)
  ArSonarAutoDisabler sonarAutoDisabler(&robot);
#endif

  // Teleoperation modes To drive by keyboard, joystick, etc:
  ArServerModeRatioDrive modeRatioDrive(&server, &robot);  



  // Prevent normal teleoperation driving if localization is lost using
  // a high-priority action, which enables itself when the particular mode is
  // active.
  // (You have to enter unsafe drive mode to drive when lost.)
  ArActionLost actionLostRatioDrive(&LOCTASK, NULL, &modeRatioDrive);
  modeRatioDrive.getActionGroup()->addAction(&actionLostRatioDrive, 110);

  // Add drive mode section to the configuration, and also some custom (simple) commands:
  modeRatioDrive.addToConfig(Aria::getConfig(), "Teleop settings");
  modeRatioDrive.addControlCommands(&commands);

  // Wander mode (also prevent wandering if lost):
  ArServerModeWander modeWander(&server, &robot);
  ArActionLost actionLostWander(&LOCTASK, NULL, &modeWander);
  modeWander.getActionGroup()->addAction(&actionLostWander, 110);

  // Tool to log data periodically to a file
  ArDataLogger dataLogger(&robot, "datalog.txt");
  dataLogger.addToConfig(Aria::getConfig()); // make it configurable through ArConfig

  // Automatically add anything from the global info group to the data logger.
  Aria::getInfoGroup()->addAddStringCallback(dataLogger.getAddStringFunctor());

  // This provides a small table of interesting information for the client
  // to display to the operator. You can add your own callbacks to show any
  // data you want.
  ArServerInfoStrings stringInfo(&server);
  Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor());
  
  // The following statements add fields to a set of informational data called
  // the InfoGroup. These are served to MobileEyes for displayi (turn on by enabling Details
  // and Custom Details in the View menu of MobileEyes.)

  Aria::getInfoGroup()->addStringInt(
	  "Motor Packet Count", 10, 
	  new ArConstRetFunctorC<int, ArRobot>(&robot, 
					       &ArRobot::getMotorPacCount));

#ifdef ARNL_LASERLOC
  Aria::getInfoGroup()->addStringDouble(
	  "Laser Localization Score", 8, 
	  new ArRetFunctorC<double, ArLocalizationTask>(
		  &locTask, &ArLocalizationTask::getLocalizationScore),
	  "%.03f");
  Aria::getInfoGroup()->addStringInt(
	  "Laser Loc Num Samples", 8, 
	  new ArRetFunctorC<int, ArLocalizationTask>(
		  &locTask, &ArLocalizationTask::getCurrentNumSamples),
	  "%4d");
#elif defined(ARNL_SONARLOC)
  Aria::getInfoGroup()->addStringDouble(
	  "Sonar Localization Score", 8, 
	  new ArRetFunctorC<double, ArSonarLocalizationTask>(
		  &locTask, 
      &ArSonarLocalizationTask::getLocalizationScore),
	  "%.03f");
  Aria::getInfoGroup()->addStringInt(
	  "Sonar Loc Num Samples", 8, 
	  new ArRetFunctorC<int, ArSonarLocalizationTask>(
		  &locTask, &ArSonarLocalizationTask::getCurrentNumSamples),
	  "%4d");
#endif

#ifdef ARNL_GPSLOC
  const char *dopfmt = "%2.4f";
  const char *posfmt = "%2.8f";
  const char *altfmt = "%3.6f m";
  Aria::getInfoGroup()->addStringString(
	    "GPS Fix Mode", 25,
	    new ArConstRetFunctorC<const char*, ArGPS>(gps, &ArGPS::getFixTypeName)
    );
  Aria::getInfoGroup()->addStringInt(
	    "GPS Num. Satellites", 4,
	    new ArConstRetFunctorC<int, ArGPS>(gps, &ArGPS::getNumSatellitesTracked)
    );
  Aria::getInfoGroup()->addStringDouble(
	    "GPS HDOP", 12,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getHDOP),
      dopfmt
    );
  Aria::getInfoGroup()->addStringDouble(
	    "GPS VDOP", 5,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getVDOP),
      dopfmt
    );
  Aria::getInfoGroup()->addStringDouble(
	    "GPS PDOP", 5,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getPDOP),
      dopfmt
    );
  Aria::getInfoGroup()->addStringDouble(
	    "Latitude", 15,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getLatitude),
      posfmt
    );
  Aria::getInfoGroup()->addStringDouble(
	    "Longitude", 15,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getLongitude),
      posfmt
    );
  Aria::getInfoGroup()->addStringDouble(
	    "Altitude", 8,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getAltitude),
      altfmt
    );

  // only some GPS receivers provide these, but you can uncomment them
  // here to enable them if yours does.
  /*
  const char *errfmt = "%2.4f m";
  Aria::getInfoGroup()->addStringDouble(
	    "GPS Lat. Err.", 6,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getLatitudeError),
      errfmt
    );
  Aria::getInfoGroup()->addStringDouble(
	    "GPS Lon. Err.", 6,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getLongitudeError),
      errfmt
    );
  Aria::getInfoGroup()->addStringDouble(
	    "GPS Alt. Err.", 6,
	    new ArConstRetFunctorC<double, ArGPS>(gps, &ArGPS::getAltitudeError),
      errfmt
    );
  */

  Aria::getInfoGroup()->addStringDouble(
    "MOGS Localization Score", 8,
    new ArRetFunctorC<double, ArGPSLocalizationTask>(
      &gpsLocTask, &ArGPSLocalizationTask::getLocalizationScore),
    "%.03f"
  );

#endif

  // Display gyro status if gyro is enabled and is being handled by the firmware (gyro types 2, 3, or 4).
  // (If the firmware detects an error communicating with the gyro or IMU it
  // returns a flag, and stops using it.)
  // (This gyro type parameter, and fault flag, are only in ARCOS, not Seekur firmware)
  if(robot.getOrigRobotConfig() && robot.getOrigRobotConfig()->getGyroType() > 1)
  {
    Aria::getInfoGroup()->addStringString(
          "Gyro/IMU Status", 10,
          new ArGlobalRetFunctor1<const char*, ArRobot*>(&getGyroStatusString, &robot)
      );
  }

  // Display system CPU and wireless network status
  ArSystemStatus::startPeriodicUpdate(1000); // update every 1 second
  Aria::getInfoGroup()->addStringDouble("CPU Use", 10, ArSystemStatus::getCPUPercentFunctor(), "% 4.0f%%");
  Aria::getInfoGroup()->addStringInt("Wireless Link Quality", 9, ArSystemStatus::getWirelessLinkQualityFunctor(), "%d");
  Aria::getInfoGroup()->addStringInt("Wireless Link Noise", 9, ArSystemStatus::getWirelessLinkNoiseFunctor(), "%d");
  Aria::getInfoGroup()->addStringInt("Wireless Signal", 9, ArSystemStatus::getWirelessLinkSignalFunctor(), "%d");
  

  // stats on how far its driven since software started
  Aria::getInfoGroup()->addStringDouble("Distance Travelled (m)", 20, new ArRetFunctorC<double, ArRobot>(&robot, &ArRobot::getOdometerDistanceMeters), "%.2f");
  Aria::getInfoGroup()->addStringDouble("Run time (min)", 20, new
ArRetFunctorC<double, ArRobot>(&robot, &ArRobot::getOdometerTimeMinutes),
"%.2f");


#ifdef ARNL_GPSLOC
  // Add some "custom commands" for setting up initial GPS offset and heading.
  gpsLocTask.addLocalizationInitCommands(&commands);
  
  // Add some commands for manually creating map objects based on GPS positions:
//  ArGPSMapTools gpsMapTools(gps, &robot, &commands, &map);

  // Add command to set simulated GPS position manually
  if(gpsConnector.getGPSType() == ArGPSConnector::Simulator)
  {
    ArSimulatedGPS *simGPS = dynamic_cast<ArSimulatedGPS*>(gps);
//    simGPS->setDummyPosition(42.80709, -71.579047, 100);
    commands.addStringCommand("GPS:setDummyPosition", 
      "Manually set a new dummy position for simulated GPS. Provide latitude (required), longitude (required) and altitude (optional)", 
      new ArFunctor1C<ArSimulatedGPS, ArArgumentBuilder*>(simGPS, &ArSimulatedGPS::setDummyPositionFromArgs)
    );
  }
#endif


  // Make Stop mode the default (If current mode deactivates without entering
  // a new mode, then Stop Mode will be selected)
  modeStop.addAsDefaultMode();
    // TODO move up near where stop mode is created?




#ifdef ARNL_MAPPING

  /* Services that allow the client to initiate scanning with the laser to
     create maps in Mapper3 (So not possible with SONARNL): */

  ArServerHandlerMapping handlerMapping(&server, &robot, firstLaser, 
					fileDir, "", true);

#ifdef ARNL_LASERLOC
  // make laser localization stop while mapping
  handlerMapping.addMappingStartCallback(
	  new ArFunctor1C<ArLocalizationTask, bool>
	  (&locTask, &ArLocalizationTask::setIdleFlag, true));

  // and then make it start again when we're doine
  handlerMapping.addMappingEndCallback(
	  new ArFunctor1C<ArLocalizationTask, bool>
	  (&locTask, &ArLocalizationTask::setIdleFlag, false));
#endif

#ifdef ARNL_GPSLOC
  // Save GPS positions in the .2d scan log when making a map
  handlerMapping.addLocationData("robotGPS", 
			    gpsLocTask.getPoseInterpPositionCallback());

  // add the starting latitude and longitude info to the .2d scan log
  handlerMapping.addMappingStartCallback(
	  new ArFunctor1C<ArGPSLocalizationTask, ArServerHandlerMapping *>
	  (&gpsLocTask, &ArGPSLocalizationTask::addScanInfo, 
	   &handlerMapping));
#endif

  // Make it so our "lost" actions don't stop us while mapping
  handlerMapping.addMappingStartCallback(actionLostRatioDrive.getDisableCB());
  handlerMapping.addMappingStartCallback(actionLostWander.getDisableCB());

  // And then let them make us stop as usual when done mapping
  handlerMapping.addMappingEndCallback(actionLostRatioDrive.getEnableCB());
  handlerMapping.addMappingEndCallback(actionLostWander.getEnableCB());

#endif // ARNL_MAPPING


  /*
  // If we are on a simulator, move the robot back to its starting position,
  // and reset its odometry.
  // This will allow localizeRobotAtHomeBlocking() below will (probably) work (it
  // tries current odometry (which will be 0,0,0) and all the map
  // home points.
  // (Ignored by a real robot)
  //robot.com(ArCommands::SIM_RESET);
  */


  // create a pose storage class, this will let the program keep track
  // of where the robot is between runs...  after we try and restore
  // from this file it will start saving the robot's pose into the
  // file
  ArPoseStorage poseStorage(&robot);
  /// if we could restore the pose from then set the sim there (this
  /// won't do anything to the real robot)... if we couldn't restore
  /// the pose then just reset the position of the robot (which again
  /// won't do anything to the real robot)
  if (poseStorage.restorePose("robotPose"))
    serverLocHandler.setSimPose(robot.getPose());
  //else
 //   robot.com(ArCommands::SIM_RESET);



  /* File transfer services: */
  
#pragma GPP off
#ifdef WIN32
  // Not implemented for Windows yet.
  ArLog::log(ArLog::Normal, "Note, file upload/download services are not implemented for Windows; not enabling them.");
#else
  // This block will allow you to set up where you get and put files
  // to/from, just comment them out if you don't want this to happen
  // /*
  ArServerFileLister fileLister(&server, fileDir);
  ArServerFileToClient fileToClient(&server, fileDir);
  ArServerFileFromClient fileFromClient(&server, fileDir, "/tmp");
  ArServerDeleteFileOnServer deleteFileOnServer(&server, fileDir);
  // */
#endif
#pragma GPP on

    /* Video image streaming, and camera controls (Requires SAVserver or ACTS) */

  // Forward one video stream if either ACTS, ArVideo videoSubServer, 
  // or SAV server are running.
  // ArHybridForwarderVideo allows this program to be separate from the ArVideo
  // library. You could replace videoForwarder and the PTZ connection code below
  // with a call to ArVideo::createVideoServers(), and link the program to the
  // ArVideo library if you want to include video capture in the same program
  // as robot control.
  ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070);
  
  // connect to first configured camera PTZ controls (in robot parameter file and
  // command line options)
  ptzConnector.connect();
  ArCameraCollection cameraCollection;
  ArPTZ *ptz = ptzConnector.getPTZ(0);
  if(ptz)
  {
    ArLog::log(ArLog::Normal, "Connected to PTZ Camera");
    cameraCollection.addCamera("Camera1", ptz->getTypeName(), "Camera", ptz->getTypeName());

    videoForwarder.setCameraName("Camera1");
    videoForwarder.addToCameraCollection(cameraCollection);

    new ArServerHandlerCamera("Camera1", 
      &server, 
      &robot,
      ptz, 
      &cameraCollection);

  } 

  // Allows client to find any camera servers created above
  ArServerHandlerCameraCollection cameraCollectionServer(&server, &cameraCollection);



    /* Load configuration values, map, and begin! */

  
  // When parsing the configuration file, also look at the program's command line options 
  // from the command-line argument parser as well as the configuration file.
  // (So you can use any argument on the command line, namely -map.) 
  Aria::getConfig()->useArgumentParser(&parser);

  // Read in parameter files.
  ArLog::log(ArLog::Normal, "Loading config file %s%s into ArConfig...", Aria::getDirectory(), Arnl::getTypicalParamFileName());
  if (!Aria::getConfig()->parseFile(Arnl::getTypicalParamFileName()))
  {
    ArLog::log(ArLog::Normal, "Could not load ARNL configuration file. Set ARNL environment variable to use non-default installation director.y");
    Aria::exit(5);
  }

  // Warn about unknown params.
  if (!simpleOpener.checkAndLog() || !parser.checkHelpAndWarnUnparsed())
  {
    logOptions(argv[0]);
    Aria::exit(6);
  }

  // Warn if there is no map
  if (map.getFileName() == NULL || strlen(map.getFileName()) <= 0)
  {
    ArLog::log(ArLog::Normal, "");
    ArLog::log(ArLog::Normal, "### No map file is set up, you can make a map with the following procedure");
#ifdef ARNL
    ArLog::log(ArLog::Normal, "   0) You can find this information in README.txt or docs/Mapping.txt");
    ArLog::log(ArLog::Normal, "   1) Connect to this server with MobileEyes");
    ArLog::log(ArLog::Normal, "   2) Go to Tools->Map Creation->Start Scan");
    ArLog::log(ArLog::Normal, "   3) Give the map a name and hit okay");
    ArLog::log(ArLog::Normal, "   4) Drive the robot around your space (see docs/Mapping.txt");
    ArLog::log(ArLog::Normal, "   5) Go to Tools->Map Creation->Stop Scan");
    ArLog::log(ArLog::Normal, "   6) Start up Mapper3");
    ArLog::log(ArLog::Normal, "   7) Go to File->Open on Robot");
    ArLog::log(ArLog::Normal, "   8) Select the .2d you created");
    ArLog::log(ArLog::Normal, "   9) Create a .map");
    ArLog::log(ArLog::Normal, "  10) Go to File->Save on Robot");
    ArLog::log(ArLog::Normal, "  11) In MobileEyes, go to Tools->Robot Config");
    ArLog::log(ArLog::Normal, "  12) Choose the Files section");
    ArLog::log(ArLog::Normal, "  13) Enter the path and name of your new .map file for the value of the Map parameter.");
    ArLog::log(ArLog::Normal, "  14) Press OK and your new map should become the map used");
    ArLog::log(ArLog::Normal, "");    
#elif defined(SONARNL)
    ArLog::log(ArLog::Normal, "   0) You can find this information in README.txt or docs/SonarMapping.txt");
    ArLog::log(ArLog::Normal, "   1) Start up Mapper3Basic");
    ArLog::log(ArLog::Normal, "   2) Go to File->New");
    ArLog::log(ArLog::Normal, "   3) Draw a line map of your area (make sure it is to scale)");
    ArLog::log(ArLog::Normal, "   4) Go to File->Save on Robot");
    ArLog::log(ArLog::Normal, "   5) In MobileEyes, go to Tools->Robot Config");
    ArLog::log(ArLog::Normal, "   6) Choose the Files section");
    ArLog::log(ArLog::Normal, "   7) Enter the path and name of your new .map file for the value of the Map parameter.");
    ArLog::log(ArLog::Normal, "   8) Press OK and your new map should become the map used");
    ArLog::log(ArLog::Normal, "");    
#endif
#ifdef ARNL_GPSLOC
    ArLog::log(ArLog::Normal, "\n   See docs/GPSMapping.txt for instructions on creating a map for GPS localization");
#endif
  }

  // Print a log message notifying user of the directory for map files
  ArLog::log(ArLog::Normal, "");
  ArLog::log(ArLog::Normal, 
	     "Directory for maps and file serving: %s", fileDir);
  
  ArLog::log(ArLog::Normal, "See the ARNL README.txt for more information");
  ArLog::log(ArLog::Normal, "");

  // Do an initial localization of the robot. ARNL and SONARNL try all the home points
  // in the map, as well as the robot's current odometric position, as possible
  // places the robot is likely to be at startup.   If successful, it will
  // also save the position it found to be the best localized position as the
  // "Home" position, which can be obtained from the localization task (and is
  // used by the "Go to home" network request).
  // MOGS instead just initializes at the current GPS position.
  // (You will stil have to drive the robot so it can determine the robot's
  // heading, however. See GPS Mapping instructions.)
  LOCTASK.localizeRobotAtHomeBlocking();
  
#ifdef ARNL_MULTIROBOT
  // Let the client switch manager (for multirobot) spin off into its own thread
  // TODO move to multirobot example?
  clientSwitch.runAsync();
#endif

  // Start the networking server's thread
  server.runAsync();

  ArLog::log(ArLog::Normal, "Server running. To exit, press CTRL-C.");

  // Enable the motors and wait until the robot exits (disconnection, etc.) or this program is
  // canceled.
  robot.enableMotors();
  robot.waitForRunExit();
  Aria::exit(0);
}
Пример #21
0
/**
 * @brief Creates an XsOutputConfigurationArray and pushes it to the sensor.
 * @details
 * - Configures the sensor with desired modules
 * - Refer to xsdataidentifier.h
 */
void mtiG::configure(){

	XsOutputConfigurationArray configArray;

	if(mSettings.orientationData){			//Quaternion - containsOrientation
			XsOutputConfiguration quat(XDI_Quaternion, mSettings.orientationFreq);// para pedir quaternion
			configArray.push_back(quat);
	}
	
	if(mSettings.gpsData){
			//LATITUDE E LONGITUDE -containsLatitudeLongitude
			XsOutputConfiguration gps(XDI_LatLon, mSettings.gpsFreq);// para pedir gps, //XDI_Quaternion 06/04
			configArray.push_back(gps);

			XsOutputConfiguration gps_age(XDI_GpsAge, mSettings.gpsFreq);// para pedir gps, //XDI_Quaternion 06/04
			configArray.push_back(gps_age);

			XsOutputConfiguration gps_sol(XDI_GpsSol, mSettings.gpsFreq);// para pedir gps, //XDI_Quaternion 06/04
			configArray.push_back(gps_sol);

			XsOutputConfiguration gps_dop(XDI_GpsDop, mSettings.gpsFreq);// para pedir gps, //XDI_Quaternion 06/04
			configArray.push_back(gps_dop);
	}
	
	if(mSettings.temperatureData){	
			//TEMPERATURA - containsTemperature
			XsOutputConfiguration temp(XDI_Temperature, mSettings.temperatureFreq);
			configArray.push_back(temp);
	}	
	
	if(mSettings.accelerationData){
			//ACCELERATION - containsCalibratedAcceleration
			XsOutputConfiguration accel(XDI_Acceleration, mSettings.accelerationFreq);
			configArray.push_back(accel);
	}

	if(mSettings.pressureData){	
			//PRESSURE - containsPressure
			XsOutputConfiguration baro(XDI_BaroPressure, mSettings.pressureFreq);
			configArray.push_back(baro);
	}

	if(mSettings.magneticData){
			//MAGNETIC FIELD - containsCalibratedMagneticField
			XsOutputConfiguration magnet(XDI_MagneticField, mSettings.magneticFreq);
			configArray.push_back(magnet);
	}

	if(mSettings.altitudeData){
			//ALTITUDE - containsAltitude
			XsOutputConfiguration alt(XDI_AltitudeEllipsoid, mSettings.altitudeFreq);
			configArray.push_back(alt);
	}

	if(mSettings.gyroscopeData){
			//GYRO - containsCalibratedGyroscopeData
			XsOutputConfiguration gyro(XDI_RateOfTurn, mSettings.gyroscopeFreq);
			configArray.push_back(gyro);
	}	

	if(mSettings.velocityData){
			//VELOCIDADE XYZ
			XsOutputConfiguration vel_xyz(XDI_VelocityXYZ, mSettings.velocityFreq);
			configArray.push_back(vel_xyz);
	}
	
	// Puts configArray into the device, overwriting the current configuration
	if (!device->setOutputConfiguration(configArray))
	{
			throw std::runtime_error("Could not configure MTmk4 device. Aborting.");
	}
}
int _tmain(int argc, char** argv)
{
    //-------------- M A I N    D E L   P R O G R A M A   D E L    R O B O T------------//
    //----------------------------------------------------------------------------------//

    //inicializaion de variables
    Aria::init();
    ArArgumentParser parser(&argc, argv);
    parser.loadDefaultArguments();
    ArSimpleConnector simpleConnector(&parser);
    ArRobot robot;
    ArSonarDevice sonar;
    ArAnalogGyro gyro(&robot);
    robot.addRangeDevice(&sonar);
    ActionTurns turn(400, 55);
    robot.addAction(&turn, 49);
    ActionTurns turn2(400, 55);
    robot.addAction(&turn2, 49);
    turn.deactivate();
    turn2.deactivate();

    // presionar tecla escape para salir del programa
    ArKeyHandler keyHandler;
    Aria::setKeyHandler(&keyHandler);
    robot.attachKeyHandler(&keyHandler);
    printf("Presionar ESC para salir\n");

    // uso de sonares para evitar colisiones con las paredes u
    // obstaculos grandes, mayores a 8cm de alto
    ArActionLimiterForwards limiterAction("limitador velocidad cerca", 300, 600, 250);
    ArActionLimiterForwards limiterFarAction("limitador velocidad lejos", 300, 1100, 400);
    ArActionLimiterTableSensor tableLimiterAction;
    robot.addAction(&tableLimiterAction, 100);
    robot.addAction(&limiterAction, 95);
    robot.addAction(&limiterFarAction, 90);


    // Inicializon la funcion de goto
    ArActionGoto gotoPoseAction("goto");
    robot.addAction(&gotoPoseAction, 50);

    // Finaliza el goto si es que no hace nada
    ArActionStop stopAction("stop");
    robot.addAction(&stopAction, 40);

    // Parser del CLI
    if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
    {
        Aria::logOptions();
        exit(1);
    }

    // Conexion del robot
    if (!simpleConnector.connectRobot(&robot))
    {
        printf("Could not connect to robot... exiting\n");
        Aria::exit(1);
    }
    robot.runAsync(true);

    // enciende motores, apaga sonidos
    robot.enableMotors();
    robot.comInt(ArCommands::SOUNDTOG, 0);

    // Imprimo algunos datos del robot como posicion velocidad y bateria
    robot.lock();
    ArLog::log(ArLog::Normal, "Posicion=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Bateria=%.2fV",
               robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getBatteryVoltage());
    robot.unlock();

    const int duration = 100000; //msec
    ArLog::log(ArLog::Normal, "Completados los puntos en %d segundos", duration/1000);

    bool first = true;
    int goalNum = 0;
    int color = 3;
    ArTime start;
    start.setToNow();
    while (Aria::getRunning())
    {
        robot.lock();

        // inicia el primer punto
        if (first || gotoPoseAction.haveAchievedGoal())
        {
            first = false;

            goalNum++; //cambia de 0 a 1 el contador
            printf("El contador esta en: --> %d <---\n",goalNum);
            if (goalNum > 20)
                goalNum = 1;

            //comienza la secuencia de puntos
            if (goalNum == 1)
            {
                gotoPoseAction.setGoal(ArPose(1150, 0));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                // Imprimo algunos datos del robot como posicion velocidad y bateria
                robot.lock();
                ArLog::log(ArLog::Normal, "Posicion=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Bateria=%.2fV",
                           robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getBatteryVoltage());
                robot.unlock();
            }
            else if (goalNum == 2)
            {
                printf("Gira 90 grados izquierda\n");
                robot.unlock();
                turn.myActivate = 1;
                turn.myDirection = 1;
                turn.activate();
                ArUtil::sleep(1000);
                turn.deactivate();
                turn.myActivate = 0;
                turn.myDirection = 0;
                robot.lock();
            }
            else if (goalNum == 3)
            {
                gotoPoseAction.setGoal(ArPose(1150, 2670));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                // Imprimo algunos datos del robot como posicion velocidad y bateria
                robot.lock();
                ArLog::log(ArLog::Normal, "Posicion=(%.2f,%.2f,%.2f), Trans. Vel=%.2f, Bateria=%.2fV",
                           robot.getX(), robot.getY(), robot.getTh(), robot.getVel(), robot.getBatteryVoltage());
                robot.unlock();
            }
            else if (goalNum == 4)
            {
                printf("Gira 90 grados izquierda\n");
                robot.unlock();
                turn2.myActivate = 1;
                turn2.myDirection = 1;
                turn2.activate();
                ArUtil::sleep(1000);
                turn2.deactivate();
                turn2.myActivate = 0;
                turn2.myDirection = 0;
                robot.lock();
            }
            else if (goalNum == 5)
            {
                gotoPoseAction.setGoal(ArPose(650, 2670));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
            }
            else if (goalNum == 6)
            {
                printf("Gira 90 grados izquierda\n");
                robot.unlock();
                turn2.myActivate = 1;
                turn2.myDirection = 1;
                turn2.activate();
                ArUtil::sleep(1000);
                turn2.deactivate();
                turn2.myActivate = 0;
                turn2.myDirection = 0;
                robot.lock();
            }
            else if (goalNum == 7)
            {
                gotoPoseAction.setGoal(ArPose(650, 0));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
            }
            else if (goalNum == 8)
            {
                gotoPoseAction.setGoal(ArPose(1800,1199));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
            }
            else if (goalNum == 9)
            {
                gotoPoseAction.setGoal(ArPose(2600, 1199));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
            }
            else if (goalNum == 10)
            {
                if (color == 1)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 850));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 2)
                {
                    gotoPoseAction.setGoal(ArPose(3500, 1199));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 3)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 1550));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
            }
            else if (goalNum == 11)
            {
                if (color == 1)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 613));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 2)
                {
                    printf("Gira 180 grados derecha\n");
                    robot.unlock();
                    turn2.myActivate = 1;
                    turn2.myDirection = 2;
                    turn2.activate();
                    ArUtil::sleep(2000);
                    turn2.deactivate();
                    turn2.myActivate = 0;
                    turn2.myDirection = 0;
                    robot.lock();
                    goalNum = 19;
                }
                if (color == 3)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 1785));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
            }
            else if (goalNum == 12)
            {
                if (color == 1)
                {
                    gotoPoseAction.setGoal(ArPose(3300, 413));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 3)
                {
                    gotoPoseAction.setGoal(ArPose(3300, 1985));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
            }
            else if (goalNum == 13)
            {
                if (color == 1)
                {
                    gotoPoseAction.setGoal(ArPose(3500, 413));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 3)
                {
                    gotoPoseAction.setGoal(ArPose(3500, 1985));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
            }
            else if (goalNum == 14)
            {
                //secuencia de drop de la figura
            }
            else if (goalNum == 15)
            {
                printf("Gira 180 grados derecha\n");
                robot.unlock();
                turn2.myActivate = 1;
                turn2.myDirection = 2;
                turn2.activate();
                ArUtil::sleep(2000);
                turn2.deactivate();
                turn2.myActivate = 0;
                turn2.myDirection = 0;
                robot.lock();
            }
            else if (goalNum == 16)
            {
                if (color == 1)
                {
                    gotoPoseAction.setGoal(ArPose(3300, 413));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 3)
                {
                    gotoPoseAction.setGoal(ArPose(3300, 1985));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
            }
            else if (goalNum == 17)
            {
                if (color == 1)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 603));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 3)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 1795));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
            }
            else if (goalNum == 18)
            {
                if (color == 1)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 860));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
                if (color == 3)
                {
                    gotoPoseAction.setGoal(ArPose(2800, 1540));
                    ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                               gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
                }
            }
            else if (goalNum == 19)
            {
                gotoPoseAction.setGoal(ArPose(2600, 1199));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
            }
            else if (goalNum == 20)
            {
                gotoPoseAction.setGoal(ArPose(1800, 1199));
                ArLog::log(ArLog::Normal, "Siguiente punto en %.0f %.0f",
                           gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
            }
        }

        if(start.mSecSince() >= duration) {
            ArLog::log(ArLog::Normal, "No puede llegar al punto, y la aplicacion saldra en %d", duration/1000);
            gotoPoseAction.cancelGoal();
            robot.unlock();
            ArUtil::sleep(3000);
            break;
        }

        robot.unlock();
        ArUtil::sleep(10);
    }

    // Robot desconectado al terminal el sleep
    Aria::shutdown();

//----------------------------------------------------------------------------------//

    return 0;
}
int main(int argc, char **argv)
{


  Aria::init();

  argc = 3;
  argv[0] = "";
  argv[1] = "-rp";
  argv[2] = "/dev/ttyUSB0";
  ArArgumentParser parser(&argc, argv);
  parser.loadDefaultArguments();
  ArRobot robot;
  ArAnalogGyro gyro(&robot);
  ArSonarDevice sonar;
  ArRobotConnector robotConnector(&parser, &robot);

  if(!robotConnector.connectRobot())
  {
    if(parser.checkHelpAndWarnUnparsed())
    {
        Aria::logOptions();
        Aria::exit(1);
    }
  }

  if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
  {
    Aria::logOptions();
    Aria::exit(1);
  }

 imgdb.setRobot(&robot);

  int Rc;
  pthread_t slam_thread;
  Rc = pthread_create(&slam_thread, NULL, slam_event, NULL);
  if (Rc) { printf("Create slam thread failed!\n"); exit(-1); }

  ImageList* current = NULL;
  while (!current) current = imgdb.getEdge();
    // current->person_point


  robot.addRangeDevice(&sonar);
  robot.runAsync(true);

  ArKeyHandler keyHandler;
  Aria::setKeyHandler(&keyHandler);
  robot.attachKeyHandler(&keyHandler);
  printf("You may press escape to exit\n");

  robot.setAbsoluteMaxRotVel(30);

  ArActionStallRecover recover;
  ArActionBumpers bumpers;
  double minDistance=10000;
 // ArPose endPoint(point.x, point.z);

//  current->collect_x
//          current->collect_y
//          robot.getX()
//          robot.getY()
//  current = imgdb.getEdge();

//  for (int i = 0; i < current->edge.size(); i++) {
//      for (int j = 0; j < current->edge[i].size() - 1; j++) {
//          double dis = sqrt(pow(current->edge[i][j].z,2)+(pow(current->edge[i][j].x,2)));
//           if(dis<minDistance){
//              minDistance=dis;
//           }
//      }
//  }

 // 引入避障action,前方安全距离为500mm,侧边安全距离为340mm
  Avoid avoidSide("Avoid side", ArPose(0, 0), 800, 100, 1000*minDistance);



  robot.addAction(&recover, 100);
  robot.addAction(&bumpers, 95);
  robot.addAction(&avoidSide, 80);

  ArActionStop stopAction("stop");
  robot.addAction(&stopAction, 50);

  robot.enableMotors();
  robot.comInt(ArCommands::SOUNDTOG, 0);


  const int duration = 500000;

  bool first = true;
  int goalNum = 0;
  ArTime start;
  start.setToNow();

  while (Aria::getRunning())
  {
    current = imgdb.getEdge();
    for (int i = 0; i < current->edge.size(); i++) {
        for (int j = 0; j < current->edge[i].size() - 1; j++) {
    //        printf("i=%d\n",i);
            double dis = sqrt(pow(current->edge[i][j].z,2)+(pow(current->edge[i][j].x,2)));
       //     printf("dis=%f,mindis=%f\n",dis,minDistance);
             if(dis<minDistance){
                minDistance=dis;
   printf("min=%f\n",minDistance);
             }
        }
    }
    //引入避障action,前方安全距离为500mm,侧边安全距离为340mm
 //   Avoid avoidSide("Avoid side", ArPose(0, 0), 800, 200, minDistance);
  //  robot.addAction(&avoidSide,80);
    robot.lock();

    if (first || avoidSide.haveAchievedGoal())
    {
      first = false;
      goalNum++;
      printf("count goalNum = %d\n", goalNum);
      if (goalNum > 2){
        goalNum = 1; // start again at goal #1
      }
//   avoidSide.setGoal(ArPose(10000,0));
        if(goalNum==1){
        printf("zuobiaox=%f,zuobiaoy=%f\n",-current->person_point.z,current->person_point.x);
        avoidSide.setGoal(ArPose(1000*current->person_point.z, -1000*current->person_point.x));
        printf("goalNum == 1\n\n");
        }
        else if(goalNum==2){
            printf("zuobiaox=%f,zuobiaoy=%f\n",-current->person_point.z,current->person_point.x);
            avoidSide.setGoal(ArPose(1000*current->person_point.z, -1000*current->person_point.x));
            printf("goalNum == 2\n\n");
        }

    }
    if(start.mSecSince() >= duration) {
      ArLog::log(ArLog::Normal, "%d seconds have elapsed. Cancelling current goal, waiting 3 seconds, and exiting.", duration/1000);
      avoidSide.cancelGoal();
      robot.unlock();
      ArUtil::sleep(3000);
      break;
    }
    robot.unlock();
  ArUtil::sleep(100);
  }

  Aria::exit(0);
  return 0;
}
Пример #24
0
void SensorFilter::update(FilteredSensorData& filteredSensorData,
                          const SensorData& theSensorData,
                          const InertiaSensorData& theInertiaSensorData,
                          const OrientationData& theOrientationData)
{
  // copy sensor data (except gyro and acc)
  Vector2<> gyro(filteredSensorData.data[SensorData::gyroX], filteredSensorData.data[SensorData::gyroY]);
  Vector3<> acc(filteredSensorData.data[SensorData::accX], filteredSensorData.data[SensorData::accY], filteredSensorData.data[SensorData::accZ]);
  (SensorData&)filteredSensorData = theSensorData;
  filteredSensorData.data[SensorData::gyroX] = gyro.x;
  filteredSensorData.data[SensorData::gyroY] = gyro.y;
  filteredSensorData.data[SensorData::accX] = acc.x;
  filteredSensorData.data[SensorData::accY] = acc.y;
  filteredSensorData.data[SensorData::accZ] = acc.z;

  // take calibrated inertia sensor data
  for(int i = 0; i < 2; ++i)
  {
    if(theInertiaSensorData.gyro[i] != InertiaSensorData::off)
      filteredSensorData.data[SensorData::gyroX + i] = theInertiaSensorData.gyro[i];
    else if(filteredSensorData.data[SensorData::gyroX + i] == SensorData::off)
      filteredSensorData.data[SensorData::gyroX + i] = 0.f;
  }
  filteredSensorData.data[SensorData::gyroZ] = 0.f;
  for(int i = 0; i < 3; ++i)
  {
    if(theInertiaSensorData.acc[i] != InertiaSensorData::off)
      filteredSensorData.data[SensorData::accX + i] = theInertiaSensorData.acc[i] / 9.80665f;
    else if(filteredSensorData.data[SensorData::accX + i] == SensorData::off)
      filteredSensorData.data[SensorData::accX + i] = 0.f;
  }

  // take orientation data
  filteredSensorData.data[SensorData::angleX] = theOrientationData.orientation.x;
  filteredSensorData.data[SensorData::angleY] = theOrientationData.orientation.y;

#ifndef RELEASE
  if(filteredSensorData.data[SensorData::gyroX] != SensorData::off)
  {
    gyroAngleXSum += filteredSensorData.data[SensorData::gyroX] * (theSensorData.timeStamp - lastIteration) * 0.001f;
    gyroAngleXSum = normalize(gyroAngleXSum);
    lastIteration = theSensorData.timeStamp;
  }
  //PLOT("module:SensorFilter:gyroAngleXSum", gyroAngleXSum);
#endif

  /*
  PLOT("module:SensorFilter:rawAngleX", theSensorData.data[SensorData::angleX]);
  PLOT("module:SensorFilter:rawAngleY", theSensorData.data[SensorData::angleY]);

  PLOT("module:SensorFilter:rawAccX", theSensorData.data[SensorData::accX]);
  PLOT("module:SensorFilter:rawAccY", theSensorData.data[SensorData::accY]);
  PLOT("module:SensorFilter:rawAccZ", theSensorData.data[SensorData::accZ]);

  PLOT("module:SensorFilter:rawGyroX", theSensorData.data[SensorData::gyroX]);
  PLOT("module:SensorFilter:rawGyroY", theSensorData.data[SensorData::gyroY]);
  PLOT("module:SensorFilter:rawGyroZ", theSensorData.data[SensorData::gyroZ]);

  PLOT("module:SensorFilter:angleX", filteredSensorData.data[SensorData::angleX]);
  PLOT("module:SensorFilter:angleY", filteredSensorData.data[SensorData::angleY]);

  PLOT("module:SensorFilter:accX", filteredSensorData.data[SensorData::accX]);
  PLOT("module:SensorFilter:accY", filteredSensorData.data[SensorData::accY]);
  PLOT("module:SensorFilter:accZ", filteredSensorData.data[SensorData::accZ]);

  PLOT("module:SensorFilter:gyroX", filteredSensorData.data[SensorData::gyroX] != float(SensorData::off) ? filteredSensorData.data[SensorData::gyroX] : 0);
  PLOT("module:SensorFilter:gyroY", filteredSensorData.data[SensorData::gyroY] != float(SensorData::off) ? filteredSensorData.data[SensorData::gyroY] : 0);
  PLOT("module:SensorFilter:gyroZ", filteredSensorData.data[SensorData::gyroZ] != float(SensorData::off) ? filteredSensorData.data[SensorData::gyroZ] : 0);

  //PLOT("module:SensorFilter:us", filteredSensorData.data[SensorData::us]);
  */
}
Пример #25
0
int main(int argc, char *argv[])
{
    // Initialize location of Aria, Arnl and their args.
    Aria::init();
    Arnl::init();


    // The robot object
    ArRobot robot;

    // Parse the command line arguments.
    ArArgumentParser parser(&argc, argv);

    // Read data_index if exists
    int data_index;
    bool exist_data_index;
    parser.checkParameterArgumentInteger("dataIndex",&data_index,&exist_data_index);


    // Load default arguments for this computer (from /etc/Aria.args, environment
    // variables, and other places)
    parser.loadDefaultArguments();


    // Object that connects to the robot or simulator using program options
    ArRobotConnector robotConnector(&parser, &robot);


    // set up a gyro
    ArAnalogGyro gyro(&robot);

    ArLog::init(ArLog::File,ArLog::Normal,"run.log",false,true,true);

    // Parse arguments for the simple connector.
    if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
    {
        ArLog::log(ArLog::Normal, "\nUsage: %s -map mapfilename\n", argv[0]);
        Aria::logOptions();
        Aria::exit(1);
    }

    // Collision avoidance actions at higher priority
    ArActionAvoidFront avoidAction("avoid",200);
    ArActionLimiterForwards limiterAction("speed limiter near", 150, 500, 150);
    ArActionLimiterForwards limiterFarAction("speed limiter far", 300, 1100, 400);
    ArActionLimiterTableSensor tableLimiterAction;
    //robot.addAction(&tableLimiterAction, 100);
    //robot.addAction(&avoidAction,100);
    //robot.addAction(&limiterAction, 95);
    //robot.addAction(&limiterFarAction, 90);

    // Goto action at lower priority
    ArActionGoto gotoPoseAction("goto");
    //robot.addAction(&gotoPoseAction, 50);
    gotoPoseAction.setCloseDist(750);

    // Stop action at lower priority, so the robot stops if it has no goal
    ArActionStop stopAction("stop");
    //robot.addAction(&stopAction, 40);




    // Connect the robot
    if (!robotConnector.connectRobot())
    {
        ArLog::log(ArLog::Normal, "Could not connect to robot... exiting");
        Aria::exit(3);
    }

    if(!robot.isConnected())
    {
        ArLog::log(ArLog::Terse, "Internal error: robot connector succeeded but ArRobot::isConnected() is false!");
    }




    // Connector for laser rangefinders
    ArLaserConnector laserConnector(&parser, &robot, &robotConnector);


    // Sonar, must be added to the robot, used by teleoperation and wander to
    // detect obstacles, and for localization if SONARNL
    ArSonarDevice sonarDev;

    // Add the sonar to the robot
    robot.addRangeDevice(&sonarDev);

    // Start the robot thread.
    robot.runAsync(true);


    // Connect to the laser(s) if lasers were configured in this robot's parameter
    // file or on the command line, and run laser processing thread if applicable
    // for that laser class.  For the purposes of this demo, add all
    // possible lasers to ArRobot's list rather than just the ones that were
    // connected by this call so when you enter laser mode, you
    // can then interactively choose which laser to use from that list of all
    // lasers mentioned in robot parameters and on command line. Normally,
    // only connected lasers are put in ArRobot's list.
    if (!laserConnector.connectLasers(
                false,  // continue after connection failures
                true,  // add only connected lasers to ArRobot
                true    // add all lasers to ArRobot
            ))
    {
        ArLog::log(ArLog::Normal ,"Could not connect to lasers... exiting\n");
        Aria::exit(2);
    }


    // Puntero a laser
    ArSick* sick=(ArSick*)robot.findLaser(1);



    // Conectamos el laser
    sick->asyncConnect();

    //Esperamos a que esté encendido
    while(!sick->isConnected())
    {
        ArUtil::sleep(100);
    }

    ArLog::log(ArLog::Normal ,"Laser conectado\n");




    // Set up things so data can be logged (only do it with the laser
    // since it can overrun a 9600 serial connection which the sonar is
    // more likely to have)
    ArDataLogger dataLogger(&robot);
    dataLogger.addToConfig(Aria::getConfig());

    // add our logging to the config
    //ArLog::addToConfig(Aria::getConfig());




    // Set up a class that'll put the movement and gyro parameters into ArConfig
    ArRobotConfig robotConfig(&robot);
    robotConfig.addAnalogGyro(&gyro);



    // Add additional range devices to the robot and path planning task.
    // IRs if the robot has them.
    robot.lock();
    ArIRs irs;
    robot.addRangeDevice(&irs);

    // Bumpers.
    ArBumpers bumpers;
    robot.addRangeDevice(&bumpers);


    // cause the sonar to turn off automatically
    // when the robot is stopped, and turn it back on when commands to move
    // are sent. (Note, this should not be done if you need the sonar
    // data to localize, or for other purposes while stopped)
    ArSonarAutoDisabler sonarAutoDisabler(&robot);



    // Read in parameter files.
    Aria::getConfig()->useArgumentParser(&parser);
    if (!Aria::getConfig()->parseFile(Arnl::getTypicalParamFileName()))
    {
        ArLog::log(ArLog::Normal, "Trouble loading configuration file, exiting");
        Aria::exit(5);
    }




    //Configuracion del laser
    sick->setMinDistBetweenCurrent(0);

    robot.enableMotors();
    robot.setAbsoluteMaxTransVel(1000);

    /* Finally, get ready to run the robot: */
    robot.unlock();



    Controlador driver(&robot);

    if(exist_data_index){
    	driver.setDataIndex(data_index);
    }

    driver.runAsync();


    ControlHandler handler(&driver,&robot);
    // Use manual key handler
    //handler.addKeyHandlers(&robot);
    robot.addSensorInterpTask("ManualKeyHandler",50,handler.getFunctor());
    ArLog::log(ArLog::Normal ,"Añadido manejador teclado\n");












//    double x,y,dist,angle;

//    ArPose punto;
//    ArPose origen=robot.getPose();

//    sick->lockDevice();

//    for(int i=-90;i<90;i++){
//	// Obtengo la medida de distancia y angulo
//	dist=sick->currentReadingPolar(i,i+1,&angle);

//	// Obtengo coordenadas del punto usando el laser como referencia
//	x=dist*ArMath::cos(angle);
//	y=dist*ArMath::sin(angle);

//	//Roto los puntos
//	ArMath::pointRotate(&x,&y,-origen.getTh());
//	punto.setX(x);
//	punto.setY(y);

//	punto=punto + origen;

//	printf("Medida: %d\t Angulo:%.2f\t Angulo:%.2f\t Distancia:%0.2f\t X:%0.2f\t Y:%0.2f\n",i,angle,angle+origen.getTh(),dist,punto.getX(),punto.getY());
//    }
//    printf("Medidas adquiridas\n");

//    sick->unlockDevice();


    robot.waitForRunExit();


    //ArUtil::sleep(10000);


    return 0;

}
Пример #26
0
int main() {

	LocalI2CBus bus(1);
	
	ADXL345 acc(&bus);
	L3G4200D gyro(&bus);
		
	acc.setEnabled(false);
	acc.setDataRate(ADXL345::DATARATE_100_HZ);
	acc.setRange(ADXL345::RANGE_16G);
	acc.setFullResolutionEnabled(true);
	acc.setEnabled(true);

	gyro.setEnabled(false);
	gyro.setOutputDataRate(L3G4200D::DATARATE_800_HZ);
	//gyro.setBlockDataUpdateEnabled(false);
	gyro.setEnabled(true);

	timespec ts, ts2;
	clock_gettime(CLOCK_REALTIME, &ts);
	for (int i=0; i<1000; i++)
		clock_gettime(CLOCK_REALTIME, &ts2);
	int gettime_delay_ns = ((ts2.tv_sec-ts.tv_sec)*1000000000 + ts2.tv_nsec-ts.tv_nsec) / 1000;
	printf("gettime delay: %d\n", gettime_delay_ns);
	usleep(1000000);
	
	
	double accv[32][3];
	double rotv[100][3];
	double rota[3], rot[3];
	for (int i=0; i<10000; i++) {
		//acc.getLinearAcceleration(accv[i][0], accv[i][1], accv[i][2]);
		//gyro.getAngularVelocity(rotv[i][0], rotv[i][1], rotv[i][2]);
		gyro.getAngularVelocity(rot[0], rot[1], rot[2]);
		rota[0] += rot[0];
		rota[1] += rot[1];
		rota[2] += rot[2];
		clock_gettime(CLOCK_REALTIME, &ts2);
		//usleep(10000);
	}
	rota[0] /= 10000;
	rota[1] /= 10000;
	rota[2] /= 10000;
	/*
	for (int i=0; i<100; i++) {
		//printf("\t%.2lf\t%.2lf\t%.2lf\n", accv[i][0], accv[i][1], accv[i][2]);
		//printf("\t%.2lf\t%.2lf\t%.2lf\n", rotv[i][0], rotv[i][1], rotv[i][2]);
	}
	printf("\n\n");
	printf("\t%.2lf\t%.2lf\t%.2lf\n", rota[0]/32, rota[1]/32, rota[2]/32);
	printf("\n\n");
	usleep(10000000);
	*/
	
	acc.calibrate(100);

	int8 ox, oy, oz;
	acc.getOffset(ox, oy, oz);
	printf("%d\t%d\t%d\n", ox, oy, oz);
	usleep(1000000);

	int16 x, y, z;
	double acc_x = 0, acc_y = 0, acc_z = 0, mag;
	double lacc_x, lacc_y, lacc_z;
	double rot_x, rot_y, rot_z;
	double ang_x = 0, ang_y = 0, ang_z = 0, interval, dang[3], gvec[3] = {0, 0, 0};
	
	clock_gettime(CLOCK_REALTIME, &ts);
		
	while (true) {
		acc.getLinearAcceleration(lacc_x, lacc_y, lacc_z);
		gyro.getAngularVelocity(rot_x, rot_y, rot_z);
		acc_x = (15 * acc_x + lacc_x) / 16;
		acc_y = (15 * acc_y + lacc_y) / 16;
		acc_z = (15 * acc_z + lacc_z) / 16;
		mag = acc_x*acc_x+acc_y*acc_y+acc_z*acc_z;
		//printf("\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t|\t%.2lf\t%.2lf\t%.2lf", acc_x, acc_y, acc_z, mag, rot_x, rot_y, rot_z);
		//usleep(10000);
		clock_gettime(CLOCK_REALTIME, &ts2);
		interval = ((ts2.tv_sec-ts.tv_sec)*1000000000 + ts2.tv_nsec-ts.tv_nsec - gettime_delay_ns)/1000.0;
		ts = ts2;
		dang[0] = - (rot_x - rota[0]) * interval / 1000000;
		dang[1] = - (rot_y - rota[1]) * interval / 1000000;
		dang[2] = - (rot_z - rota[2]) * interval / 1000000;
		ang_x += dang[0];
		ang_y += dang[1];
		ang_z += dang[2];
		dang[0] *= 3.14 / 180;
		dang[1] *= 3.14 / 180;
		dang[2] *= 3.14 / 180;
		rotateV(gvec, dang);
		mag = mag * 100 / (9.81 * 9.81);
		if (72.0 < mag && mag < 133.0) {
			gvec[0] = (gvec[0] * 600 + acc_x) / 601;
			gvec[1] = (gvec[1] * 600 + acc_y) / 601;
			gvec[2] = (gvec[2] * 600 + acc_z) / 601;
		}
		printf("\t%.2lf\t%.2lf\t%.2lf\t|\t%.2lf\t%.2lf\t|\t%.2lf\t%.2lf\t%.2lf\t[%.2lf]\n", ang_x, ang_y, ang_z, 
			atan2(gvec[1], sqrt(gvec[0]*gvec[0] + gvec[2]*gvec[2])) * 180/ 3.14, 
			atan2(gvec[0], gvec[2]) * 180/ 3.14, gvec[0], gvec[1], gvec[2], interval);
	}

}
Пример #27
0
int main(int argc, char **argv)
{
  // mandatory init
  Aria::init();

  //ArLog::init(ArLog::StdOut, ArLog::Verbose);

  // set up our parser
  ArArgumentParser parser(&argc, argv);

  // load the default arguments 
  parser.loadDefaultArguments();

  // robot
  ArRobot robot;
  // set up our simple connector
  ArRobotConnector robotConnector(&parser, &robot);


  // add a gyro, it'll see if it should attach to the robot or not
  ArAnalogGyro gyro(&robot);


  // set up the robot for connecting
  if (!robotConnector.connectRobot())
  {
    printf("Could not connect to robot... exiting\n");
    Aria::exit(1);
  }

  ArDataLogger dataLogger(&robot, "dataLog.txt");
  dataLogger.addToConfig(Aria::getConfig());
  
  // our base server object
  ArServerBase server;

  ArLaserConnector laserConnector(&parser, &robot, &robotConnector);
  ArServerSimpleOpener simpleOpener(&parser);


  ArClientSwitchManager clientSwitchManager(&server, &parser);

  // parse the command line... fail and print the help if the parsing fails
  // or if the help was requested
  if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
  {    
    Aria::logOptions();
    Aria::exit(1);
  }

  // Set up where we'll look for files such as user/password 
  char fileDir[1024];
  ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(), 
			 "ArNetworking/examples");

  // first open the server up
  if (!simpleOpener.open(&server, fileDir, 240))
  {
    if (simpleOpener.wasUserFileBad())
      printf("Bad user/password/permissions file\n");
    else
      printf("Could not open server port\n");
    exit(1);
  }

  // Range devices:
 
 
  ArSonarDevice sonarDev;
  robot.addRangeDevice(&sonarDev);

  ArIRs irs;
  robot.addRangeDevice(&irs);

  ArBumpers bumpers;
  robot.addRangeDevice(&bumpers);

  // attach services to the server
  ArServerInfoRobot serverInfoRobot(&server, &robot);
  ArServerInfoSensor serverInfoSensor(&server, &robot);
  ArServerInfoDrawings drawings(&server);

  // modes for controlling robot movement
  ArServerModeStop modeStop(&server, &robot);
  ArServerModeRatioDrive modeRatioDrive(&server, &robot);  
  ArServerModeWander modeWander(&server, &robot);
  modeStop.addAsDefaultMode();
  modeStop.activate();

  // set up the simple commands
  ArServerHandlerCommands commands(&server);
  ArServerSimpleComUC uCCommands(&commands, &robot);  // send commands directly to microcontroller
  ArServerSimpleComMovementLogging loggingCommands(&commands, &robot); // control debug logging
  ArServerSimpleComGyro gyroCommands(&commands, &robot, &gyro); // configure gyro
  ArServerSimpleComLogRobotConfig configCommands(&commands, &robot); // control more debug logging
  ArServerSimpleServerCommands serverCommands(&commands, &server); // control ArNetworking debug logging
  ArServerSimpleLogRobotDebugPackets logRobotDebugPackets(&commands, &robot, ".");  // debugging tool

  // ArServerModeDrive is an older drive mode. ArServerModeRatioDrive is newer and generally performs better,
  // but you can use this for old clients if neccesary.
  //ArServerModeDrive modeDrive(&server, &robot);
  //modeDrive.addControlCommands(&commands); // configure the drive modes (e.g. enable/disable safe drive)

  ArServerHandlerConfig serverHandlerConfig(&server, Aria::getConfig()); // make a config handler
  ArLog::addToConfig(Aria::getConfig()); // let people configure logging

  modeRatioDrive.addToConfig(Aria::getConfig(), "Teleop settings"); // able to configure teleop settings
  modeRatioDrive.addControlCommands(&commands);

  // Forward video if either ACTS or SAV server are running.
  // You can find out more about SAV and ACTS on our website
  // http://robots.activmedia.com. ACTS is for color tracking and is
  // a separate product. SAV just does software A/V transmitting and is
  // free to all our customers. Just run ACTS or SAV server before you
  // start this program and this class here will forward video from the
  // server to the client.
  ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070);
  
  // Control a pan/tilt/zoom camera, if one is installed, and the video
  // forwarder was enabled above.
  ArPTZ *camera = NULL;
  ArServerHandlerCamera *handlerCamera = NULL;
  ArCameraCollection *cameraCollection = NULL;
  if (videoForwarder.isForwardingVideo())
  {
    bool invertedCamera = false;
    camera = new ArVCC4(&robot,	invertedCamera, 
			ArVCC4::COMM_UNKNOWN, true, true);
    camera->init();

    cameraCollection = new ArCameraCollection();
    cameraCollection->addCamera("Cam1", "VCC4", "Camera", "VCC4");
    handlerCamera = new ArServerHandlerCamera("Cam1", 
		                              &server, 
					      &robot,
					      camera, 
					      cameraCollection);
  }

  // You can use this class to send a set of arbitrary strings 
  // for MobileEyes to display, this is just a small example
  ArServerInfoStrings stringInfo(&server);
  Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor());
  Aria::getInfoGroup()->addStringInt(
	  "Motor Packet Count", 10, 
	  new ArConstRetFunctorC<int, ArRobot>(&robot, 
					       &ArRobot::getMotorPacCount));
  /*
  Aria::getInfoGroup()->addStringInt(
	  "Laser Packet Count", 10, 
	  new ArRetFunctorC<int, ArSick>(&sick, 
					 &ArSick::getSickPacCount));
  */
  
  // start the robot running, true means that if we lose connection the run thread stops
  robot.runAsync(true);


  // connect the laser(s) if it was requested
  if (!laserConnector.connectLasers())
  {
    printf("Could not connect to lasers... exiting\n");
    Aria::exit(2);
  }
  

  drawings.addRobotsRangeDevices(&robot);

  // log whatever we wanted to before the runAsync
  simpleOpener.checkAndLog();
  // now let it spin off in its own thread
  server.runAsync();

  printf("Server is now running...\n");

  // Add a key handler so that you can exit by pressing
  // escape. Note that a key handler prevents you from running
  // a program in the background on Linux, since it expects an 
  // active terminal to read keys from; remove this if you want
  // to run it in the background.
  ArKeyHandler *keyHandler;
  if ((keyHandler = Aria::getKeyHandler()) == NULL)
  {
    keyHandler = new ArKeyHandler;
    Aria::setKeyHandler(keyHandler);
    robot.lock();
    robot.attachKeyHandler(keyHandler);
    robot.unlock();
    printf("To exit, press escape.\n");
  }

  // Read in parameter files.
  std::string configFile = "serverDemoConfig.txt";
  Aria::getConfig()->setBaseDirectory("./");
  if (Aria::getConfig()->parseFile(configFile.c_str(), true, true))
  {
    ArLog::log(ArLog::Normal, "Loaded config file %s", configFile.c_str());
  }
  else
  {
    if (ArUtil::findFile(configFile.c_str()))
    {
      ArLog::log(ArLog::Normal, 
		 "Trouble loading configuration file %s, continuing",
		 configFile.c_str());
    }
    else
    {
      ArLog::log(ArLog::Normal, 
		 "No configuration file %s, will try to create if config used",
		 configFile.c_str());
    }
  }

  clientSwitchManager.runAsync();

  robot.lock();
  robot.enableMotors();
  robot.unlock();

  robot.waitForRunExit();
  Aria::exit(0);
}
Пример #28
0
int main(int argc, char** argv){
	//select loggin level 
	logger_default_config(log4cxx::Level::getInfo());

	std::string adc_id;
	std::string filename;
	size_t offset = 0x08000000; // 128M * 4 -> second memory bank
	size_t block_size = 2048;
	size_t data_size = 4096;
	bool simple_mode = false;
	bool halbe_mode = false;
	bool statistic_mode = false;

	{
		namespace po = boost::program_options;
		po::options_description desc("Allowed options");
		desc.add_options()
			("help", "produce help message")
			("adc", po::value<std::string>(&adc_id)->required(), "specify ADC board")
			("data_size", po::value<size_t>(&data_size), "Amount of data to read (kB), default 4096kB")
			("block_size", po::value<size_t>(&block_size), "Read data in blocks of this size(kB), default 2048kB")
			("simple_mode", po::bool_switch(&simple_mode), "Run forever and collect statistics.")
			("halbe_mode ", po::bool_switch(&halbe_mode), "Run forever and collect statistics.")
			("statistic_mode", po::bool_switch(&statistic_mode), "Run forever and collect statistics.")
		;

		po::variables_map vm;
		po::store(po::command_line_parser(argc, argv)
						.options(desc)
						.run()
				, vm);

		if (vm.count("help")) {
			std::cout << std::endl << desc << std::endl;
			return 0;
		}
		po::notify(vm);
	}

	if (simple_mode)
	{
		//create the top of the tree
		Vmoduleusb io(usbcomm::note);

		if(io.open(usb_vendorid, usb_deviceid, adc_id)){
			std::cout << "Open failed" << std::endl;
			return -1;
		}
		else {
			std::cout << "Board " << adc_id << " opened" << std::endl;
		}

		//create sp6 class tree
		Vusbmaster usb(&io);
		//usbmaster knows three clients, must be in this order!!!
		Vusbstatus status(&usb);
		Vmemory mem(&usb);
		Vocpfifo ocp(&usb);
		//ocpfifo clients
		Vspiconfrom confrom(&ocp);
		Vspigyro gyro(&ocp);
		Vspiwireless wireless(&ocp);
		std::cout << "Transfering " << data_size << "kB in "
			      << calc_blocks(data_size * 1024, block_size * 1024)
				  << " block(s) of "
				  << calc_words(block_size) << " words." << std::endl;
		size_t errorcnt = memtest(mem, calc_words(data_size), offset, calc_words(block_size));
		std::cout << "Transmission errors: " << errorcnt << std::endl;
		if (errorcnt > 0)
			return -1;
	}
    if (halbe_mode)
	{
		Vmoduleusb io(usbcomm::note, usb_vendorid, usb_deviceid, adc_id);
		std::cout << "Board " << adc_id << " opened" << std::endl;
		Vusbmaster usb(&io);
		Vusbstatus status(&usb);
		Vmemory mem(&usb);
		Vocpfifo ocp(&usb);
		Vmux_board mux_board(&ocp, mux_board_mode(adc_id));
		Vflyspi_adc adc(&ocp);

		// write configuration to adc
		adc.configure(0);
		adc.setup_controller(0, calc_words(data_size),
				0 /* single mode */, 0 /* trigger enable */, 0 /* trigger */);

		const uint32_t startaddr = adc.get_startaddr();
		const uint32_t endaddr   = adc.get_endaddr();
		const uint32_t num_words = endaddr - startaddr;
		if (startaddr != 0 or endaddr != calc_words(data_size))
		{
			std::cout << "Invalid start or end addresses: startaddr="
				      << startaddr << " endaddr=" << endaddr;
			exit(-1);
		}
		std::cout << "Transfering " << num_words << " words in "
			      << calc_blocks(data_size * 1024, block_size * 1024)
				  << " block(s) of "
				  << num_words << " words." << std::endl;
		size_t errorcnt = memtest(mem, num_words, offset, calc_words(block_size));
		std::cout << "Transmission errors: " << errorcnt << std::endl;
		if (errorcnt > 0)
			return -1;
	}
}
Пример #29
0
int main(int argc, char **argv)
{
  Aria::init();
  ArArgumentParser parser(&argc, argv);
  parser.loadDefaultArguments();
  ArRobot robot;
  ArAnalogGyro gyro(&robot);
  ArSonarDevice sonar;
  ArRobotConnector robotConnector(&parser, &robot);
  ArLaserConnector laserConnector(&parser, &robot, &robotConnector);


  // Connect to the robot, get some initial data from it such as type and name,
  // and then load parameter files for this robot.
  if(!robotConnector.connectRobot())
  {
    ArLog::log(ArLog::Terse, "gotoActionExample: Could not connect to the robot.");
    if(parser.checkHelpAndWarnUnparsed())
    {
        // -help not given
        Aria::logOptions();
        Aria::exit(1);
    }
  }

  if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
  {
    Aria::logOptions();
    Aria::exit(1);
  }

  ArLog::log(ArLog::Normal, "gotoActionExample: Connected to robot.");

  robot.addRangeDevice(&sonar);
  robot.runAsync(true);

  // Make a key handler, so that escape will shut down the program
  // cleanly
  ArKeyHandler keyHandler;
  Aria::setKeyHandler(&keyHandler);
  robot.attachKeyHandler(&keyHandler);
  printf("You may press escape to exit\n");

  // Collision avoidance actions at higher priority
  ArActionLimiterForwards limiterAction("speed limiter near", 300, 600, 250);
  ArActionLimiterForwards limiterFarAction("speed limiter far", 300, 1100, 400);
  ArActionLimiterTableSensor tableLimiterAction;
  robot.addAction(&tableLimiterAction, 100);
  robot.addAction(&limiterAction, 95);
  robot.addAction(&limiterFarAction, 90);

  // Goto action at lower priority
  ArActionGoto gotoPoseAction("goto");
  robot.addAction(&gotoPoseAction, 50);
  
  // Stop action at lower priority, so the robot stops if it has no goal
  ArActionStop stopAction("stop");
  robot.addAction(&stopAction, 40);


  // turn on the motors, turn off amigobot sounds
  robot.enableMotors();
  robot.comInt(ArCommands::SOUNDTOG, 0);

  const int duration = 30000; //msec
  ArLog::log(ArLog::Normal, "Going to four goals in turn for %d seconds, then cancelling goal and exiting.", duration/1000);

  bool first = true;
  int goalNum = 0;
  ArTime start;
  start.setToNow();
  while (Aria::getRunning()) 
  {
    robot.lock();

    // Choose a new goal if this is the first loop iteration, or if we 
    // achieved the previous goal.
    if (first || gotoPoseAction.haveAchievedGoal())
    {
      first = false;
      goalNum++;
      if (goalNum > 4)
        goalNum = 1; // start again at goal #1

      // set our positions for the different goals
      if (goalNum == 1)
        gotoPoseAction.setGoal(ArPose(2500, 0));
      else if (goalNum == 2)
        gotoPoseAction.setGoal(ArPose(2500, 2500));
      else if (goalNum == 3)
        gotoPoseAction.setGoal(ArPose(0, 2500));
      else if (goalNum == 4)
        gotoPoseAction.setGoal(ArPose(0, 0));

      ArLog::log(ArLog::Normal, "Going to next goal at %.0f %.0f", 
		    gotoPoseAction.getGoal().getX(), gotoPoseAction.getGoal().getY());
    }

    if(start.mSecSince() >= duration) {
      ArLog::log(ArLog::Normal, "%d seconds have elapsed. Cancelling current goal, waiting 3 seconds, and exiting.", duration/1000);
      gotoPoseAction.cancelGoal();
      robot.unlock();
      ArUtil::sleep(3000);
      break;
    }

    robot.unlock();
    ArUtil::sleep(100);
  }
  
  // Robot disconnected or time elapsed, shut down
  Aria::exit(0);
  return 0;
}
/*
  process any 
 */
bool AP_InertialSensor_MPU6000::update( void )
{    
#if !MPU6000_FAST_SAMPLING
    if (_sum_count < _sample_count) {
        // we don't have enough samples yet
        return false;
    }
#endif

    // we have a full set of samples
    uint16_t num_samples;
    Vector3f accel, gyro;

    hal.scheduler->suspend_timer_procs();
#if MPU6000_FAST_SAMPLING
    gyro = _gyro_filtered;
    accel = _accel_filtered;
    num_samples = 1;
#else
    gyro(_gyro_sum.x, _gyro_sum.y, _gyro_sum.z);
    accel(_accel_sum.x, _accel_sum.y, _accel_sum.z);
    num_samples = _sum_count;
    _accel_sum.zero();
    _gyro_sum.zero();
#endif
    _sum_count = 0;
    hal.scheduler->resume_timer_procs();

    gyro *= _gyro_scale / num_samples;
    accel *= MPU6000_ACCEL_SCALE_1G / num_samples;

#if CONFIG_HAL_BOARD_SUBTYPE == HAL_BOARD_SUBTYPE_LINUX_PXF
    accel.rotate(ROTATION_PITCH_180_YAW_90);
    gyro.rotate(ROTATION_PITCH_180_YAW_90);
#endif

    _publish_accel(_accel_instance, accel);
    _publish_gyro(_gyro_instance, gyro);

#if MPU6000_FAST_SAMPLING
    if (_last_accel_filter_hz != _accel_filter_cutoff()) {
        _accel_filter.set_cutoff_frequency(1000, _accel_filter_cutoff());
        _last_accel_filter_hz = _accel_filter_cutoff();
    }

    if (_last_gyro_filter_hz != _gyro_filter_cutoff()) {
        _gyro_filter.set_cutoff_frequency(1000, _gyro_filter_cutoff());
        _last_gyro_filter_hz = _gyro_filter_cutoff();
    }
#else
    if (_last_accel_filter_hz != _accel_filter_cutoff()) {
        if (_spi_sem->take(10)) {
            _spi->set_bus_speed(AP_HAL::SPIDeviceDriver::SPI_SPEED_LOW);
            _set_filter_register(_accel_filter_cutoff());
            _spi->set_bus_speed(AP_HAL::SPIDeviceDriver::SPI_SPEED_HIGH);
            _spi_sem->give();
            _last_accel_filter_hz = _accel_filter_cutoff();
        }
    }
#endif

    return true;
}