Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

P_SensorConfig.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr 
00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 
00004 *cr University of Illinois 
00005 *cr All Rights Reserved 
00006 *cr 
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 * $RCSfile: P_SensorConfig.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.41 $ $Date: 2019年01月17日 21:21:01 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * This is Paul's new Tracker code -- pgrayson@ks.uiuc.edu
00019 ***************************************************************************/
00020 
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include "P_SensorConfig.h"
00024 #include "Inform.h"
00025 #include "utilities.h"
00026 
00027 
00028 // This function goes through all the vmdsensors files, opens them and calls
00029 // a functio defined by "behavior" for each one, and then closes the files.
00030 // It passes along the pointer "params" to the called function.
00031 // This mechanism is a bit clumsy, but it best accomodated the re-use of
00032 // the previous code.
00033 enum Scanning_Behaviors { PARSE_FOR_NAMES, PARSE_FOR_DEVICE };
00034 
00035 void SensorConfig::ScanSensorFiles (int behavior, SensorConfig *sensor, void* params) {
00036 JString sensorfile;
00037 FILE *file;
00038 int found_sensorfile=FALSE; //keeps track of whether we found a sensor file
00039 
00040 #if !defined(_MSC_VER)
00041 // First try looking for a .vmdsensors file in the user's
00042 // UNIX home directory 
00043 sensorfile = getenv("HOME");
00044 sensorfile += "/.vmdsensors";
00045 if ( (file = fopen(sensorfile,"r")) ) {
00046 found_sensorfile=TRUE;
00047 switch (behavior) {
00048 case PARSE_FOR_DEVICE:
00049 sensor->parseconfigfordevice(file, params);
00050 break;
00051 case PARSE_FOR_NAMES:
00052 parseconfigfornames(file, params);
00053 break;
00054 }
00055 fclose(file);
00056 }
00057 #endif
00058 
00059 // Then, try path pointed to by the VMDSENSORS env. variable 
00060 if (!found_sensorfile) {
00061 char *sensorfile_str = getenv("VMDSENSORS");
00062 if (sensorfile_str && (file = fopen(sensorfile_str,"r"))) {
00063 found_sensorfile=TRUE;
00064 switch (behavior) {
00065 case PARSE_FOR_DEVICE:
00066 sensor->parseconfigfordevice(file, params);
00067 break;
00068 case PARSE_FOR_NAMES:
00069 parseconfigfornames(file, params);
00070 break;
00071 }
00072 fclose(file);
00073 }
00074 }
00075 
00076 // If we couldn't find a file in the home dir or VMDSENSORS env. variable
00077 // then try finding one in the VMD installation area. 
00078 if (!found_sensorfile) {
00079 sensorfile = getenv("VMDDIR");
00080 #if defined(_MSC_VER)
00081 sensorfile += "\\.vmdsensors";
00082 #else
00083 sensorfile += "/.vmdsensors";
00084 #endif
00085 if ((file = fopen(sensorfile,"r"))) {
00086 switch (behavior) {
00087 case PARSE_FOR_DEVICE:
00088 sensor->parseconfigfordevice(file, params);
00089 break;
00090 case PARSE_FOR_NAMES:
00091 parseconfigfornames(file, params);
00092 break;
00093 }
00094 fclose(file);
00095 }
00096 }
00097 
00098 }
00099 
00100 
00101 static int splitline(FILE *f, JString *argv, int maxarg) {
00102 int argc, pos;
00103 char buf[128], word[128];
00104 memset(buf, 0, sizeof(buf));
00105 memset(word, 0, sizeof(word));
00106 
00107 if(!fgets(buf, sizeof(buf), f)) return -1;
00108 
00109 argc = 0;
00110 pos = 0;
00111 while (argc<maxarg && pos<100 && buf[pos]!=0 && buf[pos]!='\n'
00112 && buf[pos]!='\r') {
00113 
00114 if (buf[pos]!=' ' && buf[pos]!='\t') {
00115 sscanf(buf+pos, "%99s", word); 
00116 pos += strlen(word);
00117 argv[argc] = (JString)word;
00118 argc++;
00119 } else {
00120 pos++;
00121 }
00122 }
00123 
00124 return argc;
00125 }
00126 
00127 
00128 static int need_args(int argc,int need, int line) {
00129 if (need!=argc) {
00130 msgErr << "SensorConfig: Wrong number of arguments at line " << line << "." << sendmsg;
00131 msgErr << "Expected " << need << ", got " << argc << "." << sendmsg;
00132 return 1;
00133 }
00134 return 0;
00135 }
00136 
00137 float SensorConfig::getfloat(const char *from, float defalt) {
00138 int ret;
00139 float f;
00140 ret=sscanf(from,"%f",&f);
00141 if(!ret) {
00142 msgErr << "SensorConfig: Error parsing float at line " << line << sendmsg;
00143 return defalt;
00144 }
00145 return f;
00146 }
00147 
00148 int SensorConfig::needargs(int argc,int need) {
00149 return need_args(argc,need,line);
00150 }
00151 
00152 
00153 void SensorConfig::parseconfigfordevice(FILE *file, void *) {
00154 // now we have an open configuration file, search for device lines
00155 int found=FALSE, argc;
00156 line = 0;
00157 JString argv[20];
00158 while ((argc=splitline(file, argv, 20))>=0) {
00159 line++;
00160 
00161 if (!argc) continue;
00162 if (argv[0][0]=='#') continue; // this line is a comment
00163 
00164 if (!compare(argv[0],"device")) { // found a device
00165 if (found) break; // done reading info about our device
00166 if (needargs(argc,3)) return;
00167 if (!compare(argv[1],device)) { // found our device
00168 // Comment out chatty options for now, until we can reduce the number
00169 // of times we have to read the .vmdsensors file.
00170 // msgInfo << "Found device '" << argv[1] << "'" << " on line " << line << "." << sendmsg;
00171 found = TRUE;
00172 USL = argv[2];
00173 continue; // we start parsing the options on the next line
00174 }
00175 }
00176 
00177 if (!found) continue;
00178 
00179 // Comment out chatty options for now, until we can reduce the number
00180 // of times we have to read the .vmdsensors file.
00181 // msgInfo << "Reading option '" << argv[0] << "'" << sendmsg;
00182 
00183 if (!compare(argv[0],"scale")) {
00184 if (needargs(argc,2)) return;
00185 scale = getfloat(argv[1],1);
00186 }
00187 else if (!compare(argv[0],"maxforce")) {
00188 // XXX Maxforce doesn't seem to work at the moment, causing dangerously
00189 // high forces to be sent to the haptic device. Disabling for now until
00190 // the reason is discovered.
00191 #if 0
00192 if (needargs(argc,2)) return;
00193 maxforce = getfloat(argv[1],1);
00194 #else
00195 msgInfo << "Sorry, maxforce parameter not currently implemented." 
00196 << sendmsg;
00197 #endif
00198 }
00199 else if (!compare(argv[0],"offset")) {
00200 int i;
00201 if (needargs(argc,4)) return;
00202 for (i=0;i<3;i++)
00203 offset[i] = getfloat(argv[1+i],0);
00204 }
00205 else if (!compare(argv[0],"rot")) {
00206 int i;
00207 if (needargs(argc,11)) return;
00208 if (!compare(argv[1],"right"))
00209 for (i=0;i<9;i++)
00210 right_rot.mat[i+i/3] = getfloat(argv[2+i],right_rot.mat[i+i/3]);
00211 else
00212 for (i=0;i<9;i++)
00213 left_rot.mat[i+i/3] = getfloat(argv[2+i],right_rot.mat[i+i/3]);
00214 }
00215 else msgErr << "Error: Unrecognized tool option on line " << line << sendmsg;
00216 }
00217 
00218 if (USL=="") msgErr << "Device " << device << " not found." << sendmsg;
00219 else parseUSL();
00220 }
00221 
00222 
00223 SensorConfig::SensorConfig(const char *thedevice) {
00224 
00225 if (thedevice==NULL) return;
00226 
00227 USL = "";
00228 strcpy(nums,"");
00229 strcpy(name,"");
00230 strcpy(place,"");
00231 strcpy(type,"");
00232 strcpy(device,thedevice);
00233 offset[0] = offset[1] = offset[2] = 0;
00234 scale = 1;
00235 maxforce = -1; // default is to not enforce a maximum
00236 right_rot.identity();
00237 left_rot.identity();
00238 
00239 ScanSensorFiles(PARSE_FOR_DEVICE, this, NULL);
00240 }
00241 
00242 
00243 int SensorConfig::parseUSL() {
00244 int ret;
00245 strcpy(nums,"0"); // fill in default of zero
00246 
00247 ret = sscanf(USL,"%20[^:]://%100[^/]/%100[^:]:%101s",
00248 type, place, name, nums);
00249 
00250 if(ret<3) {
00251 msgErr << "USL on line " << line << " is not of the form: "
00252 << "type://place/name[:num,num,...]" << sendmsg;
00253 return 0; // if we get anything less than blah://blah/blah
00254 }
00255 
00256 read_sensor_nums();
00257 
00258 return 1;
00259 }
00260 
00261 void SensorConfig::read_sensor_nums() {
00262 char *s=strdup(nums);
00263 char *r=s;
00264 
00265 for (int cur=0; cur<= 200; cur++) {
00266 if(s[cur]==',' || s[cur]==0) {
00267 int tmp = 0;
00268 sscanf(r,"%d",&tmp);
00269 sensors.append(tmp);
00270 r = s + cur + 1;
00271 if(s[cur]==0) break;
00272 s[cur]=0;
00273 }
00274 }
00275 
00276 free(s);
00277 }
00278 
00279 
00280 // Used as a callback in SensorConfig::getnames()
00281 void SensorConfig::parseconfigfornames(FILE *f, void *ret_void) {
00282 int argc, line=0;
00283 JString argv[20];
00284 
00285 while ((argc=splitline(f, argv, 20))>=0) {
00286 line++;
00287 
00288 if(!argc) continue;
00289 if(argv[0][0]=='#') continue; // this line is a comment
00290 
00291 if(!compare(argv[0],"device")) { // found a device
00292 if(need_args(argc,3,line)) continue;
00293 JString *newname = new JString(argv[1]);
00294 ((ResizeArray<JString *>*) ret_void)->append(newname);
00295 }
00296 }
00297 }
00298 
00299 
00300 ResizeArray<JString *> *SensorConfig::getnames() {
00301 ResizeArray<JString *> *ret = new ResizeArray<JString *>;
00302 
00303 ScanSensorFiles(PARSE_FOR_NAMES, NULL, (void*)ret);
00304 return ret;
00305 }
00306 
00307 
00308 const char *SensorConfig::getUSL() const {
00309 return USL;
00310 }
00311 
00312 float SensorConfig::getscale() const {
00313 return scale;
00314 }
00315 
00316 float SensorConfig::getmaxforce() const {
00317 return maxforce;
00318 }
00319 
00320 const float *SensorConfig::getoffset() const {
00321 return offset;
00322 }
00323 
00324 const Matrix4 *SensorConfig::getright_rot() const {
00325 return &right_rot;
00326 }
00327 
00328 const Matrix4 *SensorConfig::getleft_rot() const {
00329 return &left_rot;
00330 }
00331 
00332 const char *SensorConfig::getdevice() const { return device; }
00333 const char *SensorConfig::gettype() const { return type; }
00334 const char *SensorConfig::getplace() const { return place; }
00335 const char *SensorConfig::getname() const { return name; }
00336 const char *SensorConfig::getnums() const { return nums; }
00337 const ResizeArray<int> *SensorConfig::getsensors() const { return &sensors; }
00338 
00339 SensorConfig::~SensorConfig() {
00340 }
00341 
00342 int SensorConfig::have_one_sensor() const {
00343 if (sensors.num() != 1) {
00344 msgErr << "Please specify exactly one sensor." << sendmsg;
00345 return 0;
00346 }
00347 return 1;
00348 }
00349 
00350 void SensorConfig::make_vrpn_address(char *buf) const {
00351 // As of VRPN 7.15 enforcing TCP-only connections is supported
00352 // by appending @tcp to the device name and using an USL in 
00353 // format Device@tcp://machine:port instead of Device@machine:port.
00354 // Create a new style USL when the name contains @tcp. 
00355 if (strstr(name,"@tcp"))
00356 sprintf(buf, "%s://%s", name, place);
00357 else
00358 sprintf(buf, "%s@%s", name, place);
00359 }
00360 
00361 int SensorConfig::require_local() const {
00362 if(strcmp(place,"local")) {
00363 msgErr << "Sorry, this local device requires place name \"local\"."
00364 << sendmsg;
00365 return 0;
00366 }
00367 return 1;
00368 }
00369 
00370 int SensorConfig::require_cave_name() const {
00371 if(!require_local()) return 0;
00372 if(strcmp(name,"cave")) {
00373 msgErr << "Sorry, the device name for the CAVE is \"cave\"." << sendmsg;
00374 return 0;
00375 }
00376 return 1;
00377 }
00378 
00379 int SensorConfig::require_freevr_name() const {
00380 if(!require_local()) return 0;
00381 if(strcmp(name,"freevr")) {
00382 msgErr << "Sorry, the device name for FreeVR is \"freevr\"." << sendmsg;
00383 return 0;
00384 }
00385 return 1;
00386 }
00387 

Generated on Mon Nov 17 02:46:57 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /