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....