Esempio n. 1
0
void vrpn_Tracker_Crossbow::recalibrate(vrpn_uint16 num_samples) {
	if (num_samples < 100) {
		fprintf(stderr, "vrpn_Tracker_Crossbow: Must recalibrate using at least 100 samples\n");
		return;
	}
	else if (num_samples > 25599) {
		fprintf(stderr, "vrpn_Tracker_Crossbow: Capping recalibration at 25,500 samples\n");
		num_samples = 25500;
	}

	vrpn_drain_output_buffer(serial_fd);
	vrpn_flush_input_buffer(serial_fd);

	// Prepare zero command
	unsigned char buffer[2];
	buffer[0] = 'z';
	buffer[1] = (unsigned char) (num_samples / 100);

	vrpn_write_characters(serial_fd, buffer, 2);
	vrpn_drain_output_buffer(serial_fd);
	vrpn_SleepMsecs(50);

	// Wait for affirmative response.
	// Allow two minutes before timing out.
	// Even 25500 samples should make it with a few seconds to spare.
	struct timeval timeout;
	timeout.tv_sec = 120;
	timeout.tv_usec = 0;
	if (!vrpn_read_available_characters(serial_fd, buffer, 1, &timeout) || *buffer != 'Z') {
		fprintf(stderr, "vrpn_Tracker_Crossbow: Failed to recalibrate device\n");
	}
}
Esempio n. 2
0
void vrpn_SerialPort::drain_output_buffer() {
	requiresOpen();
	int ret = vrpn_drain_output_buffer(_comm);
	if (ret == -1) {
		throw DrainFailure();
	}
}
Esempio n. 3
0
int vrpn_Nikon_Controls::set_channel(unsigned chan_num, vrpn_float64 value)
{
  // Ask to change the focus if this was channel 0.  Also, store away where we
  // asked the focus to go to so that we can know where we are when we get there
  // (the response from the microscope just says "we got here!).
  if ( (int)chan_num >= o_num_channel ) {
    char msg[1024];
    sprintf(msg,"vrpn_Nikon_Controls::set_channel(): Index out of bounds (%d of %d), value %lg\n",
      chan_num, o_num_channel, value);
    vrpn_gettimeofday(&o_timestamp, NULL);
    send_text_message(msg, o_timestamp, vrpn_TEXT_ERROR);
  }

  char  msg[256];
  sprintf(msg, "fSMV%ld\r", (long)value);
#ifdef	VERBOSE
  printf("Nikon Control: Asking to move to %ld with command %s\n", (long)value, msg);
#endif
  if (vrpn_write_characters(serial_fd, (unsigned char *)msg, strlen(msg)) != (int)strlen(msg)) {
    fprintf(stderr, "vrpn_Nikon_Controls::set_channel(): Can't write command\n");
    return -1;
  }
  if (vrpn_drain_output_buffer(serial_fd)) {
    fprintf(stderr, "vrpn_Nikon_Controls::set_channel(): Can't drain command\n");
    return -1;
  }
  _requested_focus = value;

  return 0;
}
Esempio n. 4
0
vrpn_Tracker_Flock_Parallel_Slave::~vrpn_Tracker_Flock_Parallel_Slave() {

  // Some compilers (CenterLine CC on sunos!?) still don't support 
  // automatic aggregate initialization

  int cLen=0;
  //unsigned char rgch[2]={'B','G'};
  unsigned char rgch [2];
  rgch[cLen++] = 'B';

  // slaves can't do a sleep
  //  rgch[cLen++] = 'G';

  fprintf(stderr,"\nvrpn_Tracker_Flock_Parallel_Slave %d: shutting down ...", d_sensor);
  // clear output buffer
  vrpn_flush_output_buffer( serial_fd );

  // put the flock to sleep (B to get out of stream mode, G to sleep)
  if (vrpn_write_characters(serial_fd, (const unsigned char *) rgch, cLen )!=cLen) {
    fprintf(stderr,"\nvrpn_Tracker_Flock_Parallel_Slave %d: "
	    "failed writing sleep cmd to tracker", d_sensor);
    status = vrpn_TRACKER_FAIL;
    return;
  }
  // make sure the command is sent out
  vrpn_drain_output_buffer( serial_fd );
  fprintf(stderr, " done.\n");
}
Esempio n. 5
0
int vrpn_Tracker_Dyna::get_status()
{
    int	    	bytesRead;
    unsigned char    	statusBuffer[256];

    my_flush();

    /* send request for status record   */

    vrpn_write_characters(serial_fd,(const unsigned char *) "\021", 1);
    vrpn_drain_output_buffer(serial_fd);
    vrpn_SleepMsecs(1000.0*2);

    /* do non-blocking read of status record    */
    bytesRead = vrpn_read_available_characters(serial_fd, statusBuffer, 8);
    // T_PDYN_STATUS_RECORD_LENGTH =8;

    if ( bytesRead == 8 )
    {
       /* we have correct length-  check a few chars to make sure this is a valid 
	* record
	*/
       if ( ((statusBuffer[0] & lOOO_OOOO) != lOOO_OOOO) ||
	    ((statusBuffer[1] & lOOO_OOOO) != lOOO_OOOO) )
	 return(T_ERROR);       

       /* otherwise, all is well   */
       return(T_OK);
    }

    /* if we get here, we either got too much data or not enough	*/

    /* no data means it's probably disconnected or not turned on	*/
    if ( bytesRead == 0 )
    {
//       fprintf(stderr, "No data\n");
      return(T_PDYN_NO_DATA);
    }

    /* if we got too much data, chances are that it's in continuous mode	*/
    if ( bytesRead > 8)
    {
       fprintf(stderr, "3\n");
      return(T_PDYN_SPEW_MODE);
    }

    /* if we get here, i have no idea what's going on-  could be garbage on the
     *  serial line, wrong baud rate, or that the Dynasight is flaking out.
     */
    return(T_ERROR);

}	/* t_pdyn_get_status */
Esempio n. 6
0
void vrpn_Tracker_Liberty::reset()
{
   int i,resetLen,ret;
   char reset[10];
   char errmsg[512];
   char outstring1[64],outstring3[64];

    //--------------------------------------------------------------------
   // This section deals with resetting the tracker to its default state.
   // Multiple attempts are made to reset, getting more aggressive each
   // time. This section completes when the tracker reports a valid status
   // message after the reset has completed.
   //--------------------------------------------------------------------

   // Send the tracker a string that should reset it.  The first time we
   // try this, just do the normal 'c' command to put it into polled mode.
   // after a few tries with this, use the ^Y reset.  Later, try to reset
   // to the factory defaults.  Then toggle the extended mode.
   // Then put in a carriage return to try and break it out of
   // a query mode if it is in one.  These additions are cumulative: by the
   // end, we're doing them all.
   fprintf(stderr,"[DEBUG] Beginning Reset");
   resetLen = 0;
   num_resets++;		  	// We're trying another reset
   if (num_resets > 0) {	// Try to get it out of a query loop if its in one
   	reset[resetLen++] = (char) (13); // Return key -> get ready
	reset[resetLen++] = 'F';
	reset[resetLen++] = '0';
 	reset[resetLen++] = (char) (13); // Return key -> get ready	
	//	reset[resetLen++] = (char) (13);
	//	reset[resetLen++] = (char) (13);
   }
   /* XXX These commands are probably never needed, and can cause real
      headaches for people who are keeping state in their trackers (especially
      the InterSense trackers).  Taking them out in version 05.01; you can put
      them back in if your tracker isn't resetting as well.
   if (num_resets > 3) {	// Get a little more aggressive
	reset[resetLen++] = 'W'; // Reset to factory defaults
	reset[resetLen++] = (char) (11); // Ctrl + k --> Burn settings into EPROM
   }
   */
   if (num_resets > 2) {
       reset[resetLen++] = (char) (25); // Ctrl + Y -> reset the tracker
       reset[resetLen++] = (char) (13); // Return Key
   }
   reset[resetLen++] = 'P'; // Put it into polled (not continuous) mode

   sprintf(errmsg, "Resetting the tracker (attempt %d)", num_resets);
   VRPN_MSG_WARNING(errmsg);
   for (i = 0; i < resetLen; i++) {
	if (vrpn_write_characters(serial_fd, (unsigned char*)&reset[i], 1) == 1) {
		fprintf(stderr,".");
		vrpn_SleepMsecs(1000.0*2);  // Wait after each character to give it time to respond
   	} else {
		perror("Liberty: Failed writing to tracker");
		status = vrpn_TRACKER_FAIL;
		return;
	}
   }
   //XXX Take out the sleep and make it keep spinning quickly
   // You only need to sleep 10 seconds for an actual Liberty.
   // For the Intersense trackers, you need to sleep 20. So,
   // sleeping 20 is the more general solution...
   if (num_resets > 2) {
       vrpn_SleepMsecs(1000.0*20);	// Sleep to let the reset happen, if we're doing ^Y
   }

   fprintf(stderr,"\n");

   // Get rid of the characters left over from before the reset
   vrpn_flush_input_buffer(serial_fd);

   // Make sure that the tracker has stopped sending characters
   vrpn_SleepMsecs(1000.0*2);
   unsigned char scrap[80];
   if ( (ret = vrpn_read_available_characters(serial_fd, scrap, 80)) != 0) {
     sprintf(errmsg,"Got >=%d characters after reset",ret);
     VRPN_MSG_WARNING(errmsg);
     for (i = 0; i < ret; i++) {
      	if (isprint(scrap[i])) {
         	fprintf(stderr,"%c",scrap[i]);
         } else {
         	fprintf(stderr,"[0x%02X]",scrap[i]);
         }
     }
     fprintf(stderr, "\n");
     vrpn_flush_input_buffer(serial_fd);		// Flush what's left
   }

   // Asking for tracker status. S not implemented in Liberty and hence
   // ^V (WhoAmI) is used. It retruns 196 bytes

   char statusCommand[2];
   statusCommand[0]=(char)(22); // ^V
   statusCommand[1]=(char)(13); // Return Key

   if (vrpn_write_characters(serial_fd, (const unsigned char *) &statusCommand[0], 2) == 2) {
      vrpn_SleepMsecs(1000.0*1); // Sleep for a second to let it respond
   } else {
	perror("  Liberty write failed");
	status = vrpn_TRACKER_FAIL;
	return;
   }

   // Read Status
   unsigned char statusmsg[vrpn_LIBERTY_MAX_WHOAMI_LEN+1];

   // Attempt to read whoami_len characters. 
   ret = vrpn_read_available_characters(serial_fd, statusmsg, whoami_len);
   if (ret != whoami_len) {
  	fprintf(stderr,"  Got %d of %d characters for status\n",ret, whoami_len);
   }
   if (ret != -1) {
      statusmsg[ret] = '\0';	// Null-terminate the string
   }
   // It seems like some versions of the tracker report longer
   // messages; so we reduced this check so that it does not check for the
   // appropriate length of message or for the last character being a 10,
   // so that it works more generally.  The removed tests are:
   // || (ret!=whoami_len) || (statusmsg[ret-1]!=(char)(10))
   if ( (statusmsg[0]!='0') ) {
     int i;
     fprintf(stderr, "  Liberty: status is (");
     for (i = 0; i < ret; i++) {
      	if (isprint(statusmsg[i])) {
         	fprintf(stderr,"%c",statusmsg[i]);
         } else {
         	fprintf(stderr,"[0x%02X]",statusmsg[i]);
         }
     }
     fprintf(stderr,"\n)\n");
     VRPN_MSG_ERROR("Bad status report from Liberty, retrying reset");
     return;
   } else {
     VRPN_MSG_WARNING("Liberty/Isense gives status (this is good)");
printf("LIBERTY LATUS STATUS (whoami):\n%s\n\n",statusmsg);
     num_resets = 0; 	// Success, use simple reset next time
   }

   //--------------------------------------------------------------------
   // Now that the tracker has given a valid status report, set all of
   // the parameters the way we want them. We rely on power-up setting
   // based on the receiver select switches to turn on the receivers that
   // the user wants.
   //--------------------------------------------------------------------

   // Set output format for each of the possible stations.

   for (i = 0; i < num_stations; i++) {
       if (set_sensor_output_format(i)) {
	   return;
       }
   }

   // Enable filtering if the constructor parameter said to.
   // Set filtering for both position (X command) and orientation (Y command)
   // to the values that are recommended as a "jumping off point" in the
   // Liberty manual.

   if (do_filter) {
     if (VRPN_LIBERTY_DEBUG) fprintf(stderr,"[DEBUG]: Enabling filtering\n");

     if (vrpn_write_characters(serial_fd,
	     (const unsigned char *)"X0.2,0.2,0.8,0.8\015", 17) == 17) {
	vrpn_SleepMsecs(1000.0*1); // Sleep for a second to let it respond
     } else {
	perror("  Liberty write position filter failed");
	status = vrpn_TRACKER_FAIL;
	return;
     }
     if (vrpn_write_characters(serial_fd,
	     (const unsigned char *)"Y0.2,0.2,0.8,0.8\015", 17) == 17) {
	vrpn_SleepMsecs(1000.0*1); // Sleep for a second to let it respond
     } else {
	perror("  Liberty write orientation filter failed");
	status = vrpn_TRACKER_FAIL;
	return;
     }
   } else {
     if (VRPN_LIBERTY_DEBUG) fprintf(stderr,"[DEBUG]: Disabling filtering\n");

     if (vrpn_write_characters(serial_fd,
	     (const unsigned char *)"X0,1,0,0\015", 9) == 9) {
	vrpn_SleepMsecs(1000.0*1); // Sleep for a second to let it respond
     } else {
	perror("  Liberty write position filter failed");
	status = vrpn_TRACKER_FAIL;
	return;
     }
     if (vrpn_write_characters(serial_fd,
	     (const unsigned char *)"Y0,1,0,0\015", 9) == 9) {
	vrpn_SleepMsecs(1000.0*1); // Sleep for a second to let it respond
     } else {
	perror("  Liberty write orientation filter failed");
	status = vrpn_TRACKER_FAIL;
	return;
     }
   }


   // Send the additional reset commands, if any, to the tracker.
   // These commands come in lines, with character \015 ending each
   // line. If a line start with an asterisk (*), treat it as a pause
   // command, with the number of seconds to wait coming right after
   // the asterisk. Otherwise, the line is sent directly to the tracker.
   // Wait a while for them to take effect, then clear the input
   // buffer.
   if (strlen(add_reset_cmd) > 0) {
	char	*next_line;
	char	add_cmd_copy[sizeof(add_reset_cmd)];
	char	string_to_send[sizeof(add_reset_cmd)];
	int	seconds_to_wait;

	printf("  Liberty writing extended reset commands...\n");

	// Make a copy of the additional reset string, since it is consumed
        vrpn_strcpy(add_cmd_copy, add_reset_cmd);

	// Pass through the string, testing each line to see if it is
	// a sleep command or a line to send to the tracker. Continue until
	// there are no more line delimiters ('\015'). Be sure to write the
	// \015 to the end of the string sent to the tracker.
	// Note that strok() puts a NULL character in place of the delimiter.

	next_line = strtok(add_cmd_copy, "\015");
	while (next_line != NULL) {
		if (next_line[0] == '*') {	// This is a "sleep" line, see how long
			seconds_to_wait = atoi(&next_line[1]);
			fprintf(stderr,"   ...sleeping %d seconds\n",seconds_to_wait);
			vrpn_SleepMsecs(1000.0*seconds_to_wait);
		} else {	// This is a command line, send it
			sprintf(string_to_send, "%s\015", next_line);
			fprintf(stderr, "   ...sending command: %s\n", string_to_send);
			vrpn_write_characters(serial_fd,
				(const unsigned char *)string_to_send,strlen(string_to_send));
		}
		next_line = strtok(next_line+strlen(next_line)+1, "\015");
	}

	// Sleep a little while to let this finish, then clear the input buffer
	vrpn_SleepMsecs(1000.0*2);
	vrpn_flush_input_buffer(serial_fd);
   }
   
   // Set data format to BINARY mode
   sprintf(outstring1, "F1\r");
   if (vrpn_write_characters(serial_fd, (const unsigned char *)outstring1,
			    strlen(outstring1)) == (int)strlen(outstring1)) {
      fprintf(stderr, "  Liberty set to binary mode\n");

   }

   // Set tracker to continuous mode
   sprintf(outstring3, "C\r");
   if (vrpn_write_characters(serial_fd, (const unsigned char *)outstring3,
                                strlen(outstring3)) != (int)strlen(outstring3)) {
 	perror("  Liberty write failed");
	status = vrpn_TRACKER_FAIL;
	return;
   } else {
   	fprintf(stderr, "  Liberty set to continuous mode\n");
   }

   // If we are using the Liberty timestamps, clear the timer on the device and
   // store the time when we cleared it.  First, drain any characters in the output
   // buffer to ensure we're sending right away.  Then, send the reset command and
   // store the time that we sent it, plus the estimated time for the characters to
   // get across the serial line to the device at the current baud rate.
   // Set time units to milliseconds (MT) and reset the time (MZ).

	char	clear_timestamp_cmd[] = "Q0\r";

	vrpn_drain_output_buffer(serial_fd);

	if (vrpn_write_characters(serial_fd, (const unsigned char *)clear_timestamp_cmd,
	        strlen(clear_timestamp_cmd)) != (int)strlen(clear_timestamp_cmd)) {
	    VRPN_MSG_ERROR("Cannot send command to clear timestamp");
	    status = vrpn_TRACKER_FAIL;
	    return;
	}

	// Drain the output buffer again, then record the time as the base time from
	// the tracker.
	vrpn_drain_output_buffer(serial_fd);
	vrpn_gettimeofday(&liberty_zerotime, NULL);

   // Done with reset.
   vrpn_gettimeofday(&watchdog_timestamp, NULL);	// Set watchdog now
   VRPN_MSG_WARNING("Reset Completed (this is good)");
   status = vrpn_TRACKER_SYNCING;	// We're trying for a new reading
}
Esempio n. 7
0
// slave resets are ONLY called by the master
void vrpn_Tracker_Flock_Parallel_Slave::reset()
{
  // slaves just flush on a reset and then stream (or poll)
  // master does all the real resetting

  // set vars for error handling
  // set them right away so they are set properly in the
  // event that we fail during the reset.
  cResets++;
  cSyncs=0;
  fFirstStatusReport=1;

  // Get rid of the characters left over from before the reset
  // (make sure they are processed)
  vrpn_drain_output_buffer(serial_fd);

  // put back into polled mode (need to stop stream mode
  // before doing an auto-config)
  int resetLen=0;
  unsigned char reset[3];
  reset[resetLen++]='B';

  // send the poll mode command (cmd and cmd_size are args)
  if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
    fprintf(stderr,"\nvrpn_Tracker_Flock_Parallel_Slave %d: "
	    "failed writing poll cmd to tracker", d_sensor);
    status = vrpn_TRACKER_FAIL;
    return;
  }

  // make sure the command is sent out
  vrpn_drain_output_buffer( serial_fd );

  // wait for tracker to respond and flush buffers
  vrpn_SleepMsecs(500);

  // clear the input buffer (it will contain a single point 
  // record from the poll command above and garbage from before reset)
  vrpn_flush_input_buffer(serial_fd);

  // now start it running
  resetLen = 0;

  // either stream or let poll take place later
  if (fStream==1) {
    // stream mode
    reset[resetLen++] = '@';

    if (vrpn_write_characters(serial_fd, (const unsigned char *) reset, resetLen )!=resetLen) {
      fprintf(stderr,"\nvrpn_Tracker_Flock_Parallel_Slave %d: "
	      "failed writing set mode cmds to tracker", d_sensor);
      status = vrpn_TRACKER_FAIL;
     return;
    }
    
    // make sure the commands are sent out
    vrpn_drain_output_buffer( serial_fd );
  } else {
    poll();
  }

  fprintf(stderr,"\nvrpn_Tracker_Flock_Parallel_Slave %d: "
	  "done with reset ... running.\n", d_sensor);
  
  vrpn_gettimeofday(&timestamp, NULL);	// Set watchdog now
  status = vrpn_TRACKER_SYNCING;	// We're trying for a new reading
}
Esempio n. 8
0
void vrpn_Tracker_Crossbow::reset() {
	const	char *cmd;
	unsigned char recv_buf[8];
	struct timeval timeout;

	timeout.tv_sec = 1;
	timeout.tv_usec = 0;
	
#if 0 // doesn't help
	// First, take the comm port offline for a second
	vrpn_close_commport(serial_fd);
	vrpn_SleepMsecs(1000);
	serial_fd = vrpn_open_commport(portname, baudrate);
#endif

	vrpn_flush_output_buffer(serial_fd);
	vrpn_flush_input_buffer(serial_fd);

	// Try resetting by toggling the RTS line of the serial port
	vrpn_set_rts(serial_fd);
	vrpn_SleepMsecs(750);
	vrpn_clear_rts(serial_fd);
	vrpn_SleepMsecs(250);
	vrpn_gettimeofday(&timestamp, NULL);

	vrpn_flush_input_buffer(serial_fd);

	cmd = "P";
	vrpn_write_characters(serial_fd, reinterpret_cast<const unsigned char*> (cmd), 1);
	vrpn_SleepMsecs(50); // Sleep long enough to stop receiving data
	vrpn_flush_input_buffer(serial_fd);

	cmd = "RSv";
	vrpn_write_characters(serial_fd, reinterpret_cast<const unsigned char*> (cmd), 3);
	vrpn_drain_output_buffer(serial_fd);
	if (vrpn_read_available_characters(serial_fd, recv_buf, 8, &timeout) != 8) {
		fprintf(stderr, "vrpn_Tracker_Crossbow::reset: Crossbow not responding to stimulus\n");
		status = vrpn_TRACKER_FAIL;
		return;
	}

	if ((recv_buf[0] != 'H') || (recv_buf[1] != 255) || (recv_buf[7] != 255)) {
		fprintf(stderr, "vrpn_Tracker_Crossbow::reset: Crossbow gave unexpected ping response\n");
		status = vrpn_TRACKER_FAIL;
		return;
	}

	if (recv_buf[6] != ((recv_buf[2] + recv_buf[3] + recv_buf[4] + recv_buf[5]) & 0xFF)) {
		fprintf(stderr, "vrpn_Tracker_Crossbow::reset: Crossbow gave invalid serial number checksum\n");
		status = vrpn_TRACKER_FAIL;
		return;
	}

	const char *bufptr = reinterpret_cast<const char *>(&recv_buf[2]);
	vrpn_unbuffer(&bufptr, &device_serial);

	if (0) do {
		if (!vrpn_read_available_characters(serial_fd, recv_buf, 1, &timeout)) {
			fprintf(stderr, "vrpn_Tracker_Crossbow::reset: Crossbow not responding to stimulus\n");
			status = vrpn_TRACKER_FAIL;
			return;
		}
	} while (*recv_buf != 255);

	int curSize = 4, curLen = 0;
	device_version = (char *) realloc(device_version, curSize * sizeof(char));
	if (device_version == NULL) {
		fprintf(stderr, "vrpn_Tracker_Crossbow::reset: Out of memory\n");
		status = vrpn_TRACKER_FAIL;
		return;
	}
	do {
		if (!vrpn_read_available_characters(serial_fd, recv_buf, 1, &timeout)) {
			fprintf(stderr, "vrpn_Tracker_Crossbow::reset: Crossbow not responding to stimulus\n");
			status = vrpn_TRACKER_FAIL;
			return;
		}
		if (*recv_buf != '$')
			device_version[curLen++] = *recv_buf;

		if (curLen == curSize)
			device_version = (char *) realloc(device_version, curSize *= 2);
	} while (*recv_buf != '$');

	// Now null-terminate the version string, expanding it one last time if necessary
	if (curLen == curSize)
		device_version = (char *) realloc(device_version, ++curSize);

	device_version[curLen] = 0;

	//printf("Serial %u\tVersion '%s'\n", device_serial, device_version);

	just_read_something = 0;
	status = vrpn_TRACKER_SYNCING;

}