Пример #1
0
void integratedInit() {
    BLEInit();
    initializeCompass();
}
Пример #2
0
/** 
 * main()
 * 
 * This program comprises two processes.  First, the "brain" which
 * communicates with a supervisor-client.  The brain receives
 * high-level control commands from the supervisor-client and then
 * conveys any resulting sensor data back.  The second process is the
 * "nerves"; this process translates high-level commands into
 * low-level iRobot SCI commands, executes them on the iRobot, and
 * then obtains any resulting sensor data.
 * 
 */
int main(int argc, char* argv[])
{

  /* Create a message queue using O_CREAT so that if the queue doesn't
   * already exist, it will be created.  When using mq_open with
   * O_CREAT, one must supply four arguments.  The first "name"
   * argument must begin with a slash.  The third "mode" argument is
   * derived from the symbolic constants is <sys/stat.h>.
   */
   mqd_t mqd_cmd = mq_open("/q_cmd", 
		    O_RDWR | O_CREAT , 
		    S_IRWXU | S_IRWXG | S_IRWXO, 
		    NULL);

   mqd_t mqd_sns = mq_open("/q_sns", 
		    O_RDWR | O_CREAT, 
		    S_IRWXU | S_IRWXG | S_IRWXO, 
		    NULL);
 
  printf("The message queue id is: %d\n", mqd_cmd);

  /* Determine the size of messages for this message queue
   */
  struct mq_attr a;
  mq_getattr(mqd_cmd,&a);  

  printf("The default message size is: %d\n", a.mq_msgsize);
   
   if( mqd_cmd == -1)
    {
      perror("mq_open():");
      return -1;
    }


   if( mqd_sns == -1)
    {
      perror("mq_open():");
      return -1;
    }

  

  int check = 0;
  char addresses[3][13];
  if ((check = checkArgName(argc, argv, addresses)) == -1)
    {
      printf("Not correct name entered. Exiting.\n");
      exit(0);
    }
  int i, counter, serverID, clientSock, numBytes;
  pid_t pid, pid2;

  // Arrays to hold most recent command sent by the
  // supervisor-client and the most recent command sent to the iRobot.
  char commandFromSupervisor[MAXDATASIZE] = {'\0'};
  char commandToRobot[MAXDATASIZE] = {'\0'};

  // An array to hold sensor data sent to the supervisor-client and
  // obtained from the iRobot.
  char sensDataToSupervisor[MAXDATASIZE] = {'\0'};
  char sensDataFromRobot[MAXDATASIZE] = {'\0'};
  char emptyDataToSupervisor[MAXDATASIZE] = "0000000000 ";
  char rawTimeString[12] = {'\0'};

  // An array to hold the timestamp.
  char currTime[100];


  // Create pipe to communicate between parent and child
  int fd[2];
  if(pipe(fd) < 0)
    perror("pipe error");

  //------------------------------------------------------------------------
  // Added Code to implement client
  //------------------------------------------------------------------------
  int sockfd, numbytes;  
  //buffer to store sensor information
  char sensorBuf[MAXDATASIZE];
  char msgBuf[MAXDATASIZE];
  struct addrinfo hints, *servinfo, *p;
  int rv;
  char s[INET6_ADDRSTRLEN];
  //array to hold the command sent
  char cmd[1];
  //initialize the input to NULL char
  char input = '\0';
  //------------------------------------------------------------------------
  // End of added section
  //------------------------------------------------------------------------ 

  // Create a socket-based server
  if((serverID = createServer()) == -1)
    {
      perror("createServer()");
      return -1;
    }

  printf("brainstem: waiting for connections...\n");


  // Establish a client-connection for the socket-based server
  if((clientSock = establishConnection(serverID)) == -1)
    {
      perror("establishConnection(serverID)");
      return -1;
    }
  

  // Set up signal-based communication between the child 
  // (brain) and parent (nervous system) to avoid possible
  // race conditions.
  TELL_WAIT();



  // Fork a child process.  This process will handle the "brain"
  // activities: communicating sensor data to the client
  // and receiving control commands from the client.
  if(( pid = fork()) < 0)
    {
      perror("fork error");

    }



  //------------------------------------------------------------------------
  // Code for parent (nerves)
  //------------------------------------------------------------------------
  else if (pid > 0)
    {

      // Close the client socket since this parent won't be using it.
      close(clientSock);

      //TELL_CHILD(pid);

      // Open the serial port to the robot.  If this is unsuccessful,
      // there is no point in continuing.
      if(openPort() == 0)
	{
	  printf("Port failed to open \n");
	  exit(-1);
	}

      // Initialize the robot, prepare it to receive commands.  Wait
      // for a second to give this some time to take effect.
      initialize();
      sleep(1);


#ifdef TARGET_WEBBY
      // Initialize the compass device.
      initializeCompass();

      // This is temporary until turn() works.
      // Turn Left 10 degrees
      turn(TURN_LEFT, 10);
#endif 


      // Turn on the LED to indicate the robot is ready and listening.
      // It's a nice sanity check.
      setLED(RED, PLAY_ON, ADVANCE_ON);

      //------------------------------------------------------------------------
      // Added Code to implement client
      //------------------------------------------------------------------------
      if(check == 1)
	{
#ifdef DEBUG
	  printf("%s %d \n", __FILE__, __LINE__);
#endif
      
	  memset(&hints, 0, sizeof hints);
	  hints.ai_family = AF_UNSPEC;
	  hints.ai_socktype = SOCK_STREAM;
    
	  if ((rv = getaddrinfo(addresses[1], PORT, &hints, &servinfo)) != 0) 
	    {
	      fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
	      return 1;
	    }
    
	  // loop through all the results and connect to the first we can
	  for(p = servinfo; p != NULL; p = p->ai_next) 
	    {
	      if ((sockfd = socket(p->ai_family, p->ai_socktype,
				   p->ai_protocol)) == -1) {
		perror("client: socket");
		continue;
	      }
      
	      if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
		close(sockfd);
		perror("client: connect");
		continue;
	      }
      
	      break;
	    }
    
	  if (p == NULL) 
	    {
	      fprintf(stderr, "client: failed to connect\n");
	      return 2;
	    }
    
	  inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
		    s, sizeof s);
	  printf("client: connecting to %s\n", s);
    
	  freeaddrinfo(servinfo); // all done with this structure
    
	  //if the client does not recieve anything from server then exit
	  if ((numbytes = recv(sockfd, msgBuf, MAXDATASIZE-1, 0)) == -1) 
	    {
	      perror("recv");
	      exit(1);
	    }
	}

      //------------------------------------------------------------------------
      // End of added section
      //------------------------------------------------------------------------

      while(commandToRobot[0] != ssQuit)
	{
	  commandToRobot[0] = 'z';
	  // Wait until a valid command is received.
	  while(commandToRobot[0] == 'z')
	    {
          commandToRobot[0] = readFromMessageQueueAndExecute(mqd_cmd);
	      
	    }

	  printf("commandToRobot: %d\n", commandToRobot[0]);
	  //------------------------------------------------------------------------
	  // Added Code to implement client
	  //------------------------------------------------------------------------
	  if(check == 1)
	    {
	      if(send(sockfd, &commandToRobot[0], 1, 0) == -1)
		perror("send");
	      printf("      the command code sent was: %d\n", commandToRobot[0]);
	    }
	  //------------------------------------------------------------------------
	  // End of added section
	  //------------------------------------------------------------------------

	  receiveGroupOneSensorData(sensDataFromRobot);

	  // check if any of the sensor data indicates a 
	  // sensor has been activated.  If so, react be
	  // driving backwards briefly and then stopping.
	  
	  int sensData = 0;

	  // Check sensor data first to stop ramming into wall.
	  sensData = checkSensorData(sensDataFromRobot);

#ifdef DEBUG
	  printf("%s %d \n", __FILE__, __LINE__);
#endif
	  // Wait until child has sent previous sensor data.
	  //WAIT_CHILD();

#ifdef DEBUG

	  printf("%s %d \n", __FILE__, __LINE__);
	  printf("%d \n", sensData);
#endif

	  if(sensData)
	    {
#ifdef DEBUG
	      printf("%s %d \n", __FILE__, __LINE__);	     	      
#endif
	      // Drive backwards and then stop.
	      driveBackwardsUntil(EIGHTH_SECOND, MED);
	      STOP_MACRO;	      

	      // Convey sensorData back to the child.
	      writeSensorDataToMessageQueue(sensDataFromRobot, mqd_sns, getTime(), getRawTime());

	    }  
	  // Done writing sensor data, tell child to proceed reading sensor data.
	  TELL_CHILD(pid);
	  
	  // Reset the array; fill it again in the next loop.
	  for(i = 0; i <= 6; i++)
	    {
	      sensDataFromRobot[i]= FALSE;
	    }
	}


      if (closePort() == -1)
	{
	  perror("Port failed to close \n");
	  exit(-1);
	}
      send(sockfd, &input, 1, 0);
      close(sockfd);
      kill(0, SIGTERM);
      mq_close(mqd_cmd);

      exit(0);
    }

  //------------------------------------------------------------------------
  // Code for child (brain)
  //------------------------------------------------------------------------
  else
    {
      // Child process doesn't need the listener.
      close(serverID);

      // Initially tell the parent to proceed and write sensor data.
      //TELL_PARENT(getppid());

      // Send the client the initial connection message.
      if(send(clientSock, MSG, sizeof(MSG), 0) == -1)
	perror("send");

      // At the request of the supervisor implementation team, The
      // brain follows a strict alternation of 'receive control
      // command' then 'send sensor data'.  If the control command
      // sent by the supervisor-client is 'turn left' and the iRobot
      // happens to bump into something, then the subsequent message
      // to the supervisor-client will indicate which bumper was activated.  
      // Similarly, if the control command sent by the supervisor is
      // 'turn left' and the iRobot experiences no sensory input, the
      // subsequent message to the supervisor will indicate that no sensors
      // were activated.

      // As long as the quit command 'q' has not been sent by the
      // supervisor-client, receive a control command and send the
      // subsequent sensor data.
      while(commandFromSupervisor[0] != ssQuit)
	{
	  // Wait to receive command from supervisor-client; read the command
	  // into cmdBuf.
	  if ((numBytes = recv(clientSock, commandFromSupervisor, MAXDATASIZE-1, 0)) == -1)
	    {
	      perror("recv");
	      return -1;
	    }
	  // Write the read command into shared memory so that the
	  // parent (nerves) may read and execute it.
	  //writeCommandToSharedMemory(commandFromSupervisor, cmdArea,mqd_cmd);
      writeCommandToMessageQueue(commandFromSupervisor,mqd_cmd);

	  // Wait until parent has written sensor data.
	  WAIT_PARENT();

#ifdef DEBUG
	  printf("%s %d \n", __FILE__, __LINE__);
#endif

	  // If there is sensor data available, send it to the
	  // supervisor-client.
	  if(readSensorDataFromMessageQueue(sensDataToSupervisor, mqd_sns))
	    {
	      printf("\nsensDataToSupervisor: %s \n", sensDataToSupervisor);
	      if(send(clientSock, sensDataToSupervisor, strlen(sensDataToSupervisor)-1 , 0) == -1)
		perror("send");
	    }
	  
	  // Otherwise, assume no sensor was activated.  Send an empty
	  // sensor message to the supervisor-client.
	  else
	    {
	      itoa(getRawTime(), rawTimeString);
	      
	      // Construct an empty sensor data message and send it to
	      // the supervisor-client.
	      strncat(emptyDataToSupervisor, rawTimeString, MAXDATASIZE-SIZE_OF_EMPTY_DATA);
	      strncat(emptyDataToSupervisor, " ", 1);
	      strncat(emptyDataToSupervisor, getTime(), MAXDATASIZE-SIZE_OF_EMPTY_DATA);
	      printf("\nemptySensDataToSupervisor: %s \n", emptyDataToSupervisor);
	      if(send(clientSock, emptyDataToSupervisor, MAXDATASIZE-1, 0) == -1)
		perror("send");

	      emptyDataToSupervisor[SIZE_OF_EMPTY_DATA] = '\0';
	    }

	  // Done reading sensor data, allow parent to write more sensor data.
	  TELL_PARENT(getppid());
	}
	

      // All done.  Clean up the toys and go home.
      printf("Closing socket and terminating processes.\nHave a nice day!\n");
      kill(pid, SIGTERM);
      close(clientSock);
      mq_close(mqd_cmd);

      exit(0);
    }
  // Added following code to implement communication between roomba's
 
  
	  
}