vrpn  07.33
Virtual Reality Peripheral Network
vrpn_ADBox.C
Go to the documentation of this file.
1 // -*- Mode:C++ -*-
2 
3 /*
4  * ad-box driver
5  * works with Fraunhofer IMK AD-Box and Fakespace Cubic Mouse
6  *
7  * for additional information see:
8  * http://www.imk.fraunhofer.de
9  * http://www.fakespace.com
10  *
11  * written by Sascha Scholz <sascha.scholz@imk.fraunhofer.de>
12  */
13 
14 #include <stdio.h> // for fprintf, stderr
15 
16 #include "vrpn_ADBox.h"
17 #include "vrpn_Serial.h" // for vrpn_write_characters, etc
18 #include "vrpn_Types.h" // for vrpn_float64, vrpn_int32
19 
21 
23  const char *port, long baud)
24  : vrpn_Analog(name, c), vrpn_Button_Filter(name, c),
25  ready(1), serial_fd(0), iNumBytes(0), iNumDigBytes(0), iFilterPos(0)
26 {
27  // Open the serial port
28  if ( (serial_fd=vrpn_open_commport(port, baud)) == -1) {
29  fprintf(stderr,"vrpn_ADBox: Cannot Open serial port\n");
30  ready = 0;
31  }
32 
33  // find out what time it is - needed?
34  vrpn_gettimeofday(&timestamp, 0);
35  vrpn_Analog::timestamp = timestamp;
36  vrpn_Button::timestamp = timestamp;
37 }
38 
39 
41 {
42  vrpn_close_commport(serial_fd);
43 }
44 
45 
47 {
48  // Call the generic server mainloop, since we are a server
50 
51  struct timeval timeout = {0,200000};
52  float fAnalog(0.0f);
53 
54  if(!ready) return;
55 
56  if (iNumBytes == 0)
57  {
58  vrpn_flush_output_buffer(serial_fd);
59  vrpn_flush_input_buffer(serial_fd);
60 
61  buffer[0] = 'U';
62  vrpn_write_characters(serial_fd, buffer, 1);
63 
64  while (iNumBytes < 100 && vrpn_read_available_characters(serial_fd, buffer, 1,&timeout) == 1)
65  iNumBytes++;
66 
67  switch (iNumBytes)
68  {
69  case 14:
70  case 18: iNumDigBytes = 2; break;
71  case 19: iNumDigBytes = 3; break;
72  default: iNumBytes = 0; iNumDigBytes = 0; break;
73  }
74 
75  if (iNumBytes != 0)
76  {
77  num_buttons = iNumDigBytes * 8;
78  num_channel = (iNumBytes - iNumDigBytes) / 2;
79 
80  fprintf(stderr,
81  "vrpn_ADBox: ad-box with %d digital and %d analog ports detected\n",
83 
84  buffer[0] = 'U';
85  vrpn_write_characters(serial_fd, buffer, 1);
86  ready = 1;
87 
88  // initialize the buttons and channels
89  for (vrpn_int32 i=0; i<num_buttons; i++)
91  for (vrpn_int32 j=0; j<num_channel; j++) {
92  channel[j] = last[j] = 0;
93  }
94 
95 
96  }
97  else
98  {
99  fprintf(stderr,"vrpn_ADBox: trying to detect ad-box\n");
100  vrpn_SleepMsecs(1000.0*1);
101  }
102  }
103  else
104  {
105  buffer[0] = 'U';
106  vrpn_write_characters(serial_fd, buffer, 1);
107 
108  for (int c = 0; c < iNumBytes; c++)
109  {
110  if (vrpn_read_available_characters(serial_fd, &buffer[c], 1,&timeout) != 1)
111  {
112  fprintf(stderr,"vrpn_ADBox: could only read %d chars, %d expected\n",c,iNumBytes+1);
113  iNumBytes = 0;
114  iNumDigBytes = 0;
115  break;
116  }
117  }
118 
119  vrpn_gettimeofday(&timestamp, 0);
120  vrpn_Analog::timestamp = timestamp;
121  vrpn_Button::timestamp = timestamp;
122 
123  if (iNumBytes != 0)
124  {
125  int i(0);
126  for (i = 0; i < iNumDigBytes; i++)
127  for (int b = 0; b < 8; b++)
128  buttons[8 * i + b] = (unsigned char) ((buffer[i] & (1 << b)) != 0 ? VRPN_BUTTON_OFF : VRPN_BUTTON_ON);
129 
130  for (i = 0; i < (iNumBytes - iNumDigBytes) / 2; i++)
131  {
132  int iOrg = iFilter[i][iFilterPos] =
133  (int(buffer[iNumDigBytes + i * 2]) << 8) | int(buffer[iNumDigBytes + 1 + i * 2]);
134  fAnalog = float(iOrg) / 1023.0f;
135 
136  int p(iFilterPos);
137  do p = (p + 29) % 30; while (p != iFilterPos && iFilter[i][p] == iOrg);
138  if (p != iFilterPos)
139  {
140  int iLast(iFilter[i][p]);
141  if (iOrg - iLast == 1 || iLast - iOrg == 1)
142  {
143  do p = (p + 29) % 30; while (p != iFilterPos && iFilter[i][p] == iLast);
144  if (p != iFilterPos && iFilter[i][p] == iOrg)
145  fAnalog = float(iOrg + iLast) / 2046.0f;
146  }
147  }
148 
149  channel[i] = fAnalog;
150  }
151 
152  iFilterPos = (iFilterPos + 1) % 30;
153 
156  }
157  }
158 }
vrpn_Button::report_changes
virtual void report_changes(void)
Definition: vrpn_Button.C:422
vrpn_ADBox.h
vrpn_Analog::channel
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:38
vrpn_Types.h
vrpn_Analog
Definition: vrpn_Analog.h:28
vrpn_Analog::timestamp
struct timeval timestamp
Definition: vrpn_Analog.h:41
vrpn_Serial.h
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
vrpn_Button::num_buttons
vrpn_int32 num_buttons
Definition: vrpn_Button.h:47
vrpn_ADBox::vrpn_ADBox
vrpn_ADBox(char *name, vrpn_Connection *c, const char *port="/dev/ttyS1/", long baud=9600)
Definition: vrpn_ADBox.C:22
vrpn_Button::buttons
unsigned char buttons[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:44
vrpn_flush_input_buffer
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
Definition: vrpn_Serial.C:435
vrpn_SleepMsecs
void vrpn_SleepMsecs(double dMsecs)
Definition: vrpn_Shared.C:157
vrpn_Button::timestamp
struct timeval timestamp
Definition: vrpn_Button.h:48
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Analog::num_channel
vrpn_int32 num_channel
Definition: vrpn_Analog.h:40
vrpn_ADBox::mainloop
void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_ADBox.C:46
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Button::lastbuttons
unsigned char lastbuttons[vrpn_BUTTON_MAX_BUTTONS]
Definition: vrpn_Button.h:45
vrpn_read_available_characters
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
Definition: vrpn_Serial.C:512
vrpn_close_commport
int vrpn_close_commport(int comm)
Definition: vrpn_Serial.C:345
VRPN_BUTTON_OFF
#define VRPN_BUTTON_OFF
Definition: vrpn_Button.h:222
vrpn_Analog::last
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:39
vrpn_ADBox::~vrpn_ADBox
~vrpn_ADBox()
Definition: vrpn_ADBox.C:40
vrpn_write_characters
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
Definition: vrpn_Serial.C:643
vrpn_open_commport
int vrpn_open_commport(const char *portname, long baud, int charsize, vrpn_SER_PARITY parity, bool rts_flow)
Open a serial port, given its name and baud rate.
Definition: vrpn_Serial.C:54
vrpn_Analog::report_changes
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
Definition: vrpn_Analog.C:71
vrpn_flush_output_buffer
int vrpn_flush_output_buffer(int comm)
Throw out any characters (do not send) within the output buffer.
Definition: vrpn_Serial.C:462
VRPN_API
#define VRPN_API
Definition: vrpn_Configure.h:646
vrpn_BaseClassUnique::server_mainloop
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
Definition: vrpn_BaseClass.C:603
vrpn_Button_Filter
All button servers should derive from this class, which provides the ability to turn any of the butto...
Definition: vrpn_Button.h:65
VRPN_BUTTON_ON
#define VRPN_BUTTON_ON
Definition: vrpn_Button.h:223