ACQ2XX_API
AcqCal.cpp
Go to the documentation of this file.
00001 
00002 #include "local.h"
00003 #include <vector>
00004 #include <string>
00005 
00006 #include "AcqType.h"
00007 
00008 
00009 AcqCal::AcqCal(const AcqType& _acq_type, string _base_name) :
00010         acq_type(_acq_type)
00011 {
00012 
00013 }
00014 
00015 class DefaultAcqCal : public AcqCal {
00016 
00017 public:
00018         DefaultAcqCal(const AcqType& _acq_type) :
00019                 AcqCal(_acq_type, "")
00020         {}
00021 
00022         int getCal(int ch, double& gain_v, double& offset_v) const {
00023                 gain_v = acq_type.getWordSize() == 2? 
00024                                 10.0/32768: 10.0/0x7fffffff;            
00025                 offset_v = 0;
00026                 return 0;
00027         }
00028 };
00029 
00030 /* cal file *.vin is the output of get.vin, looks like this:
00031 root@acq132_082 ~ #cat /tmp/$(hostname).vin
00032 -2.4506,2.4927,-2.4886,2.4756,-2.4958,2.4618,-2.4999,2.5065,-2.4809,2.4717,-2.4493,2.4667,-2.4927,2.4498,-2.4979,2.4805,-2.4685,2.4534,-2.5074,2.5002,-2.4390,2.4227,-2.5121,2.4736,-2.5017,2.4693,-2.4748,2.4463,-2.4587,2.4478,-2.5235,2.4732,-2.4912,2.4728,-2.4592,2.5173,-2.4918,2.4573,-2.5246,2.4947,-2.5153,2.4638,-2.4643,2.5066,-2.4645,2.5175,-2.4800,2.5012,-2.5313,2.4674,-2.5054,2.4866,-2.5396,2.4956,-2.4685,2.5002,-2.5009,2.4806,-2.4955,2.5000,-2.4573,2.5194,-2.4907,2.5321
00033 */
00034 class AcqCalImpl : public AcqCal {
00035         Pair *pairs;
00036         const unsigned raw_max;
00037         
00038 public:
00039         AcqCalImpl(const AcqType& _acq_type, string _base_name) :
00040                 AcqCal(_acq_type, _base_name),
00041                 raw_max(acq_type.getWordSize() == 2? 65535: 0xffffffffU)
00042         {
00043                 pairs = new Pair[acq_type.getNumChannels()];
00044 
00045                 memset(pairs, 0, sizeof(pairs));
00046 
00047                 FILE *fp = fopen(_base_name.c_str(), "r");
00048                 
00049                 assert(fp);
00050 
00051                 for (int ic = 0; ic < acq_type.getNumChannels(); ++ic){
00052                         if (fscanf(fp, "%f,%f,",
00053                                 &pairs[ic].p1, &pairs[ic].p2) == 2){
00054                                 dbg(2, "[%d] %f,%f", ic,
00055                                                 pairs[ic].p1, pairs[ic].p2);
00056                                 continue;
00057                         }else{
00058                                 err("early scan fail at ic=%d/%d",
00059                                                 ic, acq_type.getNumChannels());
00060                                 break;
00061                         }
00062                 }               
00063 
00064                 fclose(fp);     
00065         }
00066 
00067         virtual ~AcqCalImpl() {
00068                 delete [] pairs;
00069         }
00070 
00071         int getCal(int ch, double& gain_v, double& offset_v) const {
00072                 ch -= 1;
00073                 gain_v = (pairs[ch].p2 - pairs[ch].p1)/raw_max;
00074 
00075                 // (v - p1)/(r - r1) = (p2 - p1)/(r2 - r1)
00076                 // solve for r = 0
00077                 // v = p1 -32768 * (p2 - p1)/65535
00078 
00079                 offset_v = pairs[ch].p1 +
00080                                 32768 * (pairs[ch].p2 - pairs[ch].p1)/65535;
00081                 return 0;
00082         }
00083 };
00084 
00085 
00086 AcqCal* AcqCal::create(const AcqType& _acq_type, string _base_name)
00087 {
00088         if (_base_name == DEFAULT_CAL){
00089                 return new DefaultAcqCal(_acq_type);
00090         }else{
00091                 return new AcqCalImpl(_acq_type, _base_name);
00092         }
00093 }
00094 
00095 void AcqCal::destroy(AcqCal* acq_cal)
00096 {
00097         delete acq_cal;
00098 }