00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef ORO_MATRIX_TYPE_INFO_HPP
00040 #define ORO_MATRIX_TYPE_INFO_HPP
00041
00042 #include "types/TemplateTypeInfo.hpp"
00043 #include "types/type_discovery.hpp"
00044 #include "internal/DataSourceGenerator.hpp"
00045 #include <boost/lexical_cast.hpp>
00046
00047 namespace RTT
00048 {
00049 namespace types
00050 {
00056 template<class T>
00057 int get_rows(T const& cont)
00058 {
00059 return cont.rows();
00060 }
00061
00067 template<class T>
00068 int get_columns(T const& cont)
00069 {
00070 return cont.columns();
00071 }
00072
00080 template<class T>
00081 typename T::reference get_container_item(T & cont, int index_row, int index_column)
00082 {
00083 if (index_row >= (int) (cont.rows()) || index_row < 0 || index_column >= (int) (cont.columns()) || index_column < 0)
00084 return internal::NA<typename T::reference>::na();
00085 return cont[index_row,index_column];
00086 }
00087
00088
00098 template<typename T, bool has_ostream = false>
00099 class MatrixTypeInfo: public TemplateTypeInfo<T, has_ostream>
00100 {
00101 public:
00102 MatrixTypeInfo(std::string name) :
00103 TemplateTypeInfo<T, has_ostream> (name)
00104 {
00105 }
00106
00107 base::AttributeBase* buildVariable(std::string name,int size) const
00108 {
00109
00110 T t_init(size_rows, size_columns, typename T::value_type() );
00111
00112 log(Debug) << "Building variable '"<<name <<"' of type " << this->getTypeName() <<" and number of rows "<< size << " and number of columns " << size <<Logger::endl;
00113 return new Attribute<T>( name, new internal::UnboundDataSource<internal::ValueDataSource<T> >( t_init ) );
00114 }
00115
00116 bool resize(base::DataSourceBase::shared_ptr arg, int size_rows, int size_columns) const
00117 {
00118 if (arg->isAssignable()) {
00119 typename internal::AssignableDataSource<T>::shared_ptr asarg = internal::AssignableDataSource<T>::narrow( arg.get() );
00120 asarg->set().resize( size_rows, size_columns );
00121 asarg->updated();
00122 return true;
00123 }
00124 return false;
00125 }
00126
00130 virtual bool composeTypeImpl(const PropertyBag& bag, typename internal::AssignableDataSource<T>::reference_t result) const
00131 {
00132 if ( bag.getType() == "Matrix" ) {
00133 unsigned int rows = bag.size();
00134 unsigned int cols = 0;
00135
00136 for (unsigned int i = 1; i <= rows ; i++) {
00137 std::stringstream out;
00138 out << i;
00139 Property<PropertyBag>* row_bag = bag.getProperty<PropertyBag>(out.str());
00140 if(row_bag==NULL){
00141 log(Error)<<"Could not read row "<<i<<endlog();
00142 return false;
00143 }
00144 Property<RowVector> row_p(row_bag->getName(),row_bag->getDescription());
00145 if(!(row_p.getDataSource()->composeType(row_bag->getDataSource()))){
00146 log(Error)<<"Could not decompose row "<<i<<endlog();
00147 return false;
00148 }
00149 if(row_p.ready()){
00150 if(i==1){
00151 cols = row_p.get().size();
00152 result.resize(rows,cols);
00153 } else
00154 if(row_p.get().size()!=cols){
00155 log(Error)<<"Row "<<i+1<<" size does not match matrix columns"<<endlog();
00156 return false;
00157 }
00158 for ( unsigned int j=1; j <= row_p.get().size() ; j++){
00159 result(i,j)=row_p.get()(j);
00160 }
00161 }else{
00162 log(Error)<<"Property of Row "<<i<<"was not ready for use"<<endlog();
00163 return false;
00164 }
00165 }
00166 }else {
00167 log(Error) << "Composing Property< Matrix > :"
00168 << " type mismatch, got type '"<< bag.getType()
00169 << "', expected type "<<"Matrix."<<endlog();
00170 return false;
00171 }
00172 return true;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00205
00206 try {
00207 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00208
00209 return getMember( item, new internal::ConstantDataSource<int>(indx));
00210 } catch(...) {}
00211
00212 return getMember( item, new internal::ConstantDataSource<std::string>(name) );
00213 }
00214
00215 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00216 base::DataSourceBase::shared_ptr id) const {
00217 typename internal::AssignableDataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( item );
00218 if ( !data ) {
00219 if ( !item->isAssignable() )
00220 log(Error) << "Can't return reference to members of type "<< this->getTypeName() <<" since given object is not assignable." <<endlog();
00221 else
00222 log(Error) << "Consistency error: TypeInfo of type "<< this->getTypeName() <<" can't handle types of type "<< item->getType() <<endlog();
00223 return base::DataSourceBase::shared_ptr();
00224 }
00225
00226
00227 typename internal::DataSource<int>::shared_ptr id_indx = internal::DataSource<int>::narrow( id.get() );
00228 typename internal::DataSource<string>::shared_ptr id_name = internal::DataSource<string>::narrow( id.get() );
00229 if ( id_name ) {
00230 if ( id_name->get() == "size" ) {
00231 try {
00232 return internal::newFunctorDataSource(&get_size<T>, internal::GenerateDataSource()(item.get()) );
00233 } catch(...) {}
00234 }
00235 if ( id_name->get() == "capacity" ) {
00236 try {
00237 return internal::newFunctorDataSource(&get_capacity<T>, internal::GenerateDataSource()(item.get()) );
00238 } catch(...) {}
00239 }
00240 }
00241
00242 if ( id_indx ) {
00243 try {
00244 return internal::newFunctorDataSource(&get_container_item<T>, internal::GenerateDataSource()(item.get(), id_indx.get() ) );
00245 } catch(...) {}
00246 }
00247 if (id_name) {
00248 log(Error) << "MatrixTypeInfo: No such part : " << id_name->get() << endlog();
00249 }
00250 if (id_indx) {
00251 log(Error) << "MatrixTypeInfo: Invalid index : " << id_indx->get() <<":"<< id_indx->getTypeName() << endlog();
00252 }
00253 return base::DataSourceBase::shared_ptr();
00254 }
00255 };
00256 }
00257 }
00258
00259 #endif