00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if defined(VMDVRPN)
00024
00025 #include "P_VRPNFeedback.h"
00026 #include "utilities.h"
00027
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <math.h>
00031
00032 VRPNFeedback::VRPNFeedback() {
00033 fdv = NULL;
00034 }
00035
00036 int VRPNFeedback::do_start(const SensorConfig *config) {
00037 if (fdv) return 0;
00038 if (!config->have_one_sensor()) return 0;
00039 char myUSL[100];
00040 config->make_vrpn_address(myUSL);
00041 fdv = new vrpn_ForceDevice_Remote(myUSL);
00042 set_maxforce(config->getmaxforce());
00043
00044
00045
00046
00047
00048
00049
00050 forceoff();
00051 return 1;
00052 }
00053
00054 VRPNFeedback::~VRPNFeedback() {
00055 forceoff();
00056
00057 }
00058
00059 void VRPNFeedback::update() {
00060 if(!alive()) return;
00061
00062 }
00063
00064 void VRPNFeedback::addconstraint(float k, const float *location) {
00065 int i;
00066 for(i=0;i<3;i++) {
00067
00068 jac[i][i] -= k;
00069
00070
00071 F[i] += k*location[i];
00072 }
00073 }
00074
00075 void VRPNFeedback::addforcefield(const float *origin, const float *force,
00076 const float *jacobian) {
00077 int i;
00078 for(i=0;i<3;i++) {
00079 F[i] += force[i];
00080
00081
00082 F[i] -= origin[0] * jacobian[0+3*i]
00083 + origin[1] * jacobian[1+3*i]
00084 + origin[2] * jacobian[2+3*i];
00085 }
00086
00087 for(i=0;i<9;i++) jac[i/3][i%3] += jacobian[i];
00088
00089 }
00090
00091 void VRPNFeedback::sendforce(const float *initial_pos) {
00092 float disp[3],Finitial[3],Fmag;
00093 float origin[3]={0,0,0};
00094
00095 if (!fdv) return;
00096 vec_sub(disp,initial_pos,origin);
00097 Finitial[0] = dot_prod(jac[0],disp);
00098 Finitial[1] = dot_prod(jac[1],disp);
00099 Finitial[2] = dot_prod(jac[2],disp);
00100 vec_add(Finitial,F,Finitial);
00101
00102 Fmag=norm(Finitial);
00103 if(Fmag>=maxforce && maxforce>=0) {
00104 float newjac[3][3];
00105 float newFinitial[3];
00106 int i, j;
00107
00108 vec_scale(newFinitial,maxforce/Fmag,Finitial);
00109 for(i=0; i<3; i++) {
00110 for(j=0; j<3; j++) {
00111 float FJj = Finitial[0]*jac[0][j] +
00112 Finitial[1]*jac[1][j] +
00113 Finitial[2]*jac[2][j];
00114 newjac[i][j] = jac[i][j] - Finitial[i]*FJj/(Fmag*Fmag);
00115 }
00116 }
00117 for(i=0; i<3; i++) {
00118 vec_scale(newjac[i],maxforce/Fmag,newjac[i]);
00119 }
00120
00121 vec_copy(origin,initial_pos);
00122 fdv->sendForceField(origin, newFinitial, newjac, 1000);
00123 }
00124 else {
00125
00126 fdv->sendForceField(origin, F, jac, 1000);
00127 }
00128 }
00129
00130 inline float sqr(float x) {
00131 return x*x;
00132 }
00133
00134 void VRPNFeedback::addplaneconstraint(float k, const float *point,
00135 const float *thenormal) {
00136 int i,j;
00137 float jacobian[9], normal[3], force[3]={0,0,0}, len=0;
00138
00139 for(i=0;i<3;i++) len += sqr(thenormal[i]);
00140 len = sqrtf(len);
00141 for(i=0;i<3;i++) normal[i] = thenormal[i]/len;
00142
00143
00144
00145
00146 for(i=0;i<3;i++) {
00147 for(j=0;j<3;j++)
00148 jacobian[i+j*3] = -k * normal[j] * normal[i];
00149 }
00150 addforcefield(point,force,jacobian);
00151 }
00152
00153 inline void VRPNFeedback::zeroforce() {
00154 int i,j;
00155 for(i=0;i<3;i++) {
00156 F[i]=0;
00157 for(j=0;j<3;j++) jac[i][j]=0;
00158 }
00159 }
00160
00161 inline void VRPNFeedback::forceoff() {
00162 zeroforce();
00163 if(fdv) fdv->stopForceField();
00164 }
00165
00166 #endif
00167