Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #ifndef BOUNDSOPTION_HPP_
00009 #define BOUNDSOPTION_HPP_
00010
00011 #include <telekyb_defines/telekyb_defines.hpp>
00012
00013 #include <telekyb_base/Options/Option.hpp>
00014
00015
00016 #include <ros/console.h>
00017
00018 namespace TELEKYB_NAMESPACE
00019 {
00020
00021 template < class _T, class _Compare = std::less<_T> >
00022 class BoundsOption : public Option<_T> {
00023 protected:
00024 _T lowerBound;
00025 _T upperBound;
00026 static _Compare comp;
00027
00028 BoundsOption(OptionContainer* parent_, const std::string name_, const std::string description_, const _T& defaultValue_, const _T& lowerBound_, const _T& upperBound_,
00029 bool mandatory_ = false, bool readOnly_ = false)
00030 : Option<_T>(parent_, name_, description_, defaultValue_, mandatory_, readOnly_), lowerBound(lowerBound_), upperBound(upperBound_) {
00031
00032 if (!comp(lowerBound_, upperBound_)) {
00033 ROS_WARN_STREAM("LowerBound > UpperBound! Inverting... Option: " << name_);
00034 lowerBound = upperBound_;
00035 upperBound = lowerBound_;
00036 }
00037
00038 if (!isWithinBounds(Option<_T>::value)) {
00039
00040 ROS_ERROR_STREAM("Option " << BaseOption::getNSName() << " out of Bounds!");
00041 ROS_ERROR_STREAM("Lower Bound: " << YamlHelper::parseValueToString(lowerBound));
00042 ROS_ERROR_STREAM("Upper Bound: " << YamlHelper::parseValueToString(upperBound));
00043 if (mandatory_) {
00044
00045 ROS_FATAL_STREAM("Initial Value ("<< Option<_T>::value <<") of Mandatory(!) Option " << BaseOption::getNSName() << " out of Bounds!");
00046
00047 ros::shutdown();
00048 } else {
00049 ROS_ERROR_STREAM("Initial Value ("<< Option<_T>::value <<") of "
00050 << BaseOption::getNSName() << " is out of Bounds. Resetting to Default: " << defaultValue_);
00051 Option<_T>::value = defaultValue_;
00052 Option<_T>::initialValue = true;
00053 }
00054 }
00055
00056 }
00057
00058 friend class OptionContainer;
00059 public:
00060 virtual ~BoundsOption() {};
00061
00062 virtual bool setValueCheck(const _T& value_) {
00063
00064 if ( !isWithinBounds(value_) ) {
00065 ROS_WARN_STREAM("Trying to set Value out of Bounds. Value: " << YamlHelper::parseValueToString(value_));
00066 ROS_WARN_STREAM("Lower Bound: " << YamlHelper::parseValueToString(lowerBound));
00067 ROS_WARN_STREAM("Upper Bound: " << YamlHelper::parseValueToString(upperBound));
00068 return false;
00069 }
00070
00071 return Option<_T>::setValueCheck(value_);
00072 }
00073
00074
00075
00076
00077
00078
00079 virtual bool hasBounds() const {
00080 return true;
00081 }
00082
00083 virtual bool isWithinBounds(const _T& value_) const {
00084 return !(comp(value_,lowerBound) || comp(upperBound, value_));
00085 }
00086
00087 virtual void print() const {
00088 std::cout << "--" << BaseOption::getNSName() << " (";
00089 std::cout << YamlHelper::parseValueToString( Option<_T>::getValue() ) << ", ";
00090 std::cout << "man: " << YamlHelper::parseValueToString( Option<_T>::mandatory ) << ", ";
00091 std::cout << "r-o: " << YamlHelper::parseValueToString( Option<_T>::readOnly ) << ", ";
00092 std::cout << "min: " << YamlHelper::parseValueToString( lowerBound ) << ", ";
00093 std::cout << "max: " << YamlHelper::parseValueToString( upperBound );
00094 std::cout << "): " << Option<_T>::getDescription() << std::endl;
00095 }
00096 };
00097
00098 #endif
00099
00100 }