15#define VRPN_TIMESTAMP_MEMBER d_timestamp
21#define STATUS_RESETTING (-1)
22#define STATUS_SYNCING (0)
23#define STATUS_READING (1)
25#define TIMEOUT_TIME_INTERVAL (2000000L)
26#define POLL_INTERVAL (1000000L)
32 ,
int run_speed_tics_sec
33 ,
int start_speed_tics_sec
34 ,
int end_speed_tics_sec
35 ,
int accel_rate_tics_sec_sec
36 ,
int decel_rate_tics_sec_sec
43 ,
int high_limit_index
45 ,
int output_1_setting
46 ,
int output_2_setting
47 ,
int output_3_setting
48 ,
int output_4_setting
50 ,
double fractional_c_a
51 ,
double reset_location):
56 , d_run_speed_tics_sec(run_speed_tics_sec)
57 , d_start_speed_tics_sec(start_speed_tics_sec)
58 , d_end_speed_tics_sec(end_speed_tics_sec)
59 , d_accel_rate_tics_sec_sec(accel_rate_tics_sec_sec)
60 , d_decel_rate_tics_sec_sec(decel_rate_tics_sec_sec)
61 , d_run_current(run_current)
62 , d_hold_current(hold_current)
63 , d_accel_current(accel_current)
64 , d_decel_current(decel_current)
67 , d_high_limit_index(high_limit_index)
68 , d_low_limit_index(low_limit_index)
69 , d_output_1_setting(output_1_setting)
70 , d_output_2_setting(output_2_setting)
71 , d_output_3_setting(output_3_setting)
72 , d_output_4_setting(output_4_setting)
73 , d_initial_move(initial_move)
74 , d_fractional_c_a(fractional_c_a)
75 , d_reset_location(reset_location)
97 fprintf(stderr,
"vrpn_IDEA: can't register handler\n");
102 fprintf(stderr,
"vrpn_IDEA: can't register handler\n");
107 fprintf(stderr,
"vrpn_IDEA: can't register handler\n");
111 fprintf(stderr,
"vrpn_IDEA: Can't get connection!\n");
122 size_t len = strlen(cmd);
123 if (len >
sizeof(buf)-2) {
return false; }
128 (
const unsigned char *)((
void*)(buf)), strlen(buf))) == strlen(buf) );
132static inline int scale_int(
int val,
double scale)
134 return static_cast<int>(val*scale);
175 int edge_masks[4] = { 0, 0, 0, 0 };
176 int address_masks[4] = { 0, 0, 0, 0 };
177 int priority_masks[4] = { 1, 1, 1, 1 };
193 if (sprintf(cmd,
"i%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
194 edge_masks[0], edge_masks[1], edge_masks[2], edge_masks[3],
195 address_masks[0], address_masks[1], address_masks[2], address_masks[3],
196 priority_masks[0], priority_masks[1], priority_masks[2], priority_masks[3]
198 VRPN_MSG_ERROR(
"vrpn_IDEA::send_move_request(): Could not configure interrupt command");
203 VRPN_MSG_ERROR(
"vrpn_IDEA::send_move_request(): Could not configure interrupts");
215 VRPN_MSG_WARNING(
"vrpn_IDEA::send_move_request(): Asked to move into limit");
221 VRPN_MSG_WARNING(
"vrpn_IDEA::send_move_request(): Asked to move into limit");
228 long steps_64th =
static_cast<long>(location_in_steps*64);
229 sprintf(cmd,
"M%ld,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
258 unsigned char inbuf[1024];
265 struct timeval timeout;
267 timeout.tv_usec = 30000;
273 if ( (ret < 8) || (inbuf[ret-1] !=
'\r') ) {
280 if ( (inbuf[0] !=
'`') || (inbuf[1] !=
'o') ) {
284 moving = (inbuf[2] ==
'Y');
299 char *firstindex = strchr((
char*)(buf),
'\r');
300 char *lastindex = strrchr((
char*)(buf),
'\r');
301 if (buf[strlen((
char*)(buf))-1] !=
'\r') {
return 0; }
302 if (firstindex == lastindex) {
return 0; }
306 if (sscanf((
char *)(buf),
"`l%d\r`l#\r", &data) != 1) {
326 char *firstindex = strchr((
char*)(buf),
'\r');
327 char *lastindex = strrchr((
char*)(buf),
'\r');
328 if (buf[strlen((
char*)(buf))-1] !=
'\r') {
return 0; }
329 if (firstindex == lastindex) {
return 0; }
333 if (sscanf((
char *)(buf),
"`:%d\r`:#\r", &io_status) != 1) {
374 struct timeval timeout;
375 unsigned char inbuf[128];
388 fprintf(stderr,
"vrpn_IDEA::reset(): Could not send reset command\n");
398 fprintf(stderr,
"vrpn_IDEA::reset(): Could not request fault status\n");
403 timeout.tv_usec = 30000;
407 perror(
"vrpn_IDEA::reset(): Error reading fault status from device");
410 if ( (ret < 8) || (inbuf[ret-1] !=
'\r') ) {
412 fprintf(stderr,
"vrpn_IDEA::reset(): Bad fault status report (length %d): %s\n", ret, inbuf);
419 if (sscanf((
char *)(inbuf),
"`f%d\r`f#\r", &fault_status) != 1) {
420 fprintf(stderr,
"vrpn_IDEA::reset(): Bad fault status report: %s\n", inbuf);
424 if (fault_status != 0) {
433 fprintf(stderr,
"vrpn_IDEA::reset(): Could not set position to 0\n");
443 value |= 1 << (4 + 0);
447 value |= 1 << (4 + 1);
451 value |= 1 << (4 + 2);
455 value |= 1 << (4 + 3);
458 if (sprintf(cmd,
"O%d", value) <= 0) {
459 VRPN_MSG_ERROR(
"vrpn_IDEA::send_output(): Could not configure output command");
464 VRPN_MSG_ERROR(
"vrpn_IDEA::send_output(): Could not configure outputs");
474 fprintf(stderr,
"vrpn_IDEA::reset(): Could not request I/O status\n");
479 timeout.tv_usec = 30000;
483 perror(
"vrpn_IDEA::reset(): Error reading I/O status from device");
486 if ( (ret < 8) || (inbuf[ret-1] !=
'\r') ) {
488 fprintf(stderr,
"vrpn_IDEA::reset(): Bad I/O status report (length %d): %s\n", ret, inbuf);
495 fprintf(stderr,
"vrpn_IDEA::reset(): Bad I/O status report: %s\n", inbuf);
503 fprintf(stderr,
"vrpn_IDEA::reset(): Could not request position\n");
508 timeout.tv_usec = 30000;
512 perror(
"vrpn_IDEA::reset(): Error reading position from device");
515 if ( (ret < 8) || (inbuf[ret-1] !=
'\r') ) {
517 fprintf(stderr,
"vrpn_IDEA::reset(): Bad position report: %s\n", inbuf);
524 fprintf(stderr,
"vrpn_IDEA::reset(): Bad position report: %s\n", inbuf);
546 fprintf(stderr,
"vrpn_IDEA::reset(): Could not start limit program\n");
552 fprintf(stderr,
"vrpn_IDEA::reset(): Could not send abort to limit program\n");
558 fprintf(stderr,
"vrpn_IDEA::reset(): Could not send return to limit program\n");
564 fprintf(stderr,
"vrpn_IDEA::reset(): Could not finish limit program\n");
569 timeout.tv_usec = 300000;
575 perror(
"vrpn_IDEA::reset(): Error reading limit program response from device");
578 if ( (ret < 8) || (inbuf[ret-1] !=
'\r') ) {
580 fprintf(stderr,
"vrpn_IDEA::reset(): Bad limit program response report: %s\n", inbuf);
587 if (sscanf((
char *)(inbuf),
"`P%d\r`P#\r", &program_length) != 1) {
588 fprintf(stderr,
"vrpn_IDEA::reset(): Bad limit program report: %s\n", inbuf);
625 fprintf(stderr,
"vrpn_IDEA::reset(): Could not request position\n");
630 timeout.tv_usec = 30000;
634 perror(
"vrpn_IDEA::reset(): Error reading position from device");
637 if ( (ret < 8) || (inbuf[ret-1] !=
'\r') ) {
639 fprintf(stderr,
"vrpn_IDEA::reset(): Bad position report: %s\n", inbuf);
646 fprintf(stderr,
"vrpn_IDEA::reset(): Bad position report: %s\n", inbuf);
654 fprintf(stderr,
"vrpn_IDEA::reset(): Could not request I/O status in limit hunt\n");
659 timeout.tv_usec = 30000;
663 perror(
"vrpn_IDEA::reset(): Error reading I/O status from device in limit hunt");
666 if ( (ret < 8) || (inbuf[ret-1] !=
'\r') ) {
668 fprintf(stderr,
"vrpn_IDEA::reset(): Bad I/O status report (length %d) in limit hunt: %s\n", ret, inbuf);
675 fprintf(stderr,
"vrpn_IDEA::reset(): Bad I/O status report in limit hunt: %s\n", inbuf);
687 printf(
"XXX vrpn_IDEA: moving to %lf to find limit\n",
699 sprintf(cmd,
"Z%ld", reset_location);
701 fprintf(stderr,
"vrpn_IDEA::reset(): Could not set position to 1280\n");
710 fprintf(stderr,
"vrpn_IDEA::reset(): Could not request position\n");
751 sprintf(msg,
"Bad character (got %c, expected `), re-syncing",
d_buffer[0]);
756 VRPN_MSG_ERROR(
"Could not send position request in re-sync, resetting");
772 printf(
"... Got the 1st char\n");
791 if (ret != 0) printf(
"... got %d characters (%d total)\n",ret,
d_bufcount);
810 printf(
"got a complete report (%d)!\n",
d_bufcount);
845 printf(
"got a complete report (%d)!\n",
d_bufcount);
866 if ( (pos_ret == -1) && (but_ret == -1) ) {
875 VRPN_MSG_ERROR(
"Could not send position request in convert failure, resetting");
887 const char *bufptr = p.
buffer;
902 sprintf(msg,
"vrpn_IDEA::handle_request_message(): Index out of bounds (%d of %d), value %lg\n",
916 const char* bufptr = p.
buffer;
926 sprintf(msg,
"vrpn_IDEA::handle_request_channels_message(): Index out of bounds (%d of %d), clipping\n",
931 for (i = 0; i < num; i++) {
999 struct timeval current_time;
1017 sprintf(errmsg,
"Timeout, resetting... current_time=%ld:%ld, timestamp=%ld:%ld",
1018 current_time.tv_sec,
static_cast<long>(current_time.tv_usec),
vrpn_float64 o_channel[vrpn_CHANNEL_MAX]
vrpn_int32 request_channels_m_id
vrpn_float64 last[vrpn_CHANNEL_MAX]
vrpn_float64 channel[vrpn_CHANNEL_MAX]
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 ...
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...
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.
vrpn_Connection * d_connection
Connection that this object talks to.
vrpn_int32 d_sender_id
Sender ID registered with the connection.
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
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.
vrpn_int32 d_ping_message_id
Ask the server if they are there.
Generic connection class not specific to the transport mechanism.
int d_accel_rate_tics_sec_sec
bool send_command(const char *cmd)
Appends carriage-return and then sends the command.
struct timeval d_timestamp
struct timeval d_last_poll
bool send_move_request(vrpn_float64 location_in_steps, double scale=1.0)
Request a move from the motor to the specified location.
int d_decel_rate_tics_sec_sec
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.
virtual int get_report(void)
vrpn_IDEA(const char *name, vrpn_Connection *c, const char *port, int run_speed_tics_sec=3200, int start_speed_tics_sec=1200, int end_speed_tics_sec=2000, int accel_rate_tics_sec_sec=40000, int decel_rate_tics_sec_sec=100000, int run_current=290, int hold_current=0, int accel_current=290, int decel_current=290, int delay=50, int step=8, int high_limit_index=-1, int low_limit_index=-1, int output_1_setting=-1, int output_2_setting=-1, int output_3_setting=-1, int output_4_setting=-1, double initial_move=0, double fractional_c_a=1.0, double reset_location=0.0)
static int VRPN_CALLBACK handle_request_channels_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a request to change multiple channels at once.
int convert_report_to_buttons(unsigned char *buf)
Parses an input/output report. Returns -1 on failure, 0 on no value.
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_RELIABLE)
send report whether or not changed
int convert_report_to_position(unsigned char *buf)
Parses a position report. Returns -1 on failure, 0 on no value.
virtual void mainloop()
Called once through each main loop iteration to handle updates.
unsigned char d_buffer[512]
bool move_until_done_or_error(vrpn_float64 location_in_steps, double scale=1.0)
Send a move request and then wait for the move to complete. Repeat.
static int VRPN_CALLBACK handle_connect_message(void *userdata, vrpn_HANDLERPARAM p)
Responds to a connection request with a report of the values.
int d_start_speed_tics_sec
This structure is what is passed to a vrpn_Connection message callback.
All types of client/server/peer objects in VRPN should be derived from the vrpn_BaseClass type descri...
const vrpn_uint32 vrpn_CONNECTION_RELIABLE
Classes of service for messages, specify multiple by ORing them together Priority of satisfying these...
Header containing macros formerly duplicated in a lot of implementation files.
#define VRPN_MSG_ERROR(msg)
#define VRPN_MSG_WARNING(msg)
int vrpn_write_characters(int comm, const unsigned char *buffer, size_t bytes)
Write the buffer to the serial port.
int vrpn_flush_input_buffer(int comm)
Throw out any characters within the input buffer.
int vrpn_read_available_characters(int comm, unsigned char *buffer, size_t bytes)
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
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.
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
void vrpn_SleepMsecs(double dMilliSecs)
#define vrpn_gettimeofday