elmo_console.cpp
Go to the documentation of this file.
00001 #include <canopen_master/canopen.h>
00002 #include <canopen_master/master.h>
00003 #include <boost/make_shared.hpp>
00004 #include <iostream>
00005 
00006 #include <socketcan_interface/dispatcher.h>
00007 #include <boost/unordered_set.hpp>
00008 #include <socketcan_interface/socketcan.h>
00009 #include <socketcan_interface/threading.h>
00010 
00011 #include <boost/thread.hpp>
00012 
00013 using namespace can;
00014 using namespace canopen;
00015 
00016 class ElmoNode: public Node
00017 {
00018     static boost::shared_ptr<canopen::ObjectDict>  make_dict(){
00019         canopen::DeviceInfo info;
00020         info.nr_of_rx_pdo = 0;
00021         info.nr_of_tx_pdo = 0;
00022 
00023         boost::shared_ptr<canopen::ObjectDict>  dict = boost::make_shared<canopen::ObjectDict>(info);
00024 
00025         dict->insert(true, boost::make_shared<const canopen::ObjectDict::Entry>(0x1023, 1, ObjectDict::DEFTYPE_OCTET_STRING, "Command", false, true, false));
00026         dict->insert(true, boost::make_shared<const canopen::ObjectDict::Entry>(0x1023, 2, ObjectDict::DEFTYPE_UNSIGNED8, "Status", true, false, false));
00027         dict->insert(true, boost::make_shared<const canopen::ObjectDict::Entry>(0x1023, 3, ObjectDict::DEFTYPE_OCTET_STRING, "Reply", true, false, false));
00028 
00029 
00030         dict->insert(false, boost::make_shared<const canopen::ObjectDict::Entry>(ObjectDict::VAR, 0x1024, ObjectDict::DEFTYPE_UNSIGNED8, "OS command mode", false, true, false));
00031 
00032         dict->insert(false, boost::make_shared<const canopen::ObjectDict::Entry>(ObjectDict::VAR, 0x1001, ObjectDict::DEFTYPE_UNSIGNED8, "error register", true, false, false));
00033 
00034         dict->insert(false, boost::make_shared<const canopen::ObjectDict::Entry>(ObjectDict::VAR, 0x1017, ObjectDict::DEFTYPE_UNSIGNED16, "producer heartbeat", true, true, false, HoldAny((uint16_t)0)));
00035 
00036         return dict;
00037     }
00038 
00039     ObjectStorage::Entry<canopen::ObjectStorage::DataType<ObjectDict::DEFTYPE_OCTET_STRING>::type >  command_;
00040     ObjectStorage::Entry<canopen::ObjectStorage::DataType<ObjectDict::DEFTYPE_UNSIGNED8>::type >  status_;
00041     ObjectStorage::Entry<canopen::ObjectStorage::DataType<ObjectDict::DEFTYPE_OCTET_STRING>::type >  reply_;
00042 
00043     ObjectStorage::Entry<canopen::ObjectStorage::DataType<ObjectDict::DEFTYPE_UNSIGNED8>::type >  mode_;
00044 
00045     template<typename T> bool try_set(T & entry, const typename T::type &value){
00046         try{
00047             entry.set(value);
00048         }
00049         catch(...){
00050             return false;
00051         }
00052         return true;
00053     }
00054 public:
00055 
00056     ElmoNode(boost::shared_ptr<can::CommInterface> interface, const uint8_t &id) : Node (interface, make_dict(), id){
00057         getStorage()->entry(command_, 0x1023, 1);
00058         getStorage()->entry(status_, 0x1023, 2);
00059         getStorage()->entry(reply_, 0x1023, 3);
00060 
00061         getStorage()->entry(mode_, 0x1024);
00062     }
00063 
00064     uint8_t send_command(const std::string &s){
00065         if(!try_set(command_, String(s))) return 0;
00066 
00067         uint8_t status;
00068 
00069         do{
00070             status = status_.get();
00071         }while(status == 255);
00072 
00073         return status;
00074     }
00075     void get_response(std::string &s){
00076         String res;
00077         try{
00078             res = reply_.get();
00079             s = (const std::string&) res;
00080         }
00081         catch(const TimeoutException&){
00082             s = "<TIMEOUT>";
00083         }
00084     }
00085 
00086 };
00087 
00088 
00089 
00090 boost::shared_ptr<ThreadedSocketCANInterface> driver;
00091 boost::shared_ptr<ElmoNode> node;
00092 StateInterface::StateListener::Ptr state_printer;
00093 
00094 void print_state(const State &s){
00095     boost::shared_ptr<ThreadedSocketCANInterface> d = driver;
00096     std::string msg;
00097     if(!s.error_code && !s.internal_error) return;
00098     
00099     if(d && !d->translateError(s.internal_error, msg)) msg  =  "Undefined";
00100     std::cerr << "device error: " << s.error_code << " internal_error: " << s.internal_error << " (" << msg << ")" << std::endl;
00101 }
00102 
00103 void shutdown(boost::shared_ptr<ThreadedSocketCANInterface> &driver, boost::shared_ptr<ElmoNode> &node, int code){
00104     state_printer.reset();
00105 
00106     LayerStatus s;
00107     if(node) node->shutdown(s);
00108     if(driver) driver->shutdown();
00109     exit(code);
00110 }
00111 
00112 void sigint_handler (int param)
00113 {
00114   shutdown(driver, node, param);
00115 }
00116 
00117 int main(int argc, char *argv[]){
00118 
00119     if(argc <= 2){
00120         std::cerr << "usage: " << argv[0] << " device node_id [< INPUT] [> OUTPUT]" << std::endl;
00121        return -1;
00122     }
00123 
00124     bool tty = isatty(fileno(stdin));
00125 
00126     uint8_t nodeid = atoi(argv[2]);
00127 
00128     signal(SIGINT, sigint_handler);
00129 
00130 
00131     driver = boost::make_shared<ThreadedSocketCANInterface> ();
00132     state_printer = driver->createStateListener(print_state);
00133 
00134     if(!driver->init(argv[1],0)){
00135         std::cerr << "init failed" << std::endl;
00136         return -1;
00137     }
00138 
00139     sleep(1.0);
00140 
00141     node = boost::make_shared<ElmoNode>(driver, nodeid);
00142 
00143     LayerStatus status;
00144     try{
00145         node->init(status);
00146         if(!status.bounded<LayerStatus::Warn>()){
00147             std::cerr << status.reason() << std::endl;
00148             shutdown(driver,node,-1);
00149         }
00150     }
00151     catch( const canopen::Exception &e){
00152         std::cerr << boost::diagnostic_information(e) << std::endl;
00153         shutdown(driver,node,-1);
00154     }
00155 
00156     std::string res;
00157     std::string line;
00158 
00159     while(std::cin.good()){
00160         if(tty) std::cout << "> ";
00161         std::getline (std::cin, line);
00162 
00163         if(line.empty()) continue;
00164         
00165         if(!tty) std::cout << line <<  ": ";
00166             
00167         uint8_t status = node->send_command(line);
00168         if(status){
00169             node->get_response(res);
00170             std::cout << (status == 1 ? res : "<ERROR>")  << std::endl;
00171         }else{
00172             std::cout << "ERROR!";
00173             break;
00174         }
00175     }
00176 
00177     shutdown(driver,node,0);
00178 
00179     return 0;
00180 }


canopen_test_utils
Author(s): Mathias Lüdtke
autogenerated on Fri Feb 12 2016 02:43:15