phantom_control.cpp
Go to the documentation of this file.
1 /**************************************************************************************************
2  Software License Agreement (BSD License)
3 
4  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted
8  provided that the following conditions are met:
9 
10  *Redistributions of source code must retain the above copyright notice, this list of
11  conditions and the following disclaimer.
12  *Redistributions in binary form must reproduce the above copyright notice, this list of
13  conditions and the following disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  *Neither the name of the University of Aveiro nor the names of its contributors may be used to
16  endorse or promote products derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
19  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ***************************************************************************************************/
33 #include <phantom_control/omni.h>
34 #include <phantom_control/conio.h>
35 
36 #include <sys/types.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 
40 #include <haptic_force/Force.h>
41 
42 #include <phantom_control/State.h>
43 
44 HDSchedulerHandle gCallbackHandle = 0;
46 bool g_new=0;
47 phantom_control::State g_SS;
48 
49 hduVector3Dd g_home_pos(HOME_XX, HOME_YY, HOME_ZZ);
50 
51 void ee_convert(void);
52 void ForceCallBk ( const haptic_force::Force &force );
53 
54 void HHD_Auto_Calibration(void);
55 HDCallbackCode HDCALLBACK MonitorCallback(void *pUserData);
56 
57 void SetHomePos(void);
58 
59 
64 int main ( int argc, char **argv )
65 {
66  // Phantom device state pointer
67  OmniState *ss=&state;
68 
69 
70  /*******************************************************************
71  * Initialize Phantom device
72  *******************************************************************/
73  HDErrorInfo error;
74  HHD hHD = hdInitDevice(HD_DEFAULT_DEVICE);
75 
76  if (HD_DEVICE_ERROR(error = hdGetError()))
77  {
78  hduPrintError(stderr, &error, "Failed to initialize haptic device");
79  fprintf(stderr, "\nPress any key to quit.\n");
80  getch();
81  return -1;
82  }
83  ROS_INFO("Found %s.\n\n", hdGetString(HD_DEVICE_MODEL_TYPE));
84 
85  /* Schedule the haptic callback function for continuously monitoring the
86  button state and rendering the anchored spring force. */
87  gCallbackHandle = hdScheduleAsynchronous(MonitorCallback, ss, HD_MAX_SCHEDULER_PRIORITY);
88 
89  hdEnable(HD_FORCE_OUTPUT);
90 
91  hdStartScheduler();
92  if (HD_DEVICE_ERROR(error = hdGetError()))
93  {
94  hduPrintError(stderr, &error, "Failed to start scheduler");
95  fprintf(stderr, "\nPress any key to quit.\n");
96  getch();
97  return -1;
98  }
99 
101 
102 
103  /*******************************************************************
104  * Initialize state
105  *******************************************************************/
106  ss->buttons[0] = 0;
107  ss->buttons[1] = 0;
108  ss->home_pos = g_home_pos;
109  ss->home=0;
110 
111  /*******************************************************************
112  * Initialize ROS
113  *******************************************************************/
114  ros::init( argc, argv, "phantom_node" );
115 
116  ros::NodeHandle n("~");
117 
118  ros::Publisher pub_state= n.advertise< phantom_control::State >( "/phantom_state", 1000 );
119 
120  ros::Subscriber sub_force = n.subscribe ( "/force", 1000, ForceCallBk );
121 
122  ros::Rate loop_rate( 2.5*1300 );
123 
124  ee_convert();
125 
126  int pid = getpid(), rpid;
127 
128  boost::format fmt("sudo renice -10 %d");
129  fmt % pid;
130 
131  rpid = std::system(fmt.str().c_str());
132 
133  while ( ros::ok () )
134  {
135  if(g_new)
136  {
137  ee_convert();
138 
139  pub_state.publish( g_SS );
140 
141  g_new=0;
142  }
143 
144  // IF button 1
145 
146  // IF button 2 => Sets a new home position
147  if(g_SS.buttons[1])
148  {
149  g_home_pos[0]=g_SS.position[0];
150  g_home_pos[1]=g_SS.position[1];
151  g_home_pos[2]=g_SS.position[2];
152  ss->home_pos[0]=g_SS.position[0];
153  ss->home_pos[1]=g_SS.position[1];
154  ss->home_pos[2]=g_SS.position[2];
155  }
156 
157  ros::spinOnce ( );
158 
159  loop_rate.sleep ( );
160  }
161  /* Cleanup by stopping the haptics loop, unscheduling the asynchronous
162  callback, disabling the device. */
163  ROS_INFO("Ending Session....\n");
164  hdStopScheduler();
165  hdUnschedule(gCallbackHandle);
166  hdDisableDevice(hHD);
167 
168  return 0;
169 }
170 
177 void ee_convert(void)
178 {
179  // Phantom device state pointer
180  OmniState *ss=&state;
181 
182  g_SS.pos_hist1[0]=g_SS.position[0];
183  g_SS.pos_hist1[1]=g_SS.position[1];
184  g_SS.pos_hist1[2]=g_SS.position[2];
185 
186  g_SS.position[0]=ss->position[0];
187  g_SS.position[1]=ss->position[1];
188  g_SS.position[2]=ss->position[2];
189 
190  g_SS.rot[0]=ss->rot[0];
191  g_SS.rot[1]=ss->rot[1];
192  g_SS.rot[2]=ss->rot[2];
193 
194  g_SS.joints[0]=ss->joints[0];
195  g_SS.joints[1]=ss->joints[1];
196  g_SS.joints[2]=ss->joints[2];
197 
198  g_SS.temp[0]=ss->temp[0];
199  g_SS.temp[1]=ss->temp[1];
200  g_SS.temp[2]=ss->temp[2];
201 
202  g_SS.buttons[0]=ss->buttons[0];
203  g_SS.buttons[1]=ss->buttons[1];
204 
205  g_SS.home=ss->home;
206 
207  g_SS.home_pos[0]=ss->home_pos[0];
208  g_SS.home_pos[1]=ss->home_pos[1];
209  g_SS.home_pos[2]=ss->home_pos[2];
210 
211  g_SS.force[0]=ss->force[0];
212  g_SS.force[1]=ss->force[1];
213  g_SS.force[2]=ss->force[2];
214 
215  g_SS.header.stamp = ros::Time::now ( );
216 }
217 
224 void ForceCallBk ( const haptic_force::Force &force )
225 {
226  state.force[0]=force.force[0];
227  state.force[1]=force.force[1];
228  state.force[2]=force.force[2];
229 }
230 
238 {
239  int calibrationStyle;
240  int supportedCalibrationStyles;
241  HDErrorInfo error;
242 
243  hdGetIntegerv(HD_CALIBRATION_STYLE, &supportedCalibrationStyles);
244  if (supportedCalibrationStyles & HD_CALIBRATION_ENCODER_RESET)
245  {
246  calibrationStyle = HD_CALIBRATION_ENCODER_RESET;
247  ROS_INFO("HD_CALIBRATION_ENCODER_RESE..\n\n");
248  }
249  if (supportedCalibrationStyles & HD_CALIBRATION_INKWELL)
250  {
251  calibrationStyle = HD_CALIBRATION_INKWELL;
252  ROS_INFO("HD_CALIBRATION_INKWELL..\n\n");
253  }
254  if (supportedCalibrationStyles & HD_CALIBRATION_AUTO)
255  {
256  calibrationStyle = HD_CALIBRATION_AUTO;
257  ROS_INFO("HD_CALIBRATION_AUTO..\n\n");
258  }
259 
260  do
261  {
262  hdUpdateCalibration(calibrationStyle);
263  ROS_INFO("Calibrating.. (put stylus in well)\n");
264  if (HD_DEVICE_ERROR(error = hdGetError()))
265  {
266  hduPrintError(stderr, &error, "Reset encoders reset failed.");
267  break;
268  }
269  } while (hdCheckCalibration() != HD_CALIBRATION_OK);
270 
271  ROS_INFO("...\n...\nCalibration complete.\n");
272 }
273 
280 HDCallbackCode HDCALLBACK MonitorCallback(void *pUserData)
281 {
282  OmniState *omni_state = static_cast<OmniState *>(pUserData);
283 
284  HDErrorInfo error;
285 
286  int nButtons = 0;
287 
288  hduVector3Dd position;
289  hduVector3Dd force;
290 
291  omni_state->force=state.force;
292 
293  hdBeginFrame(hdGetCurrentDevice());
294 
295  hdGetDoublev(HD_CURRENT_GIMBAL_ANGLES, omni_state->rot);
296  hdGetDoublev(HD_CURRENT_POSITION, omni_state->position); /*milimeters*/
297  hdGetDoublev(HD_CURRENT_JOINT_ANGLES, omni_state->joints);
298 
299  //Get buttons
300  hdGetIntegerv(HD_CURRENT_BUTTONS, &nButtons);
301  omni_state->buttons[0] = (nButtons & HD_DEVICE_BUTTON_1) ? 1 : 0;
302  omni_state->buttons[1] = (nButtons & HD_DEVICE_BUTTON_2) ? 1 : 0;
303 
304  // Get motor temperatures [0...1]
305  hdGetDoublev(HD_MOTOR_TEMPERATURE, omni_state->temp);
306 
307  if(omni_state->buttons[0]!=1)
308  {
309  SetHomePos();
310  }
311  else
312  {
313  hdSetDoublev(HD_CURRENT_FORCE, omni_state->force);
314  omni_state->home=0;
315  }
316 
317  hdEndFrame(hdGetCurrentDevice());
318 
319  if (HD_DEVICE_ERROR(error = hdGetError()))
320  {
321  hduPrintError(stderr, &error, "Error during main scheduler callback\n");
322  if (hduIsSchedulerError(&error))
323  return HD_CALLBACK_DONE;
324  }
325 
326  // Get thetas
327  float t[7] = {0.0, omni_state->joints[0], omni_state->joints[1], omni_state->joints[2]-omni_state->joints[1], omni_state->rot[0], omni_state->rot[1], omni_state->rot[2]};
328 
329  for (int i = 0; i < 7; i++) omni_state->thetas[i] = t[i];
330 
331  g_new=1;
332 
333  return HD_CALLBACK_CONTINUE;
334 }
335 
336 
343 void SetHomePos(void)
344 {
345  hduVector3Dd home_pos = g_home_pos;
346  hduVector3Dd position;
347 
348  position[0]=g_SS.position[0];
349  position[1]=g_SS.position[1];
350  position[2]=g_SS.position[2];
351 
352  if( g_SS.position == g_SS.home_pos)
353  {
354  g_SS.home=1;
355  hduVector3Dd force2home(0, 0.49, 0);
356 
357  hdSetDoublev(HD_CURRENT_FORCE, force2home);
358  }
359  if(!g_SS.home)
360  {
361  hduVector3Dd force2home = (home_pos - position);
362  force2home.normalize();
363  force2home*=0.975;
364 
365  hdSetDoublev(HD_CURRENT_FORCE, force2home);
366  }
367 
368 }
float thetas[7]
Definition: omni.h:82
hduVector3Dd position
Definition: omni.h:69
hduVector3Dd g_home_pos(HOME_XX, HOME_YY, HOME_ZZ)
hduVector3Dd home_pos
Definition: omni.h:87
phantom_control::State g_SS
HDdouble temp[3]
Definition: omni.h:83
HDSchedulerHandle gCallbackHandle
void SetHomePos(void)
#define HOME_ZZ
Definition: omni.h:53
#define HOME_XX
Definition: omni.h:51
hduVector3Dd joints
Definition: omni.h:80
void HHD_Auto_Calibration(void)
void ForceCallBk(const haptic_force::Force &force)
OmniState state
bool home
Definition: omni.h:86
int buttons[2]
Definition: omni.h:84
Header for the OpenHaptics lib and the haptic device state structure.
int getch()
Definition: conio.cpp:103
hduVector3Dd rot
Definition: omni.h:79
void ee_convert(void)
Structure for holding the state variables of the haptic device.
Definition: omni.h:68
HDCallbackCode HDCALLBACK MonitorCallback(void *pUserData)
hduVector3Dd force
Definition: omni.h:81
bool g_new
#define HOME_YY
Definition: omni.h:52
int main(int argc, char **argv)


phantom_control
Author(s): Emilio Estrelinha
autogenerated on Mon Mar 2 2015 01:32:35