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 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <unistd.h>
00041 #include <string.h>
00042 #include <signal.h>
00043 #include <math.h>
00044 #include <time.h>
00045 #include <pthread.h>
00046 #include <setjmp.h>
00047 #include <errno.h>
00048
00049 #include <list>
00050 #include <vector>
00051 #include <set>
00052 #include <string>
00053 #include <map>
00054 #include <sstream>
00055
00056 #include <cstdio>
00057 #include <boost/thread/mutex.hpp>
00058 #include <boost/thread/condition.hpp>
00059 #include <boost/shared_ptr.hpp>
00060
00061 #include <ros/init.h>
00062 #include <ros/time.h>
00063 #include <ros/rate.h>
00064 #include <ros/master.h>
00065 #include <ros/this_node.h>
00066 #include <ros/node_handle.h>
00067 #include <ros/service.h>
00068 #include <rospack/rospack.h>
00069 #include <ros/param.h>
00070 #include <ros/callback_queue.h>
00071
00072
00073 #define class eus_class
00074 #define throw eus_throw
00075 #define export eus_export
00076 #define vector eus_vector
00077 #define string eus_string
00078
00079 #include "eus.h"
00080 extern "C" {
00081 pointer ___roseus(register context *ctx, int n, pointer *argv, pointer env);
00082 void register_roseus(){
00083 char modname[] = "___roseus";
00084 return add_module_initializer(modname, (pointer (*)())___roseus);}
00085 }
00086
00087 #undef class
00088 #undef throw
00089 #undef export
00090 #undef vector
00091 #undef string
00092
00093 namespace ros {
00094 namespace master {
00095 std::string g_uri;
00096 void init(const M_string& remappings);
00097 }
00098 namespace param {
00099 void init(const M_string& remappings);
00100 }
00101 }
00102
00103 using namespace ros;
00104 using namespace std;
00105
00106 #define isInstalledCheck \
00107 if( ! ros::ok() ) { error(E_USER,"You must call (ros::roseus \"name\") before creating the first NodeHandle"); }
00108
00109 class RoseusStaticData
00110 {
00111 public:
00112 RoseusStaticData() {}
00113 ~RoseusStaticData() {
00114 }
00115 boost::shared_ptr<ros::NodeHandle> node;
00116 ros::Rate *rate;
00117 map<string, boost::shared_ptr<Publisher> > mapAdvertised;
00118 map<string, boost::shared_ptr<Subscriber> > mapSubscribed;
00119 map<string, boost::shared_ptr<ServiceServer> > mapServiced;
00120 map<string, Timer > mapTimered;
00121
00122 map<string, boost::shared_ptr<NodeHandle> > mapHandle;
00123 };
00124
00125 static RoseusStaticData s_staticdata;
00126 static bool s_bInstalled = false;
00127 #define s_node s_staticdata.node
00128 #define s_rate s_staticdata.rate
00129 #define s_mapAdvertised s_staticdata.mapAdvertised
00130 #define s_mapSubscribed s_staticdata.mapSubscribed
00131 #define s_mapServiced s_staticdata.mapServiced
00132 #define s_mapTimered s_staticdata.mapTimered
00133 #define s_mapHandle s_staticdata.mapHandle
00134
00135 pointer K_ROSEUS_MD5SUM,K_ROSEUS_DATATYPE,K_ROSEUS_DEFINITION,K_ROSEUS_SERIALIZATION_LENGTH,K_ROSEUS_SERIALIZE,K_ROSEUS_DESERIALIZE,K_ROSEUS_INIT,K_ROSEUS_GET,K_ROSEUS_REQUEST,K_ROSEUS_RESPONSE,K_ROSEUS_GROUPNAME,K_ROSEUS_ONESHOT,K_ROSEUS_LAST_EXPECTED,K_ROSEUS_LAST_REAL,K_ROSEUS_CURRENT_EXPECTED,K_ROSEUS_CURRENT_REAL,K_ROSEUS_LAST_DURATION,K_ROSEUS_SEC,K_ROSEUS_NSEC,QANON,QNOOUT,QREPOVERSION,QROSDEBUG,QROSINFO,QROSWARN,QROSERROR,QROSFATAL;
00136 extern pointer LAMCLOSURE;
00137
00138
00139
00140
00141
00142 string getString(pointer message, pointer method) {
00143 context *ctx = current_ctx;
00144 pointer r, curclass;
00145 if ((pointer)findmethod(ctx,method,classof(message),&curclass)!=NIL) {
00146 r = csend(ctx,message,method,0);
00147 } else if ((pointer)findmethod(ctx,K_ROSEUS_GET,classof(message),&curclass) != NIL ) {
00148 r = csend(ctx,message,K_ROSEUS_GET,1,method);
00149 } else {
00150 r = NULL;
00151 #ifdef x86_64
00152 ROS_ERROR("could not find method %s for pointer %lx",
00153 get_string(method), (long unsigned int)message);
00154 #else
00155 ROS_ERROR("could not find method %s for pointer %x",
00156 get_string(method), (unsigned int)message);
00157 #endif
00158 }
00159 if ( !isstring(r) ) {
00160 pointer dest=(pointer)mkstream(ctx,K_OUT,makebuffer(64));
00161 prinx(ctx,message,dest);
00162 pointer str = makestring((char *)dest->c.stream.buffer->c.str.chars,
00163 intval(dest->c.stream.count));
00164 ROS_ERROR("send %s to %s returns nil", get_string(method), get_string(str));
00165 }
00166 ROS_ASSERT(isstring(r));
00167 string ret = (char *)get_string(r);
00168 return ret;
00169 }
00170
00171 int getInteger(pointer message, pointer method) {
00172 context *ctx = current_ctx;
00173 pointer a,curclass;
00174 vpush(message);
00175 a = (pointer)findmethod(ctx,method,classof(message),&curclass);
00176 if (a!=NIL) {
00177 pointer r = csend(ctx,message,method,0);
00178 vpop();
00179 return (ckintval(r));
00180 } else {
00181 #ifdef x86_64
00182 ROS_ERROR("could not find method %s for pointer %lx",
00183 get_string(method), (long unsigned int)message);
00184 #else
00185 ROS_ERROR("could not find method %s for pointer %x",
00186 get_string(method), (unsigned int)message);
00187 #endif
00188 vpop();
00189 }
00190 return 0;
00191 }
00192
00193 class EuslispMessage
00194 {
00195 public:
00196 pointer _message;
00197
00198 EuslispMessage(pointer message) : _message(message) {
00199 }
00200 EuslispMessage(const EuslispMessage &r) {
00201 context *ctx = current_ctx;
00202 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00203 if ( isclass(r._message) ) {
00204
00205 vpush(r._message);
00206 _message = makeobject(r._message);
00207 vpush(_message);
00208 csend(ctx,_message,K_ROSEUS_INIT,0);
00209 vpop();
00210 vpop();
00211 } else {
00212 ROS_WARN("r._message must be class");prinx(ctx,r._message,ERROUT);flushstream(ERROUT);terpri(ERROUT);
00213 _message = r._message;
00214 }
00215 }
00216 virtual ~EuslispMessage() { }
00217
00218 virtual void replaceContents (pointer newMessage) {
00219 _message = newMessage;
00220 }
00221
00222 virtual const string __getDataType() const {
00223 return getString(_message, K_ROSEUS_DATATYPE);
00224 }
00225 virtual const string __getMD5Sum() const {
00226 return getString(_message, K_ROSEUS_MD5SUM);
00227 }
00228 virtual const string __getMessageDefinition() const {
00229 return getString(_message, K_ROSEUS_DEFINITION);
00230 }
00231 virtual const string __getServiceDataType() const {
00232 return getString(_message, K_ROSEUS_DATATYPE);
00233 }
00234 virtual const string __getServerMD5Sum() const {
00235 return getString(_message, K_ROSEUS_MD5SUM);
00236 }
00237
00238 uint32_t serializationLength() const {
00239 context *ctx = current_ctx;
00240 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00241 pointer a,curclass;
00242 a = (pointer)findmethod(ctx,K_ROSEUS_SERIALIZATION_LENGTH,classof(_message),&curclass);
00243 ROS_ASSERT(a!=NIL);
00244 return getInteger(_message, K_ROSEUS_SERIALIZATION_LENGTH);
00245 }
00246
00247 virtual uint8_t *serialize(uint8_t *writePtr, uint32_t seqid) const
00248 {
00249 context *ctx = current_ctx;
00250 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00251 pointer a,curclass;
00252 vpush(_message);
00253 uint32_t len = serializationLength();
00254 vpop();
00255 a = (pointer)findmethod(ctx,K_ROSEUS_SERIALIZE,classof(_message),&curclass);
00256 ROS_ASSERT(a!=NIL);
00257 pointer r = csend(ctx,_message,K_ROSEUS_SERIALIZE,0);
00258 ROS_ASSERT(isstring(r));
00259 memcpy(writePtr, get_string(r), len);
00260
00261
00262 return writePtr + len;
00263 }
00264
00265 virtual uint8_t *deserialize(uint8_t *readPtr, uint32_t sz)
00266 {
00267 context *ctx = current_ctx;
00268 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00269 pointer a,curclass;
00270
00271 if ( sz == 0 ) {
00272 ROS_DEBUG("empty message!");
00273 return readPtr;
00274 }
00275 vpush(_message);
00276 a = (pointer)findmethod(ctx,K_ROSEUS_DESERIALIZE,classof(_message),&curclass);
00277 ROS_ASSERT(a!=NIL);
00278 pointer p = makestring((char *)readPtr, sz);
00279 pointer r = csend(ctx,_message,K_ROSEUS_DESERIALIZE,1,p);
00280 ROS_ASSERT(r!=NIL);
00281
00282 vpop();
00283
00284 return readPtr + sz;
00285 }
00286 };
00287
00288 namespace ros{
00289 namespace serialization{
00290 template<> struct Serializer<EuslispMessage> {
00291 template<typename Stream>
00292 inline static void write(Stream& stream, boost::call_traits<EuslispMessage>::param_type t) {
00293 t.serialize(stream.getData(), 0);
00294 }
00295
00296 template<typename Stream>
00297 inline static void read(Stream& stream, boost::call_traits<EuslispMessage>::reference t) {
00298 t.deserialize(stream.getData(), stream.getLength());
00299 }
00300 inline static uint32_t serializedLength(boost::call_traits<EuslispMessage>::param_type t) {
00301 return t.serializationLength();
00302 }
00303 };
00304 }
00305 }
00306
00307
00308
00309
00310 class EuslispSubscriptionCallbackHelper : public ros::SubscriptionCallbackHelper {
00311 public:
00312 pointer _scb,_args;
00313 EuslispMessage _msg;
00314
00315 EuslispSubscriptionCallbackHelper(pointer scb, pointer args,pointer tmpl) : _args(args), _msg(tmpl) {
00316 context *ctx = current_ctx;
00317 mutex_trylock(&mark_lock);
00318
00319
00320 if (piscode(scb)) {
00321 _scb=scb;
00322 } else if ((ccar(scb))==LAMCLOSURE) {
00323 if ( ccar(ccdr(scb)) != NIL ) {
00324 _scb=ccar(ccdr(scb));
00325 } else {
00326 _scb=scb;
00327 }
00328 } else {
00329 ROS_ERROR("subscription callback function install error");
00330 }
00331
00332 pointer p=gensym(ctx);
00333 setval(ctx,intern(ctx,(char*)(p->c.sym.pname->c.str.chars),strlen((char*)(p->c.sym.pname->c.str.chars)),lisppkg),cons(ctx,scb,args));
00334 mutex_unlock(&mark_lock);
00335 }
00336 ~EuslispSubscriptionCallbackHelper() {
00337 ROS_ERROR("subscription gc");
00338 }
00339 virtual ros::VoidConstPtr deserialize(const ros::SubscriptionCallbackHelperDeserializeParams& param) {
00340 #if DEBUG
00341 cerr << __PRETTY_FUNCTION__ << endl;
00342 cerr << "param.length = " << param.length << endl;
00343 cerr << "param.buffer = " << (param.buffer + 4) << endl;
00344 cerr << "c_header == " << param.connection_header << endl;
00345 #endif
00346 ros::VoidConstPtr ptr(new EuslispMessage(_msg));
00347 EuslispMessage *eus_msg = (EuslispMessage *)(ptr.get());
00348 eus_msg->deserialize(param.buffer, param.length);
00349
00350 return ptr;
00351 }
00352 virtual void call(ros::SubscriptionCallbackHelperCallParams& param) {
00353 EuslispMessage* eus_msg = (EuslispMessage *)((void *)param.event.getConstMessage().get());
00354 context *ctx = current_ctx;
00355 pointer argp=_args;
00356 int argc=0;
00357
00358
00359 vpush(eus_msg->_message);
00360 if ( ! ( issymbol(_scb) || piscode(_scb) || ccar(_scb)==LAMCLOSURE ) ) {
00361 ROS_ERROR("%s : can't find callback function", __PRETTY_FUNCTION__);
00362 }
00363
00364 while(argp!=NIL){ ckpush(ccar(argp)); argp=ccdr(argp); argc++;}
00365 vpush((pointer)(eus_msg->_message));argc++;
00366
00367 ufuncall(ctx,(ctx->callfp?ctx->callfp->form:NIL),_scb,(pointer)(ctx->vsp-argc),NULL,argc);
00368 while(argc-->0)vpop();
00369 vpop();
00370 }
00371 virtual const std::type_info& getTypeInfo() {
00372 return typeid(EuslispMessage);
00373 }
00374 virtual bool isConst(){
00375 return true;
00376 }
00377 virtual bool hasHeader(){
00378 return true;
00379 }
00380 };
00381
00382
00383
00384
00385 class EuslispServiceCallbackHelper : public ros::ServiceCallbackHelper {
00386 public:
00387 pointer _scb, _args;
00388 EuslispMessage _req, _res;
00389 string md5, datatype, requestDataType, responseDataType,
00390 requestMessageDefinition, responseMessageDefinition;
00391
00392 EuslispServiceCallbackHelper(pointer scb, pointer args, string smd5, string sdatatype, pointer reqclass, pointer resclass) : _args(args), _req(reqclass), _res(resclass), md5(smd5), datatype(sdatatype) {
00393 context *ctx = current_ctx;
00394 mutex_trylock(&mark_lock);
00395
00396
00397
00398 if (piscode(scb)) {
00399 _scb=scb;
00400 } else if ((ccar(scb))==LAMCLOSURE) {
00401 if ( ccar(ccdr(scb)) != NIL ) {
00402 _scb=ccar(ccdr(scb));
00403 } else {
00404 _scb=scb;
00405 }
00406 } else {
00407 ROS_ERROR("service callback function install error");
00408 }
00409
00410 pointer p=gensym(ctx);
00411 setval(ctx,intern(ctx,(char*)(p->c.sym.pname->c.str.chars),strlen((char*)(p->c.sym.pname->c.str.chars)),lisppkg),cons(ctx,scb,args));
00412
00413 requestDataType = _req.__getDataType();
00414 responseDataType = _res.__getDataType();
00415 requestMessageDefinition = _req.__getMessageDefinition();
00416 responseMessageDefinition = _res.__getMessageDefinition();
00417 mutex_unlock(&mark_lock);
00418 }
00419 ~EuslispServiceCallbackHelper() { }
00420
00421 virtual boost::shared_ptr<EuslispMessage> createRequest() { return boost::shared_ptr<EuslispMessage>(new EuslispMessage(_req)); }
00422 virtual boost::shared_ptr<EuslispMessage> createResponse() { return boost::shared_ptr<EuslispMessage>(new EuslispMessage(_res)); }
00423
00424 virtual std::string getMD5Sum() { return md5; }
00425 virtual std::string getDataType() { return datatype; }
00426 virtual std::string getRequestDataType() { return requestDataType; }
00427 virtual std::string getResponseDataType() { return responseDataType; }
00428 virtual std::string getRequestMessageDefinition() { return requestMessageDefinition; }
00429 virtual std::string getResponseMessageDefinition() { return responseMessageDefinition; }
00430
00431 virtual bool call(ros::ServiceCallbackHelperCallParams& params) {
00432 context *ctx = current_ctx;
00433 pointer r, argp=_args;
00434 int argc=0;
00435
00436 vpush(_res._message);
00437 vpush(_req._message);
00438
00439 if ( ! ( issymbol(_scb) || piscode(_scb) || ccar(_scb)==LAMCLOSURE ) ) {
00440 ROS_ERROR("%s : can't find callback function", __PRETTY_FUNCTION__);
00441 }
00442
00443 EuslispMessage eus_msg(_req);
00444 vpush(eus_msg._message);
00445 eus_msg.deserialize(params.request.message_start, params.request.num_bytes);
00446
00447 while(argp!=NIL){ ckpush(ccar(argp)); argp=ccdr(argp); argc++;}
00448 vpush((pointer) eus_msg._message);argc++;
00449
00450 r = ufuncall(ctx, (ctx->callfp?ctx->callfp->form:NIL),
00451 _scb, (pointer)(ctx->vsp-argc),
00452 NULL, argc);
00453 while(argc-->0)vpop();
00454 vpush(r);
00455
00456 EuslispMessage eus_res(_res);
00457 eus_res.replaceContents(r);
00458
00459 pointer ret_serialize_method, ret_class;
00460 ret_serialize_method = (pointer)findmethod(ctx,K_ROSEUS_SERIALIZATION_LENGTH,classof(r),&ret_class);
00461 if (ret_serialize_method == NIL) {
00462 ROS_ERROR("you may not return valid value in service callback");
00463 }
00464 vpush(eus_res._message);
00465 uint32_t serialized_length = eus_res.serializationLength();
00466 params.response.num_bytes = serialized_length + 5;
00467 params.response.buf.reset (new uint8_t[params.response.num_bytes]);
00468 params.response.message_start = 0;
00469
00470
00471 uint8_t *tmp = params.response.buf.get();
00472 *tmp++ = 1;
00473 *tmp++ = (uint8_t)((serialized_length >> 0) & 0xFF);
00474 *tmp++ = (uint8_t)((serialized_length >> 8) & 0xFF);
00475 *tmp++ = (uint8_t)((serialized_length >> 16) & 0xFF);
00476 *tmp++ = (uint8_t)((serialized_length >> 24) & 0xFF);
00477 eus_res.serialize(tmp, 0);
00478 #if DEBUG
00479 cerr << "num bytes = " << params.response.num_bytes << endl;
00480 ROS_INFO("message_start = %X",params.response.message_start);
00481 ROS_INFO("message_ptr = %X",params.response.buf.get());
00482 tmp = params.response.buf.get();
00483 for(int i=0;i<params.response.num_bytes;i++){
00484 ROS_INFO("%X", tmp[i]);
00485 }
00486 #endif
00487 vpop();
00488 vpop();
00489 vpop();
00490 vpop();
00491 vpop();
00492 return(T);
00493 }
00494 };
00495
00496 void roseusSignalHandler(int sig)
00497 {
00498
00499 context *ctx=euscontexts[thr_self()];
00500 ctx->intsig = sig;
00501 }
00502
00503
00504
00505
00506 pointer ROSEUS(register context *ctx,int n,pointer *argv)
00507 {
00508 char name[256] = "";
00509 uint32_t options = 0;
00510 int cargc = 0;
00511 char *cargv[32];
00512
00513 if( s_bInstalled ) {
00514 ROS_WARN("ROSEUS is already installed as %s", ros::this_node::getName().c_str());
00515 return (T);
00516 }
00517
00518 ckarg(3);
00519 if (isstring(argv[0]))
00520 strncpy(name,(char *)(argv[0]->c.str.chars),255);
00521 else error(E_NOSTRING);
00522 options = ckintval(argv[1]);
00523 pointer p = argv[2];
00524 if (islist(p)) {
00525 while (1) {
00526 if (!iscons(p)) break;
00527 cargv[cargc]=(char *)((ccar(p))->c.str.chars);
00528 cargc++;
00529 p=ccdr(p);
00530 }
00531 } else error(E_NOSEQ);
00532
00533 for (unsigned int i=0; i < strlen(name); i++)
00534 if ( ! isalpha(name[i]) ) name[i] = '_';
00535
00536 K_ROSEUS_MD5SUM = defkeyword(ctx,"MD5SUM-");
00537 K_ROSEUS_DATATYPE = defkeyword(ctx,"DATATYPE-");
00538 K_ROSEUS_DEFINITION = defkeyword(ctx,"DEFINITION-");
00539 K_ROSEUS_SERIALIZATION_LENGTH = defkeyword(ctx,"SERIALIZATION-LENGTH");
00540 K_ROSEUS_SERIALIZE = defkeyword(ctx,"SERIALIZE");
00541 K_ROSEUS_DESERIALIZE = defkeyword(ctx,"DESERIALIZE");
00542 K_ROSEUS_GET = defkeyword(ctx,"GET");
00543 K_ROSEUS_INIT = defkeyword(ctx,"INIT");
00544 K_ROSEUS_REQUEST = defkeyword(ctx,"REQUEST");
00545 K_ROSEUS_RESPONSE = defkeyword(ctx,"RESPONSE");
00546 K_ROSEUS_GROUPNAME = defkeyword(ctx,"GROUPNAME");
00547 K_ROSEUS_ONESHOT = defkeyword(ctx,"ONESHOT");
00548 K_ROSEUS_LAST_EXPECTED = defkeyword(ctx,"LAST-EXPECTED");
00549 K_ROSEUS_LAST_REAL = defkeyword(ctx,"LAST-REAL");
00550 K_ROSEUS_CURRENT_EXPECTED = defkeyword(ctx,"CURRENT-EXPECTED");
00551 K_ROSEUS_CURRENT_REAL = defkeyword(ctx,"CURRENT-REAL");
00552 K_ROSEUS_LAST_DURATION = defkeyword(ctx,"LAST-DURATION");
00553 K_ROSEUS_SEC = defkeyword(ctx,"SEC");
00554 K_ROSEUS_NSEC = defkeyword(ctx,"NSEC");
00555
00556 s_mapAdvertised.clear();
00557 s_mapSubscribed.clear();
00558 s_mapServiced.clear();
00559 s_mapTimered.clear();
00560 s_mapHandle.clear();
00561
00562
00563
00564
00565
00566
00567 options |= ros::init_options::NoSigintHandler;
00568
00569
00570
00571
00572
00573
00574 if (!ros::master::g_uri.empty()) {
00575 if ( ros::master::g_uri != getenv("ROS_MASTER_URI") ) {
00576 ROS_WARN("ROS master uri will be changed!!, master uri %s, which is defineed previously is differ from current ROS_MASTE_URI(%s)", ros::master::g_uri.c_str(), getenv("ROS_MASTER_URI"));
00577 ros::master::g_uri.clear();
00578 }
00579 }
00580 try {
00581 ros::init(cargc, cargv, name, options);
00582 } catch (const ros::InvalidNameException &e) {
00583 ROS_ERROR("%s",e.what());
00584 error(E_MISMATCHARG);
00585 return(NIL);
00586 }
00587
00588 s_node.reset(new ros::NodeHandle());
00589 s_rate = new ros::Rate(50);
00590
00591 s_bInstalled = true;
00592
00593
00594
00595 signal(SIGINT, roseusSignalHandler);
00596 return (T);
00597 }
00598
00599 pointer ROSEUS_CREATE_NODEHANDLE(register context *ctx,int n,pointer *argv)
00600 {
00601 isInstalledCheck;
00602 string groupname;
00603 string ns;
00604
00605 ckarg2(1, 2);
00606
00607
00608
00609 if (isstring(argv[0])) groupname.assign((char *)get_string(argv[0]));
00610 else error(E_NOSTRING);
00611 if ( n > 1 ) {
00612 if(isstring(argv[1])) ns.assign((char *)get_string(argv[1]));
00613 else error(E_NOSTRING);
00614 }
00615
00616 if( s_mapHandle.find(groupname) != s_mapHandle.end() ) {
00617 ROS_DEBUG("groupname %s is already used", groupname.c_str());
00618 return (NIL);
00619 }
00620
00621 boost::shared_ptr<NodeHandle> hd;
00622 if ( n > 1 ) {
00623 hd = boost::shared_ptr<NodeHandle> (new NodeHandle(ns));
00624 s_mapHandle[groupname] = hd;
00625 } else {
00626 hd = boost::shared_ptr<NodeHandle>(new NodeHandle());
00627 s_mapHandle[groupname] = hd;
00628 }
00629
00630 hd->setCallbackQueue( new CallbackQueue() );
00631
00632 return (T);
00633 }
00634
00635 pointer ROSEUS_SPIN(register context *ctx,int n,pointer *argv)
00636 {
00637 isInstalledCheck;
00638 while (ctx->intsig==0) {
00639 ros::spinOnce();
00640 s_rate->sleep();
00641 }
00642 return (NIL);
00643 }
00644
00645 pointer ROSEUS_SPINONCE(register context *ctx,int n,pointer *argv)
00646 {
00647 isInstalledCheck;
00648 ckarg2(0, 1);
00649
00650
00651
00652 if ( n > 0 ) {
00653 string groupname;
00654 if (isstring(argv[0])) groupname.assign((char *)get_string(argv[0]));
00655 else error(E_NOSTRING);
00656
00657 map<string, boost::shared_ptr<NodeHandle > >::iterator it = s_mapHandle.find(groupname);
00658 if( it == s_mapHandle.end() ) {
00659 ROS_ERROR("Groupname %s is missing", groupname.c_str());
00660 return (T);
00661 }
00662 boost::shared_ptr<NodeHandle > hdl = (it->second);
00663
00664 ((CallbackQueue *)hdl->getCallbackQueue())->callAvailable();
00665
00666 return (NIL);
00667 } else {
00668 ros::spinOnce();
00669 return (NIL);
00670 }
00671 }
00672
00673 pointer ROSEUS_TIME_NOW(register context *ctx,int n,pointer *argv)
00674 {
00675 isInstalledCheck;
00676 pointer timevec;
00677 ros::Time t = ros::Time::now();
00678
00679 timevec=makevector(C_INTVECTOR,2);
00680 vpush(timevec);
00681 timevec->c.ivec.iv[0]=t.sec;
00682 timevec->c.ivec.iv[1]=t.nsec;
00683 vpop();
00684 return (timevec);
00685 }
00686
00687 pointer ROSEUS_RATE(register context *ctx,int n,pointer *argv)
00688 {
00689 isInstalledCheck;
00690 numunion nu;
00691 ckarg(1);
00692 float timeout=ckfltval(argv[0]);
00693 s_rate = new ros::Rate(timeout);
00694 return(T);
00695 }
00696
00697 pointer ROSEUS_SLEEP(register context *ctx,int n,pointer *argv)
00698 {
00699 isInstalledCheck;
00700 s_rate->sleep();
00701 return (T);
00702 }
00703
00704 pointer ROSEUS_OK(register context *ctx,int n,pointer *argv)
00705 {
00706 if (ros::ok()) {
00707 return (T);
00708 } else {
00709 return (NIL);
00710 }
00711 }
00712
00713
00714 #define def_rosconsole_formatter(funcname, rosfuncname) \
00715 pointer funcname(register context *ctx,int n,pointer *argv) \
00716 { pointer *argv2,msg; \
00717 int argc2; \
00718 argc2 = n+1; \
00719 argv2 = (pointer *)malloc(sizeof(pointer)*argc2); \
00720 argv2[0] = NIL; \
00721 for(int i=0;i<n;i++) argv2[i+1]=argv[i] ; \
00722 msg = XFORMAT(ctx, argc2, argv2); \
00723 rosfuncname("%s", msg->c.str.chars); \
00724 free(argv2); \
00725 return (T); \
00726 }
00727
00728 def_rosconsole_formatter(ROSEUS_ROSDEBUG, ROS_DEBUG)
00729 def_rosconsole_formatter(ROSEUS_ROSINFO, ROS_INFO)
00730 def_rosconsole_formatter(ROSEUS_ROSWARN, ROS_WARN)
00731 def_rosconsole_formatter(ROSEUS_ROSERROR, ROS_ERROR)
00732 def_rosconsole_formatter(ROSEUS_ROSFATAL, ROS_FATAL)
00733
00734 pointer ROSEUS_EXIT(register context *ctx,int n,pointer *argv)
00735 {
00736 ROS_INFO("%s", __PRETTY_FUNCTION__);
00737 if( s_bInstalled ) {
00738 ROS_INFO("exiting roseus %ld", (n==0)?n:ckintval(argv[0]));
00739 s_mapAdvertised.clear();
00740 s_mapSubscribed.clear();
00741 s_mapServiced.clear();
00742 s_mapTimered.clear();
00743 s_mapHandle.clear();
00744 ros::shutdown();
00745 }
00746 if (n==0) _exit(0);
00747 else _exit(ckintval(argv[0]));
00748 }
00749
00750
00751
00752
00753 pointer ROSEUS_SUBSCRIBE(register context *ctx,int n,pointer *argv)
00754 {
00755 isInstalledCheck;
00756 string topicname;
00757 pointer message, fncallback, args;
00758 int queuesize = 1;
00759 NodeHandle *lnode = s_node.get();
00760
00761
00762
00763 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00764 else error(E_NOSTRING);
00765
00766 if (n > 1 && issymbol(argv[n-2]) && isstring(argv[n-1])) {
00767 if (argv[n-2] == K_ROSEUS_GROUPNAME) {
00768 string groupname;
00769 groupname.assign((char *)get_string(argv[n-1]));
00770 map<string, boost::shared_ptr<NodeHandle > >::iterator it = s_mapHandle.find(groupname);
00771 if( it != s_mapHandle.end() ) {
00772 ROS_DEBUG("subscribe with groupname=%s", groupname.c_str());
00773 lnode = (it->second).get();
00774 } else {
00775 ROS_ERROR("Groupname %s is missing. Topic %s is not subscribed. Call (ros::create-nodehandle \"%s\") first.",
00776 groupname.c_str(), topicname.c_str(), groupname.c_str());
00777 return (NIL);
00778 }
00779 n -= 2;
00780 }
00781 }
00782 if (isint(argv[n-1])) {queuesize = ckintval(argv[n-1]);n--;}
00783 ROS_DEBUG("subscribe %s queuesize=%d", topicname.c_str(), queuesize);
00784
00785 message = argv[1];
00786 fncallback = argv[2];
00787 args=NIL;
00788 for (int i=n-1;i>=3;i--) args=cons(ctx,argv[i],args);
00789
00790 EuslispMessage msg(message);
00791 boost::shared_ptr<SubscriptionCallbackHelper> *callback =
00792 (new boost::shared_ptr<SubscriptionCallbackHelper>
00793 (new EuslispSubscriptionCallbackHelper(fncallback, args, message)));
00794 SubscribeOptions so(topicname, queuesize, msg.__getMD5Sum(), msg.__getDataType());
00795 so.helper = *callback;
00796 Subscriber subscriber = lnode->subscribe(so);
00797 boost::shared_ptr<Subscriber> sub = boost::shared_ptr<Subscriber>(new Subscriber(subscriber));
00798 if ( !!sub ) {
00799 s_mapSubscribed[topicname] = sub;
00800 } else {
00801 ROS_ERROR("s_mapSubscribed");
00802 }
00803
00804 return (T);
00805 }
00806
00807 pointer ROSEUS_UNSUBSCRIBE(register context *ctx,int n,pointer *argv)
00808 {
00809 string topicname;
00810
00811 ckarg(1);
00812 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00813 else error(E_NOSTRING);
00814
00815 bool bSuccess = s_mapSubscribed.erase(topicname)>0;
00816
00817 return (bSuccess?T:NIL);
00818 }
00819
00820 pointer ROSEUS_GETNUMPUBLISHERS(register context *ctx,int n,pointer *argv)
00821 {
00822 string topicname;
00823 int ret;
00824
00825 ckarg(1);
00826 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00827 else error(E_NOSTRING);
00828
00829 bool bSuccess = false;
00830 map<string, boost::shared_ptr<Subscriber> >::iterator it = s_mapSubscribed.find(topicname);
00831 if( it != s_mapSubscribed.end() ) {
00832 boost::shared_ptr<Subscriber> subscriber = (it->second);
00833 ret = subscriber->getNumPublishers();
00834 bSuccess = true;
00835 }
00836
00837 if ( ! bSuccess ) {
00838 ROS_ERROR("attempted to getNumPublishers to topic %s, which was not " \
00839 "previously subscribed. call (ros::subscribe \"%s\") first.",
00840 topicname.c_str(), topicname.c_str());
00841 }
00842
00843 return (bSuccess?(makeint(ret)):NIL);
00844 }
00845
00846 pointer ROSEUS_GETTOPICSUBSCRIBER(register context *ctx,int n,pointer *argv)
00847 {
00848 string topicname;
00849 string ret;
00850
00851 ckarg(1);
00852 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00853 else error(E_NOSTRING);
00854
00855 bool bSuccess = false;
00856 map<string, boost::shared_ptr<Subscriber> >::iterator it = s_mapSubscribed.find(topicname);
00857 if( it != s_mapSubscribed.end() ) {
00858 boost::shared_ptr<Subscriber> subscriber = (it->second);
00859 ret = subscriber->getTopic();
00860 bSuccess = true;
00861 }
00862
00863 return (bSuccess?(makestring((char *)ret.c_str(), ret.length())):NIL);
00864 }
00865
00866 pointer ROSEUS_ADVERTISE(register context *ctx,int n,pointer *argv)
00867 {
00868 isInstalledCheck;
00869 string topicname;
00870 pointer message;
00871 int queuesize = 1;
00872 bool latch = false;
00873
00874 ckarg2(2,4);
00875 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00876 else error(E_NOSTRING);
00877 message = argv[1];
00878 if ( n > 2 ) {
00879 queuesize = ckintval(argv[2]);
00880 }
00881 if ( n > 3 ) {
00882 latch = (argv[3]!=NIL ? true : false);
00883 }
00884 ROS_DEBUG("advertise %s %d %d", topicname.c_str(), queuesize, latch);
00885 if( s_mapAdvertised.find(topicname) != s_mapAdvertised.end() ) {
00886 ROS_WARN("topic %s already advertised", topicname.c_str());
00887 return (NIL);
00888 }
00889
00890 EuslispMessage msg(message);
00891 AdvertiseOptions ao(topicname, queuesize, msg.__getMD5Sum(), msg.__getDataType(), msg.__getMessageDefinition());
00892 ao.latch = latch;
00893 Publisher publisher = s_node->advertise(ao);
00894 boost::shared_ptr<Publisher> pub = boost::shared_ptr<Publisher>(new Publisher(publisher));
00895 if ( !!pub ) {
00896 s_mapAdvertised[topicname] = pub;
00897 } else {
00898 ROS_ERROR("s_mapAdvertised");
00899 }
00900
00901 return (T);
00902 }
00903
00904 pointer ROSEUS_UNADVERTISE(register context *ctx,int n,pointer *argv)
00905 {
00906 string topicname;
00907
00908 ckarg(1);
00909 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00910 else error(E_NOSTRING);
00911
00912 bool bSuccess = s_mapAdvertised.erase(topicname)>0;
00913
00914 return (bSuccess?T:NIL);
00915 }
00916
00917 pointer ROSEUS_PUBLISH(register context *ctx,int n,pointer *argv)
00918 {
00919 isInstalledCheck;
00920 string topicname;
00921 pointer emessage;
00922
00923 ckarg(2);
00924 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00925 else error(E_NOSTRING);
00926 emessage = argv[1];
00927
00928 bool bSuccess = false;
00929 map<string, boost::shared_ptr<Publisher> >::iterator it = s_mapAdvertised.find(topicname);
00930 if( it != s_mapAdvertised.end() ) {
00931 boost::shared_ptr<Publisher> publisher = (it->second);
00932 EuslispMessage message(emessage);
00933 publisher->publish(message);
00934 bSuccess = true;
00935 }
00936
00937 if ( ! bSuccess ) {
00938 ROS_ERROR("attempted to publish to topic %s, which was not " \
00939 "previously advertised. call (ros::advertise \"%s\") first.",
00940 topicname.c_str(), topicname.c_str());
00941 }
00942
00943 return (T);
00944 }
00945
00946 pointer ROSEUS_GETNUMSUBSCRIBERS(register context *ctx,int n,pointer *argv)
00947 {
00948 string topicname;
00949 int ret;
00950
00951 ckarg(1);
00952 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00953 else error(E_NOSTRING);
00954
00955 bool bSuccess = false;
00956 map<string, boost::shared_ptr<Publisher> >::iterator it = s_mapAdvertised.find(topicname);
00957 if( it != s_mapAdvertised.end() ) {
00958 boost::shared_ptr<Publisher> publisher = (it->second);
00959 ret = publisher->getNumSubscribers();
00960 bSuccess = true;
00961 }
00962
00963 if ( ! bSuccess ) {
00964 ROS_ERROR("attempted to getNumSubscribers to topic %s, which was not " \
00965 "previously advertised. call (ros::advertise \"%s\") first.",
00966 topicname.c_str(), topicname.c_str());
00967 }
00968
00969 return (bSuccess?(makeint(ret)):NIL);
00970 }
00971
00972 pointer ROSEUS_GETTOPICPUBLISHER(register context *ctx,int n,pointer *argv)
00973 {
00974 string topicname;
00975 string ret;
00976
00977 ckarg(1);
00978 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00979 else error(E_NOSTRING);
00980
00981 bool bSuccess = false;
00982 map<string, boost::shared_ptr<Publisher> >::iterator it = s_mapAdvertised.find(topicname);
00983 if( it != s_mapAdvertised.end() ) {
00984 boost::shared_ptr<Publisher> publisher = (it->second);
00985 ret = publisher->getTopic();
00986 bSuccess = true;
00987 }
00988
00989 return (bSuccess?(makestring((char *)ret.c_str(), ret.length())):NIL);
00990 }
00991
00992
00993
00994
00995 pointer ROSEUS_WAIT_FOR_SERVICE(register context *ctx,int n,pointer *argv)
00996 {
00997 isInstalledCheck;
00998 string service;
00999
01000 ckarg2(1,2);
01001 if (isstring(argv[0])) service.assign((char *)(argv[0]->c.str.chars));
01002 else error(E_NOSTRING);
01003
01004 int32_t timeout = -1;
01005
01006 if( n > 1 )
01007 timeout = (int32_t)ckintval(argv[1]);
01008
01009 bool bSuccess = service::waitForService(ros::names::resolve(service), ros::Duration(timeout));
01010
01011 return (bSuccess?T:NIL);
01012 }
01013
01014 pointer ROSEUS_SERVICE_EXISTS(register context *ctx,int n,pointer *argv)
01015 {
01016 isInstalledCheck;
01017 string service;
01018
01019 ckarg(1);
01020 if (isstring(argv[0])) service.assign((char *)(argv[0]->c.str.chars));
01021 else error(E_NOSTRING);
01022
01023 bool bSuccess = service::exists(ros::names::resolve(service), true);
01024
01025 return (bSuccess?T:NIL);
01026 }
01027
01028 pointer ROSEUS_SERVICE_CALL(register context *ctx,int n,pointer *argv)
01029 {
01030 isInstalledCheck;
01031 string service;
01032 pointer emessage;
01033 bool persist = false;
01034 ckarg2(2,3);
01035 if (isstring(argv[0])) service.assign((char *)(argv[0]->c.str.chars));
01036 else error(E_NOSTRING);
01037 emessage = argv[1];
01038 if ( n > 2 ) {
01039 persist = (argv[2] != NIL ? true : false);
01040 }
01041 static std::map<std::string, ros::ServiceClient> service_cache;
01042 std::string service_name = ros::names::resolve(service);
01043 ServiceClient client;
01044 EuslispMessage request(emessage);
01045 vpush(request._message);
01046 EuslispMessage response(csend(ctx,emessage,K_ROSEUS_RESPONSE,0));
01047 vpush(response._message);
01048 if (persist == false) {
01049 ServiceClientOptions sco(service_name, request.__getMD5Sum(), false, M_string());
01050 client = s_node->serviceClient(sco);
01051 }
01052 else {
01053
01054
01055 if (service_cache.find(service_name) != service_cache.end()) {
01056 client = service_cache[service_name];
01057 }
01058 else {
01059 ServiceClientOptions sco(service_name, request.__getMD5Sum(), true, M_string());
01060 client = s_node->serviceClient(sco);
01061 service_cache[service_name] = client;
01062 }
01063 }
01064
01065 bool bSuccess = client.call(request, response, request.__getMD5Sum());
01066 vpop();
01067 vpop();
01068 if ( ! bSuccess ) {
01069 ROS_ERROR("attempted to call service %s, but failed ",
01070 ros::names::resolve(service).c_str());
01071 if (persist) {
01072
01073 service_cache.erase(service_cache.find(service_name));
01074 }
01075 }
01076
01077 return (response._message);
01078 }
01079
01080 pointer ROSEUS_ADVERTISE_SERVICE(register context *ctx,int n,pointer *argv)
01081 {
01082 isInstalledCheck;
01083 string service;
01084 pointer emessage;
01085 pointer fncallback, args;
01086
01087 if (isstring(argv[0])) service.assign((char *)get_string(argv[0]));
01088 else error(E_NOSTRING);
01089 emessage = argv[1];
01090 fncallback = argv[2];
01091 args=NIL;
01092 for (int i=n-1;i>=3;i--) args=cons(ctx,argv[i],args);
01093 if( s_mapServiced.find(service) != s_mapServiced.end() ) {
01094 ROS_INFO("service %s already advertised", service.c_str());
01095 return (NIL);
01096 }
01097
01098 EuslispMessage message(emessage);
01099 vpush(message._message);
01100 pointer request(csend(ctx,emessage,K_ROSEUS_GET,1,K_ROSEUS_REQUEST));
01101 pointer response(csend(ctx,emessage,K_ROSEUS_GET,1,K_ROSEUS_RESPONSE));
01102 vpop();
01103 boost::shared_ptr<EuslispServiceCallbackHelper> *callback =
01104 (new boost::shared_ptr<EuslispServiceCallbackHelper>
01105 (new EuslispServiceCallbackHelper(fncallback, args, message.__getMD5Sum(),
01106 message.__getDataType(), request, response)));
01107 AdvertiseServiceOptions aso;
01108 aso.service.assign(service);
01109 aso.datatype = (*callback->get()).getDataType();
01110 aso.md5sum = (*callback->get()).getMD5Sum();
01111 aso.req_datatype = (*callback->get()).getRequestDataType();
01112 aso.res_datatype = (*callback->get()).getResponseDataType();
01113 aso.helper = *callback;
01114 ServiceServer server = s_node->advertiseService(aso);
01115 boost::shared_ptr<ServiceServer> ser = boost::shared_ptr<ServiceServer>(new ServiceServer(server));
01116 if ( !!ser ) {
01117 s_mapServiced[service] = ser;
01118 } else {
01119 ROS_ERROR("s_mapServiced");
01120 }
01121
01122 return (T);
01123 }
01124
01125 pointer ROSEUS_UNADVERTISE_SERVICE(register context *ctx,int n,pointer *argv)
01126 {
01127 string service;
01128
01129 ckarg(1);
01130 if (isstring(argv[0])) service.assign((char *)get_string(argv[0]));
01131 else error(E_NOSTRING);
01132
01133 ROS_DEBUG("unadvertise %s", service.c_str());
01134 bool bSuccess = s_mapServiced.erase(service)>0;
01135
01136 return (bSuccess?T:NIL);
01137 }
01138
01139 pointer ROSEUS_SET_PARAM(register context *ctx,int n,pointer *argv)
01140 {
01141 numunion nu;
01142 string key;
01143 string s;
01144 double d;
01145 int i;
01146
01147 ckarg(2);
01148 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01149 else error(E_NOSTRING);
01150 if ( isstring(argv[1]) ) {
01151 s.assign((char *)get_string(argv[1]));
01152 ros::param::set(key,s);
01153 } else if (isint(argv[1])) {
01154 i = intval(argv[1]);
01155 ros::param::set(key,i);
01156 } else if (isflt(argv[1])) {
01157 d = fltval(argv[1]);
01158 ros::param::set(key,d);
01159 } else if (argv[1] == T) {
01160 bool b = true;
01161 ros::param::set(key, b);
01162 } else if (argv[1] == NIL) {
01163 bool b = false;
01164 ros::param::set(key, b);
01165 } else {
01166 error(E_MISMATCHARG);
01167 }
01168 return (T);
01169 }
01170
01171 pointer XmlRpcToEusValue(register context *ctx, XmlRpc::XmlRpcValue rpc_value)
01172 {
01173 numunion nu;
01174 pointer ret, first;
01175
01176 if ( rpc_value.getType() == XmlRpc::XmlRpcValue::TypeBoolean ){
01177 if ( rpc_value ) return T; else return NIL;
01178 }
01179 else if ( rpc_value.getType() == XmlRpc::XmlRpcValue::TypeDouble ){
01180 return makeflt((double)rpc_value);
01181 }
01182 else if ( rpc_value.getType() == XmlRpc::XmlRpcValue::TypeInt ){
01183 return makeint((int)rpc_value);
01184 }
01185 else if ( rpc_value.getType() == XmlRpc::XmlRpcValue::TypeString ){
01186 std::string str = rpc_value;
01187 return makestring((char*)str.c_str(), ((std::string)rpc_value).length());
01188 }
01189 else if ( rpc_value.getType() == XmlRpc::XmlRpcValue::TypeArray ){
01190 ret = cons(ctx, NIL, NIL);
01191 first = ret;
01192 vpush(ret);
01193 for ( int i = 0; i < rpc_value.size(); i++){
01194 ccdr(ret) = cons(ctx, XmlRpcToEusValue(ctx, rpc_value[i]), NIL);
01195 ret = ccdr(ret);
01196 }
01197 vpop();
01198 return ccdr(first);
01199 }
01200 else if ( rpc_value.getType() == XmlRpc::XmlRpcValue::TypeStruct ){
01201 ret = cons(ctx, NIL, NIL);
01202 first = ret;
01203 vpush(ret);
01204 XmlRpc::XmlRpcValue::iterator it = rpc_value.begin();
01205 while(it !=rpc_value.end()) {
01206 std::string key = it->first;
01207 pointer tmp = cons(ctx, makestring((char*)key.c_str(), key.length()), NIL);
01208 vpush(tmp);
01209 ccdr(tmp) = XmlRpcToEusValue(ctx, it->second);
01210 ccdr(ret) = cons(ctx, tmp, NIL);
01211 ret = ccdr(ret);
01212 vpop();
01213 it++;
01214 }
01215 vpop();
01216 return ccdr(first);
01217 } else {
01218 ROS_FATAL("unkown rosparam type!");
01219 return NIL;
01220 }
01221 return NIL;
01222 }
01223
01224 pointer XmlRpcToEusList(register context *ctx, XmlRpc::XmlRpcValue param_list)
01225 {
01226 numunion nu;
01227 pointer ret, first;
01228 ret = cons(ctx, NIL, NIL);
01229 first = ret;
01230 vpush(ret);
01231 if ( param_list.getType() == XmlRpc::XmlRpcValue::TypeArray ){
01232 for ( int i = 0; i < param_list.size(); i++){
01233 if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeBoolean ){
01234 if ( param_list[i] ){
01235 ccdr(ret) = cons(ctx, T, NIL);
01236 ret = ccdr(ret);
01237 } else {
01238 ccdr(ret) = cons(ctx, NIL, NIL);
01239 ret = ccdr(ret);
01240 }
01241 }
01242 else if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble ){
01243 ccdr(ret) = cons(ctx, makeflt((double)param_list[i]), NIL);
01244 ret = ccdr(ret);
01245 }
01246 else if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeInt ){
01247 ccdr(ret) = cons(ctx, makeint((int)param_list[i]), NIL);
01248 ret = ccdr(ret);
01249 }
01250 else if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeString ){
01251 std::string str = param_list[i];
01252 ccdr(ret) = cons(ctx, makestring((char*)str.c_str(), ((std::string)param_list[i]).length()), NIL);
01253 ret = ccdr(ret);
01254 }
01255 else if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeStruct ){
01256 ccdr(ret) = cons(ctx, XmlRpcToEusValue(ctx, param_list[i]), NIL);
01257 ret = ccdr(ret);
01258 }
01259 else {
01260 ROS_FATAL("unkown rosparam type!");
01261 vpop();
01262 return NIL;
01263 }
01264 }
01265 vpop();
01266 return ccdr(first);
01267 } else if ( param_list.getType() == XmlRpc::XmlRpcValue::TypeStruct ) {
01268 return XmlRpcToEusValue(ctx, param_list);
01269 } else
01270 return (NIL);
01271 }
01272
01273 pointer ROSEUS_GET_PARAM(register context *ctx,int n,pointer *argv)
01274 {
01275 numunion nu;
01276 string key;
01277
01278 ckarg2(1,2);
01279 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01280 else error(E_NOSTRING);
01281
01282 string s;
01283 double d;
01284 bool b;
01285 int i;
01286 pointer ret;
01287 XmlRpc::XmlRpcValue param_list;
01288
01289 if ( ros::param::get(key, s) ) {
01290 ret = makestring((char *)s.c_str(), s.length());
01291 } else if ( ros::param::get(key, d) ) {
01292 ret = makeflt(d);
01293 } else if ( ros::param::get(key, i) ) {
01294 ret = makeint(i);
01295 } else if ( ros::param::get(key, b) ) {
01296 if ( b == true )
01297 ret = T;
01298 else
01299 ret = NIL;
01300 } else if (ros::param::get(key, param_list)){
01301 ret = XmlRpcToEusList(ctx, param_list);
01302 }else {
01303 if ( n == 2 ) {
01304 ret = COPYOBJ(ctx,1,argv+1);
01305 } else {
01306 ROS_ERROR("unknown ros::param::get, key=%s", key.c_str());
01307 ret = NIL;
01308 }
01309 }
01310 return (ret);
01311 }
01312
01313 pointer ROSEUS_GET_PARAM_CASHED(register context *ctx,int n,pointer *argv)
01314 {
01315 numunion nu;
01316 string key;
01317
01318 ckarg2(1,2);
01319 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01320 else error(E_NOSTRING);
01321
01322 string s;
01323 double d;
01324 int i;
01325 bool b;
01326 pointer ret;
01327 XmlRpc::XmlRpcValue param_list;
01328 if ( ros::param::getCached(key, s) ) {
01329 ret = makestring((char *)s.c_str(), s.length());
01330 } else if ( ros::param::getCached(key, d) ) {
01331 ret = makeflt(d);
01332 } else if ( ros::param::getCached(key, i) ) {
01333 ret = makeint(i);
01334 } else if ( ros::param::getCached(key, b) ) {
01335 if ( b == true )
01336 ret = T;
01337 else
01338 ret = NIL;
01339 } else if (ros::param::getCached(key, param_list)){
01340 ret = XmlRpcToEusList(ctx, param_list);
01341 } else {
01342 if ( n == 2 ) {
01343 ret = COPYOBJ(ctx,1,argv+1);
01344 } else {
01345 ROS_ERROR("unknown ros::param::get, key=%s", key.c_str());
01346 ret = NIL;
01347 }
01348 }
01349 return (ret);
01350 }
01351
01352 pointer ROSEUS_HAS_PARAM(register context *ctx,int n,pointer *argv)
01353 {
01354 string key;
01355
01356 ckarg(1);
01357 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01358 else error(E_NOSTRING);
01359
01360 return((ros::param::has(key))?(T):(NIL));
01361 }
01362
01363 pointer ROSEUS_ROSPACK_FIND(register context *ctx,int n,pointer *argv)
01364 {
01365 ckarg(1);
01366
01367 string pkg;
01368 if (isstring(argv[0])) pkg.assign((char *)get_string(argv[0]));
01369 else error(E_NOSTRING);
01370
01371 try {
01372 #ifdef ROSPACK_EXPORT
01373 rospack::ROSPack rp;
01374 rospack::Package *p = rp.get_pkg(pkg);
01375 if (p!=NULL) return(makestring((char *)p->path.c_str(),p->path.length()));
01376 #else
01377 rospack::Rospack rp;
01378 std::vector<std::string> search_path;
01379 rp.getSearchPathFromEnv(search_path);
01380 rp.crawl(search_path, 1);
01381 std::string path;
01382 if (rp.find(pkg,path)==true) return(makestring((char *)path.c_str(),path.length()));
01383 #endif
01384 } catch (runtime_error &e) {
01385 }
01386 return(NIL);
01387 }
01388
01389 pointer ROSEUS_RESOLVE_NAME(register context *ctx,int n,pointer *argv)
01390 {
01391 ckarg(1);
01392 if (!isstring(argv[0])) error(E_NOSTRING);
01393 std::string src;
01394 src.assign((char *)(argv[0]->c.str.chars));
01395 std::string dst = ros::names::resolve(src);
01396 return(makestring((char *)dst.c_str(), dst.length()));
01397 }
01398
01399 pointer ROSEUS_GETNAME(register context *ctx,int n,pointer *argv)
01400 {
01401 ckarg(0);
01402 return(makestring((char *)ros::this_node::getName().c_str(),
01403 ros::this_node::getName().length()));
01404 }
01405
01406 pointer ROSEUS_GETNAMESPACE(register context *ctx,int n,pointer *argv)
01407 {
01408 ckarg(0);
01409 return(makestring((char *)ros::this_node::getNamespace().c_str(),
01410 ros::this_node::getNamespace().length()));
01411 }
01412
01413 pointer ROSEUS_SET_LOGGER_LEVEL(register context *ctx, int n, pointer *argv)
01414 {
01415 ckarg(2);
01416 string logger;
01417 if (isstring(argv[0])) logger.assign((char *)get_string(argv[0]));
01418 else error(E_NOSTRING);
01419 int log_level = intval(argv[1]);
01420 ros::console::levels::Level level = ros::console::levels::Debug;
01421 switch(log_level){
01422 case 1:
01423 level = ros::console::levels::Debug;
01424 break;
01425 case 2:
01426 level = ros::console::levels::Info;
01427 break;
01428 case 3:
01429 level = ros::console::levels::Warn;
01430 break;
01431 case 4:
01432 level = ros::console::levels::Error;
01433 break;
01434 case 5:
01435 level = ros::console::levels::Fatal;
01436 break;
01437 default:
01438 return (NIL);
01439 }
01440
01441 bool success = ::ros::console::set_logger_level(logger, level);
01442 if (success)
01443 {
01444 console::notifyLoggerLevelsChanged();
01445 return (T);
01446 }
01447 return (NIL);
01448 }
01449
01450 pointer ROSEUS_GET_HOST(register context *ctx,int n,pointer *argv)
01451 {
01452 ckarg(0);
01453
01454 std::string host = ros::master::getHost();
01455 return makestring((char*)host.c_str(), host.length());
01456 }
01457
01458 pointer ROSEUS_GET_NODES(register context *ctx,int n,pointer *argv)
01459 {
01460 ckarg(0);
01461
01462 ros::V_string nodes;
01463 if ( ! ros::master::getNodes(nodes) ) {
01464 return NIL;
01465 }
01466
01467 register pointer ret, first;
01468 ret=cons(ctx, NIL, NIL);
01469 first = ret;
01470 vpush(ret);
01471 for (ros::V_string::iterator it = nodes.begin() ; it != nodes.end(); it++) {
01472 std::string node = *it;
01473 ccdr(ret) = cons(ctx, makestring((char *)node.c_str(), node.length()), NIL);
01474 ret = ccdr(ret);
01475 }
01476 vpop();
01477
01478 return ccdr(first);
01479 }
01480
01481 pointer ROSEUS_GET_PORT(register context *ctx,int n,pointer *argv)
01482 {
01483 ckarg(0);
01484
01485 return makeint(ros::master::getPort());
01486 }
01487
01488 pointer ROSEUS_GET_URI(register context *ctx,int n,pointer *argv)
01489 {
01490 ckarg(0);
01491
01492 std::string uri = ros::master::getURI();
01493 return makestring((char*)uri.c_str(), uri.length());
01494 }
01495
01496 pointer ROSEUS_GET_TOPICS(register context *ctx,int n,pointer *argv)
01497 {
01498 ckarg(0);
01499
01500 ros::master::V_TopicInfo topics;
01501 if ( !ros::master::getTopics(topics) ) {
01502 return NIL;
01503 }
01504
01505 register pointer ret, first;
01506 ret=cons(ctx, NIL, NIL);
01507 first = ret;
01508 vpush(ret);
01509 for (ros::master::V_TopicInfo::iterator it = topics.begin() ; it != topics.end(); it++) {
01510 const ros::master::TopicInfo& info = *it;
01511 pointer tmp = cons(ctx,makestring((char*)info.name.c_str(), info.name.length()), makestring((char*)info.datatype.c_str(), info.datatype.length()));
01512 vpush(tmp);
01513 ccdr(ret) = cons(ctx, tmp, NIL);
01514 ret = ccdr(ret);
01515 vpop();
01516 }
01517 vpop();
01518
01519 return ccdr(first);
01520 }
01521
01522 class TimerFunction
01523 {
01524 pointer _scb, _args;
01525 public:
01526 TimerFunction(pointer scb, pointer args) : _scb(scb), _args(args) {
01527 context *ctx = current_ctx;
01528
01529
01530 }
01531 void operator()(const ros::TimerEvent& event)
01532 {
01533 mutex_trylock(&mark_lock);
01534 context *ctx = current_ctx;
01535 numunion nu;
01536 pointer argp=_args;
01537 int argc=0;
01538
01539 pointer clsptr = NIL;
01540 for(int i=0; i<nextcix;i++) {
01541 if(!memcmp(classtab[i].def->c.cls.name->c.sym.pname->c.str.chars,(char *)"TIMER-EVENT",11)) {
01542 clsptr = classtab[i].def;
01543 }
01544 }
01545 if ( ! ( issymbol(_scb) || piscode(_scb) || ccar(_scb)==LAMCLOSURE ) ) {
01546 ROS_ERROR("%s : can't find callback function", __PRETTY_FUNCTION__);
01547 }
01548
01549 pointer tevent = makeobject(clsptr);
01550 csend(ctx,tevent,K_ROSEUS_INIT,0);
01551 csend(ctx,tevent,K_ROSEUS_LAST_EXPECTED,2,K_ROSEUS_SEC,makeint(event.last_expected.sec));
01552 csend(ctx,tevent,K_ROSEUS_LAST_EXPECTED,2,K_ROSEUS_NSEC,makeint(event.last_expected.nsec));
01553 csend(ctx,tevent,K_ROSEUS_LAST_REAL,2,K_ROSEUS_SEC,makeint(event.last_real.sec));
01554 csend(ctx,tevent,K_ROSEUS_LAST_REAL,2,K_ROSEUS_NSEC,makeint(event.last_real.nsec));
01555 csend(ctx,tevent,K_ROSEUS_CURRENT_EXPECTED,2,K_ROSEUS_SEC,makeint(event.current_expected.sec));
01556 csend(ctx,tevent,K_ROSEUS_CURRENT_EXPECTED,2,K_ROSEUS_NSEC,makeint(event.current_expected.nsec));
01557 csend(ctx,tevent,K_ROSEUS_CURRENT_REAL,2,K_ROSEUS_SEC,makeint(event.current_real.sec));
01558 csend(ctx,tevent,K_ROSEUS_CURRENT_REAL,2,K_ROSEUS_NSEC,makeint(event.current_real.nsec));
01559 csend(ctx,tevent,K_ROSEUS_LAST_DURATION,2,K_ROSEUS_SEC,makeint(event.profile.last_duration.sec));
01560 csend(ctx,tevent,K_ROSEUS_LAST_DURATION,2,K_ROSEUS_NSEC,makeint(event.profile.last_duration.nsec));
01561
01562 while(argp!=NIL){ ckpush(ccar(argp)); argp=ccdr(argp); argc++;}
01563 vpush((pointer)(tevent));argc++;
01564
01565 ufuncall(ctx,(ctx->callfp?ctx->callfp->form:NIL),_scb,(pointer)(ctx->vsp-argc),NULL,argc);
01566 while(argc-->0)vpop();
01567
01568 mutex_unlock(&mark_lock);
01569 }
01570 };
01571
01572 pointer ROSEUS_CREATE_TIMER(register context *ctx,int n,pointer *argv)
01573 {
01574 isInstalledCheck;
01575 numunion nu;
01576 bool oneshot = false;
01577 pointer fncallback, args;
01578 NodeHandle *lnode = s_node.get();
01579 string fncallname;
01580 float period=ckfltval(argv[0]);
01581
01582 mutex_trylock(&mark_lock);
01583
01584
01585 if (n > 1 && issymbol(argv[n-2]) && issymbol(argv[n-1])) {
01586 if (argv[n-2] == K_ROSEUS_ONESHOT) {
01587 if ( argv[n-1] != NIL ) {
01588 oneshot = true;
01589 }
01590 n -= 2;
01591 }
01592 }
01593
01594 if (piscode(argv[1])) {
01595 fncallback=argv[1];
01596 std::ostringstream stringstream;
01597 stringstream << reinterpret_cast<long>(argv[2]) << " ";
01598 for (int i=3; i<n;i++)
01599 stringstream << string((char*)(argv[i]->c.sym.pname->c.str.chars)) << " ";
01600 fncallname = stringstream.str();
01601 } else if ((ccar(argv[1]))==LAMCLOSURE) {
01602 if ( ccar(ccdr(argv[1])) != NIL ) {
01603 fncallback=ccar(ccdr(argv[1]));
01604 fncallname = string((char*)(fncallback->c.sym.pname->c.str.chars));
01605 } else {
01606 fncallback=argv[1];
01607 std::ostringstream stringstream;
01608 stringstream << reinterpret_cast<long>(argv[1]);
01609 fncallname = stringstream.str();
01610 }
01611 } else {
01612 ROS_ERROR("subscription callback function install error");
01613 }
01614
01615
01616 args=NIL;
01617 for (int i=n-1;i>=2;i--) args=cons(ctx,argv[i],args);
01618
01619
01620 pointer p=gensym(ctx);
01621 setval(ctx,intern(ctx,(char*)(p->c.sym.pname->c.str.chars),strlen((char*)(p->c.sym.pname->c.str.chars)),lisppkg),cons(ctx,fncallback,args));
01622
01623
01624 ROS_DEBUG("create timer %s at %f (oneshot=%d)", fncallname.c_str(), period, oneshot);
01625 s_mapTimered[fncallname] = lnode->createTimer(ros::Duration(period), TimerFunction(fncallback, args), oneshot);
01626
01627 mutex_unlock(&mark_lock);
01628 return (T);
01629 }
01630
01631
01632
01633
01634 extern pointer K_FUNCTION_DOCUMENTATION;
01635 pointer _defun(context *ctx, char *name, pointer mod, pointer (*f)(), char *doc) {
01636 pointer sym = defun(ctx,name, mod, f);
01637 if(strcmp(doc, "")) {
01638 pointer pdoc = makestring(doc,strlen(doc));
01639 vpush(pdoc); putprop(ctx,sym,pdoc,K_FUNCTION_DOCUMENTATION); vpop();}
01640 return sym;}
01641
01642 pointer ___roseus(register context *ctx, int n, pointer *argv, pointer env)
01643 {
01644 pointer rospkg,p=Spevalof(PACKAGE);
01645 rospkg=findpkg(makestring("ROS",3));
01646 if (rospkg == 0) rospkg=makepkg(ctx,makestring("ROS", 3),NIL,NIL);
01647 Spevalof(PACKAGE)=rospkg;
01648
01649 QANON=defvar(ctx,"*ANONYMOUS-NAME*",makeint(ros::init_options::AnonymousName),rospkg);
01650 QNOOUT=defvar(ctx,"*NO-ROSOUT*",makeint(ros::init_options::NoRosout),rospkg);
01651 QROSDEBUG=defvar(ctx,"*ROSDEBUG*",makeint(1),rospkg);
01652 QROSINFO=defvar(ctx,"*ROSINFO*",makeint(2),rospkg);
01653 QROSWARN=defvar(ctx,"*ROSWARN*",makeint(3),rospkg);
01654 QROSERROR=defvar(ctx,"*ROSERROR*",makeint(4),rospkg);
01655 QROSFATAL=defvar(ctx,"*ROSFATAL*",makeint(5),rospkg);
01656 _defun(ctx,"SPIN",argv[0],(pointer (*)())ROSEUS_SPIN, "Enter simple event loop");
01657
01658 _defun(ctx,"SPIN-ONCE",argv[0],(pointer (*)())ROSEUS_SPINONCE,
01659 "&optional groupname ;; spin only group\n\n"
01660 "Process a single round of callbacks.\n");
01661 _defun(ctx,"TIME-NOW-RAW",argv[0],(pointer (*)())ROSEUS_TIME_NOW, "");
01662 _defun(ctx,"RATE",argv[0],(pointer (*)())ROSEUS_RATE, "frequency\n\n" "Construct ros timer for periodic sleeps");
01663 _defun(ctx,"SLEEP",argv[0],(pointer (*)())ROSEUS_SLEEP, "Sleeps for any leftover time in a cycle. Calculated from the last time sleep, reset, or the constructor was called.");
01664 _defun(ctx,"OK",argv[0],(pointer (*)())ROSEUS_OK, "Check whether it's time to exit. ");
01665
01666 _defun(ctx,"ROS-DEBUG",argv[0],(pointer (*)())ROSEUS_ROSDEBUG,
01667 "write mesage to debug output\n"
01668 "\n"
01669 " (ros::ros-debug \"this is error ~A\" 0)\n");
01670 _defun(ctx,"ROS-INFO",argv[0],(pointer (*)())ROSEUS_ROSINFO, "write mesage to info output");
01671 _defun(ctx,"ROS-WARN",argv[0],(pointer (*)())ROSEUS_ROSWARN, "write mesage to warn output");
01672 _defun(ctx,"ROS-ERROR",argv[0],(pointer (*)())ROSEUS_ROSERROR, "write mesage to error output");
01673 _defun(ctx,"ROS-FATAL",argv[0],(pointer (*)())ROSEUS_ROSFATAL, "write mesage to fatal output");
01674 _defun(ctx,"EXIT",argv[0],(pointer (*)())ROSEUS_EXIT, "Exit ros clinet");
01675
01676 _defun(ctx,"SUBSCRIBE",argv[0],(pointer (*)())ROSEUS_SUBSCRIBE,
01677 "topicname message_type callbackfunc args0 ... argsN &optional queuesize %key (:groupname groupname)\n\n"
01678 "Subscribe to a topic, version for class member function with bare pointer.\n"
01679 "This method connects to the master to register interest in a given topic. The node will automatically be connected with publishers on this topic. On each message receipt, fp is invoked and passed a shared pointer to the message received. This message should not be changed in place, as it is shared with any other subscriptions to this topic.\n"
01680 "\n"
01681 "This version of subscribe is a convenience function for using function, member function, lmabda function:\n"
01682 " ;; callback function\n"
01683 " (defun string-cb (msg) (print (list 'cb (sys::thread-self) (send msg :data))))\n"
01684 " (ros::subscribe \"chatter\" std_msgs::string #'string-cb)\n"
01685 " ;; lambda function\n"
01686 " (ros::subscribe \"chatter\" std_msgs::string\n"
01687 " #'(lambda (msg) (ros::ros-info\n"
01688 " (format nil \"I heard ~A\" (send msg :data)))))\n"
01689 " ;; method call\n"
01690 " (defclass string-cb-class\n"
01691 " :super propertied-object\n"
01692 " :slots ())\n"
01693 " (defmethod string-cb-class\n"
01694 " (:init () (ros::subscribe \"chatter\" std_msgs::string #'send self :string-cb))\n"
01695 " (:string-cb (msg) (print (list 'cb self (send msg :data)))))\n"
01696 " (setq m (instance string-cb-class :init))\n"
01697 );
01698 _defun(ctx,"UNSUBSCRIBE",argv[0],(pointer (*)())ROSEUS_UNSUBSCRIBE, "topicname\n\n""Unsubscribe topic");
01699 _defun(ctx,"GET-NUM-PUBLISHERS",argv[0],(pointer (*)())ROSEUS_GETNUMPUBLISHERS, "Returns the number of publishers this subscriber is connected to. ");
01700 _defun(ctx,"GET-TOPIC-SUBSCRIBER",argv[0],(pointer (*)())ROSEUS_GETTOPICSUBSCRIBER, "topicname\n\n""Retuns the name of topic if it already subscribed");
01701 _defun(ctx,"ADVERTISE",argv[0],(pointer (*)())ROSEUS_ADVERTISE,
01702 "topic message_class &optional queuesize latch\n"
01703 "Advertise a topic.\n"
01704 "This call connects to the master to publicize that the node will be publishing messages on the given topic. This method returns a Publisher that allows you to publish a message on this topic.\n"
01705 " (ros::advertise \"chatter\" std_msgs::string 1)");
01706 _defun(ctx,"UNADVERTISE",argv[0],(pointer (*)())ROSEUS_UNADVERTISE, "Unadvertise topic");
01707 _defun(ctx,"PUBLISH",argv[0],(pointer (*)())ROSEUS_PUBLISH,
01708 "topic message\n\n"
01709 "Publish a message on the topic\n"
01710 " (ros::roseus \"talker\")\n"
01711 " (ros::advertise \"chatter\" std_msgs::string 1)\n"
01712 " (ros::rate 100)\n"
01713 " (while (ros::ok)\n"
01714 " (setq msg (instance std_msgs::string :init))\n"
01715 " (send msg :data (format nil \"hello world ~a\" (send (ros::time-now) :sec-nsec)))\n"
01716 " (ros::publish \"chatter\" msg)\n"
01717 " (ros::sleep))\n");
01718 _defun(ctx,"GET-NUM-SUBSCRIBERS",argv[0],(pointer (*)())ROSEUS_GETNUMSUBSCRIBERS, "Retuns number of subscribers this publish is connected to");
01719 _defun(ctx,"GET-TOPIC-PUBLISHER",argv[0],(pointer (*)())ROSEUS_GETTOPICPUBLISHER, "topicname\n\n""Retuns the name of topic if it already published");
01720
01721 _defun(ctx,"WAIT-FOR-SERVICE",argv[0],(pointer (*)())ROSEUS_WAIT_FOR_SERVICE, "servicename &optional timeout\n\n""Wait for a service to be advertised and available. Blocks until it is.");
01722 _defun(ctx,"SERVICE-EXISTS", argv[0], (pointer (*)())ROSEUS_SERVICE_EXISTS, "servicename\n\n""Checks if a service is both advertised and available.");
01723 _defun(ctx,"SERVICE-CALL",argv[0],(pointer (*)())ROSEUS_SERVICE_CALL,
01724 "servicename message_type &optional persist\n\n"
01725 "Invoke RPC service\n"
01726 " (ros::roseus \"add_two_ints_client\")\n"
01727 " (ros::wait-for-service \"add_two_ints\")\n"
01728 " (setq req (instance roseus::AddTwoIntsRequest :init))\n"
01729 " (send req :a (random 10))\n"
01730 " (send req :b (random 20))\n"
01731 " (setq res (ros::service-call \"add_two_ints\" req t))\n"
01732 " (format t \"~d + ~d = ~d~~%\" (send req :a) (send req :b) (send res :sum))\n");
01733 _defun(ctx,"ADVERTISE-SERVICE",argv[0],(pointer (*)())ROSEUS_ADVERTISE_SERVICE,
01734 "servicename message_type callback function\n\n"
01735 "Advertise a service\n"
01736 " (ros::advertise-service \"add_two_ints\" roseus::AddTwoInts #'add-two-ints)");
01737 _defun(ctx,"UNADVERTISE-SERVICE",argv[0],(pointer (*)())ROSEUS_UNADVERTISE_SERVICE, "Unadvertise service");
01738
01739 _defun(ctx,"SET-PARAM",argv[0],(pointer (*)())ROSEUS_SET_PARAM, "key value\n\n""Set parameter");
01740 _defun(ctx,"GET-PARAM",argv[0],(pointer (*)())ROSEUS_GET_PARAM, "key\n\n""Get parameter");
01741 _defun(ctx,"GET-PARAM-CASHED",argv[0],(pointer (*)())ROSEUS_GET_PARAM_CASHED, "Get chached parameter");
01742 _defun(ctx,"HAS-PARAM",argv[0],(pointer (*)())ROSEUS_HAS_PARAM, "Check whether a parameter exists on the parameter server.");
01743
01744 _defun(ctx,"ROSPACK-FIND",argv[0],(pointer (*)())ROSEUS_ROSPACK_FIND, "Returns ros package path");
01745 _defun(ctx,"RESOLVE-NAME",argv[0],(pointer (*)())ROSEUS_RESOLVE_NAME, "Returns ros resolved name");
01746 _defun(ctx,"GET-NAME",argv[0],(pointer (*)())ROSEUS_GETNAME, "Returns current node name");
01747 _defun(ctx,"GET-NAMESPACE",argv[0],(pointer (*)())ROSEUS_GETNAMESPACE, "Returns current node name space");
01748
01749 _defun(ctx,"ROSEUS-RAW",argv[0],(pointer (*)())ROSEUS, "");
01750 _defun(ctx,"CREATE-NODEHANDLE", argv[0], (pointer (*)())ROSEUS_CREATE_NODEHANDLE, "groupname &optional namespace ;;\n\n"
01751 "Create ros NodeHandle with given group name. \n"
01752 "\n"
01753 " (ros::roseus \"test\")\n"
01754 " (ros::create-node-handle \"mygroup\")\n"
01755 " (ros::subscribe \"/test\" std_msgs::String #'(lambda (m) (print m)) :groupname \"mygroup\")\n"
01756 " (while (ros::ok) (ros::spin-once \"mygroup\"))\n");
01757 _defun(ctx,"SET-LOGGER-LEVEL",argv[0],(pointer (*)())ROSEUS_SET_LOGGER_LEVEL, "");
01758
01759 _defun(ctx,"GET-HOST",argv[0],(pointer (*)())ROSEUS_GET_HOST, "Get the hostname where the master runs.");
01760 _defun(ctx,"GET-NODES",argv[0],(pointer (*)())ROSEUS_GET_NODES, "Retreives the currently-known list of nodes from the master.");
01761 _defun(ctx,"GET-PORT",argv[0],(pointer (*)())ROSEUS_GET_PORT, "Get the port where the master runs.");
01762 _defun(ctx,"GET-URI",argv[0],(pointer (*)())ROSEUS_GET_URI, "Get the full URI to the master ");
01763 _defun(ctx,"GET-TOPICS",argv[0],(pointer (*)())ROSEUS_GET_TOPICS, "Get the list of topics that are being published by all nodes.");
01764
01765 defun(ctx,"CREATE-TIMER",argv[0],(pointer (*)())ROSEUS_CREATE_TIMER);
01766
01767 pointer_update(Spevalof(PACKAGE),p);
01768
01769 pointer l;
01770 l=makestring(REPOVERSION,strlen(REPOVERSION));
01771 vpush(l);
01772 l=stacknlist(ctx,1);
01773 QREPOVERSION=defvar(ctx, "ROSEUS-REPO-VERSION", l, rospkg);
01774
01775 M_string remappings;
01776 pointer argp = speval(intern(ctx,"*EUSTOP-ARGUMENT*", strlen("*EUSTOP-ARGUMENT*"),lisppkg));
01777 while(argp!=NIL) {
01778 std::string arg = string((char *)(ccar(argp)->c.str.chars));
01779
01780 size_t pos = arg.find(":=");
01781 if (pos != std::string::npos) {
01782 std::string local_name = arg.substr(0, pos);
01783 std::string external_name = arg.substr(pos + 2);
01784 remappings[local_name] = external_name;
01785 }
01786 argp=ccdr(argp);
01787 }
01788 ros::master::init(remappings);
01789
01790
01791 return 0;
01792 }
01793