unit_converter.h
Go to the documentation of this file.
00001 
00002 #ifndef CANOPEN_MOTOR_NODE_UNIT_CONVERTER_H_
00003 #define CANOPEN_MOTOR_NODE_UNIT_CONVERTER_H_
00004 
00005 #include <string>
00006 #include <list>
00007 #include <boost/function.hpp>
00008 #include <boost/shared_ptr.hpp>
00009 #include "muParser.h"
00010 #include <boost/math/special_functions/fpclassify.hpp> // for isnan
00011 
00012 namespace canopen {
00013 class UnitConverter{
00014 public:
00015     typedef boost::function<double * (const std::string &) > get_var_func_type;
00016 
00017     UnitConverter(const std::string &expression, get_var_func_type var_func)
00018     : var_func_(var_func)
00019     {
00020         parser_.SetVarFactory(UnitConverter::createVariable, this);
00021 
00022         parser_.DefineConst("pi", M_PI);
00023         parser_.DefineConst("nan", std::numeric_limits<double>::quiet_NaN());
00024 
00025         parser_.DefineFun("rad2deg", UnitConverter::rad2deg);
00026         parser_.DefineFun("deg2rad", UnitConverter::deg2rad);
00027         parser_.DefineFun("norm", UnitConverter::norm);
00028         parser_.DefineFun("smooth", UnitConverter::smooth);
00029         parser_.DefineFun("avg", UnitConverter::avg);
00030 
00031         parser_.SetExpr(expression);
00032     }
00033 
00034     void reset(){
00035         for(variable_ptr_list::iterator it = var_list_.begin(); it != var_list_.end(); ++it){
00036             **it = std::numeric_limits<double>::quiet_NaN();
00037         }
00038     }
00039     double evaluate() { int num; return parser_.Eval(num)[0]; }
00040 private:
00041     typedef boost::shared_ptr<double> variable_ptr;
00042     typedef std::list<variable_ptr> variable_ptr_list;
00043 
00044     static double* createVariable(const char *name, void * userdata) {
00045         UnitConverter * uc = static_cast<UnitConverter*>(userdata);
00046         double *p = uc->var_func_ ? uc->var_func_(name) : 0;
00047         if(!p){
00048             p = new double(std::numeric_limits<double>::quiet_NaN());
00049             uc->var_list_.push_back(variable_ptr(p));
00050         }
00051         return p;
00052     }
00053     variable_ptr_list var_list_;
00054     get_var_func_type var_func_;
00055 
00056     mu::Parser parser_;
00057 
00058     static double rad2deg(double r){
00059         return r*180.0/M_PI;
00060     }
00061     static double deg2rad(double d){
00062         return d*M_PI/180.0;
00063     }
00064     static double norm(double val, double min, double max){
00065         while(val >= max) val -= (max-min);
00066         while(val < min) val += (max-min);
00067         return val;
00068     }
00069     static double smooth(double val, double old_val, double alpha){
00070         if(boost::math::isnan(val)) return 0;
00071         if(boost::math::isnan(old_val)) return val;
00072         return alpha*val + (1.0-alpha)*old_val;
00073     }
00074     static double avg(const double *vals, int num)
00075     {
00076         double s = 0.0;
00077         int i=0;
00078         for (; i<num; ++i){
00079             const double &val = vals[i];
00080             if(boost::math::isnan(val)) break;
00081             s += val;
00082         }
00083         return s / double(i+1);
00084     }
00085 };
00086 
00087 }
00088 
00089 #endif /* CANOPEN_MOTOR_NODE_UNIT_CONVERTER_H_ */


canopen_motor_node
Author(s): Mathias Lüdtke
autogenerated on Sun Sep 3 2017 03:10:55