Lisp client library for ROS, the Robot Operating System.
roslisp is a library for writing ROS nodes in ANSI Common Lisp. See the tutorial at for how to set up roslisp for standalone compilation of lisp source files and/or interactive use. This page lists the functions available in the client library and other miscellaneous information. Detailed documentation about the functions is available within the Lisp environment using the documentation feature.
Roslisp is integrated with the asdf build system. When using roslisp nodes from within a lisp environment, add the following lines to your .sbclrc:
(push #P"/path/to/roslisp/asdf/" asdf:*central-registry*) (asdf:operate 'asdf:load-op :ros-load-manifest)
This extends asdf to use two additional rospack-based search methods to finding .asd files.
You can also build standalone nodes in the CMakeLists.txt file. For example, roslisp_examples/CMakeLists.txt contains
rospack_add_lisp_executable(bin/talker roslisp-examples roslisp-talker:main)
This produces the executable roslisp_examples/bin/talker when built. When run from the command line, the executable does not load your standard .sbclrc init file. Rather, it loads ~/.sbclrc-roslisp (if it exists). It then sets current-ros-package to roslisp_examples, and loads the asdf system roslisp-examples into memory (using rospack). Next, it loads the files bin/roslisp-init.lisp and bin/roslisp-talker:main.init.lisp (if they exist). These are the places where you can put global, package-specific, and node-specific runtime customizations (customizing debug levels, setting optimization flags, modifying constants) respectively. Finally, it calls the function roslisp-talker:main. Also, when running standalone, the keyword :roslisp-standalone-executable is pushed on to the features list, in case you want to make use of this information in some way. Finally, setting the ROSLISP_BACKTRACE_ON_ERRORS environment variable before running the node will print debugging info if it dies.
The current trunk version of the rosemacs package contains a slime contrib that adds a slime repl shortcut to load systems in ros packages. Please see the rosemacs documentation for more information.
Roslisp provides a hierarchical, customizable-at-runtime, logging scheme, similar to rosconsole for roscpp. Debug topics are lists, e.g. (roslisp top). For such a topic, the debug level of (roslisp top) would be looked up. If this is not present (roslisp) is looked up. If this is not present, () is looked up (and this is always present in the topic list). The level at runtime then determines whether the message is evaluated and outputted (to stdout and rosout).
To set debug levels, from within Lisp use set-debug-levels. To produce debugging output, use ros-{debug|info|warn|error|fatal}. Additionally, debug levels correspond to ros parameters, e.g., topic (foo bar) corresponds to the private parameter ~debug/foo/bar/level. Upon node initialization, these are read from the parameter server, and must be one of the five strings debug, info, warn, error, or fatal. If they are changed after node startup, call the node's ~reset-debug-levels service to update. A more permanent way to update debug levels is to call set-debug-levels in an initialization file.
Roslisp itself uses debugging levels starting with :roslisp, with subtopics such as :top, :tcp, and :rosout. For example, if debugging roslisp_examples/bin/talker, add the following line to roslisp_examples/bin/roslisp-init.lisp:
(roslisp:set-debug-levels roslisp :debug)
To reduce the number of connection-related debugging messages, also add the line
(roslisp:set-debug-levels (roslisp tcp) :info)
The functions in the client API below belong to the Lisp package (namespace) named :roslisp, with the exception of the constructors and field accessors for ROS message data types, which belong to a Lisp package with the same name as the message's ROS package concatenated with "-msg" (and likewise for services, with the suffix "-srv").
Names (of topics, services, and parameters) are handled according to standard ROS conventions. Command-line arguments to the executable, of the form foo:=bar, where foo does not begin with '_', are known as command line remappings. Given such a remapping, any topic, parameter, or service referred to as foo in the node's code would then be replaced by bar. The node name is given by the argument to start-ros-node or with-ros-node. It can, however, be overridden by including a command-line argument of the form __name=foo. The namespace is set as follows: if there is a command-line argument __ns:=foo, the namespace is foo. If not, and if the environment variable ROS_NAMESPACE is set to bar, the namespace is bar. If not, the namespace is /. All commands below that take a name of a topic, service, or parameter can be given an absolute (/foo/bar/baz), relative (baz/qux), or private (~qux) name.
See documentation for functions start-ros-node, shutdown-ros-node, and with-ros-node.
See functions advertise, subscribe, publish, publish-msg.
See functions call-service, def-service-callback, register-service, register-service-fn, wait-for-service, make-request.
See functions get-param, set-param, has-param, delete-param.
See function node-status.
See make-uri, fully-qualified-name, loop-at-most-every, ros-time,
Each ROS message type has a corresponding Lisp class and operations on it. A message type foo in ROS package bar corresponds to a Lisp class named <foo> in the bar-msg Lisp package. If your code will create or operate on objects of this type, it should contain the form (roslisp:load-message-types "bar/foo"). Operations in the message's package:
However, it is recommended that you use the list operations below such as with-fields, unless this is slowing your code down.
The roslisp Lisp package contains some additional generic operations that work on any message:
There are a few additional operations that use the list representation of ros messages, and are therefore less efficient, but more readable and convenient for interactive use. See with-fields, make-message, modify-message-copy, and setf-msg.
IMPORTANT: message objects are assumed to be immutable; this assumption may be used in future to cache various things. In other words, if m is a variable that refers to some message object, don't do something like (setf (slot-value m 'my-field) 42). Instead, in this situation, do something like (setf-msg m 'my-field 42) (of course, it's always legal to do something like (setq m (function-that-returns-new-message-object)) since that just changes what m refers to rather than modifying the pointed-to object). When constructing messages, either use the form (make-instance '<Foo> :field1 42 :field24) or (make-msg "my_package/Foo" :field1 42 :field2 24). Don't use the C++-inspired way of first creating the object then setting its fields.
Given a ROS service type qux in the bar ROS package, there are corresponding message types <qux-request> and <qux-response> in the bar-srv Lisp package. The request and response messages can be operated on like any other message.