15 #include "vrpnClient.h" 16 #include "vrpnTracker.h" 17 #include "vrpnTrackerDevice.h" 18 #include "vrpnButton.h" 19 #include "vrpnButtonDevice.h" 20 #include "vrpnAnalog.h" 21 #include "vrpnAnalogDevice.h" 23 #include "vrpnDialDevice.h" 24 #include "config_vrpn.h" 27 #include "string_utils.h" 38 VrpnClient(
const string &server_name) :
39 _server_name(server_name)
41 if (vrpn_cat.is_debug()) {
43 <<
"Attempting to connect to VRPN server " << _server_name
46 _connection = vrpn_get_connection_by_name(_server_name.c_str());
47 nassertv(_connection != (vrpn_Connection *)NULL);
51 <<
"Unable to establish connection to VRPN server " << _server_name
73 write(ostream &out,
int indent_level)
const {
74 indent(out, indent_level)
75 <<
"VrpnClient, server " << _server_name <<
"\n";
78 indent(out, indent_level + 2)
81 indent(out, indent_level + 2)
82 <<
"(no connection)\n";
85 if (!_trackers.empty()) {
86 indent(out, indent_level + 2)
87 << _trackers.size() <<
" trackers:\n";
88 Trackers::const_iterator ti;
89 for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
91 vrpn_tracker->write(out, indent_level + 4);
95 if (!_buttons.empty()) {
96 indent(out, indent_level + 2)
97 << _buttons.size() <<
" buttons:\n";
98 Buttons::const_iterator bi;
99 for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
101 vrpn_button->write(out, indent_level + 4);
105 if (!_analogs.empty()) {
106 indent(out, indent_level + 2)
107 << _analogs.size() <<
" analogs:\n";
108 Analogs::const_iterator ai;
109 for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
111 vrpn_analog->write(out, indent_level + 4);
115 if (!_dials.empty()) {
116 indent(out, indent_level + 2)
117 << _dials.size() <<
" dials:\n";
118 Dials::const_iterator di;
119 for (di = _dials.begin(); di != _dials.end(); ++di) {
121 vrpn_dial->write(out, indent_level + 4);
140 make_device(
TypeHandle device_type,
const string &device_name) {
141 if (device_type == ClientTrackerDevice::get_class_type()) {
142 return make_tracker_device(device_name);
144 }
else if (device_type == ClientButtonDevice::get_class_type()) {
145 return make_button_device(device_name);
147 }
else if (device_type == ClientAnalogDevice::get_class_type()) {
148 return make_analog_device(device_name);
150 }
else if (device_type == ClientDialDevice::get_class_type()) {
151 return make_dial_device(device_name);
172 disconnect_device(
TypeHandle device_type,
const string &device_name,
174 if (vrpn_cat.is_debug()) {
176 <<
"Disconnecting device " << *device <<
"\n";
179 if (ClientBase::disconnect_device(device_type, device_name, device)) {
180 if (device->
is_of_type(VrpnTrackerDevice::get_class_type())) {
183 }
else if (device->
is_of_type(VrpnButtonDevice::get_class_type())) {
186 }
else if (device->
is_of_type(VrpnAnalogDevice::get_class_type())) {
189 }
else if (device->
is_of_type(VrpnDialDevice::get_class_type())) {
210 ClientBase::do_poll();
212 if (vrpn_cat.is_spam()) {
214 <<
"VrpnClient " << _server_name <<
" polling " 215 << _trackers.size() + _buttons.size() + _analogs.size() + _dials.size()
219 Trackers::iterator ti;
220 for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
222 vrpn_tracker->
poll();
225 Buttons::iterator bi;
226 for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
231 Analogs::iterator ai;
232 for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
238 for (di = _dials.begin(); di != _dials.end(); ++di) {
273 make_tracker_device(
const string &device_name) {
274 if (vrpn_cat.is_debug()) {
276 <<
"Making tracker device for " << device_name <<
"\n";
279 string tracker_name = device_name;
281 VrpnTrackerDevice::DataType data_type = VrpnTrackerDevice::DT_position;
283 size_t colon = device_name.rfind(
':');
284 if (colon != string::npos && colon + 1 < device_name.length()) {
285 size_t begin = colon + 1;
286 size_t end = device_name.length();
287 VrpnTrackerDevice::DataType maybe_data_type = data_type;
289 switch (device_name[end - 1]) {
291 maybe_data_type = VrpnTrackerDevice::DT_position;
296 maybe_data_type = VrpnTrackerDevice::DT_velocity;
301 maybe_data_type = VrpnTrackerDevice::DT_acceleration;
306 if (string_to_int(device_name.substr(begin, end - begin), maybe_sensor)) {
308 sensor = maybe_sensor;
309 data_type = maybe_data_type;
310 tracker_name = device_name.substr(0, colon);
319 if (vrpn_cat.is_debug()) {
321 <<
"Creating " << *device <<
"\n";
324 tracker->
mark(device);
335 make_button_device(
const string &device_name) {
336 if (vrpn_cat.is_debug()) {
338 <<
"Making button device for " << device_name <<
"\n";
346 if (vrpn_cat.is_debug()) {
348 <<
"Creating " << *device <<
"\n";
351 button->
mark(device);
362 make_analog_device(
const string &device_name) {
363 if (vrpn_cat.is_debug()) {
365 <<
"Making analog device for " << device_name <<
"\n";
373 if (vrpn_cat.is_debug()) {
375 <<
"Creating " << *device <<
"\n";
378 analog->
mark(device);
389 make_dial_device(
const string &device_name) {
390 if (vrpn_cat.is_debug()) {
392 <<
"Making dial device for " << device_name <<
"\n";
395 VrpnDial *dial = get_dial(device_name);
400 if (vrpn_cat.is_debug()) {
402 <<
"Creating " << *device <<
"\n";
418 vrpn_tracker->
unmark(device);
420 free_tracker(vrpn_tracker);
433 vrpn_button->
unmark(device);
435 free_button(vrpn_button);
448 vrpn_analog->
unmark(device);
450 free_analog(vrpn_analog);
463 vrpn_dial->
unmark(device);
465 free_dial(vrpn_dial);
477 get_tracker(
const string &tracker_name) {
478 Trackers::iterator ti;
479 ti = _trackers.find(tracker_name);
481 if (ti != _trackers.end()) {
486 _trackers.insert(Trackers::value_type(tracker_name, vrpn_tracker));
488 if (vrpn_cat.is_debug()) {
490 <<
"Creating tracker " << *vrpn_tracker <<
"\n";
506 if (vrpn_cat.is_debug()) {
508 <<
"Deleting tracker " << *vrpn_tracker <<
"\n";
511 Trackers::iterator ti;
513 nassertv(ti != _trackers.end());
514 nassertv((*ti).second == vrpn_tracker);
528 get_button(
const string &button_name) {
529 Buttons::iterator bi;
530 bi = _buttons.find(button_name);
532 if (bi != _buttons.end()) {
537 _buttons.insert(Buttons::value_type(button_name, vrpn_button));
539 if (vrpn_cat.is_debug()) {
541 <<
"Creating button " << *vrpn_button <<
"\n";
557 if (vrpn_cat.is_debug()) {
559 <<
"Deleting button " << *vrpn_button <<
"\n";
562 Buttons::iterator bi;
564 nassertv(bi != _buttons.end());
565 nassertv((*bi).second == vrpn_button);
579 get_analog(
const string &analog_name) {
580 Analogs::iterator ai;
581 ai = _analogs.find(analog_name);
583 if (ai != _analogs.end()) {
588 _analogs.insert(Analogs::value_type(analog_name, vrpn_analog));
590 if (vrpn_cat.is_debug()) {
592 <<
"Creating analog " << *vrpn_analog <<
"\n";
608 if (vrpn_cat.is_debug()) {
610 <<
"Deleting analog " << *vrpn_analog <<
"\n";
613 Analogs::iterator ai;
615 nassertv(ai != _analogs.end());
616 nassertv((*ai).second == vrpn_analog);
630 get_dial(
const string &dial_name) {
632 di = _dials.find(dial_name);
634 if (di != _dials.end()) {
639 _dials.insert(Dials::value_type(dial_name, vrpn_dial));
641 if (vrpn_cat.is_debug()) {
643 <<
"Creating dial " << *vrpn_dial <<
"\n";
659 if (vrpn_cat.is_debug()) {
661 <<
"Deleting dial " << *vrpn_dial <<
"\n";
666 nassertv(di != _dials.end());
667 nassertv((*di).second == vrpn_dial);
676 #include "datagram.h" 677 #include "datagramIterator.h" 692 add_remote_tracker(
const string &tracker,
int sensor) {
694 vrpn_Tracker_Remote *vrpn_tracker =
new vrpn_Tracker_Remote(tracker.c_str(), _connection);
695 if (vrpn_tracker == (vrpn_Tracker_Remote *)NULL) {
702 VrpnClientInfo *data =
new VrpnClientInfo;
703 data->device_name = tracker;
706 vrpn_tracker->register_change_handler((
void*)data, st_tracker_position);
707 vrpn_tracker->register_change_handler((
void*)data, st_tracker_velocity);
708 vrpn_tracker->register_change_handler((
void*)data, st_tracker_acceleration);
710 _vrpn_trackers[tracker] = vrpn_tracker;
711 _trackers.push_back(tracker);
712 _sensors[tracker].push_back(sensor);
724 add_remote_analog(
const string &analog) {
726 vrpn_Analog_Remote *vrpn_analog =
new vrpn_Analog_Remote(analog.c_str(), _connection);
727 if (vrpn_analog == (vrpn_Analog_Remote *)NULL) {
734 VrpnClientInfo *data =
new VrpnClientInfo;
735 data->device_name = analog;
738 vrpn_analog->register_change_handler((
void*)data, st_analog);
740 _vrpn_analogs[analog] = vrpn_analog;
741 _analogs.push_back(analog);
753 add_remote_button(
const string &button) {
755 vrpn_Button_Remote *vrpn_button =
new vrpn_Button_Remote(button.c_str(), _connection);
756 if (vrpn_button == (vrpn_Button_Remote *)NULL) {
763 VrpnClientInfo *data =
new VrpnClientInfo;
764 data->device_name = button;
767 vrpn_button->register_change_handler((
void*)data, st_button);
769 _vrpn_buttons[button] = vrpn_button;
770 _buttons.push_back(button);
782 add_remote_dial(
const string &dial) {
784 vrpn_Dial_Remote *vrpn_dial =
new vrpn_Dial_Remote(dial.c_str(), _connection);
785 if (vrpn_dial == (vrpn_Dial_Remote *)NULL) {
792 VrpnClientInfo *data =
new VrpnClientInfo;
793 data->device_name = dial;
796 vrpn_dial->register_change_handler((
void*)data, st_dial);
798 _vrpn_dials[dial] = vrpn_dial;
799 _dials.push_back(dial);
810 max_analog_channels() {
811 return vrpn_CHANNEL_MAX;
826 poll_tracker(
const string &tracker) {
827 _vrpn_trackers[tracker]->mainloop();
836 poll_analog(
const string &analog) {
837 _vrpn_analogs[analog]->mainloop();
846 poll_button(
const string &button) {
847 _vrpn_buttons[button]->mainloop();
856 poll_dial(
const string &dial) {
857 _vrpn_dials[dial]->mainloop();
866 void VRPN_CALLBACK VrpnClient::
867 st_tracker_position(
void *userdata,
const vrpn_TRACKERCB info) {
868 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
869 ((
VrpnClient *)data->self)->tracker_position(data->device_name, info);
878 void VRPN_CALLBACK VrpnClient::
879 st_tracker_velocity(
void *userdata,
const vrpn_TRACKERVELCB info) {
880 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
881 ((
VrpnClient *)data->self)->tracker_velocity(data->device_name, info);
889 void VRPN_CALLBACK VrpnClient::
890 st_tracker_acceleration(
void *userdata,
const vrpn_TRACKERACCCB info) {
891 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
892 ((
VrpnClient *)data->self)->tracker_acceleration(data->device_name, info);
902 st_analog(
void *userdata,
const vrpn_ANALOGCB info) {
903 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
904 ((
VrpnClient *)data->self)->analog(data->device_name, info);
914 st_button(
void *userdata,
const vrpn_BUTTONCB info) {
915 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
916 ((
VrpnClient *)data->self)->button(data->device_name, info);
926 st_dial(
void *userdata,
const vrpn_DIALCB info) {
927 VrpnClientInfo *data = (VrpnClientInfo *)userdata;
928 ((
VrpnClient *)data->self)->dial(data->device_name, info);
VrpnDial * get_vrpn_dial() const
Returns a pointer to the particular VrpnDial this device gets its data from.
VrpnTracker * get_vrpn_tracker() const
Returns a pointer to the particular VrpnTracker this device gets its data from.
bool is_connected() const
Returns true if the connection is established successfully, false otherwise.
void write(ostream &out, int indent_level=0) const
Writes a list of the active devices that the VrpnClient is currently polling each frame...
A specific ClientBase that connects to a VRPN server and records information on the connected VRPN de...
void unmark(VrpnAnalogDevice *device)
Removes the indicated VrpnAnalogDevice from the list of devices that are sharing this VrpnAnalog...
void poll()
Polls the connected device.
void unmark(VrpnTrackerDevice *device)
Removes the indicated VrpnTrackerDevice from the list of devices that are sharing this VrpnTracker...
The Panda interface to a VRPN analog device.
This is the actual interface to a particular VRPN tracker object, and all of its sensors.
The Panda interface to a VRPN tracker.
The Panda interface to a VRPN dial device.
const string & get_dial_name() const
Returns the name of the dial device that was used to create this VrpnDial.
bool is_valid() const
Returns true if everything seems to be kosher with the server (even if there is no connection)...
VrpnAnalog * get_vrpn_analog() const
Returns a pointer to the particular VrpnAnalog this device gets its data from.
void mark(VrpnTrackerDevice *device)
Adds the indicated VrpnTrackerDevice to the list of devices that are sharing this VrpnTracker...
void mark(VrpnDialDevice *device)
Adds the indicated VrpnDialDevice to the list of devices that are sharing this VrpnDial.
void poll()
Polls the connected device.
bool is_empty() const
Returns true if no VrpnDialDevices reference this VrpnDial, or false otherwise.
void poll()
Polls the connected device.
const string & get_tracker_name() const
Returns the name of the tracker device that was used to create this VrpnTracker.
bool is_empty() const
Returns true if no VrpnTrackerDevices reference this VrpnTracker, or false otherwise.
bool is_empty() const
Returns true if no VrpnAnalogDevices reference this VrpnAnalog, or false otherwise.
This is the actual interface to a particular VRPN dial device, and all of its numbered dials...
const string & get_analog_name() const
Returns the name of the analog device that was used to create this VrpnAnalog.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
void unmark(VrpnDialDevice *device)
Removes the indicated VrpnDialDevice from the list of devices that are sharing this VrpnDial...
void mark(VrpnAnalogDevice *device)
Adds the indicated VrpnAnalogDevice to the list of devices that are sharing this VrpnAnalog.
TypeHandle is the identifier used to differentiate C++ class types.
This is the actual interface to a particular VRPN analog device, and all of its numbered controls...
Any of a number of different devices that might be attached to a ClientBase, including trackers...