opspace/src/Factory.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 The Board of Trustees of The Leland Stanford Junior University. All rights reserved.
00003  *
00004  * Author: Roland Philippsen
00005  *         http://cs.stanford.edu/group/manips/
00006  *
00007  * This program is free software: you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation, either version 3 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this program.  If not, see
00019  * <http://www.gnu.org/licenses/>
00020  */
00021 
00022 #include <opspace/Factory.hpp>
00023 #include <opspace/Skill.hpp>
00024 #include <opspace/task_library.hpp>
00025 #include <opspace/skill_library.hpp>
00026 #include <opspace/parse_yaml.hpp>
00027 #include <fstream>
00028 #include <stdexcept>
00029 
00030 using jspace::pretty_print;
00031 
00032 namespace opspace {
00033   
00034 
00035   static bool shops_initialized__(false);
00036   
00037   static void init_shops()
00038   {
00039     if (shops_initialized__) {
00040       return;
00041     }
00042     shops_initialized__ = true;
00043     
00044     Factory::addTaskType<opspace::SelectedJointPostureTask>("opspace::SelectedJointPostureTask");
00045     Factory::addTaskType<opspace::CartPosTrjTask>("opspace::CartPosTrjTask");
00046     Factory::addTaskType<opspace::JPosTrjTask>("opspace::JPosTrjTask");
00047     Factory::addTaskType<opspace::CartPosTask>("opspace::CartPosTask");
00048     Factory::addTaskType<opspace::JPosTask>("opspace::JPosTask");
00049     Factory::addTaskType<opspace::JointLimitTask>("opspace::JointLimitTask");
00050     Factory::addTaskType<opspace::OrientationTask>("opspace::OrientationTask");
00051     Factory::addTaskType<opspace::DraftPIDTask>("opspace::DraftPIDTask");
00052 
00053     Factory::addSkillType<opspace::GenericSkill>("opspace::GenericSkill");
00054     Factory::addSkillType<opspace::TaskPostureSkill>("opspace::TaskPostureSkill");
00055     Factory::addSkillType<opspace::TaskPostureTrjSkill>("opspace::TaskPostureTrjSkill");
00056   }
00057   
00058   
00059   std::ostream * Factory::dbg__(0);
00060   Factory::task_shop_t Factory::task_shop__;
00061   Factory::skill_shop_t Factory::skill_shop__;
00062   
00063   
00064   void Factory::
00065   setDebugStream(std::ostream * dbg)
00066   {
00067     dbg__ = dbg;
00068   }
00069   
00070   
00071   Task * Factory::
00072   createTask(std::string const & type, std::string const & name)
00073   {
00074     init_shops();
00075     task_shop_t::iterator ii(task_shop__.find(type));
00076     if (task_shop__.end() == ii) {
00077       if (dbg__) {
00078   (*dbg__) << "Factory::createTask(): no task type `" << type << "'\n"
00079      << "  registered types are:\n";
00080   for (ii = task_shop__.begin(); ii != task_shop__.end(); ++ii) {
00081     (*dbg__) << "    " << ii->first << "\n";
00082   }
00083       }
00084       return 0;
00085     }
00086     return ii->second->create(name);
00087   }
00088   
00089   
00090   Skill * Factory::
00091   createSkill(std::string const & type, std::string const & name)
00092   {
00093     init_shops();
00094     skill_shop_t::iterator ii(skill_shop__.find(type));
00095     if (skill_shop__.end() == ii) {
00096       if (dbg__) {
00097   (*dbg__) << "Factory::createSkill(): no skill type `" << type << "'\n"
00098      << "  registered types are:\n";
00099   for (ii = skill_shop__.begin(); ii != skill_shop__.end(); ++ii) {
00100     (*dbg__) << "    " << ii->first << "\n";
00101   }
00102       }
00103       return 0;
00104     }
00105     return ii->second->create(name);
00106   }
00107   
00108   
00109   Status Factory::
00110   parseString(std::string const & yaml_string)
00111   {
00112     std::istringstream is(yaml_string);
00113     return parseStream(is);
00114   }
00115   
00116   
00117   Status Factory::
00118   parseFile(std::string const & yaml_filename)
00119   {
00120     std::ifstream is(yaml_filename.c_str());
00121     if ( ! is) {
00122       return Status(false, "could not open file `" + yaml_filename + "' for reading");
00123     }
00124     return parseStream(is);
00125   }
00126 
00127 
00128   Status Factory::
00129   parseStream(std::istream & yaml_istream)
00130   {
00131     Status st;
00132     boost::shared_ptr<Task> task;
00133     
00134     try {
00135       YAML::Parser parser(yaml_istream);
00136       YAML::Node doc;
00137       TaskTableParser task_table_parser(*this, task_table_, dbg__);
00138       SkillTableParser skill_table_parser(*this, skill_table_, dbg__);
00139       
00140       parser.GetNextDocument(doc); // <sigh>this'll have merge conflicts again</sigh>
00141       //while (parser.GetNextDocument(doc)) {
00142       {
00143   for (YAML::Iterator ilist(doc.begin()); ilist != doc.end(); ++ilist) {
00144     for (YAML::Iterator idict(ilist->begin()); idict != ilist->end(); ++idict) {
00145       std::string key;
00146       idict.first() >> key;
00147       if ("tasks" == key) {
00148         idict.second() >> task_table_parser;
00149       }
00150       else if ("skills" == key) {
00151         idict.second() >> skill_table_parser;
00152       }
00153       else if ("behaviors" == key) {
00154         throw std::runtime_error("deprecated key `behaviors' (use `skills' instead)");
00155       }
00156       else {
00157         throw std::runtime_error("invalid key `" + key + "'");
00158       }
00159     }
00160   }
00161       }
00162     }
00163     catch (YAML::Exception const & ee) {
00164       if (dbg__) {
00165   *dbg__ << "YAML::Exception: " << ee.what() << "\n";
00166       }
00167       st.ok = false;
00168       st.errstr = ee.what();
00169     }
00170     catch (std::runtime_error const & ee) {
00171       if (dbg__) {
00172   *dbg__ << "std::runtime_error: " << ee.what() << "\n";
00173       }
00174       st.ok = false;
00175       st.errstr = ee.what();
00176     }
00177     
00178     return st;
00179   }
00180   
00181   
00182   Factory::task_table_t const & Factory::
00183   getTaskTable() const
00184   {
00185     return task_table_;
00186   }
00187   
00188   
00189   Factory::skill_table_t const & Factory::
00190   getSkillTable() const
00191   {
00192     return skill_table_;
00193   }
00194   
00195   
00196   void Factory::
00197   dump(std::ostream & os,
00198        std::string const & title,
00199        std::string const & prefix) const
00200   {
00201     if ( ! title.empty()) {
00202       os << title << "\n";
00203     }
00204     os << prefix << "  tasks:\n";
00205     for (task_table_t::const_iterator it(task_table_.begin());
00206    it != task_table_.end(); ++it) {
00207       (*it)->dump(os, "", prefix + "    ");
00208     }
00209     os << prefix << "  skills:\n";
00210     for (skill_table_t::const_iterator it(skill_table_.begin());
00211    it != skill_table_.end(); ++it) {
00212       (*it)->dump(os, "", prefix + "    ");
00213     }
00214   }
00215 
00216   
00217   boost::shared_ptr<Task> Factory::
00218   findTask(std::string const & name)
00219     const
00220   {
00221     for (size_t ii(0); ii < task_table_.size(); ++ii) {
00222       if (name == task_table_[ii]->getName()) {
00223   return task_table_[ii];
00224       }
00225     }
00226     return boost::shared_ptr<Task>();
00227   }
00228 
00229   
00230   boost::shared_ptr<Skill> Factory::
00231   findSkill(std::string const & name)
00232     const
00233   {
00234     for (size_t ii(0); ii < skill_table_.size(); ++ii) {
00235       if (name == skill_table_[ii]->getName()) {
00236   return skill_table_[ii];
00237       }
00238     }
00239     return boost::shared_ptr<Skill>();
00240   }
00241   
00242   
00243   ReflectionRegistry * Factory::
00244   createRegistry()
00245   {
00246     ReflectionRegistry * reg(new ReflectionRegistry());
00247     for (size_t ii(0); ii < task_table_.size(); ++ii) {
00248       reg->add(task_table_[ii]);
00249     }
00250     for (size_t ii(0); ii < skill_table_.size(); ++ii) {
00251       reg->add(skill_table_[ii]);
00252     }
00253     return reg;
00254   }
00255   
00256 }

Generated on Fri Aug 26 01:31:17 2011 for Stanford Whole-Body Control Framework by  doxygen 1.5.4