CyberCalib.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:12k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. //############################################################
  2. // 
  3. // CyberCalib.cc
  4. //
  5. // Daniel Wood
  6. // Fri Dec 11 11:40:42 CET 1998
  7. //
  8. //
  9. // Class for storing calibration data for the SLSS and
  10. // reading the data from a calibration file.
  11. //
  12. // Basically just a bag of doubles and a reader.  Along
  13. // with some defaults.
  14. //
  15. //############################################################
  16. #include "CyberCalib.h"
  17. #include <stdlib.h>
  18. #include <ctype.h>
  19. #include <iostream.h>
  20. #include <fstream.h>
  21. CyberCalib::CyberCalib()
  22. {
  23.   const char *calibFN = getenv( "SLSS_CALIBRATION_FILE" );
  24.   if( calibFN ) {
  25.     RopeDV r2dv;
  26.     ifstream in( calibFN );
  27.     if( in.fail() || !readNumbers( in, r2dv ) || !setMap(r2dv) ) {
  28.       cerr << "Couldn't read calibration file: " 
  29.    << calibFN << endl;
  30.       exit( 1 );
  31.     } else {
  32.       cout << "Read calibration file " << calibFN << endl;
  33.     }
  34.   } else {
  35.     setDefault();
  36.   }
  37.   setDerived();
  38.   SHOW(offt);
  39. }
  40.                                 // helpers
  41. #ifdef WIN32
  42. // MSVC can't compile the template flavor below,
  43. // but it's only called with argument sizes 3 and 16,
  44. // so expand these here.
  45. bool
  46. setval( double (&d)[3], vector<double> &vd )
  47. // Set the size contents of the size n array d to be the same as the
  48. // contents of the vector, if possible.
  49. // 
  50. // If not possible return false.
  51. {
  52.     if( vd.size() != 3 )
  53.         return 0;
  54.     memcpy( d, (double *) vd.begin(), sizeof(d) );
  55.     return 1;
  56. }
  57. bool
  58. setval( double (&d)[16], vector<double> &vd )
  59. {
  60.     if( vd.size() != 16 )
  61.         return 0;
  62.     memcpy( d, (double *) vd.begin(), sizeof(d) );
  63.     return 1;
  64. }
  65. #else
  66. template< int N >
  67. bool
  68. setval( double (&d)[N], vector<double> &vd )
  69. // Set the size contents of the size n array d to be the same as the
  70. // contents of the vector, if possible.
  71. // 
  72. // If not possible return false.
  73. {
  74.     if( vd.size() != N )
  75.         return 0;
  76.     memcpy( d, (double *) vd.begin(), sizeof(d) );
  77.     return 1;
  78. }
  79. #endif
  80. bool
  81. setval( double &d, vector<double> &vd )
  82. // Set d to be the value of the one and only element of vd, if possible.
  83. // 
  84. // If not possible return false.
  85. {
  86.     if( vd.size() != 1 )
  87.         return 0;
  88.     d = vd[0];
  89.     return 1;
  90. }
  91. bool
  92. CyberCalib::setMap( RopeDV &r2dv )
  93. // Set all of the input calibration values using the map r2dv.  If
  94. // something doesn't work return false, otherwise return true.
  95. {
  96.     return
  97.         setval( axturn, r2dv["axturn"] ) &&
  98.         setval( axturn0, r2dv["axturn0"] ) &&
  99.         setval( axnod, r2dv["axnod"] ) &&
  100.         setval( axnod0, r2dv["axnod0"] ) &&
  101.         setval( A, r2dv["A"] ) &&
  102.         setval( opt_frm_v, r2dv["opt_frm_v"] ) &&
  103.         setval( opt_frm_h, r2dv["opt_frm_h"] ) &&
  104.         setval( arm_up1, r2dv["arm_up1"] ) &&
  105.         setval( arm_up2, r2dv["arm_up2"] ) &&
  106.         setval( arm_up3, r2dv["arm_up3"] ) &&
  107.         setval( arm_up4, r2dv["arm_up4"] ) &&
  108.         setval( arm_down1, r2dv["arm_down1"] ) &&
  109.         setval( arm_down2, r2dv["arm_down2"] ) &&
  110.         setval( arm_down3, r2dv["arm_down3"] ) &&
  111.         setval( arm_down4, r2dv["arm_down4"] ) &&
  112.         setval( dnssp, r2dv["dnssp"] ) &&
  113.         setval( dnsep, r2dv["dnsep"] ) &&
  114.         setval( offn, r2dv["offn"] ) &&
  115.         setval( dtssp, r2dv["dtssp"] ) &&
  116.         setval( dtsep, r2dv["dtsep"] ) &&
  117.         setval( offt, r2dv["offt"] ) &&
  118.         setval( minscrew, r2dv["minscrew"] );
  119. }
  120. //#define OLD_DEFAULTS
  121. #ifndef OLD_DEFAULTS
  122. void
  123. CyberCalib::setDefault()
  124. // Set all of the values to their compiled in defaults.    
  125. {
  126.                                 // turn axis and point on it.
  127.     axturn[0] =  0.01805376092094;
  128.     axturn[1] =  0.01485705900017;
  129.     axturn[2] = -0.99972662739095;
  130.     axturn0[0] =  565.165097159111;
  131.     axturn0[1] =  566.718122653641;
  132.     axturn0[2] = -125.285854617229;
  133.                                 // nod axis.  axis and point on it.
  134.     axnod[0] =  0.64018246222957;
  135.     axnod[1] =  0.76822163316833;
  136.     axnod[2] = -0.00139190008991;
  137.     axnod0[0] =  530.462789245481;
  138.     axnod0[1] =  453.963537662380;
  139.     axnod0[2] = -143.122138720635;
  140.     
  141.                                 // optical correction matrix
  142.     static const double default_A[] =
  143.     {
  144.         1.0,               0.0,                0.0,                0.0,
  145.         0.0,  018.579261546745,  -000.088087061526,   000.000675546148,
  146.         0.0,  000.278844123926,  -017.924459594106,   000.014749815686,
  147.         0.0, -021.380307002909,   162.548102595433,   001.000000000000
  148.     };
  149.     memcpy( A, default_A, sizeof(A) );
  150.     
  151.                                 // transforms from working value to scanner
  152.     static const double default_opt_frm_v[] =
  153.     {
  154.   -000.601766364057,   000.468859880636,   000.646566048768,   0,
  155.   -000.625274483242,  -000.780237623214,  -000.016157720391,   0,
  156.    000.496899450288,  -000.414004424676,   000.762686877199,   0,
  157.    993.138114642769,   139.346085979040,   931.016548440975,   1
  158.     };
  159.     static const double default_opt_frm_h[] =
  160.     {
  161.    000.098796918656,   000.868618161141,   000.485532345988,   0,
  162.   -000.995101967634,   000.084594164467,   000.051145883015,   0,
  163.    000.003353039724,  -000.488207248486,   000.872721284059,   0,
  164.    913.128490923706,  -110.657398062714,  -294.415768931665,   1
  165.     };
  166.     memcpy( opt_frm_v, default_opt_frm_v, sizeof(opt_frm_v) );
  167.     memcpy( opt_frm_h, default_opt_frm_h, sizeof(opt_frm_h) );
  168.                                 // horizontal arm direction
  169.     arm_up1[0] = -0.02791322161013;
  170.     arm_up1[1] =  0.99960644654600;
  171.     arm_up1[2] =  0.00279357889050;
  172.     arm_up2[0] = -0.99960789687213;
  173.     arm_up2[1] = -0.02800054167491;
  174.     arm_up2[2] =  0.00014891875503;
  175.     arm_up3[0] =  0.02790980783040;
  176.     arm_up3[1] = -0.99959720870661;
  177.     arm_up3[2] = -0.00514421741692;
  178.     arm_up4[0] =  0.99960935645185;
  179.     arm_up4[1] =  0.02784414108967;
  180.     arm_up4[2] = -0.00241625762067;
  181.     arm_down1[0] = -0.02957577082291;
  182.     arm_down1[1] =  0.99955034883522;
  183.     arm_down1[2] =  0.00493699540412;
  184.     arm_down2[0] =  0.99956770750527;
  185.     arm_down2[1] =  0.02940017976736;
  186.     arm_down2[2] = -0.00016595877419;
  187.     arm_down3[0] =  0.02952064420397;
  188.     arm_down3[1] = -0.99955906286331;
  189.     arm_down3[2] = -0.00319553025334;
  190.     arm_down4[0] = -0.99959430058334;
  191.     arm_down4[1] = -0.02847051690376;
  192.     arm_down4[2] =  0.00081480582161;
  193.                                 // screw parameters
  194.                                 // from ~kapu/matlab/f99/second/xform.m
  195.     dnssp = 212.052011651496;  // dist. for nod screw start pivot to axis
  196.     dnsep = 181.973116924546;  // dist. for nod screw end   pivot to axis
  197.     offn  = 041.630447912442;  // offset dist. for nod when screw length = -6
  198.     dtssp = 208.506382766528;  // dist. for turn screw start pivot to axis
  199.     dtsep = 181.006348828133;  // dist. for turn screw end   pivot to axis
  200.     offt  = 035.807639467137;  // offset dist. for turn when screw length = -6
  201.     minscrew = -6.0;
  202. };
  203. #else
  204. void
  205. CyberCalib::setDefault()
  206. // Set all of the values to their compiled in defaults.    
  207. {
  208.                                 // turn axis and point on it.
  209.     axturn[0] = -0.00113981711955;
  210.     axturn[1] =  0.00438021200568;
  211.     axturn[2] = -0.99998975722740;
  212.     axturn0[0] =  564.786527057630;
  213.     axturn0[1] =  568.240210030879;
  214.     axturn0[2] = -124.331900000000;
  215.                                 // nod axis.  axis and point on it.
  216.     axnod[0] = 0.64170209799692;
  217.     axnod[1] = 0.76693964441216;
  218.     axnod[2] = 0.00469033637535;
  219.     axnod0[0] =  531.824138280106;
  220.     axnod0[1] =  452.981000000000;
  221.     axnod0[2] = -143.274367000629;
  222.     
  223.                                 // optical correction matrix
  224.     static const double default_A[] =
  225.     {
  226.         1.0,               0.0,                0.0,                0.0,
  227.         0.0,  018.579261546745,  -000.088087061526,   000.000675546148,
  228.         0.0,  000.278844123926,  -017.924459594106,   000.014749815686,
  229.         0.0, -021.380307002909,   162.548102595433,   001.000000000000
  230.     };
  231.     memcpy( A, default_A, sizeof(A) );
  232.     
  233.                                 // transforms from working value to scanner
  234.     static const double default_opt_frm_v[] =
  235.     {
  236.         -000.586680931764,   000.487547825028,   000.646608538928,  0.0,
  237.         -000.641134237921,  -000.767422605421,  -000.003071425476,  0.0,
  238.         000.494724542821,  -000.416364819599,   000.762815812455,  0.0,
  239.         998.060615792253,   155.870567377795,   924.974506168649,  1.0
  240.     };
  241.     static const double default_opt_frm_h[] =
  242.     {
  243.         000.087724034478,  000.837773482966,   000.538924934489,   0.0,
  244.         -000.996126263463,  000.077077755152,   000.042325960125,   0.0,
  245.         -000.006079557112, -000.540550285265,   000.841289740865,   0.0,
  246.         915.077953743209, -100.746998128001,  -320.665670992974,   1.0
  247.     };
  248.     memcpy( opt_frm_v, default_opt_frm_v, sizeof(opt_frm_v) );
  249.     memcpy( opt_frm_h, default_opt_frm_h, sizeof(opt_frm_h) );
  250.                                 // horizontal arm direction
  251.     arm_up1[0] = -0.02791322161013;
  252.     arm_up1[1] =  0.99960644654600;
  253.     arm_up1[2] =  0.00279357889050;
  254.     arm_up2[0] = -0.99960789687213;
  255.     arm_up2[1] = -0.02800054167491;
  256.     arm_up2[2] =  0.00014891875503;
  257.     arm_up3[0] =  0.02790980783040;
  258.     arm_up3[1] = -0.99959720870661;
  259.     arm_up3[2] = -0.00514421741692;
  260.     arm_up4[0] =  0.99960935645185;
  261.     arm_up4[1] =  0.02784414108967;
  262.     arm_up4[2] = -0.00241625762067;
  263.     arm_down1[0] = -0.02957577082291;
  264.     arm_down1[1] =  0.99955034883522;
  265.     arm_down1[2] =  0.00493699540412;
  266.     arm_down2[0] =  0.99956770750527;
  267.     arm_down2[1] =  0.02940017976736;
  268.     arm_down2[2] = -0.00016595877419;
  269.     arm_down3[0] =  0.02952064420397;
  270.     arm_down3[1] = -0.99955906286331;
  271.     arm_down3[2] = -0.00319553025334;
  272.     arm_down4[0] = -0.99959430058334;
  273.     arm_down4[1] = -0.02847051690376;
  274.     arm_down4[2] =  0.00081480582161;
  275.                                 // screw parameters
  276.                                 // from ~kapu/matlab/f99/second/xform.m
  277.     dnssp = 210.9230287253126;  // dist. for nod screw start pivot to axis
  278.     dnsep = 180.0069624362592;  // dist. for nod screw end   pivot to axis
  279.     offn  = 39.38131386985114;  // offset dist. for nod when screw length = -6
  280.     dtssp = 210.4423446244252;  // dist. for turn screw start pivot to axis
  281.     dtsep = 180.0344270613032;  // dist. for turn screw end   pivot to axis
  282.     offt  = 39.70382980035739;  // offset dist. for turn when screw length = -6
  283.     minscrew = -6.0;
  284. };
  285. #endif
  286. void
  287. CyberCalib::setDerived()
  288. // Compute the derived calibration values (which are used to optimize some
  289. // computations in CyberXform.cc).
  290. {
  291.                                 // pre-computed values for quickly calculating the
  292.                                 // angle from a screw value.  these are used by
  293.                                 // the SCREW_TO_ANGLE and ANGLE_TO_SCREW macros
  294.                                 // in CyberXform.cc
  295.     n_h1 = offn - minscrew;
  296.     n_h2 = dnssp*dnssp + dnsep*dnsep;
  297.     n_h3 = 1.0 / (2.0 * dnssp * dnsep);
  298.     n_h4 = acos((dnssp*dnssp + dnsep*dnsep - offn*offn)/(2*dnssp*dnsep));
  299.     t_h1 = offt - minscrew;
  300.     t_h2 = dtssp*dtssp + dtsep*dtsep;
  301.     t_h3 = 1.0 / (2.0 * dtssp * dtsep);
  302.     t_h4 = acos((dtssp*dtssp + dtsep*dtsep - offt*offt)/(2*dtssp*dtsep));
  303. }
  304. bool
  305. CyberCalib::readNumbers( istream &in, RopeDV &r2dv )
  306. // Reads in a file of the format
  307. //
  308. //    <string> <double> . . . .
  309. //    [repeat ad nauseum]
  310. //
  311. // for each <string> makes a vector out of the following doubles and
  312. // inserts the element <string> -> vector into the map m.
  313. //
  314. // RETURNS true if the file is successfully read,
  315. //         false otherwise
  316. {
  317.     while( 1 )
  318.     {
  319.         in >> ws;
  320.         if( in.peek() == EOF )
  321.             return 1;
  322.                                 // read until next white space into rope
  323.         crope s;
  324.         while( in.peek() != EOF && !isspace(in.peek())  )
  325.             s += (char) in.get();
  326.         vector<double> &vd = r2dv[s];
  327.         while( 1 )
  328.         {
  329.             double d;
  330.             in >> ws >> d;
  331.             if( in.fail() )
  332.             {
  333.                 in.clear();
  334.                 break;
  335.             }
  336.             vd.push_back(d);
  337.         }
  338.         if( in.fail() )
  339.             return 0;
  340.     }
  341. }