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::init() 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
00121 map<string, boost::shared_ptr<NodeHandle> > mapHandle;
00122 };
00123
00124 static RoseusStaticData s_staticdata;
00125 static bool s_bInstalled = false;
00126 #define s_node s_staticdata.node
00127 #define s_rate s_staticdata.rate
00128 #define s_mapAdvertised s_staticdata.mapAdvertised
00129 #define s_mapSubscribed s_staticdata.mapSubscribed
00130 #define s_mapServiced s_staticdata.mapServiced
00131 #define s_mapHandle s_staticdata.mapHandle
00132
00133 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,QANON,QNOOUT,QREPOVERSION;
00134 extern pointer LAMCLOSURE;
00135
00136
00137
00138
00139
00140 string getString(pointer message, pointer method) {
00141 context *ctx = current_ctx;
00142 pointer r, curclass;
00143 if ((pointer)findmethod(ctx,method,classof(message),&curclass)!=NIL) {
00144 r = csend(ctx,message,method,0);
00145 } else if ((pointer)findmethod(ctx,K_ROSEUS_GET,classof(message),&curclass) != NIL ) {
00146 r = csend(ctx,message,K_ROSEUS_GET,1,method);
00147 } else {
00148 r = NULL;
00149 #ifdef x86_64
00150 ROS_ERROR("could not find method %s for pointer %lx",
00151 get_string(method), (long unsigned int)message);
00152 #else
00153 ROS_ERROR("could not find method %s for pointer %x",
00154 get_string(method), (unsigned int)message);
00155 #endif
00156 }
00157 if ( !isstring(r) ) {
00158 pointer dest=(pointer)mkstream(ctx,K_OUT,makebuffer(64));
00159 prinx(ctx,message,dest);
00160 pointer str = makestring((char *)dest->c.stream.buffer->c.str.chars,
00161 intval(dest->c.stream.count));
00162 ROS_ERROR("send %s to %s returns nil", get_string(method), get_string(str));
00163 }
00164 ROS_ASSERT(isstring(r));
00165 string ret = (char *)get_string(r);
00166 return ret;
00167 }
00168
00169 int getInteger(pointer message, pointer method) {
00170 context *ctx = current_ctx;
00171 pointer a,curclass;
00172 vpush(message);
00173 a = (pointer)findmethod(ctx,method,classof(message),&curclass);
00174 if (a!=NIL) {
00175 pointer r = csend(ctx,message,method,0);
00176 vpop();
00177 return (ckintval(r));
00178 } else {
00179 #ifdef x86_64
00180 ROS_ERROR("could not find method %s for pointer %lx",
00181 get_string(method), (long unsigned int)message);
00182 #else
00183 ROS_ERROR("could not find method %s for pointer %x",
00184 get_string(method), (unsigned int)message);
00185 #endif
00186 vpop();
00187 }
00188 return 0;
00189 }
00190
00191 class EuslispMessage
00192 {
00193 public:
00194 pointer _message;
00195
00196 EuslispMessage(pointer message) : _message(message) {
00197 }
00198 EuslispMessage(const EuslispMessage &r) {
00199 context *ctx = current_ctx;
00200 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00201 if ( isclass(r._message) ) {
00202
00203 vpush(r._message);
00204 _message = makeobject(r._message);
00205 vpush(_message);
00206 csend(ctx,_message,K_ROSEUS_INIT,0);
00207 vpop();
00208 vpop();
00209 } else {
00210 ROS_WARN("r._message must be class");prinx(ctx,r._message,ERROUT);flushstream(ERROUT);terpri(ERROUT);
00211 _message = r._message;
00212 }
00213 }
00214 virtual ~EuslispMessage() { }
00215
00216 virtual void replaceContents (pointer newMessage) {
00217 _message = newMessage;
00218 }
00219
00220 virtual const string __getDataType() const {
00221 return getString(_message, K_ROSEUS_DATATYPE);
00222 }
00223 virtual const string __getMD5Sum() const {
00224 return getString(_message, K_ROSEUS_MD5SUM);
00225 }
00226 virtual const string __getMessageDefinition() const {
00227 return getString(_message, K_ROSEUS_DEFINITION);
00228 }
00229 virtual const string __getServiceDataType() const {
00230 return getString(_message, K_ROSEUS_DATATYPE);
00231 }
00232 virtual const string __getServerMD5Sum() const {
00233 return getString(_message, K_ROSEUS_MD5SUM);
00234 }
00235
00236 uint32_t serializationLength() const {
00237 context *ctx = current_ctx;
00238 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00239 pointer a,curclass;
00240 a = (pointer)findmethod(ctx,K_ROSEUS_SERIALIZATION_LENGTH,classof(_message),&curclass);
00241 ROS_ASSERT(a!=NIL);
00242 return getInteger(_message, K_ROSEUS_SERIALIZATION_LENGTH);
00243 }
00244
00245 virtual uint8_t *serialize(uint8_t *writePtr, uint32_t seqid) const
00246 {
00247 context *ctx = current_ctx;
00248 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00249 pointer a,curclass;
00250 vpush(_message);
00251 uint32_t len = serializationLength();
00252 vpop();
00253 a = (pointer)findmethod(ctx,K_ROSEUS_SERIALIZE,classof(_message),&curclass);
00254 ROS_ASSERT(a!=NIL);
00255 pointer r = csend(ctx,_message,K_ROSEUS_SERIALIZE,0);
00256 ROS_ASSERT(isstring(r));
00257 memcpy(writePtr, get_string(r), len);
00258
00259
00260 return writePtr + len;
00261 }
00262
00263 virtual uint8_t *deserialize(uint8_t *readPtr, uint32_t sz)
00264 {
00265 context *ctx = current_ctx;
00266 if (ctx!=euscontexts[0])ROS_WARN("ctx is not correct %d\n",thr_self());
00267 pointer a,curclass;
00268
00269 if ( sz == 0 ) {
00270 ROS_DEBUG("empty message!");
00271 return readPtr;
00272 }
00273 vpush(_message);
00274 a = (pointer)findmethod(ctx,K_ROSEUS_DESERIALIZE,classof(_message),&curclass);
00275 ROS_ASSERT(a!=NIL);
00276 pointer p = makestring((char *)readPtr, sz);
00277 pointer r = csend(ctx,_message,K_ROSEUS_DESERIALIZE,1,p);
00278 ROS_ASSERT(r!=NIL);
00279
00280 vpop();
00281
00282 return readPtr + sz;
00283 }
00284 };
00285
00286 namespace ros{
00287 namespace serialization{
00288 template<> struct Serializer<EuslispMessage> {
00289 template<typename Stream>
00290 inline static void write(Stream& stream, boost::call_traits<EuslispMessage>::param_type t) {
00291 t.serialize(stream.getData(), 0);
00292 }
00293
00294 template<typename Stream>
00295 inline static void read(Stream& stream, boost::call_traits<EuslispMessage>::reference t) {
00296 t.deserialize(stream.getData(), stream.getLength());
00297 }
00298 inline static uint32_t serializedLength(boost::call_traits<EuslispMessage>::param_type t) {
00299 return t.serializationLength();
00300 }
00301 };
00302 }
00303 }
00304
00305
00306
00307
00308 class EuslispSubscriptionCallbackHelper : public ros::SubscriptionCallbackHelper {
00309 public:
00310 pointer _scb,_args;
00311 EuslispMessage _msg;
00312
00313 EuslispSubscriptionCallbackHelper(pointer scb, pointer args,pointer tmpl) : _args(args), _msg(tmpl) {
00314 context *ctx = current_ctx;
00315 mutex_trylock(&mark_lock);
00316
00317
00318 if (piscode(scb)) {
00319 _scb=scb;
00320 } else if ((ccar(scb))==LAMCLOSURE) {
00321 if ( ccar(ccdr(scb)) != NIL ) {
00322 _scb=ccar(ccdr(scb));
00323 } else {
00324 _scb=scb;
00325 }
00326 } else {
00327 ROS_ERROR("subcriptoin callback function install error");
00328 }
00329
00330 pointer p=gensym(ctx);
00331 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));
00332 mutex_unlock(&mark_lock);
00333 }
00334 ~EuslispSubscriptionCallbackHelper() {
00335 ROS_ERROR("subcriptoin gc");
00336 }
00337 virtual ros::VoidConstPtr deserialize(const ros::SubscriptionCallbackHelperDeserializeParams& param) {
00338 #if DEBUG
00339 cerr << __PRETTY_FUNCTION__ << endl;
00340 cerr << "param.length = " << param.length << endl;
00341 cerr << "param.buffer = " << (param.buffer + 4) << endl;
00342 cerr << "c_header == " << param.connection_header << endl;
00343 #endif
00344 ros::VoidConstPtr ptr(new EuslispMessage(_msg));
00345 EuslispMessage *eus_msg = (EuslispMessage *)(ptr.get());
00346 eus_msg->deserialize(param.buffer, param.length);
00347
00348 return ptr;
00349 }
00350 virtual void call(ros::SubscriptionCallbackHelperCallParams& param) {
00351 EuslispMessage* eus_msg = (EuslispMessage *)((void *)param.event.getConstMessage().get());
00352 context *ctx = current_ctx;
00353 pointer argp=_args;
00354 int argc=0;
00355
00356
00357 vpush(eus_msg->_message);
00358 if ( ! ( issymbol(_scb) || piscode(_scb) || ccar(_scb)==LAMCLOSURE ) ) {
00359 ROS_ERROR("%s : can't find callback function", __PRETTY_FUNCTION__);
00360 }
00361
00362 while(argp!=NIL){ ckpush(ccar(argp)); argp=ccdr(argp); argc++;}
00363 vpush((pointer)(eus_msg->_message));argc++;
00364
00365 ufuncall(ctx,(ctx->callfp?ctx->callfp->form:NIL),_scb,(pointer)(ctx->vsp-argc),NULL,argc);
00366 while(argc-->0)vpop();
00367 vpop();
00368 }
00369 virtual const std::type_info& getTypeInfo() {
00370 return typeid(EuslispMessage);
00371 }
00372 virtual bool isConst(){
00373 return true;
00374 }
00375 virtual bool hasHeader(){
00376 return true;
00377 }
00378 };
00379
00380
00381
00382
00383 class EuslispServiceCallbackHelper : public ros::ServiceCallbackHelper {
00384 public:
00385 pointer _scb, _args;
00386 EuslispMessage _req, _res;
00387 string md5, datatype, requestDataType, responseDataType,
00388 requestMessageDefinition, responseMessageDefinition;
00389
00390 EuslispServiceCallbackHelper(pointer scb, pointer args, string smd5, string sdatatype, pointer reqclass, pointer resclass) : _args(args), _req(reqclass), _res(resclass), md5(smd5), datatype(sdatatype) {
00391 context *ctx = current_ctx;
00392 mutex_trylock(&mark_lock);
00393
00394
00395
00396 if (piscode(scb)) {
00397 _scb=scb;
00398 } else if ((ccar(scb))==LAMCLOSURE) {
00399 if ( ccar(ccdr(scb)) != NIL ) {
00400 _scb=ccar(ccdr(scb));
00401 } else {
00402 _scb=scb;
00403 }
00404 } else {
00405 ROS_ERROR("service callback function install error");
00406 }
00407
00408 pointer p=gensym(ctx);
00409 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));
00410
00411 requestDataType = _req.__getDataType();
00412 responseDataType = _res.__getDataType();
00413 requestMessageDefinition = _req.__getMessageDefinition();
00414 responseMessageDefinition = _res.__getMessageDefinition();
00415 mutex_unlock(&mark_lock);
00416 }
00417 ~EuslispServiceCallbackHelper() { }
00418
00419 virtual boost::shared_ptr<EuslispMessage> createRequest() { return boost::shared_ptr<EuslispMessage>(new EuslispMessage(_req)); }
00420 virtual boost::shared_ptr<EuslispMessage> createResponse() { return boost::shared_ptr<EuslispMessage>(new EuslispMessage(_res)); }
00421
00422 virtual std::string getMD5Sum() { return md5; }
00423 virtual std::string getDataType() { return datatype; }
00424 virtual std::string getRequestDataType() { return requestDataType; }
00425 virtual std::string getResponseDataType() { return responseDataType; }
00426 virtual std::string getRequestMessageDefinition() { return requestMessageDefinition; }
00427 virtual std::string getResponseMessageDefinition() { return responseMessageDefinition; }
00428
00429 virtual bool call(ros::ServiceCallbackHelperCallParams& params) {
00430 context *ctx = current_ctx;
00431 pointer r, argp=_args;
00432 int argc=0;
00433
00434 vpush(_res._message);
00435 vpush(_req._message);
00436
00437 if ( ! ( issymbol(_scb) || piscode(_scb) || ccar(_scb)==LAMCLOSURE ) ) {
00438 ROS_ERROR("%s : can't find callback function", __PRETTY_FUNCTION__);
00439 }
00440
00441 EuslispMessage eus_msg(_req);
00442 vpush(eus_msg._message);
00443 eus_msg.deserialize(params.request.message_start, params.request.num_bytes);
00444
00445 while(argp!=NIL){ ckpush(ccar(argp)); argp=ccdr(argp); argc++;}
00446 vpush((pointer) eus_msg._message);argc++;
00447
00448 r = ufuncall(ctx, (ctx->callfp?ctx->callfp->form:NIL),
00449 _scb, (pointer)(ctx->vsp-argc),
00450 NULL, argc);
00451 while(argc-->0)vpop();
00452 vpush(r);
00453
00454
00455 EuslispMessage eus_res(_res);
00456 eus_res.replaceContents(r);
00457 vpush(eus_res._message);
00458
00459 uint32_t serialized_length = eus_res.serializationLength();
00460 params.response.num_bytes = serialized_length + 5;
00461 params.response.buf.reset (new uint8_t[params.response.num_bytes]);
00462 params.response.message_start = 0;
00463
00464
00465 uint8_t *tmp = params.response.buf.get();
00466 *tmp++ = 1;
00467 *tmp++ = (uint8_t)((serialized_length >> 0) & 0xFF);
00468 *tmp++ = (uint8_t)((serialized_length >> 8) & 0xFF);
00469 *tmp++ = (uint8_t)((serialized_length >> 16) & 0xFF);
00470 *tmp++ = (uint8_t)((serialized_length >> 24) & 0xFF);
00471 eus_res.serialize(tmp, 0);
00472 #if DEBUG
00473 cerr << "num bytes = " << params.response.num_bytes << endl;
00474 ROS_INFO("message_start = %X",params.response.message_start);
00475 ROS_INFO("message_ptr = %X",params.response.buf.get());
00476 tmp = params.response.buf.get();
00477 for(int i=0;i<params.response.num_bytes;i++){
00478 ROS_INFO("%X", tmp[i]);
00479 }
00480 #endif
00481 vpop();
00482 vpop();
00483 vpop();
00484 vpop();
00485 vpop();
00486 return(T);
00487 }
00488 };
00489
00490 void roseusSignalHandler(int sig)
00491 {
00492
00493 context *ctx=euscontexts[thr_self()];
00494 ctx->intsig = sig;
00495 }
00496
00497
00498
00499
00500 pointer ROSEUS(register context *ctx,int n,pointer *argv)
00501 {
00502 char name[256] = "";
00503 uint32_t options = 0;
00504 int cargc = 0;
00505 char *cargv[32];
00506
00507 if( s_bInstalled ) {
00508 ROS_WARN("ROSEUS is already installed as %s", ros::this_node::getName().c_str());
00509 return (T);
00510 }
00511
00512 ckarg(3);
00513 if (isstring(argv[0]))
00514 strncpy(name,(char *)(argv[0]->c.str.chars),255);
00515 else error(E_NOSTRING);
00516 options = ckintval(argv[1]);
00517 pointer p = argv[2];
00518 if (islist(p)) {
00519 while (1) {
00520 if (!iscons(p)) break;
00521 cargv[cargc]=(char *)((ccar(p))->c.str.chars);
00522 cargc++;
00523 p=ccdr(p);
00524 }
00525 } else error(E_NOSEQ);
00526
00527 for (unsigned int i=0; i < strlen(name); i++)
00528 if ( ! isalpha(name[i]) ) name[i] = '_';
00529
00530 K_ROSEUS_MD5SUM = defkeyword(ctx,"MD5SUM-");
00531 K_ROSEUS_DATATYPE = defkeyword(ctx,"DATATYPE-");
00532 K_ROSEUS_DEFINITION = defkeyword(ctx,"DEFINITION-");
00533 K_ROSEUS_SERIALIZATION_LENGTH = defkeyword(ctx,"SERIALIZATION-LENGTH");
00534 K_ROSEUS_SERIALIZE = defkeyword(ctx,"SERIALIZE");
00535 K_ROSEUS_DESERIALIZE = defkeyword(ctx,"DESERIALIZE");
00536 K_ROSEUS_GET = defkeyword(ctx,"GET");
00537 K_ROSEUS_INIT = defkeyword(ctx,"INIT");
00538 K_ROSEUS_REQUEST = defkeyword(ctx,"REQUEST");
00539 K_ROSEUS_RESPONSE = defkeyword(ctx,"RESPONSE");
00540 K_ROSEUS_GROUPNAME = defkeyword(ctx,"GROUPNAME");
00541
00542 s_mapAdvertised.clear();
00543 s_mapSubscribed.clear();
00544 s_mapServiced.clear();
00545 s_mapHandle.clear();
00546
00547
00548
00549
00550
00551
00552 options |= ros::init_options::NoSigintHandler;
00553
00554
00555
00556
00557
00558
00559 if (!ros::master::g_uri.empty()) {
00560 if ( ros::master::g_uri != getenv("ROS_MASTER_URI") ) {
00561 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"));
00562 ros::master::g_uri.clear();
00563 }
00564 }
00565 try {
00566 ros::init(cargc, cargv, name, options);
00567 } catch (const ros::InvalidNameException &e) {
00568 ROS_ERROR("%s",e.what());
00569 error(E_MISMATCHARG);
00570 return(NIL);
00571 }
00572
00573 s_node.reset(new ros::NodeHandle());
00574 s_rate = new ros::Rate(50);
00575
00576 s_bInstalled = true;
00577
00578
00579
00580 signal(SIGINT, roseusSignalHandler);
00581 return (T);
00582 }
00583
00584 pointer ROSEUS_CREATE_NODEHANDLE(register context *ctx,int n,pointer *argv)
00585 {
00586 isInstalledCheck;
00587 string groupname;
00588 string ns;
00589
00590 ckarg2(1, 2);
00591
00592
00593
00594 if (isstring(argv[0])) groupname.assign((char *)get_string(argv[0]));
00595 else error(E_NOSTRING);
00596 if ( n > 1 ) {
00597 if(isstring(argv[1])) ns.assign((char *)get_string(argv[1]));
00598 else error(E_NOSTRING);
00599 }
00600
00601 if( s_mapHandle.find(groupname) != s_mapHandle.end() ) {
00602 ROS_DEBUG("groupname %s is already used", groupname.c_str());
00603 return (NIL);
00604 }
00605
00606 boost::shared_ptr<NodeHandle> hd;
00607 if ( n > 1 ) {
00608 hd = boost::shared_ptr<NodeHandle> (new NodeHandle(ns));
00609 s_mapHandle[groupname] = hd;
00610 } else {
00611 hd = boost::shared_ptr<NodeHandle>(new NodeHandle());
00612 s_mapHandle[groupname] = hd;
00613 }
00614
00615 hd->setCallbackQueue( new CallbackQueue() );
00616
00617 return (T);
00618 }
00619
00620 pointer ROSEUS_SPIN(register context *ctx,int n,pointer *argv)
00621 {
00622 isInstalledCheck;
00623 while (ctx->intsig==0) {
00624 ros::spinOnce();
00625 s_rate->sleep();
00626 }
00627 return (NIL);
00628 }
00629
00630 pointer ROSEUS_SPINONCE(register context *ctx,int n,pointer *argv)
00631 {
00632 isInstalledCheck;
00633 ckarg2(0, 1);
00634
00635
00636
00637 if ( n > 0 ) {
00638 string groupname;
00639 if (isstring(argv[0])) groupname.assign((char *)get_string(argv[0]));
00640 else error(E_NOSTRING);
00641
00642 map<string, boost::shared_ptr<NodeHandle > >::iterator it = s_mapHandle.find(groupname);
00643 if( it == s_mapHandle.end() ) {
00644 ROS_ERROR("Groupname %s is missing", groupname.c_str());
00645 return (T);
00646 }
00647 boost::shared_ptr<NodeHandle > hdl = (it->second);
00648
00649 ((CallbackQueue *)hdl->getCallbackQueue())->callAvailable();
00650
00651 return (NIL);
00652 } else {
00653 ros::spinOnce();
00654 return (NIL);
00655 }
00656 }
00657
00658 pointer ROSEUS_TIME_NOW(register context *ctx,int n,pointer *argv)
00659 {
00660 isInstalledCheck;
00661 pointer timevec;
00662 ros::Time t = ros::Time::now();
00663
00664 timevec=makevector(C_INTVECTOR,2);
00665 vpush(timevec);
00666 timevec->c.ivec.iv[0]=t.sec;
00667 timevec->c.ivec.iv[1]=t.nsec;
00668 vpop();
00669 return (timevec);
00670 }
00671
00672 pointer ROSEUS_RATE(register context *ctx,int n,pointer *argv)
00673 {
00674 isInstalledCheck;
00675 numunion nu;
00676 ckarg(1);
00677 float timeout=ckfltval(argv[0]);
00678 s_rate = new ros::Rate(timeout);
00679 return(T);
00680 }
00681
00682 pointer ROSEUS_SLEEP(register context *ctx,int n,pointer *argv)
00683 {
00684 isInstalledCheck;
00685 s_rate->sleep();
00686 return (T);
00687 }
00688
00689 pointer ROSEUS_OK(register context *ctx,int n,pointer *argv)
00690 {
00691 if (ros::ok()) {
00692 return (T);
00693 } else {
00694 return (NIL);
00695 }
00696 }
00697
00698
00699 #define def_rosconsole_formatter(funcname, rosfuncname) \
00700 pointer funcname(register context *ctx,int n,pointer *argv) \
00701 { pointer *argv2,msg; \
00702 int argc2; \
00703 argc2 = n+1; \
00704 argv2 = (pointer *)malloc(sizeof(pointer)*argc2); \
00705 argv2[0] = NIL; \
00706 for(int i=0;i<n;i++) argv2[i+1]=argv[i] ; \
00707 msg = XFORMAT(ctx, argc2, argv2); \
00708 rosfuncname("%s", msg->c.str.chars); \
00709 free(argv2); \
00710 return (T); \
00711 }
00712
00713 def_rosconsole_formatter(ROSEUS_ROSDEBUG, ROS_DEBUG)
00714 def_rosconsole_formatter(ROSEUS_ROSINFO, ROS_INFO)
00715 def_rosconsole_formatter(ROSEUS_ROSWARN, ROS_WARN)
00716 def_rosconsole_formatter(ROSEUS_ROSERROR, ROS_ERROR)
00717 def_rosconsole_formatter(ROSEUS_ROSFATAL, ROS_FATAL)
00718
00719 pointer ROSEUS_EXIT(register context *ctx,int n,pointer *argv)
00720 {
00721 ROS_INFO("%s", __PRETTY_FUNCTION__);
00722 if( s_bInstalled ) {
00723 ROS_INFO("exiting roseus %ld", (n==0)?n:ckintval(argv[0]));
00724 s_mapAdvertised.clear();
00725 s_mapSubscribed.clear();
00726 s_mapServiced.clear();
00727 s_mapHandle.clear();
00728 ros::shutdown();
00729 }
00730 if (n==0) _exit(0);
00731 else _exit(ckintval(argv[0]));
00732 }
00733
00734
00735
00736
00737 pointer ROSEUS_SUBSCRIBE(register context *ctx,int n,pointer *argv)
00738 {
00739 isInstalledCheck;
00740 string topicname;
00741 pointer message, fncallback, args;
00742 int queuesize = 1;
00743 NodeHandle *lnode = s_node.get();
00744
00745
00746
00747 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00748 else error(E_NOSTRING);
00749
00750 if (n > 1 && issymbol(argv[n-2]) && isstring(argv[n-1])) {
00751 if (argv[n-2] == K_ROSEUS_GROUPNAME) {
00752 string groupname;
00753 groupname.assign((char *)get_string(argv[n-1]));
00754 map<string, boost::shared_ptr<NodeHandle > >::iterator it = s_mapHandle.find(groupname);
00755 if( it != s_mapHandle.end() ) {
00756 ROS_DEBUG("subscribe with groupname=%s", groupname.c_str());
00757 lnode = (it->second).get();
00758 } else {
00759 ROS_ERROR("Groupname %s is missing. Topic %s is not subscribed. Call (ros::create-nodehandle \"%s\") first.",
00760 groupname.c_str(), topicname.c_str(), groupname.c_str());
00761 return (NIL);
00762 }
00763 n -= 2;
00764 }
00765 }
00766 if (isint(argv[n-1])) {queuesize = ckintval(argv[n-1]);n--;}
00767 ROS_DEBUG("subscribe %s queuesize=%d", topicname.c_str(), queuesize);
00768
00769 message = argv[1];
00770 fncallback = argv[2];
00771 args=NIL;
00772 for (int i=n-1;i>=3;i--) args=cons(ctx,argv[i],args);
00773
00774 EuslispMessage msg(message);
00775 boost::shared_ptr<SubscriptionCallbackHelper> *callback =
00776 (new boost::shared_ptr<SubscriptionCallbackHelper>
00777 (new EuslispSubscriptionCallbackHelper(fncallback, args, message)));
00778 SubscribeOptions so(topicname, queuesize, msg.__getMD5Sum(), msg.__getDataType());
00779 so.helper = *callback;
00780 Subscriber subscriber = lnode->subscribe(so);
00781 boost::shared_ptr<Subscriber> sub = boost::shared_ptr<Subscriber>(new Subscriber(subscriber));
00782 if ( !!sub ) {
00783 s_mapSubscribed[topicname] = sub;
00784 } else {
00785 ROS_ERROR("s_mapSubscribed");
00786 }
00787
00788 return (T);
00789 }
00790
00791 pointer ROSEUS_UNSUBSCRIBE(register context *ctx,int n,pointer *argv)
00792 {
00793 string topicname;
00794
00795 ckarg(1);
00796 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00797 else error(E_NOSTRING);
00798
00799 bool bSuccess = s_mapSubscribed.erase(topicname)>0;
00800
00801 return (bSuccess?T:NIL);
00802 }
00803
00804 pointer ROSEUS_GETNUMPUBLISHERS(register context *ctx,int n,pointer *argv)
00805 {
00806 string topicname;
00807 int ret;
00808
00809 ckarg(1);
00810 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00811 else error(E_NOSTRING);
00812
00813 bool bSuccess = false;
00814 map<string, boost::shared_ptr<Subscriber> >::iterator it = s_mapSubscribed.find(topicname);
00815 if( it != s_mapSubscribed.end() ) {
00816 boost::shared_ptr<Subscriber> subscriber = (it->second);
00817 ret = subscriber->getNumPublishers();
00818 bSuccess = true;
00819 }
00820
00821 if ( ! bSuccess ) {
00822 ROS_ERROR("attempted to getNumPublishers to topic %s, which was not " \
00823 "previously subscribed. call (ros::subscribe \"%s\") first.",
00824 topicname.c_str(), topicname.c_str());
00825 }
00826
00827 return (bSuccess?(makeint(ret)):NIL);
00828 }
00829
00830 pointer ROSEUS_GETTOPICSUBSCRIBER(register context *ctx,int n,pointer *argv)
00831 {
00832 string topicname;
00833 string ret;
00834
00835 ckarg(1);
00836 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00837 else error(E_NOSTRING);
00838
00839 bool bSuccess = false;
00840 map<string, boost::shared_ptr<Subscriber> >::iterator it = s_mapSubscribed.find(topicname);
00841 if( it != s_mapSubscribed.end() ) {
00842 boost::shared_ptr<Subscriber> subscriber = (it->second);
00843 ret = subscriber->getTopic();
00844 bSuccess = true;
00845 }
00846
00847 if ( ! bSuccess ) {
00848 ROS_ERROR("attempted to getTopic to topic %s, which was not " \
00849 "previously advertised. call (ros::advertise \"%s\") first.",
00850 topicname.c_str(), topicname.c_str());
00851 }
00852
00853 return (bSuccess?(makestring((char *)ret.c_str(), ret.length())):NIL);
00854 }
00855
00856 pointer ROSEUS_ADVERTISE(register context *ctx,int n,pointer *argv)
00857 {
00858 isInstalledCheck;
00859 string topicname;
00860 pointer message;
00861 int queuesize = 1;
00862 bool latch = false;
00863
00864 ckarg2(2,4);
00865 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00866 else error(E_NOSTRING);
00867 message = argv[1];
00868 if ( n > 2 ) {
00869 queuesize = ckintval(argv[2]);
00870 }
00871 if ( n > 3 ) {
00872 latch = (argv[3]!=NIL ? true : false);
00873 }
00874 ROS_DEBUG("advertise %s %d %d", topicname.c_str(), queuesize, latch);
00875 if( s_mapAdvertised.find(topicname) != s_mapAdvertised.end() ) {
00876 ROS_WARN("topic %s already advertised", topicname.c_str());
00877 return (NIL);
00878 }
00879
00880 EuslispMessage msg(message);
00881 AdvertiseOptions ao(topicname, queuesize, msg.__getMD5Sum(), msg.__getDataType(), msg.__getMessageDefinition());
00882 ao.latch = latch;
00883 Publisher publisher = s_node->advertise(ao);
00884 boost::shared_ptr<Publisher> pub = boost::shared_ptr<Publisher>(new Publisher(publisher));
00885 if ( !!pub ) {
00886 s_mapAdvertised[topicname] = pub;
00887 } else {
00888 ROS_ERROR("s_mapAdvertised");
00889 }
00890
00891 return (T);
00892 }
00893
00894 pointer ROSEUS_UNADVERTISE(register context *ctx,int n,pointer *argv)
00895 {
00896 string topicname;
00897
00898 ckarg(1);
00899 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00900 else error(E_NOSTRING);
00901
00902 bool bSuccess = s_mapAdvertised.erase(topicname)>0;
00903
00904 return (bSuccess?T:NIL);
00905 }
00906
00907 pointer ROSEUS_PUBLISH(register context *ctx,int n,pointer *argv)
00908 {
00909 isInstalledCheck;
00910 string topicname;
00911 pointer emessage;
00912
00913 ckarg(2);
00914 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00915 else error(E_NOSTRING);
00916 emessage = argv[1];
00917
00918 bool bSuccess = false;
00919 map<string, boost::shared_ptr<Publisher> >::iterator it = s_mapAdvertised.find(topicname);
00920 if( it != s_mapAdvertised.end() ) {
00921 boost::shared_ptr<Publisher> publisher = (it->second);
00922 EuslispMessage message(emessage);
00923 publisher->publish(message);
00924 bSuccess = true;
00925 }
00926
00927 if ( ! bSuccess ) {
00928 ROS_ERROR("attempted to publish to topic %s, which was not " \
00929 "previously advertised. call (ros::advertise \"%s\") first.",
00930 topicname.c_str(), topicname.c_str());
00931 }
00932
00933 return (T);
00934 }
00935
00936 pointer ROSEUS_GETNUMSUBSCRIBERS(register context *ctx,int n,pointer *argv)
00937 {
00938 string topicname;
00939 int ret;
00940
00941 ckarg(1);
00942 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00943 else error(E_NOSTRING);
00944
00945 bool bSuccess = false;
00946 map<string, boost::shared_ptr<Publisher> >::iterator it = s_mapAdvertised.find(topicname);
00947 if( it != s_mapAdvertised.end() ) {
00948 boost::shared_ptr<Publisher> publisher = (it->second);
00949 ret = publisher->getNumSubscribers();
00950 bSuccess = true;
00951 }
00952
00953 if ( ! bSuccess ) {
00954 ROS_ERROR("attempted to getNumSubscribers to topic %s, which was not " \
00955 "previously advertised. call (ros::advertise \"%s\") first.",
00956 topicname.c_str(), topicname.c_str());
00957 }
00958
00959 return (bSuccess?(makeint(ret)):NIL);
00960 }
00961
00962 pointer ROSEUS_GETTOPICPUBLISHER(register context *ctx,int n,pointer *argv)
00963 {
00964 string topicname;
00965 string ret;
00966
00967 ckarg(1);
00968 if (isstring(argv[0])) topicname.assign((char *)get_string(argv[0]));
00969 else error(E_NOSTRING);
00970
00971 bool bSuccess = false;
00972 map<string, boost::shared_ptr<Publisher> >::iterator it = s_mapAdvertised.find(topicname);
00973 if( it != s_mapAdvertised.end() ) {
00974 boost::shared_ptr<Publisher> publisher = (it->second);
00975 ret = publisher->getTopic();
00976 bSuccess = true;
00977 }
00978
00979 if ( ! bSuccess ) {
00980 ROS_ERROR("attempted to getTopic to topic %s, which was not " \
00981 "previously advertised. call (ros::advertise \"%s\") first.",
00982 topicname.c_str(), topicname.c_str());
00983 }
00984
00985 return (bSuccess?(makestring((char *)ret.c_str(), ret.length())):NIL);
00986 }
00987
00988
00989
00990
00991 pointer ROSEUS_WAIT_FOR_SERVICE(register context *ctx,int n,pointer *argv)
00992 {
00993 isInstalledCheck;
00994 string service;
00995
00996 ckarg2(1,2);
00997 if (isstring(argv[0])) service.assign((char *)(argv[0]->c.str.chars));
00998 else error(E_NOSTRING);
00999
01000 int32_t timeout = -1;
01001
01002 if( n > 1 )
01003 timeout = (int32_t)ckintval(argv[1]);
01004
01005 bool bSuccess = service::waitForService(ros::names::resolve(service), ros::Duration(timeout));
01006
01007 return (bSuccess?T:NIL);
01008 }
01009
01010 pointer ROSEUS_SERVICE_EXISTS(register context *ctx,int n,pointer *argv)
01011 {
01012 isInstalledCheck;
01013 string service;
01014
01015 ckarg(1);
01016 if (isstring(argv[0])) service.assign((char *)(argv[0]->c.str.chars));
01017 else error(E_NOSTRING);
01018
01019 bool bSuccess = service::exists(ros::names::resolve(service), true);
01020
01021 return (bSuccess?T:NIL);
01022 }
01023
01024 pointer ROSEUS_SERVICE_CALL(register context *ctx,int n,pointer *argv)
01025 {
01026 isInstalledCheck;
01027 string service;
01028 pointer emessage;
01029 bool persist = false;
01030 ckarg2(2,3);
01031 if (isstring(argv[0])) service.assign((char *)(argv[0]->c.str.chars));
01032 else error(E_NOSTRING);
01033 emessage = argv[1];
01034 if ( n > 2 ) {
01035 persist = (argv[2] != NIL ? true : false);
01036 }
01037 static std::map<std::string, ros::ServiceClient> service_cache;
01038 std::string service_name = ros::names::resolve(service);
01039 ServiceClient client;
01040 EuslispMessage request(emessage);
01041 vpush(request._message);
01042 EuslispMessage response(csend(ctx,emessage,K_ROSEUS_RESPONSE,0));
01043 vpush(response._message);
01044 if (persist == false) {
01045 ServiceClientOptions sco(service_name, request.__getMD5Sum(), false, M_string());
01046 client = s_node->serviceClient(sco);
01047 }
01048 else {
01049
01050
01051 if (service_cache.find(service_name) != service_cache.end()) {
01052 client = service_cache[service_name];
01053 }
01054 else {
01055 ServiceClientOptions sco(service_name, request.__getMD5Sum(), true, M_string());
01056 client = s_node->serviceClient(sco);
01057 service_cache[service_name] = client;
01058 }
01059 }
01060
01061 bool bSuccess = client.call(request, response, request.__getMD5Sum());
01062 vpop();
01063 vpop();
01064 if ( ! bSuccess ) {
01065 ROS_ERROR("attempted to call service %s, but failed ",
01066 ros::names::resolve(service).c_str());
01067 if (persist) {
01068
01069 service_cache.erase(service_cache.find(service_name));
01070 }
01071 }
01072
01073 return (response._message);
01074 }
01075
01076 pointer ROSEUS_ADVERTISE_SERVICE(register context *ctx,int n,pointer *argv)
01077 {
01078 isInstalledCheck;
01079 string service;
01080 pointer emessage;
01081 pointer fncallback, args;
01082
01083 if (isstring(argv[0])) service.assign((char *)get_string(argv[0]));
01084 else error(E_NOSTRING);
01085 emessage = argv[1];
01086 fncallback = argv[2];
01087 args=NIL;
01088 for (int i=n-1;i>=3;i--) args=cons(ctx,argv[i],args);
01089 if( s_mapServiced.find(service) != s_mapServiced.end() ) {
01090 ROS_INFO("service %s already advertised", service.c_str());
01091 return (NIL);
01092 }
01093
01094 EuslispMessage message(emessage);
01095 vpush(message._message);
01096 pointer request(csend(ctx,emessage,K_ROSEUS_GET,1,K_ROSEUS_REQUEST));
01097 pointer response(csend(ctx,emessage,K_ROSEUS_GET,1,K_ROSEUS_RESPONSE));
01098 vpop();
01099 boost::shared_ptr<EuslispServiceCallbackHelper> *callback =
01100 (new boost::shared_ptr<EuslispServiceCallbackHelper>
01101 (new EuslispServiceCallbackHelper(fncallback, args, message.__getMD5Sum(),
01102 message.__getDataType(), request, response)));
01103 AdvertiseServiceOptions aso;
01104 aso.service.assign(service);
01105 aso.datatype = (*callback->get()).getDataType();
01106 aso.md5sum = (*callback->get()).getMD5Sum();
01107 aso.req_datatype = (*callback->get()).getRequestDataType();
01108 aso.res_datatype = (*callback->get()).getResponseDataType();
01109 aso.helper = *callback;
01110 ServiceServer server = s_node->advertiseService(aso);
01111 boost::shared_ptr<ServiceServer> ser = boost::shared_ptr<ServiceServer>(new ServiceServer(server));
01112 if ( !!ser ) {
01113 s_mapServiced[service] = ser;
01114 } else {
01115 ROS_ERROR("s_mapServiced");
01116 }
01117
01118 return (T);
01119 }
01120
01121 pointer ROSEUS_UNADVERTISE_SERVICE(register context *ctx,int n,pointer *argv)
01122 {
01123 string service;
01124
01125 ckarg(1);
01126 if (isstring(argv[0])) service.assign((char *)get_string(argv[0]));
01127 else error(E_NOSTRING);
01128
01129 ROS_DEBUG("unadvertise %s", service.c_str());
01130 bool bSuccess = s_mapServiced.erase(service)>0;
01131
01132 return (bSuccess?T:NIL);
01133 }
01134
01135 pointer ROSEUS_SET_PARAM(register context *ctx,int n,pointer *argv)
01136 {
01137 numunion nu;
01138 string key;
01139 string s;
01140 double d;
01141 int i;
01142
01143 ckarg(2);
01144 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01145 else error(E_NOSTRING);
01146 if ( isstring(argv[1]) ) {
01147 s.assign((char *)get_string(argv[1]));
01148 ros::param::set(key,s);
01149 } else if (isint(argv[1])) {
01150 i = intval(argv[1]);
01151 ros::param::set(key,i);
01152 } else if (isflt(argv[1])) {
01153 d = fltval(argv[1]);
01154 ros::param::set(key,d);
01155 } else if (argv[1] == T) {
01156 bool b = true;
01157 ros::param::set(key, b);
01158 } else if (argv[1] == NIL) {
01159 bool b = false;
01160 ros::param::set(key, b);
01161 } else {
01162 error(E_MISMATCHARG);
01163 }
01164 return (T);
01165 }
01166
01167 pointer XmlRpcToEusList(register context *ctx, XmlRpc::XmlRpcValue param_list)
01168 {
01169 numunion nu;
01170 pointer ret, first;
01171 ret = cons(ctx, NIL, NIL);
01172 first = ret;
01173 vpush(ret);
01174 if ( param_list.getType() == XmlRpc::XmlRpcValue::TypeArray ){
01175 for ( int i = 0; i < param_list.size(); i++){
01176 if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeBoolean ){
01177 if ( param_list[i] ){
01178 ccdr(ret) = cons(ctx, T, NIL);
01179 ret = ccdr(ret);
01180 } else {
01181 ccdr(ret) = cons(ctx, NIL, NIL);
01182 ret = ccdr(ret);
01183 }
01184 }
01185 else if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeDouble ){
01186 ccdr(ret) = cons(ctx, makeflt((double)param_list[i]), NIL);
01187 ret = ccdr(ret);
01188 }
01189 else if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeInt ){
01190 ccdr(ret) = cons(ctx, makeint((int)param_list[i]), NIL);
01191 ret = ccdr(ret);
01192 }
01193 else if ( param_list[i].getType() == XmlRpc::XmlRpcValue::TypeString ){
01194 std::string str = param_list[i];
01195 ccdr(ret) = cons(ctx, makestring((char*)str.c_str(), ((std::string)param_list[i]).length()), NIL);
01196 ret = ccdr(ret);
01197 }
01198 else {
01199 ROS_FATAL("unkown rosparam type!");
01200 vpop();
01201 return NIL;
01202 }
01203 }
01204 vpop();
01205 return ccdr(first);
01206 } else
01207 return (NIL);
01208 }
01209
01210 pointer ROSEUS_GET_PARAM(register context *ctx,int n,pointer *argv)
01211 {
01212 numunion nu;
01213 string key;
01214
01215 ckarg2(1,2);
01216 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01217 else error(E_NOSTRING);
01218
01219 string s;
01220 double d;
01221 bool b;
01222 int i;
01223 pointer ret;
01224 XmlRpc::XmlRpcValue param_list;
01225
01226 if ( ros::param::get(key, s) ) {
01227 ret = makestring((char *)s.c_str(), s.length());
01228 } else if ( ros::param::get(key, d) ) {
01229 ret = makeflt(d);
01230 } else if ( ros::param::get(key, i) ) {
01231 ret = makeint(i);
01232 } else if ( ros::param::get(key, b) ) {
01233 if ( b == true )
01234 ret = T;
01235 else
01236 ret = NIL;
01237 } else if (ros::param::get(key, param_list)){
01238 ret = XmlRpcToEusList(ctx, param_list);
01239 }else {
01240 if ( n == 2 ) {
01241 ret = copyobj(ctx,argv[1]);
01242 } else {
01243 ROS_ERROR("unknown ros::param::get, key=%s", key.c_str());
01244 ret = NIL;
01245 }
01246 }
01247 return (ret);
01248 }
01249
01250 pointer ROSEUS_GET_PARAM_CASHED(register context *ctx,int n,pointer *argv)
01251 {
01252 numunion nu;
01253 string key;
01254
01255 ckarg2(1,2);
01256 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01257 else error(E_NOSTRING);
01258
01259 string s;
01260 double d;
01261 int i;
01262 bool b;
01263 pointer ret;
01264 XmlRpc::XmlRpcValue param_list;
01265 if ( ros::param::getCached(key, s) ) {
01266 ret = makestring((char *)s.c_str(), s.length());
01267 } else if ( ros::param::getCached(key, d) ) {
01268 ret = makeflt(d);
01269 } else if ( ros::param::getCached(key, i) ) {
01270 ret = makeint(i);
01271 } else if ( ros::param::getCached(key, b) ) {
01272 if ( b == true )
01273 ret = T;
01274 else
01275 ret = NIL;
01276 } else if (ros::param::getCached(key, param_list)){
01277 ret = XmlRpcToEusList(ctx, param_list);
01278 } else {
01279 if ( n == 2 ) {
01280 ret = copyobj(ctx,argv[1]);
01281 } else {
01282 ROS_ERROR("unknown ros::param::get, key=%s", key.c_str());
01283 ret = NIL;
01284 }
01285 }
01286 return (ret);
01287 }
01288
01289 pointer ROSEUS_HAS_PARAM(register context *ctx,int n,pointer *argv)
01290 {
01291 string key;
01292
01293 ckarg(1);
01294 if (isstring(argv[0])) key.assign((char *)get_string(argv[0]));
01295 else error(E_NOSTRING);
01296
01297 return((ros::param::has(key))?(T):(NIL));
01298 }
01299
01300 pointer ROSEUS_ROSPACK_FIND(register context *ctx,int n,pointer *argv)
01301 {
01302 ckarg(1);
01303
01304 string pkg;
01305 if (isstring(argv[0])) pkg.assign((char *)get_string(argv[0]));
01306 else error(E_NOSTRING);
01307
01308 try {
01309 #ifdef ROSPACK_EXPORT
01310 rospack::ROSPack rp;
01311 rospack::Package *p = rp.get_pkg(pkg);
01312 if (p!=NULL) return(makestring((char *)p->path.c_str(),p->path.length()));
01313 #else
01314 rospack::Rospack rp;
01315 std::vector<std::string> search_path;
01316 rp.getSearchPathFromEnv(search_path);
01317 rp.crawl(search_path, 1);
01318 std::string path;
01319 if (rp.find(pkg,path)==true) return(makestring((char *)path.c_str(),path.length()));
01320 #endif
01321 } catch (runtime_error &e) {
01322 }
01323 return(NIL);
01324 }
01325
01326 pointer ROSEUS_RESOLVE_NAME(register context *ctx,int n,pointer *argv)
01327 {
01328 ckarg(1);
01329 if (!isstring(argv[0])) error(E_NOSTRING);
01330 std::string src;
01331 src.assign((char *)(argv[0]->c.str.chars));
01332 std::string dst = ros::names::resolve(src);
01333 return(makestring((char *)dst.c_str(), dst.length()));
01334 }
01335
01336 pointer ROSEUS_GETNAME(register context *ctx,int n,pointer *argv)
01337 {
01338 ckarg(0);
01339 return(makestring((char *)ros::this_node::getName().c_str(),
01340 ros::this_node::getName().length()));
01341 }
01342
01343 pointer ROSEUS_GETNAMESPACE(register context *ctx,int n,pointer *argv)
01344 {
01345 ckarg(0);
01346 return(makestring((char *)ros::this_node::getNamespace().c_str(),
01347 ros::this_node::getNamespace().length()));
01348 }
01349
01350
01351
01352
01353
01354 pointer ___roseus(register context *ctx, int n, pointer *argv, pointer env)
01355 {
01356 pointer rospkg,p=Spevalof(PACKAGE);
01357 rospkg=findpkg(makestring("ROS",3));
01358 if (rospkg == 0) rospkg=makepkg(ctx,makestring("ROS", 3),NIL,NIL);
01359 Spevalof(PACKAGE)=rospkg;
01360
01361 QANON=defvar(ctx,"*ANONYMOUS-NAME*",makeint(ros::init_options::AnonymousName),rospkg);
01362 QNOOUT=defvar(ctx,"*NO-ROSOUT*",makeint(ros::init_options::NoRosout),rospkg);
01363 defun(ctx,"SPIN",argv[0],(pointer (*)())ROSEUS_SPIN);
01364 defun(ctx,"SPIN-ONCE",argv[0],(pointer (*)())ROSEUS_SPINONCE);
01365 defun(ctx,"TIME-NOW-RAW",argv[0],(pointer (*)())ROSEUS_TIME_NOW);
01366 defun(ctx,"RATE",argv[0],(pointer (*)())ROSEUS_RATE);
01367 defun(ctx,"SLEEP",argv[0],(pointer (*)())ROSEUS_SLEEP);
01368 defun(ctx,"OK",argv[0],(pointer (*)())ROSEUS_OK);
01369
01370 defun(ctx,"ROS-DEBUG",argv[0],(pointer (*)())ROSEUS_ROSDEBUG);
01371 defun(ctx,"ROS-INFO",argv[0],(pointer (*)())ROSEUS_ROSINFO);
01372 defun(ctx,"ROS-WARN",argv[0],(pointer (*)())ROSEUS_ROSWARN);
01373 defun(ctx,"ROS-ERROR",argv[0],(pointer (*)())ROSEUS_ROSERROR);
01374 defun(ctx,"ROS-FATAL",argv[0],(pointer (*)())ROSEUS_ROSFATAL);
01375 defun(ctx,"EXIT",argv[0],(pointer (*)())ROSEUS_EXIT);
01376
01377 defun(ctx,"SUBSCRIBE",argv[0],(pointer (*)())ROSEUS_SUBSCRIBE);
01378 defun(ctx,"UNSUBSCRIBE",argv[0],(pointer (*)())ROSEUS_UNSUBSCRIBE);
01379 defun(ctx,"GET-NUM-PUBLISHERS",argv[0],(pointer (*)())ROSEUS_GETNUMPUBLISHERS);
01380 defun(ctx,"GET-TOPIC-SUBSCRIBER",argv[0],(pointer (*)())ROSEUS_GETTOPICSUBSCRIBER);
01381
01382 defun(ctx,"ADVERTISE",argv[0],(pointer (*)())ROSEUS_ADVERTISE);
01383 defun(ctx,"UNADVERTISE",argv[0],(pointer (*)())ROSEUS_UNADVERTISE);
01384 defun(ctx,"PUBLISH",argv[0],(pointer (*)())ROSEUS_PUBLISH);
01385 defun(ctx,"GET-NUM-SUBSCRIBERS",argv[0],(pointer (*)())ROSEUS_GETNUMSUBSCRIBERS);
01386 defun(ctx,"GET-TOPIC-PUBLISHER",argv[0],(pointer (*)())ROSEUS_GETTOPICPUBLISHER);
01387
01388 defun(ctx,"WAIT-FOR-SERVICE",argv[0],(pointer (*)())ROSEUS_WAIT_FOR_SERVICE);
01389 defun(ctx,"SERVICE-EXISTS", argv[0], (pointer (*)())ROSEUS_SERVICE_EXISTS);
01390 defun(ctx,"SERVICE-CALL",argv[0],(pointer (*)())ROSEUS_SERVICE_CALL);
01391 defun(ctx,"ADVERTISE-SERVICE",argv[0],(pointer (*)())ROSEUS_ADVERTISE_SERVICE);
01392 defun(ctx,"UNADVERTISE-SERVICE",argv[0],(pointer (*)())ROSEUS_UNADVERTISE_SERVICE);
01393
01394 defun(ctx,"SET-PARAM",argv[0],(pointer (*)())ROSEUS_SET_PARAM);
01395 defun(ctx,"GET-PARAM",argv[0],(pointer (*)())ROSEUS_GET_PARAM);
01396 defun(ctx,"GET-PARAM-CASHED",argv[0],(pointer (*)())ROSEUS_GET_PARAM_CASHED);
01397 defun(ctx,"HAS-PARAM",argv[0],(pointer (*)())ROSEUS_HAS_PARAM);
01398
01399 defun(ctx,"ROSPACK-FIND",argv[0],(pointer (*)())ROSEUS_ROSPACK_FIND);
01400 defun(ctx,"RESOLVE-NAME",argv[0],(pointer (*)())ROSEUS_RESOLVE_NAME);
01401 defun(ctx,"GET-NAME",argv[0],(pointer (*)())ROSEUS_GETNAME);
01402 defun(ctx,"GET-NAMESPACE",argv[0],(pointer (*)())ROSEUS_GETNAMESPACE);
01403
01404 defun(ctx,"ROSEUS-RAW",argv[0],(pointer (*)())ROSEUS);
01405 defun(ctx,"CREATE-NODEHANDLE", argv[0], (pointer (*)())ROSEUS_CREATE_NODEHANDLE);
01406
01407 pointer_update(Spevalof(PACKAGE),p);
01408
01409 pointer l;
01410 l=makestring(REPOVERSION,strlen(REPOVERSION));
01411 vpush(l);
01412 l=stacknlist(ctx,1);
01413 QREPOVERSION=defvar(ctx, "ROSEUS-REPO-VERSION", l, rospkg);
01414
01415 M_string remappings;
01416 pointer argp = speval(intern(ctx,"*EUSTOP-ARGUMENT*", strlen("*EUSTOP-ARGUMENT*"),lisppkg));
01417 while(argp!=NIL) {
01418 std::string arg = string((char *)(ccar(argp)->c.str.chars));
01419
01420 size_t pos = arg.find(":=");
01421 if (pos != std::string::npos) {
01422 std::string local_name = arg.substr(0, pos);
01423 std::string external_name = arg.substr(pos + 2);
01424 remappings[local_name] = external_name;
01425 }
01426 argp=ccdr(argp);
01427 }
01428 ros::master::init(remappings);
01429
01430
01431 return 0;
01432 }
01433