8 #ifdef VRPN_USE_NATIONAL_INSTRUMENTS 9 #include "server_src/NIUtil.cpp" 14 const char *boardName,
15 int numInChannels,
int numOutChannels,
16 double minInputReportDelaySecs,
17 bool inBipolar,
int inputMode,
int inputRange,
bool driveAIS,
int inputGain,
18 bool outBipolar,
double minOutVoltage,
double maxOutVoltage) :
21 #if defined(VRPN_USE_NATIONAL_INSTRUMENTS_MX)
22 d_analog_task_handle(0),
23 d_analog_out_task_handle(0),
27 d_out_min_voltage(minOutVoltage),
28 d_out_max_voltage(maxOutVoltage),
29 d_in_min_delay(minInputReportDelaySecs),
47 #if defined(VRPN_USE_NATIONAL_INSTRUMENTS_MX) 55 terminalConfig = DAQmx_Val_Diff;
58 terminalConfig = DAQmx_Val_RSE;
61 terminalConfig = DAQmx_Val_NRSE;
64 fprintf(stderr,
"vrpn_National_Instruments_Server::vrpn_National_Instruments_Server(): Invalid inputMode (%d)\n", inputMode);
71 double min_val = 0.0, max_val = inputRange;
81 if (numInChannels > 0) {
82 sprintf(portName,
"%s/ai0:%d", boardName, numInChannels-1);
85 error = DAQmxCreateAIVoltageChan(
94 fprintf(stderr,
"vrpn_National_Instruments_Server::vrpn_National_Instruments_Server(): Cannot create input voltage channel\n");
99 fprintf(stderr,
"vrpn_National_Instruments_Server::vrpn_National_Instruments_Server(): Cannot create input voltage task\n");
109 if (numOutChannels > 0) {
110 sprintf(portName,
"%s/ao0:%d", boardName, numOutChannels-1);
113 error = DAQmxCreateAOVoltageChan(
117 , minOutVoltage, maxOutVoltage
118 , DAQmx_Val_Volts,
"" 121 fprintf(stderr,
"vrpn_National_Instruments_Server::vrpn_National_Instruments_Server(): Cannot create output voltage channel\n");
130 fprintf(stderr,
"vrpn_National_Instruments_Server::vrpn_National_Instruments_Server(): Cannot create or start output voltage task\n");
137 float64 minval = 0.0;
138 if (minval < minOutVoltage) { minval = minOutVoltage; }
144 fprintf(stderr,
"vrpn_National_Instruments_Server::vrpn_National_Instruments_Server(): Could not set values\n");
149 #elif defined(VRPN_USE_NATIONAL_INSTRUMENTS) 151 short update_mode = 0;
152 short ref_source = 0;
153 double ref_voltage = 10.0;
156 d_device_number = NIUtil::findDevice(boardName);
157 if (d_device_number == -1) {
158 fprintf(stderr,
"vrpn_National_Instruments_Server: Error opening the D/A board %s\n", boardName);
164 int ret = AI_Clear(d_device_number);
166 fprintf(stderr,
"vrpn_National_Instruments_Server: Cannot clear analog input (error %d)\n", ret);
171 int ret = AI_Configure(d_device_number, i, inputMode, inputRange,
d_in_polarity, driveAIS);
173 fprintf(stderr,
"vrpn_National_Instruments_Server: Cannot configure input channel %d (error %d)\n", i, ret);
182 int ret = AO_Configure(d_device_number, i,
d_out_polarity, ref_source, ref_voltage, update_mode);
184 if ( (ret < 0) && (ret != -10403) ) {
185 fprintf(stderr,
"vrpn_National_Instruments_Server: Cannot configure output channel %d (error %d)\n", i, ret);
186 fprintf(stderr,
" polarity: %d, reference source: %d, reference_voltage: %lg, update_mode: %d\n",
193 fprintf(stderr,
"vrpn_National_Instruments_Server: Cannot set output channel %d to %lg\n", i,
d_out_min_voltage);
199 fprintf(stderr,
"vrpn_National_Instruments_Server: Support for NI not compiled in, edit vrpn_Configure.h and recompile VRPN\n");
204 fprintf(stderr,
"vrpn_National_Instruments_Server: Can't get connection!\n");
210 fprintf(stderr,
"vrpn_Analog_Output_Server_NI: can't register change channel request handler\n");
217 fprintf(stderr,
"vrpn_Analog_Output_Server_NI: can't register change channels request handler\n");
225 fprintf( stderr,
"vrpn_Analog_Output_Server_NI: can't register new connection handler\n");
237 #ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX 273 #if defined(VRPN_USE_NATIONAL_INSTRUMENTS_MX) 278 int32 channelsRead = 0;
292 for (i = 0; i < channelsRead; i++) {
297 #elif defined(VRPN_USE_NATIONAL_INSTRUMENTS) 302 int ret = AI_Read(d_device_number, i,
d_in_gain, &value);
322 if (sizeRequested < 0) sizeRequested = 0;
330 if (sizeRequested < 0) sizeRequested = 0;
341 const char* bufptr = p.
buffer;
356 sprintf( msg,
"Error: (handle_request_message): channel %d is not active. Squelching.", chan_num );
363 sprintf( msg,
"Error: (handle_request_message): voltage %g is too low. Clamping to %g.", value, me->
d_out_min_voltage);
369 sprintf( msg,
"Error: (handle_request_message): voltage %g is too high. Clamping to %g.", value, me->
d_out_max_voltage);
376 #if defined(VRPN_USE_NATIONAL_INSTRUMENTS_MX) 382 #elif defined(VRPN_USE_NATIONAL_INSTRUMENTS) 383 if (me->d_device_number != -1) {
384 AO_VWrite(me->d_device_number, (
short)(chan_num), value);
394 const char* bufptr = p.
buffer;
407 sprintf( msg,
"Error: (handle_request_channels_message): channels above %d not active; " 408 "bad request up to channel %d. Squelching.", me->
o_num_channel, num );
415 sprintf( msg,
"Error: (handle_request_channels_message): invalid channel %d. Squelching.", num );
419 for (chan_num = 0; chan_num < num; chan_num++) {
425 sprintf( msg,
"Error: (handle_request_messages): voltage %g is too low. Clamping to %g.", value, me->
d_out_min_voltage);
431 sprintf( msg,
"Error: (handle_request_messages): voltage %g is too high. Clamping to %g.", value, me->
d_out_max_voltage);
438 #ifdef VRPN_USE_NATIONAL_INSTRUMENTS 439 if (me->d_device_number != -1) {
440 AO_VWrite(me->d_device_number, (
short)(chan_num), value);
445 #if defined(VRPN_USE_NATIONAL_INSTRUMENTS_MX) 455 #if defined(VRPN_USE_NATIONAL_INSTRUMENTS_MX) 466 DAQmx_Val_GroupByChannel, outbuffer, NULL, NULL);
487 fprintf( stderr,
"Error: failed sending active channels to client.\n" );
494 char msgbuf[
sizeof( vrpn_int32) ];
495 vrpn_int32 len =
sizeof( vrpn_int32 );;
503 fprintf(stderr,
"vrpn_Analog_Output_Server_NI (report_num_channels): cannot write message: tossing\n");
513 int buflen =
sizeof(vrpn_int32);
516 return sizeof(vrpn_int32);
520 const char *boardName,
521 vrpn_int16 numChannels,
bool bipolar,
522 double minVoltage,
double maxVoltage) :
524 NI_device_number(-1),
525 min_voltage(minVoltage),
526 max_voltage(maxVoltage),
527 NI_num_channels(numChannels)
529 #ifdef VRPN_USE_NATIONAL_INSTRUMENTS 531 short update_mode = 0;
532 short ref_source = 0;
533 double ref_voltage = 0.0;
546 fprintf(stderr,
"vrpn_Analog_Output_Server_NI: Error opening the D/A board %s\n", boardName);
564 fprintf(stderr,
"vrpn_Analog_Output_Server_NI: Can't get connection!\n");
570 fprintf(stderr,
"vrpn_Analog_Output_Server_NI: can't register change channel request handler\n");
577 fprintf(stderr,
"vrpn_Analog_Output_Server_NI: can't register change channels request handler\n");
585 fprintf( stderr,
"vrpn_Analog_Output_Server_NI: can't register new connection handler\n");
589 fprintf(stderr,
"vrpn_Analog_Output_Server_NI: Support for NI not compiled in, edit vrpn_Configure.h and recompile\n");
604 if (sizeRequested < 0) sizeRequested = 0;
616 const char* bufptr = p.
buffer;
631 sprintf( msg,
"Error: (handle_request_message): channel %d is not active. Squelching.", chan_num );
638 sprintf( msg,
"Error: (handle_request_message): voltage %g is too low. Clamping to %g.", value, me->
min_voltage);
644 sprintf( msg,
"Error: (handle_request_message): voltage %g is too high. Clamping to %g.", value, me->
max_voltage);
651 #ifdef VRPN_USE_NATIONAL_INSTRUMENTS 663 const char* bufptr = p.
buffer;
676 sprintf( msg,
"Error: (handle_request_channels_message): channels above %d not active; " 677 "bad request up to channel %d. Squelching.", me->
o_num_channel, num );
684 sprintf( msg,
"Error: (handle_request_channels_message): invalid channel %d. Squelching.", num );
688 for (chan_num = 0; chan_num < num; chan_num++) {
694 sprintf( msg,
"Error: (handle_request_messages): voltage %g is too low. Clamping to %g.", value, me->
min_voltage);
700 sprintf( msg,
"Error: (handle_request_messages): voltage %g is too high. Clamping to %g.", value, me->
max_voltage);
707 #ifdef VRPN_USE_NATIONAL_INSTRUMENTS 724 fprintf( stderr,
"Error: failed sending active channels to client.\n" );
732 char msgbuf[
sizeof( vrpn_int32) ];
733 vrpn_int32 len =
sizeof( vrpn_int32 );;
741 fprintf(stderr,
"vrpn_Analog_Output_Server_NI (report_num_channels): cannot write message: tossing\n");
752 int buflen =
sizeof(vrpn_int32);
755 return sizeof(vrpn_int32);
759 #ifdef VRPN_USE_NATIONAL_INSTRUMENTS_MX 762 char errBuff[2048]={
'\0'};
764 if( DAQmxFailed(errnumber) )
766 DAQmxGetExtendedErrorInfo(errBuff,2048);
767 printf(
"DAQmx Error: %s\n",errBuff);
768 if (exitProgram==vrpn_true) {
769 printf(
"Exiting...\n") ;
772 printf(
"Sleeping...\n") ;
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
virtual vrpn_int32 encode_num_channels_to(char *buf, vrpn_int32 num)
struct timeval d_last_report_time
struct timeval o_timestamp
void vrpn_SleepMsecs(double dMsecs)
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
vrpn_int32 request_channels_m_id
TaskHandle d_analog_task_handle
virtual vrpn_int32 encode_num_channels_to(char *buf, vrpn_int32 num)
static int VRPN_CALLBACK handle_got_connection(void *userdata, vrpn_HANDLERPARAM p)
Used to notify us when a new connection is requested, so that we can let the client know how many cha...
int setNumOutChannels(int sizeRequested)
Sets the size of the array; returns the size actually set. (May be clamped to vrpn_CHANNEL_MAX) This ...
vrpn_float64 o_channel[vrpn_CHANNEL_MAX]
vrpn_National_Instruments_Server(const char *name, vrpn_Connection *c, const char *boardName="PCI-6713", int numInChannels=vrpn_CHANNEL_MAX, int numOutChannels=vrpn_CHANNEL_MAX, double minInputReportDelaySecs=0.0, bool inBipolar=false, int inputMode=vrpn_NI_INPUT_MODE_DIFFERENTIAL, int inputRange=vrpn_NI_INPUT_RANGE_10V, bool driveAIS=false, int inputGain=1, bool outBipolar=false, double minOutVoltage=0.0, double maxOutVoltage=10.0)
vrpn_float64 channel[vrpn_CHANNEL_MAX]
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
virtual bool report_num_channels(vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
Generic connection class not specific to the transport mechanism.
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report whether something has changed or not (for servers) Optionally, tell what time to stamp ...
int setNumInChannels(int sizeRequested)
Sets the size of the array; returns the size actually set. (May be clamped to vrpn_CHANNEL_MAX) This ...
virtual bool report_num_channels(vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
double vrpn_TimevalDurationSeconds(struct timeval endT, struct timeval startT)
Return the number of seconds between startT and endT as a floating-point value.
static int VRPN_CALLBACK handle_got_connection(void *userdata, vrpn_HANDLERPARAM p)
Used to notify us when a new connection is requested, so that we can let the client know how many cha...
static int VRPN_CALLBACK handle_request_channels_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change a number of channels Derived class must either install handlers for t...
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
virtual ~vrpn_Analog_Output_Server_NI(void)
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
vrpn_Connection * d_connection
Connection that this object talks to.
This structure is what is passed to a vrpn_Connection message callback.
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
vrpn_int32 got_connection_m_id
vrpn_int32 setNumChannels(vrpn_int32 sizeRequested)
Sets the size of the array; returns the size actually set. (May be clamped to vrpn_CHANNEL_MAX) This ...
vrpn_int32 report_num_channels_m_id
static int VRPN_CALLBACK handle_request_channels_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change a number of channels Derived class must either install handlers for t...
#define vrpn_NI_INPUT_MODE_DIFFERENTIAL
int send_text_message(const char *msg, struct timeval timestamp, vrpn_TEXT_SEVERITY type=vrpn_TEXT_NORMAL, vrpn_uint32 level=0)
Sends a NULL-terminated text message from the device d_sender_id.
#define vrpn_gettimeofday
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message...
virtual ~vrpn_National_Instruments_Server()
vrpn_int32 d_sender_id
Sender ID registered with the connection.
#define vrpn_NI_INPUT_MODE_NON_REF_SINGLE_ENDED
void reportError(int32 errnumber, vrpn_bool exitProgram=vrpn_false)
static int VRPN_CALLBACK handle_request_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to the AnalogOutput to change one of the values by setting the channel to that ...
TaskHandle d_analog_out_task_handle
vrpn_Analog_Output_Server_NI(const char *name, vrpn_Connection *c, const char *boardName="PCI-6713", vrpn_int16 numChannels=vrpn_CHANNEL_MAX, bool bipolar=false, double minVoltage=0.0, double maxVoltage=10.0)
#define vrpn_NI_INPUT_MODE_REF_SINGLE_ENDED
static int VRPN_CALLBACK handle_request_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change one of the values by setting the channel to that value. Derived class must either install handlers for this routine or else make its own routines to handle the request message.