├── .gitignore ├── AUTHORS ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README ├── doc ├── index.html ├── luadoc.css └── modules │ ├── roslua.html │ ├── roslua.logging.html │ ├── roslua.logging.rosout.html │ ├── roslua.logging.stdout.html │ ├── roslua.master_proxy.html │ ├── roslua.message.html │ ├── roslua.msg_spec.html │ ├── roslua.param_proxy.html │ ├── roslua.publisher.html │ ├── roslua.registry.html │ ├── roslua.service.html │ ├── roslua.service_client.html │ ├── roslua.slave_api.html │ ├── roslua.slave_proxy.html │ ├── roslua.srv_spec.html │ ├── roslua.subscriber.html │ ├── roslua.tcpros.html │ ├── roslua.time.html │ ├── roslua.timer.html │ └── roslua.utils.html ├── etc └── luadoc │ ├── file.lp │ ├── function.lp │ ├── index.lp │ ├── luadoc.css │ ├── menu.lp │ ├── module.lp │ └── table.lp ├── mainpage.dox ├── manifest.xml ├── rosdep.yaml └── src ├── examples ├── publisher.lua ├── service_client.lua ├── service_client_concexec.lua ├── service_provider.lua ├── subscriber.lua └── timer.lua ├── lua_modules ├── lposix.c ├── lsignal.c ├── modemuncher.c └── struct.c ├── roslua ├── init.lua ├── logging.lua ├── logging │ ├── rosout.lua │ └── stdout.lua ├── master_proxy.lua ├── message.lua ├── msg_spec.lua ├── names.lua ├── param_proxy.lua ├── publisher.lua ├── registry.lua ├── service.lua ├── service_client.lua ├── slave_api.lua ├── slave_proxy.lua ├── srv_spec.lua ├── subscriber.lua ├── tcpros.lua ├── time.lua ├── timer.lua ├── utils.lua └── xmlrpc_post.lua └── test ├── logtest.lua ├── masterquery.lua ├── msgstest.lua ├── publishertest.lua ├── serializetest.lua ├── serviceclienttest.lua ├── serviceprovidertest.lua ├── srvtest.lua ├── subscribertest.lua ├── talkertest.lua └── timetest.lua /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.luaso 3 | /build/ 4 | /ROS_NOBUILD 5 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Tim Niemueller 2 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.4.6) 2 | include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) 3 | 4 | # Set the build type. Options are: 5 | # Coverage : w/ debug symbols, w/o optimization, w/ code-coverage 6 | # Debug : w/ debug symbols, w/o optimization 7 | # Release : w/o debug symbols, w/ optimization 8 | # RelWithDebInfo : w/ debug symbols, w/ optimization 9 | # MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries 10 | #set(ROS_BUILD_TYPE RelWithDebInfo) 11 | 12 | rosbuild_init() 13 | 14 | #set the default path for built executables to the "bin" directory 15 | set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) 16 | #set the default path for built libraries to the "lib" directory 17 | set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) 18 | 19 | # We give Lua libraries a special suffix, otherwise some ROS tools written 20 | # in Python crash 21 | set(CMAKE_SHARED_LIBRARY_PREFIX "") 22 | set(CMAKE_SHARED_LIBRARY_SUFFIX ".luaso") 23 | 24 | include_directories(/usr/include/lua5.1) 25 | 26 | #uncomment if you have defined messages 27 | #rosbuild_genmsg() 28 | #uncomment if you have defined services 29 | #rosbuild_gensrv() 30 | 31 | #common commands for building c++ executables and libraries 32 | #rosbuild_add_library(${PROJECT_NAME} src/example.cpp) 33 | #target_link_libraries(${PROJECT_NAME} another_library) 34 | #rosbuild_add_boost_directories() 35 | #rosbuild_link_boost(${PROJECT_NAME} thread) 36 | #rosbuild_add_executable(example examples/example.cpp) 37 | #target_link_libraries(example ${PROJECT_NAME}) 38 | 39 | rosbuild_add_library(signal src/lua_modules/lsignal.c) 40 | rosbuild_add_library(struct src/lua_modules/struct.c) 41 | rosbuild_add_library(posix src/lua_modules/lposix.c) 42 | 43 | target_link_libraries(posix rt crypt) 44 | 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD License 2 | 3 | Copyright (c) 2010, Tim Niemueller 4 | Copyright (c) 2010, Carnegie Mellon University 5 | Copyright (c) 2010, Intel Research Pittsburgh 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the names of Carnegie Mellon University or Intel Research 16 | Pittsburgh nor the names of its contributors may be used to endorse or 17 | promote products derived from this software without specific prior 18 | written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | POSSIBILITY OF SUCH DAMAGE. 31 | 32 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include $(shell rospack find mk)/cmake.mk 2 | 3 | .PHONY: doc 4 | doc: 5 | LUA_PATH="./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua" \ 6 | luadoc --nofiles -d doc/ -t etc/luadoc src/roslua/*.lua 7 | sed -i '// r README' doc/index.html 8 | 9 | -------------------------------------------------------------------------------- /doc/luadoc.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-left: 1em; 3 | margin-right: 1em; 4 | font-family: arial, helvetica, geneva, sans-serif; 5 | background-color:#ffffff; margin:0px; 6 | } 7 | 8 | code { 9 | font-family: "Andale Mono", monospace; 10 | } 11 | 12 | tt { 13 | font-family: "Andale Mono", monospace; 14 | } 15 | 16 | body, td, th { font-size: 11pt; } 17 | 18 | h1, h2, h3, h4 { margin-left: 0em; } 19 | 20 | textarea, pre, tt { font-size:10pt; } 21 | body, td, th { color:#000000; } 22 | small { font-size:0.85em; } 23 | h1 { font-size:1.5em; } 24 | h2 { font-size:1.25em; } 25 | h3 { font-size:1.15em; } 26 | h4 { font-size:1.06em; } 27 | 28 | a:link { font-weight:bold; color: #004080; text-decoration: none; } 29 | a:visited { font-weight:bold; color: #006699; text-decoration: none; } 30 | a:link:hover { text-decoration:underline; } 31 | hr { color:#cccccc } 32 | img { border-width: 0px; } 33 | 34 | 35 | h3 { padding-top: 1em; } 36 | 37 | p { margin-left: 1em; } 38 | 39 | p.name { 40 | font-family: "Andale Mono", monospace; 41 | padding-top: 1em; 42 | margin-left: 0em; 43 | } 44 | 45 | blockquote { margin-left: 3em; } 46 | 47 | pre.example { 48 | background-color: rgb(245, 245, 245); 49 | border-top-width: 1px; 50 | border-right-width: 1px; 51 | border-bottom-width: 1px; 52 | border-left-width: 1px; 53 | border-top-style: solid; 54 | border-right-style: solid; 55 | border-bottom-style: solid; 56 | border-left-style: solid; 57 | border-top-color: silver; 58 | border-right-color: silver; 59 | border-bottom-color: silver; 60 | border-left-color: silver; 61 | padding: 1em; 62 | margin-left: 1em; 63 | margin-right: 1em; 64 | font-family: "Andale Mono", monospace; 65 | font-size: smaller; 66 | } 67 | 68 | 69 | hr { 70 | margin-left: 0em; 71 | background: #00007f; 72 | border: 0px; 73 | height: 1px; 74 | } 75 | 76 | ul { list-style-type: disc; } 77 | 78 | table.index { border: 1px #00007f; } 79 | table.index td { text-align: left; vertical-align: top; } 80 | table.index ul { padding-top: 0em; margin-top: 0em; } 81 | 82 | table { 83 | border: 1px solid black; 84 | border-collapse: collapse; 85 | margin-left: auto; 86 | margin-right: auto; 87 | } 88 | th { 89 | border: 1px solid black; 90 | padding: 0.5em; 91 | } 92 | td { 93 | border: 1px solid black; 94 | padding: 0.5em; 95 | } 96 | div.header, div.footer { margin-left: 0em; } 97 | 98 | #container 99 | { 100 | margin-left: 1em; 101 | margin-right: 1em; 102 | background-color: #f0f0f0; 103 | } 104 | 105 | #product 106 | { 107 | text-align: center; 108 | border-bottom: 1px solid #cccccc; 109 | background-color: #ffffff; 110 | } 111 | 112 | #product big { 113 | font-size: 2em; 114 | } 115 | 116 | #product_logo 117 | { 118 | } 119 | 120 | #product_name 121 | { 122 | } 123 | 124 | #product_description 125 | { 126 | } 127 | 128 | #main 129 | { 130 | background-color: #f0f0f0; 131 | border-left: 2px solid #cccccc; 132 | } 133 | 134 | #navigation 135 | { 136 | float: left; 137 | width: 18em; 138 | margin: 0; 139 | vertical-align: top; 140 | background-color: #f0f0f0; 141 | overflow:visible; 142 | } 143 | 144 | #navigation h1 { 145 | background-color:#e7e7e7; 146 | font-size:1.1em; 147 | color:#000000; 148 | text-align:left; 149 | margin:0px; 150 | padding:0.2em; 151 | border-top:1px solid #dddddd; 152 | border-bottom:1px solid #dddddd; 153 | } 154 | 155 | #navigation ul 156 | { 157 | font-size:1em; 158 | list-style-type: none; 159 | padding: 0; 160 | margin: 1px; 161 | } 162 | 163 | #navigation li 164 | { 165 | text-indent: -1em; 166 | margin: 0em 0em 0em 0.5em; 167 | display: block; 168 | padding: 3px 0px 0px 12px; 169 | } 170 | 171 | #navigation li li a 172 | { 173 | padding: 0px 3px 0px -1em; 174 | } 175 | 176 | #content 177 | { 178 | margin-left: 18em; 179 | padding: 1em; 180 | border-left: 2px solid #cccccc; 181 | border-right: 2px solid #cccccc; 182 | background-color: #ffffff; 183 | } 184 | 185 | #about 186 | { 187 | clear: both; 188 | margin: 0; 189 | padding: 5px; 190 | border-top: 2px solid #cccccc; 191 | background-color: #ffffff; 192 | } 193 | 194 | @media print { 195 | body { 196 | font: 12pt "Times New Roman", "TimeNR", Times, serif; 197 | } 198 | a { font-weight:bold; color: #004080; text-decoration: underline; } 199 | 200 | #main { background-color: #ffffff; border-left: 0px; } 201 | #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } 202 | 203 | #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } 204 | 205 | #navigation { display: none; 206 | } 207 | pre.example { 208 | font-family: "Andale Mono", monospace; 209 | font-size: 10pt; 210 | page-break-inside: avoid; 211 | } 212 | } 213 | 214 | table.module_list td 215 | { 216 | border-width: 1px; 217 | padding: 3px; 218 | border-style: solid; 219 | border-color: #cccccc; 220 | } 221 | table.module_list td.name { background-color: #f0f0f0; } 222 | table.module_list td.summary { width: 100%; } 223 | 224 | table.file_list 225 | { 226 | border-width: 1px; 227 | border-style: solid; 228 | border-color: #cccccc; 229 | border-collapse: collapse; 230 | } 231 | table.file_list td 232 | { 233 | border-width: 1px; 234 | padding: 3px; 235 | border-style: solid; 236 | border-color: #cccccc; 237 | } 238 | table.file_list td.name { background-color: #f0f0f0; } 239 | table.file_list td.summary { width: 100%; } 240 | 241 | 242 | table.function_list 243 | { 244 | border-width: 1px; 245 | border-style: solid; 246 | border-color: #cccccc; 247 | border-collapse: collapse; 248 | } 249 | table.function_list td 250 | { 251 | border-width: 1px; 252 | padding: 3px; 253 | border-style: solid; 254 | border-color: #cccccc; 255 | } 256 | table.function_list td.name { background-color: #f0f0f0; } 257 | table.function_list td.summary { width: 100%; } 258 | 259 | 260 | table.table_list 261 | { 262 | border-width: 1px; 263 | border-style: solid; 264 | border-color: #cccccc; 265 | border-collapse: collapse; 266 | } 267 | table.table_list td 268 | { 269 | border-width: 1px; 270 | padding: 3px; 271 | border-style: solid; 272 | border-color: #cccccc; 273 | } 274 | table.table_list td.name { background-color: #f0f0f0; } 275 | table.table_list td.summary { width: 100%; } 276 | 277 | dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} 278 | dl.function dd {padding-bottom: 1em;} 279 | dl.function h3 {padding: 0; margin: 0; font-size: medium;} 280 | 281 | dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;} 282 | dl.table dd {padding-bottom: 1em;} 283 | dl.table h3 {padding: 0; margin: 0; font-size: medium;} 284 | 285 | #TODO: make module_list, file_list, function_list, table_list inherit from a list 286 | 287 | -------------------------------------------------------------------------------- /doc/modules/roslua.logging.rosout.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 | 123 | 124 |
125 | 126 |

Module roslua.logging.rosout

127 | 128 |

Logging facilities for roslua. This module provides a logger that logs to stdout.

129 | 130 | 131 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

132 | 133 | 134 |

Release: Released under BSD license

135 | 136 | 137 | 138 |

Functions

139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
get_logger ()Get logger.
log_rosout (level, time, msg)Log message to /rosout topic.
152 | 153 | 154 | 155 | 156 | 157 | 158 |
159 |
160 | 161 | 162 | 163 |

Functions

164 |
165 | 166 | 167 | 168 |
get_logger ()
169 |
170 | Get logger. Get the rosout logger, as a side effects initializes publisher. 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 |

Return value:

179 | initialized rosout logger 180 | 181 | 182 | 183 |
184 | 185 | 186 | 187 | 188 |
log_rosout (level, time, msg)
189 |
190 | Log message to /rosout topic. 191 | 192 | 193 |

Parameters

194 |
    195 | 196 |
  • 197 | level: log level 198 |
  • 199 | 200 |
  • 201 | time: timestamp of message 202 |
  • 203 | 204 |
  • 205 | msg: message 206 |
  • 207 | 208 |
209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 |
218 | 219 | 220 |
221 | 222 | 223 | 224 | 225 | 226 | 227 |
228 | 229 |
230 | 231 |
232 |

Valid XHTML 1.0!

233 |
234 | 235 |
236 | 237 | 238 | -------------------------------------------------------------------------------- /doc/modules/roslua.logging.stdout.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 | 123 | 124 |
125 | 126 |

Module roslua.logging.stdout

127 | 128 |

Logging facilities for roslua. This module provides a logger that logs to stdout.

129 | 130 | 131 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

132 | 133 | 134 |

Release: Released under BSD license

135 | 136 | 137 | 138 |

Functions

139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
get_logger ()Get logger.
log_stdout (level, time, msg)Log message to stdout.
152 | 153 | 154 | 155 | 156 | 157 | 158 |
159 |
160 | 161 | 162 | 163 |

Functions

164 |
165 | 166 | 167 | 168 |
get_logger ()
169 |
170 | Get logger. 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 |

Return value:

179 | initialized stdout logger 180 | 181 | 182 | 183 |
184 | 185 | 186 | 187 | 188 |
log_stdout (level, time, msg)
189 |
190 | Log message to stdout. 191 | 192 | 193 |

Parameters

194 |
    195 | 196 |
  • 197 | level: log level 198 |
  • 199 | 200 |
  • 201 | time: timestamp of message 202 |
  • 203 | 204 |
  • 205 | msg: message 206 |
  • 207 | 208 |
209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 |
218 | 219 | 220 |
221 | 222 | 223 | 224 | 225 | 226 | 227 |
228 | 229 |
230 | 231 |
232 |

Valid XHTML 1.0!

233 |
234 | 235 |
236 | 237 | 238 | -------------------------------------------------------------------------------- /doc/modules/roslua.param_proxy.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.param_proxy

124 | 125 |

Parameter XML-RPC API proxy. This module contains the ParamProxy class to call methods provided via XML-RPC by the parameter server.

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 |
ParamProxy:delete_param (key)Delete parameter.
ParamProxy:getParam (key)Get parameter.
ParamProxy:get_param_names ()Get names of all available parameters.
ParamProxy:has_param (key)Check if parameter exists.
ParamProxy:new (ros_master_uri, node_name)Constructor.
ParamProxy:search_param (key)Search for parameter.
ParamProxy:set_param (key, value)Set parameter.
ParamProxy:subscribe_param (key)Subscribe to parameter.
ParamProxy:unsubscribe_param (key)Unsubscribe from parameter.
184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 |
192 | 193 | 194 | 195 |

Functions

196 |
197 | 198 | 199 | 200 |
ParamProxy:delete_param (key)
201 |
202 | Delete parameter. 203 | 204 | 205 |

Parameters

206 |
    207 | 208 |
  • 209 | key: key of the parameter to delete 210 |
  • 211 | 212 |
213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 |
222 | 223 | 224 | 225 | 226 |
ParamProxy:getParam (key)
227 |
228 | Get parameter. 229 | 230 | 231 |

Parameters

232 |
    233 | 234 |
  • 235 | key: key of the parameter to query 236 |
  • 237 | 238 |
239 | 240 | 241 | 242 | 243 | 244 | 245 |

Return value:

246 | value of the parameter 247 | 248 | 249 | 250 |
251 | 252 | 253 | 254 | 255 |
ParamProxy:get_param_names ()
256 |
257 | Get names of all available parameters. 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 |

Return value:

266 | array with names of all parameters 267 | 268 | 269 | 270 |
271 | 272 | 273 | 274 | 275 |
ParamProxy:has_param (key)
276 |
277 | Check if parameter exists. 278 | 279 | 280 |

Parameters

281 |
    282 | 283 |
  • 284 | key: key of the parameter to query 285 |
  • 286 | 287 |
288 | 289 | 290 | 291 | 292 | 293 | 294 |

Return value:

295 | true if the parameter exists, false otherwise 296 | 297 | 298 | 299 |
300 | 301 | 302 | 303 | 304 |
ParamProxy:new (ros_master_uri, node_name)
305 |
306 | Constructor. 307 | 308 | 309 |

Parameters

310 |
    311 | 312 |
  • 313 | ros_master_uri: XML-RPC HTTP URI of ROS master 314 |
  • 315 | 316 |
  • 317 | node_name: name of this node 318 |
  • 319 | 320 |
321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 |
330 | 331 | 332 | 333 | 334 |
ParamProxy:search_param (key)
335 |
336 | Search for parameter. 337 | 338 | 339 |

Parameters

340 |
    341 | 342 |
  • 343 | key: substring of the key to look for 344 |
  • 345 | 346 |
347 | 348 | 349 | 350 | 351 | 352 | 353 |

Return value:

354 | first key that matched 355 | 356 | 357 | 358 |
359 | 360 | 361 | 362 | 363 |
ParamProxy:set_param (key, value)
364 |
365 | Set parameter. 366 | 367 | 368 |

Parameters

369 |
    370 | 371 |
  • 372 | key: key of the parameter to set 373 |
  • 374 | 375 |
  • 376 | value: value of the parameter to set 377 |
  • 378 | 379 |
380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 |
389 | 390 | 391 | 392 | 393 |
ParamProxy:subscribe_param (key)
394 |
395 | Subscribe to parameter. 396 | 397 | 398 |

Parameters

399 |
    400 | 401 |
  • 402 | key: key to subscribe to 403 |
  • 404 | 405 |
406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
415 | 416 | 417 | 418 | 419 |
ParamProxy:unsubscribe_param (key)
420 |
421 | Unsubscribe from parameter. 422 | 423 | 424 |

Parameters

425 |
    426 | 427 |
  • 428 | key: key to unsubscribe from 429 |
  • 430 | 431 |
432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 |
441 | 442 | 443 |
444 | 445 | 446 | 447 | 448 | 449 | 450 |
451 | 452 |
453 | 454 |
455 |

Valid XHTML 1.0!

456 |
457 | 458 |
459 | 460 | 461 | -------------------------------------------------------------------------------- /doc/modules/roslua.publisher.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.publisher

124 | 125 |

Topic publisher. This module contains the Publisher class to publish to a ROS topic. The class is used to publish messages to a specified topic. It is created using the function roslua.publisher().

The main interaction for applications is using the publish() method to send new messages. The publisher spins automatically when created using roslua.publisher().

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
Publisher:finalize ()Finalize instance.
Publisher:get_stats ()Get statistics about this publisher.
Publisher:new (topic, type)Constructor.
Publisher:publish (message)Publish message to topic.
Publisher:spin ()Spin function.
Publisher:start_server ()Start the internal TCP server to accept ROS subscriber connections.
Publisher:wait_for_subscriber ()Wait for a subscriber to connect.
174 | 175 | 176 | 177 | 178 | 179 | 180 |
181 |
182 | 183 | 184 | 185 |

Functions

186 |
187 | 188 | 189 | 190 |
Publisher:finalize ()
191 |
192 | Finalize instance. 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 |
203 | 204 | 205 | 206 | 207 |
Publisher:get_stats ()
208 |
209 | Get statistics about this publisher. 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 |

Return value:

218 | an array containing the topic name as the first entry, and another array as the second entry. This array contains itself tables with four fields each: the remote caller ID of the connection, the number of bytes sent, number of messages sent and connection aliveness (always true). Suitable for getBusStats of slave API. 219 | 220 | 221 | 222 |
223 | 224 | 225 | 226 | 227 |
Publisher:new (topic, type)
228 |
229 | Constructor. Create a new publisher instance. 230 | 231 | 232 |

Parameters

233 |
    234 | 235 |
  • 236 | topic: topic to publish to 237 |
  • 238 | 239 |
  • 240 | type: type of the topic 241 |
  • 242 | 243 |
244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 |
253 | 254 | 255 | 256 | 257 |
Publisher:publish (message)
258 |
259 | Publish message to topic. The messages are sent immediately. Busy or bad network connections or a large number of subscribers can slow down this method. 260 | 261 | 262 |

Parameters

263 |
    264 | 265 |
  • 266 | message: message to publish 267 |
  • 268 | 269 |
270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 |
279 | 280 | 281 | 282 | 283 |
Publisher:spin ()
284 |
285 | Spin function. While spinning the publisher accepts new connections. 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 |
296 | 297 | 298 | 299 | 300 |
Publisher:start_server ()
301 |
302 | Start the internal TCP server to accept ROS subscriber connections. 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 |
313 | 314 | 315 | 316 | 317 |
Publisher:wait_for_subscriber ()
318 |
319 | Wait for a subscriber to connect. 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 |
330 | 331 | 332 |
333 | 334 | 335 | 336 | 337 | 338 | 339 |
340 | 341 |
342 | 343 |
344 |

Valid XHTML 1.0!

345 |
346 | 347 |
348 | 349 | 350 | -------------------------------------------------------------------------------- /doc/modules/roslua.registry.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.registry

124 | 125 |

Registry housekeeping. This module contains functions used for housekeeping of subscriptions, publishers, and services. They should not be used directly.

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 |
register_publisher (topic, type, publisher)Register publisher.
register_service (service, type, provider, topic)Register service provider.
register_subscriber (topic, type, subscriber)Register subscriber.
register_timer (timer)Register timer.
unregister_publisher (topic, type, publisher)Unregister publisher.
unregister_service (service, type, provider, topic)Unregister service provider.
unregister_subscriber (topic, type, subscriber)Unregister subscriber.
unregister_timer (timer)Unregister timer
179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 |
187 | 188 | 189 | 190 |

Functions

191 |
192 | 193 | 194 | 195 |
register_publisher (topic, type, publisher)
196 |
197 | Register publisher. As a side effect registers the publisher with the master. 198 | 199 | 200 |

Parameters

201 |
    202 | 203 |
  • 204 | topic: topic to register publisher for 205 |
  • 206 | 207 |
  • 208 | type: type of topic 209 |
  • 210 | 211 |
  • 212 | publisher: Publisher instance to register 213 |
  • 214 | 215 |
216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 |

See also:

225 | 232 | 233 |
234 | 235 | 236 | 237 | 238 |
register_service (service, type, provider, topic)
239 |
240 | Register service provider. As a side effect registers the service provider with the master. 241 | 242 | 243 |

Parameters

244 |
    245 | 246 |
  • 247 | service: 248 |
  • 249 | 250 |
  • 251 | type: type of topic 252 |
  • 253 | 254 |
  • 255 | provider: Service instance to register 256 |
  • 257 | 258 |
  • 259 | topic: topic to register service provider for 260 |
  • 261 | 262 |
263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 |

See also:

272 | 279 | 280 |
281 | 282 | 283 | 284 | 285 |
register_subscriber (topic, type, subscriber)
286 |
287 | Register subscriber. As a side effect registers the subscriber with the master. 288 | 289 | 290 |

Parameters

291 |
    292 | 293 |
  • 294 | topic: topic to register subscriber for 295 |
  • 296 | 297 |
  • 298 | type: type of topic 299 |
  • 300 | 301 |
  • 302 | subscriber: Subscriber instance to register 303 |
  • 304 | 305 |
306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 |

See also:

315 | 322 | 323 |
324 | 325 | 326 | 327 | 328 |
register_timer (timer)
329 |
330 | Register timer. 331 | 332 | 333 |

Parameters

334 |
    335 | 336 |
  • 337 | timer: timer to register 338 |
  • 339 | 340 |
341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 |

See also:

350 | 357 | 358 |
359 | 360 | 361 | 362 | 363 |
unregister_publisher (topic, type, publisher)
364 |
365 | Unregister publisher. As a side effect unregisters the publisher with the master. 366 | 367 | 368 |

Parameters

369 |
    370 | 371 |
  • 372 | topic: topic to unregister publisher for 373 |
  • 374 | 375 |
  • 376 | type: type of topic 377 |
  • 378 | 379 |
  • 380 | publisher: Publisher instance to unregister 381 |
  • 382 | 383 |
384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 |

See also:

393 | 400 | 401 |
402 | 403 | 404 | 405 | 406 |
unregister_service (service, type, provider, topic)
407 |
408 | Unregister service provider. As a side effect unregisters the service provider with the master. 409 | 410 | 411 |

Parameters

412 |
    413 | 414 |
  • 415 | service: 416 |
  • 417 | 418 |
  • 419 | type: type of topic 420 |
  • 421 | 422 |
  • 423 | provider: Service instance to unregister 424 |
  • 425 | 426 |
  • 427 | topic: topic to unregister service provider for 428 |
  • 429 | 430 |
431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 |

See also:

440 | 447 | 448 |
449 | 450 | 451 | 452 | 453 |
unregister_subscriber (topic, type, subscriber)
454 |
455 | Unregister subscriber. As a side effect unregisters the subscriber with the master. 456 | 457 | 458 |

Parameters

459 |
    460 | 461 |
  • 462 | topic: topic to register subscriber for 463 |
  • 464 | 465 |
  • 466 | type: type of topic 467 |
  • 468 | 469 |
  • 470 | subscriber: Subscriber instance to unregister 471 |
  • 472 | 473 |
474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 |

See also:

483 | 490 | 491 |
492 | 493 | 494 | 495 | 496 |
unregister_timer (timer)
497 |
498 | Unregister timer 499 | 500 | 501 |

Parameters

502 |
    503 | 504 |
  • 505 | timer: timer to unregister 506 |
  • 507 | 508 |
509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 |

See also:

518 | 525 | 526 |
527 | 528 | 529 |
530 | 531 | 532 | 533 | 534 | 535 | 536 |
537 | 538 |
539 | 540 |
541 |

Valid XHTML 1.0!

542 |
543 | 544 |
545 | 546 | 547 | -------------------------------------------------------------------------------- /doc/modules/roslua.service.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.service

124 | 125 |

Service provider. This module contains the Service class to provide services to other ROS nodes. It is created using the function roslua.service().

The service needs a handler to which incoming requests are dispatched. A handler is either a function or a class instance with a service_call() method. On a connection, the request message is called with the fields of the message passed as positional arguments. Sub-messages (i.e. non-builtin complex types) are themselves passed as arrays with the entries being the sub-message fields. This is done recursively for larger hierarchies of parameters.

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
Service:dispatch (client)Dispatch incoming service requests from client.
Service:finalize ()Finalize instance.
Service:get_stats ()Get stats.
Service:new (service, srvtype, handler, type)Constructor.
Service:spin ()Spin service provider.
Service:start_server ()Start the internal TCP server to accept ROS RPC connections.
Service:uri ()Get the URI for this service.
174 | 175 | 176 | 177 | 178 | 179 | 180 |
181 |
182 | 183 | 184 | 185 |

Functions

186 |
187 | 188 | 189 | 190 |
Service:dispatch (client)
191 |
192 | Dispatch incoming service requests from client. 193 | 194 | 195 |

Parameters

196 |
    197 | 198 |
  • 199 | client: client whose requests to process 200 |
  • 201 | 202 |
203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 |
212 | 213 | 214 | 215 | 216 |
Service:finalize ()
217 |
218 | Finalize instance. 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 |
Service:get_stats ()
234 |
235 | Get stats. 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 |

Return value:

244 | currently empty array until this is fixed in the XML-RPC specification. 245 | 246 | 247 | 248 |
249 | 250 | 251 | 252 | 253 |
Service:new (service, srvtype, handler, type)
254 |
255 | Constructor. Create a new service provider instance. 256 | 257 | 258 |

Parameters

259 |
    260 | 261 |
  • 262 | service: name of the provided service 263 |
  • 264 | 265 |
  • 266 | srvtype: 267 |
  • 268 | 269 |
  • 270 | handler: handler function or class instance 271 |
  • 272 | 273 |
  • 274 | type: type of the service 275 |
  • 276 | 277 |
278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 |
287 | 288 | 289 | 290 | 291 |
Service:spin ()
292 |
293 | Spin service provider. This will accept new connections to the service and dispatch incoming service requests. 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 |
304 | 305 | 306 | 307 | 308 |
Service:start_server ()
309 |
310 | Start the internal TCP server to accept ROS RPC connections. 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 |
321 | 322 | 323 | 324 | 325 |
Service:uri ()
326 |
327 | Get the URI for this service. 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 |

Return value:

336 | rosrpc URI 337 | 338 | 339 | 340 |
341 | 342 | 343 |
344 | 345 | 346 | 347 | 348 | 349 | 350 |
351 | 352 |
353 | 354 |
355 |

Valid XHTML 1.0!

356 |
357 | 358 |
359 | 360 | 361 | -------------------------------------------------------------------------------- /doc/modules/roslua.slave_proxy.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.slave_proxy

124 | 125 |

Slave XML-RPC API proxy. This module contains the SlaveProxy class to call methods provided via XML-RPC by ROS slaves.

The user should not have to directly interact with the slave. It is used to initiate topic connections and get information about the slave. It can also be used to remotely shutdown a slave.

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 |
SlaveProxy:getBusStats ()Get bus stats.
SlaveProxy:getMasterUri ()Get slaves master URI.
SlaveProxy:getPid ()Get PID of remote slave.
SlaveProxy:getPublications ()Get all publications of remote node.
SlaveProxy:getSubscriptions ()Get all subscriptions of remote node.
SlaveProxy:new (slave_uri, node_name)Constructor.
SlaveProxy:requestTopic (topic)Request a TCPROS connection for a specific topic.
SlaveProxy:shutdown (msg)Shutdown remote node.
179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 |
187 | 188 | 189 | 190 |

Functions

191 |
192 | 193 | 194 | 195 |
SlaveProxy:getBusStats ()
196 |
197 | Get bus stats. 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |

Return value:

206 | bus stats 207 | 208 | 209 | 210 |
211 | 212 | 213 | 214 | 215 |
SlaveProxy:getMasterUri ()
216 |
217 | Get slaves master URI. 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 |

Return value:

226 | slaves master URI 227 | 228 | 229 | 230 |
231 | 232 | 233 | 234 | 235 |
SlaveProxy:getPid ()
236 |
237 | Get PID of remote slave. Can be used to "ping" the remote node. 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 |
248 | 249 | 250 | 251 | 252 |
SlaveProxy:getPublications ()
253 |
254 | Get all publications of remote node. 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 |

Return value:

263 | list of publications 264 | 265 | 266 | 267 |
268 | 269 | 270 | 271 | 272 |
SlaveProxy:getSubscriptions ()
273 |
274 | Get all subscriptions of remote node. 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 |

Return value:

283 | list of subscriptions 284 | 285 | 286 | 287 |
288 | 289 | 290 | 291 | 292 |
SlaveProxy:new (slave_uri, node_name)
293 |
294 | Constructor. 295 | 296 | 297 |

Parameters

298 |
    299 | 300 |
  • 301 | slave_uri: XML-RPC HTTP slave URI 302 |
  • 303 | 304 |
  • 305 | node_name: name of this node 306 |
  • 307 | 308 |
309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 |
318 | 319 | 320 | 321 | 322 |
SlaveProxy:requestTopic (topic)
323 |
324 | Request a TCPROS connection for a specific topic. 325 | 326 | 327 |

Parameters

328 |
    329 | 330 |
  • 331 | topic: name of topic 332 |
  • 333 | 334 |
335 | 336 | 337 | 338 | 339 | 340 | 341 |

Return value:

342 | TCPROS communication parameters 343 | 344 | 345 | 346 |
347 | 348 | 349 | 350 | 351 |
SlaveProxy:shutdown (msg)
352 |
353 | Shutdown remote node. 354 | 355 | 356 |

Parameters

357 |
    358 | 359 |
  • 360 | msg: shutdown message 361 |
  • 362 | 363 |
364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 |
373 | 374 | 375 |
376 | 377 | 378 | 379 | 380 | 381 | 382 |
383 | 384 |
385 | 386 |
387 |

Valid XHTML 1.0!

388 |
389 | 390 |
391 | 392 | 393 | -------------------------------------------------------------------------------- /doc/modules/roslua.srv_spec.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.srv_spec

124 | 125 |

Service specification. This module contains the SrvSpec class to read and represent ROS service specification (YAML files). Service specifications should be obtained by using the get_srvspec() function, which is aliased for convenience as roslua.get_srvspec().

The service files are read on the fly, no offline code generation is necessary. This avoids the need to write yet another code generator. After reading the service specifications contains two fields, the reqspec field contains the request message specification, the respspec field contains the response message specification.

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 |
SrvSpec:load ()Load service specification from file.
SrvSpec:load_from_string (s)Load specification from string.
SrvSpec:md5 ()Get MD5 sum of type specification.
SrvSpec:new (o)Constructor.
SrvSpec:print (indent)Print specification.
get_srvspec (srv_type)Get service specification.
is_srvspec (testobj)Check if the given object is a message spec.
174 | 175 | 176 | 177 | 178 | 179 | 180 |
181 |
182 | 183 | 184 | 185 |

Functions

186 |
187 | 188 | 189 | 190 |
SrvSpec:load ()
191 |
192 | Load service specification from file. Will search for the appropriate service specification file (using rospack) and will then read and parse the file. 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 |
203 | 204 | 205 | 206 | 207 |
SrvSpec:load_from_string (s)
208 |
209 | Load specification from string. 210 | 211 | 212 |

Parameters

213 |
    214 | 215 |
  • 216 | s: string containing the service specification 217 |
  • 218 | 219 |
220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 |
SrvSpec:md5 ()
234 |
235 | Get MD5 sum of type specification. This will create a text representation of the service specification and generate the MD5 sum for it. The value is cached so concurrent calls will cause the cached value to be returned 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 |

Return value:

244 | MD5 sum of message specification 245 | 246 | 247 | 248 |
249 | 250 | 251 | 252 | 253 |
SrvSpec:new (o)
254 |
255 | Constructor. 256 | 257 | 258 |

Parameters

259 |
    260 | 261 |
  • 262 | o: Object initializer, must contain a field type with the string representation of the type name. 263 |
  • 264 | 265 |
266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 |
275 | 276 | 277 | 278 | 279 |
SrvSpec:print (indent)
280 |
281 | Print specification. 282 | 283 | 284 |

Parameters

285 |
    286 | 287 |
  • 288 | indent: string (normally spaces) to put before every line of output 289 |
  • 290 | 291 |
292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 |
301 | 302 | 303 | 304 | 305 |
get_srvspec (srv_type)
306 |
307 | Get service specification. It is recommended to use the aliased version roslua.get_srvspec(). 308 | 309 | 310 |

Parameters

311 |
    312 | 313 |
  • 314 | srv_type: service type (e.g. std_msgs/String). The name must include the package. 315 |
  • 316 | 317 |
318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 |
327 | 328 | 329 | 330 | 331 |
is_srvspec (testobj)
332 |
333 | Check if the given object is a message spec. 334 | 335 | 336 |

Parameters

337 |
    338 | 339 |
  • 340 | testobj: object to test 341 |
  • 342 | 343 |
344 | 345 | 346 | 347 | 348 | 349 | 350 |

Return value:

351 | true if testobj is a message spec, false otherwise 352 | 353 | 354 | 355 |
356 | 357 | 358 |
359 | 360 | 361 | 362 | 363 | 364 | 365 |
366 | 367 |
368 | 369 |
370 |

Valid XHTML 1.0!

371 |
372 | 373 |
374 | 375 | 376 | -------------------------------------------------------------------------------- /doc/modules/roslua.subscriber.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.subscriber

124 | 125 |

Topic subscriber. This module contains the Subscriber class to subscribe to a ROS topic. The class is used to connect to all publishers for a certain topic and receive messages published by and of these.

During spinning the messages are received and registered listeners are called to process the messages.

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 |
Subscriber:add_listener (listener)Add a listener to this subscriber.
Subscriber:connect ()Connect to all available publishers to which no connection has yet been established.
Subscriber:finalize ()Finalize instance.
Subscriber:get_stats ()Get statistics about this subscriber.
Subscriber:new (topic, type)Constructor.
Subscriber:remove_listener (listener)remove the given listener.
Subscriber:reset_messages ()Reset messages.
Subscriber:spin ()Spin all connections to subscribers and dispatch incoming messages.
Subscriber:update_publishers (publishers, connect_now)Update the publishers.
184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 |
192 | 193 | 194 | 195 |

Functions

196 |
197 | 198 | 199 | 200 |
Subscriber:add_listener (listener)
201 |
202 | Add a listener to this subscriber. 203 | 204 | 205 |

Parameters

206 |
    207 | 208 |
  • 209 | listener: A listener is either a function or a class which provides a message_received() method. The function or method is called for any successively received message. Note that your listener blocks all other listeners from receiving any further messages. For lengthy task you might consider storing the message and interleaving processing and node spinning. 210 |
  • 211 | 212 |
213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 |
222 | 223 | 224 | 225 | 226 |
Subscriber:connect ()
227 |
228 | Connect to all available publishers to which no connection has yet been established. 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 |
239 | 240 | 241 | 242 | 243 |
Subscriber:finalize ()
244 |
245 | Finalize instance. 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 |
256 | 257 | 258 | 259 | 260 |
Subscriber:get_stats ()
261 |
262 | Get statistics about this subscriber. 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 |

Return value:

271 | an array containing the topic name as the first entry, and another array as the second entry. This array contains itself tables with five fields each: the remote caller ID of the connection, the number of bytes received, number of messages received, the drop estimate (always -1) and connection aliveness (always true). Suitable for getBusStats of slave API. 272 | 273 | 274 | 275 |
276 | 277 | 278 | 279 | 280 |
Subscriber:new (topic, type)
281 |
282 | Constructor. Create a new subscriber instance. 283 | 284 | 285 |

Parameters

286 |
    287 | 288 |
  • 289 | topic: topic to subscribe to 290 |
  • 291 | 292 |
  • 293 | type: type of the topic 294 |
  • 295 | 296 |
297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 |
306 | 307 | 308 | 309 | 310 |
Subscriber:remove_listener (listener)
311 |
312 | remove the given listener. The listener will no longer be notified of incoming messages. 313 | 314 | 315 |

Parameters

316 |
    317 | 318 |
  • 319 | listener: listener to remove 320 |
  • 321 | 322 |
323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 |
332 | 333 | 334 | 335 | 336 |
Subscriber:reset_messages ()
337 |
338 | Reset messages. You can use this for a latching subscriber to erase the messages at a certain point manually. 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 |
349 | 350 | 351 | 352 | 353 |
Subscriber:spin ()
354 |
355 | Spin all connections to subscribers and dispatch incoming messages. Connections which are found dead are removed. 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 |
366 | 367 | 368 | 369 | 370 |
Subscriber:update_publishers (publishers, connect_now)
371 |
372 | Update the publishers. This method is called by the slave API handler when the publisherUpdate() XML-RPC method is called. The subscriber instance will connect to any new publishers that it had not connected to before (during the next call to spin() and will (immediately) disconnect from any publishers that are no longer available. 373 | 374 | 375 |

Parameters

376 |
    377 | 378 |
  • 379 | publishers: an array of currently available and slave URIs that were registered at the core 380 |
  • 381 | 382 |
  • 383 | connect_now: if set to true will immediately try to connect to unconnected publishers instead of only marking enqueuing a try for the next spin 384 |
  • 385 | 386 |
387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 |
396 | 397 | 398 |
399 | 400 | 401 | 402 | 403 | 404 | 405 |
406 | 407 |
408 | 409 |
410 |

Valid XHTML 1.0!

411 |
412 | 413 |
414 | 415 | 416 | -------------------------------------------------------------------------------- /doc/modules/roslua.timer.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.timer

124 | 125 |

Timer. This module contains the Timer class for periodical execution of a function. A time period is given, in which the function should be executed. Due to the nature of Lua, especially because it is inherently single-threaded, the times cannot be guaranteed, rather, a minimum time between calls to the function is defined.

During spinning the all timers are evaluated and executed if the minimum time has gone by. Make sure that timer callbacks are functions that run quickly and have a very short duration as not to influence the overall system performance negatively.

The rate at which the spinning function is called defines the minimum period for which timers can be called somewhat accurately. For example, if the roslua.spin() function is called once every 30ms, then these 30ms are the very minimum duration of a timer, a shorter time is not possible. You will see increasing offsets between the current_expected and current_real times which will periodically get small once the offset approaches half the spinning time.

The callback is invoked with a table as parameter of the following entries: * last_expected Time when the last callback should have happened * last_real Time when the last callback actually happened * current_expected Time when the current callback should have happened * current_real Time at the start of the current execution * last_duration Time in seconds the last callback ran

126 | 127 | 128 |

Copyright© Tim Niemueller, SRI International, Carnegie Mellon University, Intel Labs Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 |
Timer:finalize ()Finalize instance.
Timer:new (period, callback)Constructor.
Timer:spin ()Check time and execute callback if due.
154 | 155 | 156 | 157 | 158 | 159 | 160 |
161 |
162 | 163 | 164 | 165 |

Functions

166 |
167 | 168 | 169 | 170 |
Timer:finalize ()
171 |
172 | Finalize instance. 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 |
183 | 184 | 185 | 186 | 187 |
Timer:new (period, callback)
188 |
189 | Constructor. Create a new Timer instance. 190 | 191 | 192 |

Parameters

193 |
    194 | 195 |
  • 196 | period: minimum time between invocations, i.e. the desired time interval between invocations. Either a number, which is considered as time in seconds, or an instance of Duration. 197 |
  • 198 | 199 |
  • 200 | callback: function to execute when the timer is due 201 |
  • 202 | 203 |
204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
213 | 214 | 215 | 216 | 217 |
Timer:spin ()
218 |
219 | Check time and execute callback if due. 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 |
230 | 231 | 232 |
233 | 234 | 235 | 236 | 237 | 238 | 239 |
240 | 241 |
242 | 243 |
244 |

Valid XHTML 1.0!

245 |
246 | 247 |
248 | 249 | 250 | -------------------------------------------------------------------------------- /doc/modules/roslua.utils.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 120 | 121 |
122 | 123 |

Module roslua.utils

124 | 125 |

General roslua utilities. This module contains useful functions used in roslua.

126 | 127 | 128 |

Copyright© Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh

129 | 130 | 131 |

Release: Released under BSD license

132 | 133 | 134 | 135 |

Functions

136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 |
assert_rospack ()Assert availability of rospack.
c_package_loader (module)Package loader to find Lua modules written in C in ROS packages.
find_rospack (package)Get path for a package.
package_loader (module)Package loader to find Lua modules in ROS packages.
split (s, sep)Split string.
164 | 165 | 166 | 167 | 168 | 169 | 170 |
171 |
172 | 173 | 174 | 175 |

Functions

176 |
177 | 178 | 179 | 180 |
assert_rospack ()
181 |
182 | Assert availability of rospack. Throws an error if rospack cannot be executed, for example because ROS is not installed or the binary is not in the PATH. 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 |
193 | 194 | 195 | 196 | 197 |
c_package_loader (module)
198 |
199 | Package loader to find Lua modules written in C in ROS packages. This will use the first part of the module name and assume it to be the name of a ROS package. It will then try to determine the path using rospack and if found try to load the module in the package directory. Additionally it appends the string "_lua" to the package name, thus allowing a module named my_module in the ROS package my_module_lua. This is done to allow to mark Lua ROS packages, but avoid having to have the _lua suffix in module names. The suffixed version takes precedence. 200 | 201 | 202 |

Parameters

203 |
    204 | 205 |
  • 206 | module: module name as given to require() 207 |
  • 208 | 209 |
210 | 211 | 212 | 213 | 214 | 215 | 216 |

Return value:

217 | function of loaded code if module was found, nil otherwise 218 | 219 | 220 | 221 |
222 | 223 | 224 | 225 | 226 |
find_rospack (package)
227 |
228 | Get path for a package. Uses rospack to find the path to a certain package. The path is cached so that consecutive calls will not trigger another rospack execution, but are rather handled directly from the cache. An error is thrown if the package cannot be found. 229 | 230 | 231 |

Parameters

232 |
    233 | 234 |
  • 235 | package: 236 |
  • 237 | 238 |
239 | 240 | 241 | 242 | 243 | 244 | 245 |

Return value:

246 | path to give package 247 | 248 | 249 | 250 |
251 | 252 | 253 | 254 | 255 |
package_loader (module)
256 |
257 | Package loader to find Lua modules in ROS packages. This will use the first part of the module name and assume it to be the name of a ROS package. It will then try to determine the path using rospack and if found try to load the module in the package directory. Additionally it appends the string "_lua" to the package name, thus allowing a module named my_module in the ROS package my_module_lua. This is done to allow to mark Lua ROS packages, but avoid having to have the _lua suffix in module names. The suffixed version takes precedence. 258 | 259 | 260 |

Parameters

261 |
    262 | 263 |
  • 264 | module: module name as given to require() 265 |
  • 266 | 267 |
268 | 269 | 270 | 271 | 272 | 273 | 274 |

Return value:

275 | function of loaded code if module was found, nil otherwise 276 | 277 | 278 | 279 |
280 | 281 | 282 | 283 | 284 |
split (s, sep)
285 |
286 | Split string. Splits a string at a given separator and returns the parts in a table. 287 | 288 | 289 |

Parameters

290 |
    291 | 292 |
  • 293 | s: string to split 294 |
  • 295 | 296 |
  • 297 | sep: separator to split at 298 |
  • 299 | 300 |
301 | 302 | 303 | 304 | 305 | 306 | 307 |

Return value:

308 | table with splitted parts 309 | 310 | 311 | 312 |
313 | 314 | 315 |
316 | 317 | 318 | 319 | 320 | 321 | 322 |
323 | 324 |
325 | 326 |
327 |

Valid XHTML 1.0!

328 |
329 | 330 |
331 | 332 | 333 | -------------------------------------------------------------------------------- /etc/luadoc/file.lp: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 |
17 |
18 | 19 |
20 | 21 | 25 | 26 |
27 | 28 |

File <%=file_doc.name%>

29 | 30 | <%if file_doc.description then%> 31 |

<%=file_doc.description%>

32 | <%end%> 33 | <%if file_doc.author then%> 34 |

<%= #file_doc.author>1 and "Authors" or "Author" %>: 35 | 36 | <%for _, author in ipairs(file_doc.author) do%> 37 | 38 | <%end%> 39 |
<%= author %>
40 |

41 | <%end%> 42 | <%if file_doc.copyright then%> 43 |

Copyright ©<%=file_doc.copyright%>

44 | <%end%> 45 | <%if file_doc.release then%> 46 |

Release: <%=file_doc.release%>

47 | <%end%> 48 | 49 | <%if #file_doc.functions > 0 then%> 50 |

Functions

51 | 52 | <%for _, func_name in ipairs(file_doc.functions) do 53 | local func_data = file_doc.functions[func_name]%> 54 | 55 | 56 | 57 | 58 | <%end%> 59 |
<%=func_data.private and "local " or ""%><%=func_name%> (<%=table.concat(func_data.param, ", ")%>)<%=func_data.summary%>
60 | <%end%> 61 | 62 | 63 | <%if #file_doc.tables > 0 then%> 64 |

Tables

65 | 66 | <%for _, tab_name in ipairs(file_doc.tables) do%> 67 | 68 | 69 | 70 | 71 | <%end%> 72 |
<%=tab_name%><%=file_doc.tables[tab_name].summary%>
73 | <%end%> 74 | 75 | 76 |
77 |
78 | 79 | 80 | 81 | <%if #file_doc.functions > 0 then%> 82 |

Functions

83 |
84 | <%for _, func_name in ipairs(file_doc.functions) do%> 85 | <%=luadoc.doclet.html.include("function.lp", { doc=doc, file_doc=file_doc, func=file_doc.functions[func_name] })%> 86 | <%end%> 87 |
88 | <%end%> 89 | 90 | 91 | <%if #file_doc.tables > 0 then%> 92 |

Tables

93 |
94 | <%for _, tab_name in ipairs(file_doc.tables) do%> 95 | <%=luadoc.doclet.html.include("table.lp", { doc=doc, file_doc=file_doc, tab=file_doc.tables[tab_name] })%> 96 | <%end%> 97 |
98 | <%end%> 99 | 100 | 101 | 102 |
103 | 104 |
105 | 106 |
107 |

Valid XHTML 1.0!

108 |
109 | 110 |
111 | 112 | 113 | -------------------------------------------------------------------------------- /etc/luadoc/function.lp: -------------------------------------------------------------------------------- 1 | <% 2 | if module_doc then 3 | from = "modules/"..module_doc.name 4 | elseif file_doc then 5 | from = "files/.."..file_doc.name 6 | else 7 | from = "" 8 | end 9 | %> 10 | 11 |
<%=func.private and "local " or ""%><%=func.name%> (<%=table.concat(func.param, ", ")%>)
12 |
13 | <%=func.description or ""%> 14 | 15 | <%if type(func.param) == "table" and #func.param > 0 then%> 16 |

Parameters

17 | 24 | <%end%> 25 | 26 | 27 | <%if type(func.usage) == "string" then%> 28 |

Usage:

29 | <%=func.usage%> 30 | <%elseif type(func.usage) == "table" then%> 31 |

Usage

32 | 37 | <%end%> 38 | 39 | <%if type(func.ret) == "string" then%> 40 |

Return value:

41 | <%=func.ret%> 42 | <%elseif type(func.ret) == "table" then%> 43 |

Return values:

44 |
    45 | <%for _, ret in ipairs(func.ret) do%> 46 |
  1. <%= ret %> 47 | <%end%> 48 |
49 | <%end%> 50 | 51 | <%if type(func.see) == "string" then %> 52 |

See also:

53 | <%=func.see%> 54 | <%elseif type(func.see) == "table" and #func.see > 0 then %> 55 |

See also:

56 | 63 | <%end%> 64 |
65 | -------------------------------------------------------------------------------- /etc/luadoc/index.lp: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | " type="text/css" /> 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 25 | 26 |
27 |

README

28 |
29 | 
30 | 31 | <%if not options.nomodules and #doc.modules > 0 then%> 32 |

Modules

33 | 34 | 35 | <%for _, modulename in ipairs(doc.modules) do%> 36 | 37 | 38 | 39 | 40 | <%end%> 41 |
<%=modulename%><%=doc.modules[modulename].summary%>
42 | <%end%> 43 | 44 | 45 | 46 | <%if not options.nofiles and #doc.files > 0 then%> 47 |

Files

48 | 49 | 50 | <%for _, filepath in ipairs(doc.files) do%> 51 | 52 | 53 | 54 | 55 | <%end%> 56 |
<%=filepath%>
57 | <%end%> 58 | 59 |
60 | 61 |
62 | 63 | 66 | 67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /etc/luadoc/luadoc.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-left: 1em; 3 | margin-right: 1em; 4 | font-family: arial, helvetica, geneva, sans-serif; 5 | background-color:#ffffff; margin:0px; 6 | } 7 | 8 | code { 9 | font-family: "Andale Mono", monospace; 10 | } 11 | 12 | tt { 13 | font-family: "Andale Mono", monospace; 14 | } 15 | 16 | body, td, th { font-size: 11pt; } 17 | 18 | h1, h2, h3, h4 { margin-left: 0em; } 19 | 20 | textarea, pre, tt { font-size:10pt; } 21 | body, td, th { color:#000000; } 22 | small { font-size:0.85em; } 23 | h1 { font-size:1.5em; } 24 | h2 { font-size:1.25em; } 25 | h3 { font-size:1.15em; } 26 | h4 { font-size:1.06em; } 27 | 28 | a:link { font-weight:bold; color: #004080; text-decoration: none; } 29 | a:visited { font-weight:bold; color: #006699; text-decoration: none; } 30 | a:link:hover { text-decoration:underline; } 31 | hr { color:#cccccc } 32 | img { border-width: 0px; } 33 | 34 | 35 | h3 { padding-top: 1em; } 36 | 37 | p { margin-left: 1em; } 38 | 39 | p.name { 40 | font-family: "Andale Mono", monospace; 41 | padding-top: 1em; 42 | margin-left: 0em; 43 | } 44 | 45 | blockquote { margin-left: 3em; } 46 | 47 | pre.example { 48 | background-color: rgb(245, 245, 245); 49 | border-top-width: 1px; 50 | border-right-width: 1px; 51 | border-bottom-width: 1px; 52 | border-left-width: 1px; 53 | border-top-style: solid; 54 | border-right-style: solid; 55 | border-bottom-style: solid; 56 | border-left-style: solid; 57 | border-top-color: silver; 58 | border-right-color: silver; 59 | border-bottom-color: silver; 60 | border-left-color: silver; 61 | padding: 1em; 62 | margin-left: 1em; 63 | margin-right: 1em; 64 | font-family: "Andale Mono", monospace; 65 | font-size: smaller; 66 | } 67 | 68 | 69 | hr { 70 | margin-left: 0em; 71 | background: #00007f; 72 | border: 0px; 73 | height: 1px; 74 | } 75 | 76 | ul { list-style-type: disc; } 77 | 78 | table.index { border: 1px #00007f; } 79 | table.index td { text-align: left; vertical-align: top; } 80 | table.index ul { padding-top: 0em; margin-top: 0em; } 81 | 82 | table { 83 | border: 1px solid black; 84 | border-collapse: collapse; 85 | margin-left: auto; 86 | margin-right: auto; 87 | } 88 | th { 89 | border: 1px solid black; 90 | padding: 0.5em; 91 | } 92 | td { 93 | border: 1px solid black; 94 | padding: 0.5em; 95 | } 96 | div.header, div.footer { margin-left: 0em; } 97 | 98 | #container 99 | { 100 | margin-left: 1em; 101 | margin-right: 1em; 102 | background-color: #f0f0f0; 103 | } 104 | 105 | #product 106 | { 107 | text-align: center; 108 | border-bottom: 1px solid #cccccc; 109 | background-color: #ffffff; 110 | } 111 | 112 | #product big { 113 | font-size: 2em; 114 | } 115 | 116 | #product_logo 117 | { 118 | } 119 | 120 | #product_name 121 | { 122 | } 123 | 124 | #product_description 125 | { 126 | } 127 | 128 | #main 129 | { 130 | background-color: #f0f0f0; 131 | border-left: 2px solid #cccccc; 132 | } 133 | 134 | #navigation 135 | { 136 | float: left; 137 | width: 18em; 138 | margin: 0; 139 | vertical-align: top; 140 | background-color: #f0f0f0; 141 | overflow:visible; 142 | } 143 | 144 | #navigation h1 { 145 | background-color:#e7e7e7; 146 | font-size:1.1em; 147 | color:#000000; 148 | text-align:left; 149 | margin:0px; 150 | padding:0.2em; 151 | border-top:1px solid #dddddd; 152 | border-bottom:1px solid #dddddd; 153 | } 154 | 155 | #navigation ul 156 | { 157 | font-size:1em; 158 | list-style-type: none; 159 | padding: 0; 160 | margin: 1px; 161 | } 162 | 163 | #navigation li 164 | { 165 | text-indent: -1em; 166 | margin: 0em 0em 0em 0.5em; 167 | display: block; 168 | padding: 3px 0px 0px 12px; 169 | } 170 | 171 | #navigation li li a 172 | { 173 | padding: 0px 3px 0px -1em; 174 | } 175 | 176 | #content 177 | { 178 | margin-left: 18em; 179 | padding: 1em; 180 | border-left: 2px solid #cccccc; 181 | border-right: 2px solid #cccccc; 182 | background-color: #ffffff; 183 | } 184 | 185 | #about 186 | { 187 | clear: both; 188 | margin: 0; 189 | padding: 5px; 190 | border-top: 2px solid #cccccc; 191 | background-color: #ffffff; 192 | } 193 | 194 | @media print { 195 | body { 196 | font: 12pt "Times New Roman", "TimeNR", Times, serif; 197 | } 198 | a { font-weight:bold; color: #004080; text-decoration: underline; } 199 | 200 | #main { background-color: #ffffff; border-left: 0px; } 201 | #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } 202 | 203 | #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } 204 | 205 | #navigation { display: none; 206 | } 207 | pre.example { 208 | font-family: "Andale Mono", monospace; 209 | font-size: 10pt; 210 | page-break-inside: avoid; 211 | } 212 | } 213 | 214 | table.module_list td 215 | { 216 | border-width: 1px; 217 | padding: 3px; 218 | border-style: solid; 219 | border-color: #cccccc; 220 | } 221 | table.module_list td.name { background-color: #f0f0f0; } 222 | table.module_list td.summary { width: 100%; } 223 | 224 | table.file_list 225 | { 226 | border-width: 1px; 227 | border-style: solid; 228 | border-color: #cccccc; 229 | border-collapse: collapse; 230 | } 231 | table.file_list td 232 | { 233 | border-width: 1px; 234 | padding: 3px; 235 | border-style: solid; 236 | border-color: #cccccc; 237 | } 238 | table.file_list td.name { background-color: #f0f0f0; } 239 | table.file_list td.summary { width: 100%; } 240 | 241 | 242 | table.function_list 243 | { 244 | border-width: 1px; 245 | border-style: solid; 246 | border-color: #cccccc; 247 | border-collapse: collapse; 248 | } 249 | table.function_list td 250 | { 251 | border-width: 1px; 252 | padding: 3px; 253 | border-style: solid; 254 | border-color: #cccccc; 255 | } 256 | table.function_list td.name { background-color: #f0f0f0; } 257 | table.function_list td.summary { width: 100%; } 258 | 259 | 260 | table.table_list 261 | { 262 | border-width: 1px; 263 | border-style: solid; 264 | border-color: #cccccc; 265 | border-collapse: collapse; 266 | } 267 | table.table_list td 268 | { 269 | border-width: 1px; 270 | padding: 3px; 271 | border-style: solid; 272 | border-color: #cccccc; 273 | } 274 | table.table_list td.name { background-color: #f0f0f0; } 275 | table.table_list td.summary { width: 100%; } 276 | 277 | dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} 278 | dl.function dd {padding-bottom: 1em;} 279 | dl.function h3 {padding: 0; margin: 0; font-size: medium;} 280 | 281 | dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;} 282 | dl.table dd {padding-bottom: 1em;} 283 | dl.table h3 {padding: 0; margin: 0; font-size: medium;} 284 | 285 | #TODO: make module_list, file_list, function_list, table_list inherit from a list 286 | 287 | -------------------------------------------------------------------------------- /etc/luadoc/menu.lp: -------------------------------------------------------------------------------- 1 | <% 2 | if module_doc then 3 | from = "modules/"..module_doc.name 4 | elseif file_doc then 5 | from = "files/.."..file_doc.name 6 | else 7 | from = "" 8 | end 9 | %> 10 | 11 |

roslua

12 | 13 | 20 | 21 | 22 | 23 | <%if not options.nomodules and #doc.modules > 0 then%> 24 |

Modules

25 | 36 | <%end%> 37 | 38 | 39 | 40 | <%if not options.nofiles and #doc.files > 0 then%> 41 |

Files

42 | 53 | <%end%> 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /etc/luadoc/module.lp: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Reference 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 | 15 |
roslua: ROS client library for Lua
16 |
17 |
18 | 19 |
20 | 21 | 25 | 26 |
27 | 28 |

Module <%=module_doc.name%>

29 | 30 |

<%=module_doc.description%>

31 | <%if module_doc.author then%> 32 |

<%= #module_doc.author>1 and "Authors" or "Author" %>: 33 | 34 | <%for _, author in ipairs(module_doc.author) do%> 35 | 36 | <%end%> 37 |
<%= author %>
38 |

39 | <%end%> 40 | <%if module_doc.copyright then%> 41 |

Copyright© <%=module_doc.copyright%>

42 | <%end%> 43 | <%if module_doc.release then%> 44 |

Release: <%=module_doc.release%>

45 | <%end%> 46 | 47 | <%if #module_doc.functions > 0 then%> 48 |

Functions

49 | 50 | <%for _, func_name in ipairs(module_doc.functions) do 51 | local func_data = module_doc.functions[func_name]%> 52 | 53 | 54 | 55 | 56 | <%end%> 57 |
<%=func_data.private and "local " or ""%><%=func_name%> (<%=table.concat(module_doc.functions[func_name].param, ", ")%>)<%=module_doc.functions[func_name].summary%>
58 | <%end%> 59 | 60 | 61 | <%if #module_doc.tables > 0 then%> 62 |

Tables

63 | 64 | <%for _, tab_name in ipairs(module_doc.tables) do%> 65 | 66 | 67 | 68 | 69 | <%end%> 70 |
<%=tab_name%><%=module_doc.tables[tab_name].summary%>
71 | <%end%> 72 | 73 | 74 |
75 |
76 | 77 | 78 | <%if #module_doc.functions > 0 then%> 79 |

Functions

80 |
81 | <%for _, func_name in ipairs(module_doc.functions) do%> 82 | <%=luadoc.doclet.html.include("function.lp", { doc=doc, module_doc=module_doc, func=module_doc.functions[func_name] })%> 83 | <%end%> 84 |
85 | <%end%> 86 | 87 | 88 | <%if #module_doc.tables > 0 then%> 89 |

Tables

90 |
91 | <%for _, tab_name in ipairs(module_doc.tables) do%> 92 | <%=luadoc.doclet.html.include("table.lp", { doc=doc, module_doc=module_doc, tab=module_doc.tables[tab_name] })%> 93 | <%end%> 94 |
95 | <%end%> 96 | 97 | 98 |
99 | 100 |
101 | 102 |
103 |

Valid XHTML 1.0!

104 |
105 | 106 |
107 | 108 | 109 | -------------------------------------------------------------------------------- /etc/luadoc/table.lp: -------------------------------------------------------------------------------- 1 |
<%=tab.name%>
2 |
<%=tab.description%> 3 | 4 | <%if type(tab.field) == "table" and #tab.field > 0 then%> 5 | Fields 6 | 13 | <%end%> 14 | 15 |
16 | -------------------------------------------------------------------------------- /mainpage.dox: -------------------------------------------------------------------------------- 1 | /** 2 | \mainpage 3 | \htmlinclude manifest.html 4 | 5 | \b roslua is ... 6 | 7 | 10 | 11 | 12 | \section codeapi Code API 13 | 14 | 24 | 25 | 26 | */ 27 | -------------------------------------------------------------------------------- /manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | This package is a Lua client library for ROS. It allows connecting to a 4 | rosmaster instance and to develop ROS packages in Lua. 5 | 6 | Tim Niemueller 7 | BSD 8 | 9 | http://ros.org/wiki/roslua 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /rosdep.yaml: -------------------------------------------------------------------------------- 1 | lua: 2 | fedora: lua 3 | ubuntu: lua5.1 4 | lua-devel: 5 | fedora: lua-devel 6 | ubuntu: liblua5.1-0-dev 7 | lua-md5: 8 | fedora: lua-md5 9 | ubuntu: liblua5.1-md5-0 10 | lua-posix: 11 | fedora: lua-posix 12 | ubuntu: liblua5.1-posix1 13 | lua-socket: 14 | fedora: lua-socket 15 | ubuntu: liblua5.1-socket2 16 | lua-wsapi: 17 | fedora: lua-wsapi 18 | ubuntu: liblua5.1-wsapi1 19 | lua-xmlrpc: 20 | fedora: lua-xmlrpc 21 | ubuntu: liblua5.1-xmlrpc0 22 | tolua++: 23 | fedora: tolua++ 24 | ubuntu: libtolua++5.1-dev 25 | xavante: 26 | fedora: xavante 27 | ubuntu: xavante 28 | -------------------------------------------------------------------------------- /src/examples/publisher.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- publisher.lua - publisher implementation test 4 | -- 5 | -- Created: Tue Jul 28 10:40:33 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- Licensed under BSD license, cf. LICENSE file of roslua 8 | ---------------------------------------------------------------------------- 9 | 10 | require("roslua") 11 | 12 | roslua.init_node{node_name="talkerpub"} 13 | 14 | local topic = "chatter" 15 | local msgtype = "std_msgs/String" 16 | 17 | local p = roslua.publisher(topic, msgtype) 18 | 19 | while not roslua.quit do 20 | roslua.spin() 21 | 22 | local m = p.msgspec:instantiate() 23 | m.values.data = "hello world " .. tostring(roslua.Time.now()) 24 | p:publish(m) 25 | roslua.sleep(0.1) 26 | end 27 | roslua.finalize() 28 | 29 | -------------------------------------------------------------------------------- /src/examples/service_client.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- service_client.lua - service client example 4 | -- 5 | -- Created: Fri Jul 30 10:58:59 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- Licensed under BSD license, cf. LICENSE file of roslua 8 | ---------------------------------------------------------------------------- 9 | 10 | require("roslua") 11 | 12 | roslua.init_node{node_name="serviceclient"} 13 | 14 | -- Number of iterations to call the service 15 | local LOOPS = 3 16 | -- Sleep 5 seconds after each iteration but the last? 17 | local SLEEP_PER_LOOP = false 18 | 19 | local service = "add_two_ints" 20 | local srvtype = "rospy_tutorials/AddTwoInts" 21 | 22 | local s = roslua.service_client(service, srvtype, {simplified_return=true}) 23 | math.randomseed(os.time()) 24 | 25 | for i = 1, LOOPS do 26 | local a, b = math.random(1000), math.random(1000) 27 | 28 | -- Use simple form without concurrent execution 29 | local ok, res = pcall(s, {a, b}) 30 | 31 | if ok then 32 | print(a .. " + " .. b .. " = " .. res) 33 | else 34 | printf("%s", res) 35 | end 36 | 37 | -- Sleep after loop, for example to restart provider in between loops 38 | if i ~= LOOPS and SLEEP_PER_LOOP then roslua.sleep(5.0) end 39 | end 40 | 41 | roslua.finalize() 42 | -------------------------------------------------------------------------------- /src/examples/service_client_concexec.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- service_client_concexec.lua - concurrent service client example 4 | -- 5 | -- Created: Tue Sep 20 18:27:22 2011 (Papas 65.!) 6 | -- Copyright 2010-2011 Tim Niemueller [www.niemueller.de] 7 | -- Licensed under BSD license, cf. LICENSE file of roslua 8 | ---------------------------------------------------------------------------- 9 | 10 | require("roslua") 11 | 12 | roslua.init_node{node_name="serviceclient"} 13 | 14 | -- Number of iterations to call the service 15 | local LOOPS = 3 16 | -- Sleep 5 seconds after each iteration but the last? 17 | local SLEEP_PER_LOOP = false 18 | 19 | local service = "add_two_ints" 20 | local srvtype = "rospy_tutorials/AddTwoInts" 21 | 22 | local s = roslua.service_client(service, srvtype, {simplified_return=true}) 23 | math.randomseed(os.time()) 24 | 25 | for i = 1, LOOPS do 26 | local a, b = math.random(1000), math.random(1000) 27 | 28 | -- Use more complex but also more powerful form of execution 29 | -- which can be run concurrent to other tasks 30 | 31 | s:concexec_start{a, b} 32 | 33 | local running = true 34 | while running do 35 | if s:concexec_succeeded() then 36 | print(a .. " + " .. b .. " = " .. s:concexec_result()) 37 | running = false 38 | elseif s:concexec_failed() then 39 | printf("%s", s.concexec_error) 40 | running = false 41 | end 42 | roslua.sleep(0.1) 43 | end 44 | 45 | -- Sleep after loop, for example to restart provider in between loops 46 | if i ~= LOOPS and SLEEP_PER_LOOP then roslua.sleep(5.0) end 47 | end 48 | 49 | roslua.finalize() 50 | -------------------------------------------------------------------------------- /src/examples/service_provider.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- service_provider.lua - service provider example 4 | -- 5 | -- Created: Thu Jul 29 15:55:38 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- Licensed under BSD license, cf. LICENSE file of roslua 8 | ---------------------------------------------------------------------------- 9 | 10 | require("roslua") 11 | 12 | roslua.init_node{node_name="serviceprovider"} 13 | 14 | local service = "add_two_ints" 15 | local srvtype = "rospy_tutorials/AddTwoInts" 16 | 17 | function add_two_ints(a, b) 18 | -- Randomly fail to show and test error handling 19 | if math.random() < 0.3 then error("Failed on purpose") end 20 | print(a .. " + " .. b .. " = " .. a+b) 21 | return { a + b } 22 | end 23 | 24 | local p = roslua.service(service, srvtype, add_two_ints) 25 | 26 | roslua.run() 27 | 28 | -------------------------------------------------------------------------------- /src/examples/subscriber.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- subscriber.lua - subscriber example 4 | -- 5 | -- Created: Mon Jul 27 15:37:01 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- Licensed under BSD license, cf. LICENSE file of roslua 8 | ---------------------------------------------------------------------------- 9 | 10 | require("roslua") 11 | require("roslua.names") 12 | 13 | roslua.init_node{node_name="talkersub"} 14 | 15 | local topic = "chatter" 16 | local msgtype = "std_msgs/String" 17 | 18 | local s = roslua.subscriber(topic, msgtype) 19 | s:add_listener(function (message) 20 | message:print() 21 | end) 22 | 23 | roslua.run() 24 | 25 | -------------------------------------------------------------------------------- /src/examples/timer.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- timer.lua - timer example 4 | -- 5 | -- Created: Fri Apr 15 12:53:22 2011 6 | -- Copyright 2010-2011 Tim Niemueller [www.niemueller.de] 7 | -- 2010-2011 Carnegie Mellon University 8 | -- 2010-2011 Intel Labs Pittsburgh 9 | -- 2011 SRI International 10 | -- Licensed under BSD license, cf. LICENSE file of roslua 11 | ---------------------------------------------------------------------------- 12 | 13 | require("roslua") 14 | 15 | roslua.init_node{node_name="timertest"} 16 | 17 | function callback(event) 18 | local offset = (event.current_real - event.current_expected):to_sec() 19 | 20 | printf("Timer CB, Last Exp: %s Last Real: %s Cur Exp: %s Cur Real: %s " 21 | .. " Last Dur: %f Offset: %f", tostring(event.last_expected), 22 | tostring(event.last_real), tostring(event.current_expected), 23 | tostring(event.current_real), event.last_duration, offset) 24 | end 25 | 26 | local t = roslua.timer(1.0, callback) 27 | 28 | roslua.run(10) 29 | --[[ 30 | while not roslua.quit do 31 | roslua.spin() 32 | roslua.sleep(0.1) 33 | end 34 | roslua.finalize() 35 | --]] 36 | -------------------------------------------------------------------------------- /src/lua_modules/modemuncher.c: -------------------------------------------------------------------------------- 1 | /* 2 | Mode Muncher -- modemuncher.c 3 | 961110 Claudio Terra 4 | 5 | munch vb 6 | [ME monchen, perh. influenced by MF mangier to eat --more at MANGER] 7 | :to chew with a crunching sound: eat with relish 8 | :to chew food with a crunching sound: eat food with relish 9 | --munch-er n 10 | 11 | The NeXT Digital Edition of Webster's Ninth New Collegiate Dictionary 12 | and Webster's Collegiate Thesaurus 13 | */ 14 | 15 | /* struct for rwx <-> POSIX constant lookup tables */ 16 | struct modeLookup 17 | { 18 | char rwx; 19 | mode_t bits; 20 | }; 21 | 22 | typedef struct modeLookup modeLookup; 23 | 24 | static modeLookup modesel[] = 25 | { 26 | /* RWX char Posix Constant */ 27 | {'r', S_IRUSR}, 28 | {'w', S_IWUSR}, 29 | {'x', S_IXUSR}, 30 | 31 | {'r', S_IRGRP}, 32 | {'w', S_IWGRP}, 33 | {'x', S_IXGRP}, 34 | 35 | {'r', S_IROTH}, 36 | {'w', S_IWOTH}, 37 | {'x', S_IXOTH}, 38 | {0, (mode_t)-1} /* do not delete this line */ 39 | }; 40 | 41 | 42 | 43 | static int rwxrwxrwx(mode_t *mode, const char *p) 44 | { 45 | int count; 46 | mode_t tmp_mode = *mode; 47 | 48 | tmp_mode &= ~(S_ISUID | S_ISGID); /* turn off suid and sgid flags */ 49 | for (count=0; count<9; count ++) 50 | { 51 | if (*p == modesel[count].rwx) tmp_mode |= modesel[count].bits; /* set a bit */ 52 | else if (*p == '-') tmp_mode &= ~modesel[count].bits; /* clear a bit */ 53 | else if (*p=='s') switch(count) 54 | { 55 | case 2: /* turn on suid flag */ 56 | tmp_mode |= S_ISUID | S_IXUSR; 57 | break; 58 | 59 | case 5: /* turn on sgid flag */ 60 | tmp_mode |= S_ISGID | S_IXGRP; 61 | break; 62 | 63 | default: 64 | return -4; /* failed! -- bad rwxrwxrwx mode change */ 65 | break; 66 | } 67 | p++; 68 | } 69 | *mode = tmp_mode; 70 | return 0; 71 | } 72 | 73 | static void modechopper(mode_t mode, char *p) 74 | { 75 | /* requires char p[10] */ 76 | int count; 77 | char *pp; 78 | 79 | pp=p; 80 | 81 | for (count=0; count<9; count ++) 82 | { 83 | if (mode & modesel[count].bits) *p = modesel[count].rwx; 84 | else *p='-'; 85 | 86 | p++; 87 | } 88 | *p=0; /* to finish the string */ 89 | 90 | /* dealing with suid and sgid flags */ 91 | if (mode & S_ISUID) pp[2] = (mode & S_IXUSR) ? 's' : 'S'; 92 | if (mode & S_ISGID) pp[5] = (mode & S_IXGRP) ? 's' : 'S'; 93 | 94 | } 95 | 96 | static int mode_munch(mode_t *mode, const char* p) 97 | { 98 | char op=0; 99 | mode_t affected_bits, ch_mode; 100 | int doneFlag = 0; 101 | #ifdef DEBUG 102 | char tmp[10]; 103 | #endif 104 | 105 | #ifdef DEBUG 106 | modechopper(*mode, tmp); 107 | printf("modemuncher: got base mode = %s\n", tmp); 108 | #endif 109 | 110 | while (!doneFlag) 111 | { 112 | /* step 0 -- clear temporary variables */ 113 | affected_bits=0; 114 | ch_mode=0; 115 | 116 | /* step 1 -- who's affected? */ 117 | 118 | #ifdef DEBUG 119 | printf("modemuncher step 1\n"); 120 | #endif 121 | 122 | /* mode string given in rwxrwxrwx format */ 123 | if (*p== 'r' || *p == '-') return rwxrwxrwx(mode, p); 124 | 125 | /* mode string given in ugoa+-=rwx format */ 126 | for ( ; ; p++) 127 | switch (*p) 128 | { 129 | case 'u': 130 | affected_bits |= 04700; 131 | break; 132 | 133 | case 'g': 134 | affected_bits |= 02070; 135 | break; 136 | 137 | case 'o': 138 | affected_bits |= 01007; 139 | break; 140 | 141 | case 'a': 142 | affected_bits |= 07777; 143 | break; 144 | 145 | /* ignore spaces */ 146 | case ' ': 147 | break; 148 | 149 | 150 | default: 151 | goto no_more_affected; 152 | } 153 | 154 | no_more_affected: 155 | /* If none specified, affect all bits. */ 156 | if (affected_bits == 0) affected_bits = 07777; 157 | 158 | /* step 2 -- how is it changed? */ 159 | 160 | #ifdef DEBUG 161 | printf("modemuncher step 2 (*p='%c')\n", *p); 162 | #endif 163 | 164 | switch (*p) 165 | { 166 | case '+': 167 | case '-': 168 | case '=': 169 | op = *p; 170 | break; 171 | 172 | /* ignore spaces */ 173 | case ' ': 174 | break; 175 | 176 | default: 177 | return -1; /* failed! -- bad operator */ 178 | } 179 | 180 | 181 | /* step 3 -- what are the changes? */ 182 | 183 | #ifdef DEBUG 184 | printf("modemuncher step 3\n"); 185 | #endif 186 | 187 | for (p++ ; *p!=0 ; p++) 188 | switch (*p) 189 | { 190 | case 'r': 191 | ch_mode |= 00444; 192 | break; 193 | 194 | case 'w': 195 | ch_mode |= 00222; 196 | break; 197 | 198 | case 'x': 199 | ch_mode |= 00111; 200 | break; 201 | 202 | case 's': 203 | /* Set the setuid/gid bits if `u' or `g' is selected. */ 204 | ch_mode |= 06000; 205 | break; 206 | 207 | /* ignore spaces */ 208 | case ' ': 209 | break; 210 | 211 | default: 212 | goto specs_done; 213 | } 214 | 215 | specs_done: 216 | /* step 4 -- apply the changes */ 217 | 218 | #ifdef DEBUG 219 | printf("modemuncher step 4\n"); 220 | #endif 221 | if (*p != ',') doneFlag = 1; 222 | if (*p != 0 && *p != ' ' && *p != ',') 223 | { 224 | 225 | #ifdef DEBUG 226 | printf("modemuncher: comma error!\n"); 227 | printf("modemuncher: doneflag = %u\n", doneFlag); 228 | #endif 229 | return -2; /* failed! -- bad mode change */ 230 | 231 | } 232 | p++; 233 | /*if (!ch_mode) return -2;*/ /* failed! -- bad mode change */ 234 | if (ch_mode) switch (op) 235 | { 236 | case '+': 237 | *mode |= ch_mode & affected_bits; 238 | break; 239 | 240 | case '-': 241 | *mode &= ~(ch_mode & affected_bits); 242 | break; 243 | 244 | case '=': 245 | *mode = ch_mode & affected_bits; 246 | break; 247 | 248 | default: 249 | return -3; /* failed! -- unknown error */ 250 | } 251 | } 252 | #ifdef DEBUG 253 | modechopper(*mode, tmp); 254 | printf("modemuncher: returning mode = %s\n", tmp); 255 | #endif 256 | 257 | return 0; /* successful call */ 258 | } 259 | 260 | 261 | -------------------------------------------------------------------------------- /src/roslua/logging.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- logging.lua - roslua logging facilities 4 | -- 5 | -- Created: Tue Aug 10 09:46:10 2010 (at Intel Research, Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010-2011 Tim Niemueller [www.niemueller.de] 8 | -- 2010-2011 Carnegie Mellon University 9 | -- 2010 Intel Research Pittsburgh 10 | -- 2011 SRI International 11 | ---------------------------------------------------------------------------- 12 | 13 | --- Logging facilities for roslua. 14 | -- This module provides the framework for logging messages. Multiple loggers 15 | -- can be registered which are called for output. Two submodules are 16 | -- provided for logging to stdout and to rosout. 17 | -- A convenience method overrides the internal print function and adds a few 18 | -- more for specific log levels for convenient logging. 19 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 20 | -- @release Released under BSD license 21 | module("roslua.logging", package.seeall) 22 | 23 | DEBUG = 1 24 | INFO = 2 25 | WARN = 4 26 | ERROR = 8 27 | FATAL = 16 28 | 29 | log_level_strings = {} 30 | log_level_strings[DEBUG] = "DEBUG" 31 | log_level_strings[INFO] = "INFO" 32 | log_level_strings[WARN] = "WARN" 33 | log_level_strings[ERROR] = "ERROR" 34 | log_level_strings[FATAL] = "FATAL" 35 | 36 | local log_level = DEBUG 37 | local loggers = {} 38 | 39 | require("roslua.logging.stdout") 40 | local stdout_logger = roslua.logging.stdout.get_logger() 41 | loggers[stdout_logger] = stdout_logger 42 | 43 | --- Add a logger. 44 | -- @param logger logger to add, must be a function that accepts three arguments, 45 | -- the log level (number), the time (Time instance), and the message (string) 46 | function add_logger(logger) 47 | assert(type(logger) == "function", "Logger must be a function") 48 | loggers[logger] = logger 49 | end 50 | 51 | --- Remove a logger. 52 | -- @param logger logger to remove 53 | function remove_logger(logger) 54 | loggers[logger] = nil 55 | end 56 | 57 | --- Remove the stdout logger which is added by default. 58 | function remove_stdout_logger() 59 | remove_logger(stdout_logger) 60 | stdout_logger = nil 61 | end 62 | 63 | --- Set the log level 64 | -- @param level log level. Anything of the same or a higher level is shown. 65 | -- Anything below is not. 66 | function set_log_level(level) 67 | log_level = level 68 | end 69 | 70 | 71 | --- Register print functions. 72 | -- In the given environment it overwrites the print function and adds printf, 73 | -- print_debug, print_info, print_warn, print_error, and print_fatal. 74 | -- @param export_to module or table to export to 75 | function register_print_funcs(export_to) 76 | export_to.printscr = _M.printscr 77 | export_to.print = _M.print 78 | export_to.printf = _M.printf 79 | export_to.print_debug = _M.print_debug 80 | export_to.print_info = _M.print_info 81 | export_to.print_warn = _M.print_warn 82 | export_to.print_error = _M.print_error 83 | export_to.print_fatal = _M.print_fatal 84 | end 85 | 86 | local function dispatch(level, msg) 87 | if level < log_level then return end 88 | 89 | local t = roslua.Time.now() 90 | for _, l in pairs(loggers) do 91 | l(level, t, msg) 92 | end 93 | end 94 | 95 | --- Print function replacement for loggers. 96 | -- Can replace the standard print function and prints the given elements 97 | -- to loggers. Will be posted with INFO log level. 98 | -- @param ... variable number of string arguments 99 | function print(...) 100 | return dispatch(INFO, table.concat({...}, "\t")) 101 | end 102 | 103 | 104 | --- Print formatted to screen only. 105 | -- Prints a formatted string to screen. 106 | -- @param format format string (cf. string.format() documentation) 107 | -- @param ... appropriate arguments for format string 108 | function printscr(format, ...) 109 | io.write(string.format("[SCREEN] %s %s\n", 110 | tostring(roslua.Time.now()), string.format(format, ...))) 111 | end 112 | 113 | --- Print formatted. 114 | -- Prints a formatted string to loggers. Will be posted with INFO log level. 115 | -- @param format format string (cf. string.format() documentation) 116 | -- @param ... appropriate arguments for format string 117 | function printf(format, ...) 118 | return dispatch(INFO, string.format(format, ...)) 119 | end 120 | 121 | --- Print formatted. 122 | -- Prints a formatted string to loggers. Will be posted with DEBUG log level. 123 | -- @param format format string (cf. string.format() documentation) 124 | -- @param ... appropriate arguments for format string 125 | function print_debug(format, ...) 126 | return dispatch(DEBUG, string.format(format, ...)) 127 | end 128 | 129 | --- Print formatted. 130 | -- Prints a formatted string to loggers. Will be posted with INFO log level. 131 | -- @param format format string (cf. string.format() documentation) 132 | -- @param ... appropriate arguments for format string 133 | function print_info(format, ...) 134 | return dispatch(INFO, string.format(format, ...)) 135 | end 136 | 137 | --- Print formatted. 138 | -- Prints a formatted string to loggers. Will be posted with WARN log level. 139 | -- @param format format string (cf. string.format() documentation) 140 | -- @param ... appropriate arguments for format string 141 | function print_warn(format, ...) 142 | return dispatch(WARN, string.format(format, ...)) 143 | end 144 | 145 | --- Print formatted. 146 | -- Prints a formatted string to loggers. Will be posted with ERROR log level. 147 | -- @param format format string (cf. string.format() documentation) 148 | -- @param ... appropriate arguments for format string 149 | function print_error(format, ...) 150 | return dispatch(ERROR, string.format(format, ...)) 151 | end 152 | 153 | --- Print formatted. 154 | -- Prints a formatted string to loggers. Will be posted with FATAL log level. 155 | -- @param format format string (cf. string.format() documentation) 156 | -- @param ... appropriate arguments for format string 157 | function print_fatal(format, ...) 158 | return dispatch(FATAL, string.format(format, ...)) 159 | end 160 | -------------------------------------------------------------------------------- /src/roslua/logging/rosout.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- rosout.lua - rosout logger 4 | -- 5 | -- Created: Tue Aug 10 10:10:17 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | --- Logging facilities for roslua. 13 | -- This module provides a logger that logs to stdout. 14 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 15 | -- @release Released under BSD license 16 | module("roslua.logging.rosout", package.seeall) 17 | 18 | require("roslua") 19 | require("roslua.utils") 20 | 21 | pub_rosout = nil 22 | 23 | --- Log message to /rosout topic. 24 | -- @param level log level 25 | -- @param time timestamp of message 26 | -- @param msg message 27 | function log_rosout(level, time, msg) 28 | local lmsg = pub_rosout.msgspec:instantiate() 29 | lmsg.values.header.values.stamp = time 30 | lmsg.values.level = level 31 | lmsg.values.name = roslua.node_name 32 | lmsg.values.msg = msg 33 | lmsg.values.topics = {} 34 | for t, _ in pairs(roslua.publishers) do 35 | table.insert(lmsg.values.topics, t) 36 | end 37 | pub_rosout:publish(lmsg) 38 | end 39 | 40 | --- Get logger. 41 | -- Get the rosout logger, as a side effects initializes publisher. 42 | -- @return initialized rosout logger 43 | function get_logger() 44 | if not pub_rosout then 45 | local ros_ver_codename, ros_ver_major, ros_ver_minor, ros_ver_micro = 46 | roslua.utils.rosversion() 47 | if ros_ver_major < 1 or (ros_ver_major == 1 and ros_ver_minor < 4) then 48 | pub_rosout = roslua.publisher("/rosout", "roslib/Log") 49 | else 50 | pub_rosout = roslua.publisher("/rosout", "rosgraph_msgs/Log") 51 | end 52 | end 53 | return log_rosout 54 | end 55 | -------------------------------------------------------------------------------- /src/roslua/logging/stdout.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- stdout.lua - stdout logger 4 | -- 5 | -- Created: Tue Aug 10 10:05:49 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | -- Save this so that it is not overwritten once the logger is initialized 13 | -- and has overridden print 14 | local print = print 15 | 16 | --- Logging facilities for roslua. 17 | -- This module provides a logger that logs to stdout. 18 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 19 | -- @release Released under BSD license 20 | module("roslua.logging.stdout", package.seeall) 21 | 22 | require("roslua.logging") 23 | 24 | COLOR_GRAY = "\27[2;37m" 25 | COLOR_RED = "\27[0;31m" 26 | COLOR_BROWN = "\27[0;33m" 27 | COLOR_CYAN = "\27[0;36m" 28 | COLOR_PURPLE = "\27[0;35m" 29 | COLOR_NONE = "\27[0;39m" 30 | 31 | local overhang = {} 32 | overhang[roslua.logging.DEBUG]= "" 33 | overhang[roslua.logging.INFO] = " " 34 | overhang[roslua.logging.WARN] = " " 35 | overhang[roslua.logging.ERROR]= "" 36 | 37 | --- Log message to stdout. 38 | -- @param level log level 39 | -- @param time timestamp of message 40 | -- @param msg message 41 | function log_stdout(level, time, msg) 42 | local color, color_none = "", "" 43 | if level == roslua.logging.DEBUG then 44 | color = COLOR_GRAY 45 | elseif level == roslua.logging.WARN then 46 | color = COLOR_BROWN 47 | elseif level == roslua.logging.ERROR then 48 | color = COLOR_RED 49 | elseif level == roslua.logging.FATAL then 50 | color = COLOR_CYAN 51 | end 52 | if color ~= "" then color_none = COLOR_NONE end 53 | 54 | io.write(string.format("%s[%s]%s %s %s%s\n", color, roslua.logging.log_level_strings[level], 55 | overhang[level], tostring(time), msg, color_none)) 56 | end 57 | 58 | --- Get logger. 59 | -- @return initialized stdout logger 60 | function get_logger() 61 | return log_stdout 62 | end 63 | -------------------------------------------------------------------------------- /src/roslua/master_proxy.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- master_proxy.lua - Master XML-RPC proxy 4 | -- 5 | -- Created: Thu Jul 22 11:31:05 2010 (at Intel Research, Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 8 | -- 2010 Carnegie Mellon University 9 | -- 2010 Intel Research Pittsburgh 10 | ---------------------------------------------------------------------------- 11 | 12 | --- Master XML-RPC API proxy. 13 | -- This module contains the MasterProxy class to call methods provided via 14 | -- XML-RPC by the ROS master. 15 | --

16 | -- The user should not have to directly interact with the master. It is used 17 | -- register and unregister topic publishers/subscribers and services, to 18 | -- lookup nodes and services, and to gather information about the master. 19 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 20 | -- @release Released under BSD license 21 | module("roslua.master_proxy", package.seeall) 22 | 23 | require("roslua") 24 | require("xmlrpc") 25 | require("xmlrpc.http") 26 | assert(xmlrpc._VERSION_MAJOR and (xmlrpc._VERSION_MAJOR > 1 or xmlrpc._VERSION_MAJOR == 1 and xmlrpc._VERSION_MINOR >= 2), 27 | "You must use version 1.2 or newer of lua-xmlrpc") 28 | require("roslua.xmlrpc_post") 29 | 30 | __DEBUG = false 31 | 32 | MasterProxy = { ros_master_uri = nil, node_name = nil } 33 | 34 | --- Constructor. 35 | -- @param ros_master_uri XML-RPC HTTP URI of ROS master 36 | -- @param node_name name of this node 37 | function MasterProxy:new() 38 | local o = {} 39 | setmetatable(o, self) 40 | self.__index = self 41 | 42 | return o 43 | end 44 | 45 | -- (internal) execute XML-RPC call 46 | -- Will always prefix the arguments with the caller ID. 47 | -- @param method_name name of the method to execute 48 | -- @param ... Arguments depending on the method call 49 | function MasterProxy:do_call(method_name, ...) 50 | local ok, res = xmlrpc.http.call(roslua.master_uri, 51 | method_name, roslua.node_name, ...) 52 | assert(ok, string.format("XML-RPC call %s failed on client: %s", 53 | method_name, tostring(res))) 54 | if res[1] ~= 1 then 55 | error(string.format("XML-RPC call %s failed on server: %s", 56 | method_name, tostring(res[2])), 0) 57 | end 58 | 59 | if __DEBUG then 60 | print(string.format("Ok: %s Code: %d Error: %s", 61 | tostring(ok), res[1], res[2])) 62 | end 63 | 64 | return res 65 | end 66 | 67 | --- Get master system state. 68 | -- @return three array of registered publishers, subscribers, and services 69 | function MasterProxy:getSystemState() 70 | local res = self:do_call("getSystemState") 71 | 72 | local publishers = {} 73 | local subscribers = {} 74 | local services = {} 75 | 76 | for i, v in ipairs(res[3][1]) do 77 | publishers[v[1]] = v[2] 78 | end 79 | 80 | for i, v in ipairs(res[3][2]) do 81 | subscribers[v[1]] = v[2] 82 | end 83 | 84 | for i, v in ipairs(res[3][3]) do 85 | services[v[1]] = v[2] 86 | end 87 | 88 | return publishers, subscribers, services 89 | end 90 | 91 | --- Lookup node by name. 92 | -- @param name of node to lookup 93 | -- @return Slave API XML-RPC HTTP URI 94 | function MasterProxy:lookupNode(node_name) 95 | local res = self:do_call("lookupNode", node_name) 96 | 97 | return tostring(res[3]) 98 | end 99 | 100 | --- Get published topics. 101 | -- @param subgraph subgraph to query from master 102 | -- @return graph of topics 103 | function MasterProxy:getPublishedTopics(subgraph) 104 | local subgraph = subgraph or "" 105 | local res = self:do_call("getPublishedTopics", subgraph) 106 | 107 | return res[3] 108 | end 109 | 110 | --- Get master URI. 111 | -- Considering that you need to know the URI to call this method is's quite 112 | -- useless. 113 | -- @return ROS master URI 114 | function MasterProxy:getUri() 115 | local res = self:do_call("getUri") 116 | 117 | return res[3] 118 | end 119 | 120 | --- Lookup service by name. 121 | -- @param service name of service to lookup 122 | -- @return ROS RPC URI of service provider 123 | function MasterProxy:lookupService(service) 124 | local res = self:do_call("lookupService", roslua.resolve(service)) 125 | 126 | return res[3] 127 | end 128 | 129 | --- Start a lookup request. 130 | -- This starts a concurrent execution of lookupService(). 131 | -- @param service service to lookup 132 | -- @return XmlRpcRequest handle for the started request 133 | function MasterProxy:lookupService_conc(service) 134 | return roslua.xmlrpc_post.XmlRpcRequest:new(roslua.master_uri, "lookupService", 135 | roslua.node_name, 136 | roslua.resolve(service)) 137 | end 138 | 139 | --- Register a service with the master. 140 | -- @param service name of service to register 141 | -- @param service_api ROS RPC URI of service 142 | function MasterProxy:registerService(service, service_api) 143 | self:do_call("registerService", roslua.resolve(service), 144 | service_api, roslua.slave_uri) 145 | end 146 | 147 | --- Unregister a service from master. 148 | -- @param service name of service to register 149 | -- @param service_api ROS RPC URI of service 150 | function MasterProxy:unregisterService(service, service_api) 151 | self:do_call("unregisterService", roslua.resolve(service), service_api) 152 | end 153 | 154 | 155 | --- Register subscriber with the master. 156 | -- @param topic topic to register for 157 | -- @param topic_type type of the topic 158 | function MasterProxy:registerSubscriber(topic, topic_type) 159 | local res = self:do_call("registerSubscriber", roslua.resolve(topic), 160 | topic_type, roslua.slave_uri) 161 | 162 | return res[3] 163 | end 164 | 165 | --- Unregister subscriber from master. 166 | -- @param topic topic to register for 167 | function MasterProxy:unregisterSubscriber(topic) 168 | self:do_call("unregisterSubscriber", roslua.resolve(topic), roslua.slave_uri) 169 | end 170 | 171 | 172 | --- Register Publisher with the master. 173 | -- @param topic topic to register for 174 | -- @param topic_type type of the topic 175 | function MasterProxy:registerPublisher(topic, topic_type) 176 | local res = self:do_call("registerPublisher", 177 | roslua.resolve(topic), topic_type, roslua.slave_uri) 178 | 179 | return res[3] 180 | end 181 | 182 | --- Unregister publisher from master. 183 | -- @param topic topic to register for 184 | function MasterProxy:unregisterPublisher(topic) 185 | self:do_call("unregisterPublisher", roslua.resolve(topic), roslua.slave_uri) 186 | end 187 | -------------------------------------------------------------------------------- /src/roslua/names.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- names.lua - ROS name utilities 4 | -- 5 | -- Created: Wed Aug 03 10:58:26 2011 (at SRI International) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2011 Tim Niemueller [www.niemueller.de] 8 | -- 2011 SRI International 9 | -- 2011 Carnegie Mellon University 10 | ---------------------------------------------------------------------------- 11 | 12 | --- ROS name utilities. 13 | -- This module contains utilities to resolve ROS names based on 14 | -- namespace and remapping information. See http://www.ros.org/wiki/Names 15 | -- for information about ROS names. 16 | -- 17 | -- @copyright Tim Niemueller, SRI International, Carnegie Mellon University 18 | -- @release Released under BSD license 19 | module("roslua.names", package.seeall) 20 | 21 | require("roslua") 22 | 23 | remappings = {} 24 | 25 | --- Read remappings from arguments. 26 | -- This function is called before the node is initialized and before any 27 | -- ROS specific features have been initialized. 28 | function read_remappings() 29 | -- arg is a global array with command line arguments 30 | if not _G.arg then return end 31 | for i,v in ipairs(_G.arg) do 32 | local from, to = v:match("^([%w_/]+):=([%w_/.]+)$") 33 | if from and to then -- it's a mapping 34 | remappings[from] = to 35 | end 36 | end 37 | end 38 | 39 | --- Initialize remappings. 40 | -- This needs to be called after the namespace has been defined, but 41 | -- before the node is registered. It will apply name resolution to all 42 | -- left and right hand sides of remapping entries. 43 | function init_remappings() 44 | local resolved_remappings = {} 45 | for k, v in pairs(remappings) do 46 | if not k:match("^_") then 47 | resolved_remappings[resolve(k, true)] = resolve(v, true) 48 | else 49 | resolved_remappings[k] = v 50 | end 51 | end 52 | remappings = resolved_remappings 53 | end 54 | 55 | --- Validate a name. 56 | -- A name is valid if name is a string and it is either empty or 57 | -- matches the Lua pattern "^[%a/~][%w_/]*$". 58 | -- @param name name to validate 59 | -- @return true if the name is valid, false otherwise 60 | function validate(name) 61 | if type(name) ~= "string" then return false end 62 | if name == "" then return true end 63 | 64 | return name:match("^[%a/~][%w_/]*$") ~= nil 65 | end 66 | 67 | --- Validate the nodename. 68 | -- A valid nodename is a valid name with the special constraints that 69 | -- it may not start with slash or tilde. 70 | -- @param name name to validate 71 | -- @return true if the name is valid, false otherwise 72 | function validate_nodename(name) 73 | return validate(name) and not name:find("/") and not name:find("~") 74 | end 75 | 76 | --- Check if name is absolute. 77 | -- @param name name to check 78 | -- @return true if name is absolute, false otherwise 79 | function is_absolute(name) 80 | return name:match("^/") ~= nil 81 | end 82 | 83 | 84 | --- Cleanup name. 85 | -- This aggregates all sequential slashes to just one. 86 | -- @param name name to cleanup 87 | -- @return cleaned name 88 | function clean(name) 89 | assert(validate(name), "Invalid name passed for cleanup") 90 | local rv = name 91 | while rv:find("//") do 92 | rv = rv:gsub("//", "/") 93 | end 94 | if rv:match("/$") then 95 | rv = rv:sub(1, #rv - 1) 96 | end 97 | return rv 98 | end 99 | 100 | --- Get sanitized version of concatenated string. 101 | -- @param left left hand side 102 | -- @param right right hand side 103 | -- @return cleaned version of left .. "/" .. right 104 | function append(left, right) 105 | return clean(left .. "/" .. right) 106 | end 107 | 108 | --- Resolve a name. 109 | -- This function will resolve the given name according to the set 110 | -- namespace and remapping rules. 111 | -- @param name name to resolve 112 | -- @param no_remapping if omitted or false remapping is applied, if 113 | -- true remapping rules will not be applied 114 | -- @return resolved name 115 | function resolve(name, no_remapping) 116 | return resolve_ns(roslua.namespace, name, no_remapping) 117 | end 118 | 119 | 120 | --- Resolve a name relative to a namespace. 121 | -- This function will resolve the given name according to the set 122 | -- namespace and remapping rules relative to the given namespace. 123 | -- @param namespace namespace to use for name resolution 124 | -- @param name name to resolve 125 | -- @param no_remapping if omitted or false remapping is applied, if 126 | -- true remapping rules will not be applied 127 | -- @return resolved name 128 | function resolve_ns(namespace, name, no_remapping) 129 | assert(validate(name), "Invalid name") 130 | 131 | if name == "" then 132 | if roslua.namespace == "" then 133 | return "/" 134 | else 135 | return append("/", roslua.namespace) 136 | end 137 | end 138 | 139 | if name:match("^~") then 140 | name = append(roslua.node_name, name:sub(2)) 141 | end 142 | if not name:match("^/") then 143 | name = append("/" .. namespace, name) 144 | end 145 | 146 | if not no_remapping then 147 | name = remap(name) 148 | end 149 | 150 | return name 151 | end 152 | 153 | 154 | --- Apply remapping to given name. 155 | -- @param name name to apply remapping to 156 | -- @return name after applying remapping 157 | function remap(name) 158 | local resolved = resolve_ns(roslua.namespace, name, true) 159 | 160 | return remappings[resolved] or name 161 | end 162 | -------------------------------------------------------------------------------- /src/roslua/param_proxy.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- param_proxy.lua - Parameter server XML-RPC proxy 4 | -- 5 | -- Created: Thu Jul 22 14:37:22 2010 (at Intel Research, Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 8 | -- 2010 Carnegie Mellon University 9 | -- 2010 Intel Research Pittsburgh 10 | ---------------------------------------------------------------------------- 11 | 12 | --- Parameter XML-RPC API proxy. 13 | -- This module contains the ParamProxy class to call methods provided via 14 | -- XML-RPC by the parameter server. 15 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 16 | -- @release Released under BSD license 17 | module("roslua.param_proxy", package.seeall) 18 | 19 | require("xmlrpc") 20 | require("xmlrpc.http") 21 | assert(xmlrpc._VERSION_MAJOR and (xmlrpc._VERSION_MAJOR > 1 or xmlrpc._VERSION_MAJOR == 1 and xmlrpc._VERSION_MINOR >= 2), 22 | "You must use version 1.2 or newer of lua-xmlrpc") 23 | 24 | require("roslua") 25 | require("roslua.names") 26 | 27 | __DEBUG = false 28 | 29 | 30 | --- Initialize parameters. 31 | -- This reads the remappings and stores parameters (remapping left hand 32 | -- sides that start with a single underscore) in the parameter server. 33 | function init() 34 | for k, v in pairs(roslua.names.remappings) do 35 | local param = k:match("^_([%w][%w/_]*)$") 36 | if param then 37 | roslua.set_param("~" .. param, v) 38 | end 39 | end 40 | end 41 | 42 | 43 | ParamProxy = { ros_master_uri = nil, node_name = nil } 44 | 45 | --- Constructor. 46 | -- @param ros_master_uri XML-RPC HTTP URI of ROS master 47 | -- @param node_name name of this node 48 | function ParamProxy:new() 49 | local o = {} 50 | setmetatable(o, self) 51 | self.__index = self 52 | 53 | return o 54 | end 55 | 56 | 57 | -- (internal) execute XML-RPC call 58 | -- Will always prefix the arguments with the caller ID. 59 | -- @param method_name name of the method to execute 60 | -- @param ... Arguments depending on the method call 61 | function ParamProxy:do_call(method_name, ...) 62 | local ok, res = xmlrpc.http.call(roslua.master_uri, 63 | method_name, roslua.node_name, ...) 64 | assert(ok, string.format("XML-RPC call %s failed on client: %s", 65 | method_name, tostring(res))) 66 | assert(res[1] == 1, string.format("XML-RPC call %s failed on server: %s", 67 | method_name, tostring(res[2]))) 68 | 69 | if __DEBUG then 70 | print(string.format("Ok: %s Code: %d Error: %s", 71 | tostring(ok), res[1], res[2])) 72 | end 73 | 74 | return res 75 | end 76 | 77 | --- Get names of all available parameters. 78 | -- @return array with names of all parameters 79 | function ParamProxy:get_param_names() 80 | local res = self:do_call("getParamNames") 81 | 82 | return res[3] 83 | end 84 | 85 | --- Check if parameter exists. 86 | -- @param key key of the parameter to query 87 | -- @return true if the parameter exists, false otherwise 88 | function ParamProxy:has_param(key) 89 | local res = self:do_call("hasParam", roslua.resolve(key)) 90 | 91 | return res[3] 92 | end 93 | 94 | --- Get parameter. 95 | -- @param key key of the parameter to query 96 | -- @return value of the parameter 97 | function ParamProxy:get_param(key) 98 | local res = self:do_call("getParam", roslua.resolve(key)) 99 | 100 | return res[3] 101 | end 102 | 103 | --- Set parameter. 104 | -- @param key key of the parameter to set 105 | -- @param value value of the parameter to set 106 | function ParamProxy:set_param(key, value) 107 | self:do_call("setParam", roslua.resolve(key), tonumber(value) or value) 108 | end 109 | 110 | --- Delete parameter. 111 | -- @param key key of the parameter to delete 112 | function ParamProxy:delete_param(key) 113 | self:do_call("deleteParam", roslua.resolve(key)) 114 | end 115 | 116 | --- Search for parameter. 117 | -- @param key substring of the key to look for 118 | -- @return first key that matched 119 | function ParamProxy:search_param(key) 120 | local res = self:do_call("searchParam", roslua.resolve(key)) 121 | 122 | return res[3] 123 | end 124 | 125 | --- Subscribe to parameter. 126 | -- @param key key to subscribe to 127 | function ParamProxy:subscribe_param(key) 128 | local res = self:do_call("subscribeParam", roslua.slave_uri, 129 | roslua.resolve(key)) 130 | 131 | return res[3] 132 | end 133 | 134 | --- Unsubscribe from parameter. 135 | -- @param key key to unsubscribe from 136 | function ParamProxy:unsubscribe_param(key) 137 | self:do_call("subscribeParam", roslua.slave_uri, roslua.resolve(key)) 138 | end 139 | 140 | -------------------------------------------------------------------------------- /src/roslua/registry.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- registry.lua - Registry for topic/service registration 4 | -- 5 | -- Created: Fri Jul 30 14:52:10 2010 (at Intel Research, Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 8 | -- 2010 Carnegie Mellon University 9 | -- 2010 Intel Research Pittsburgh 10 | ---------------------------------------------------------------------------- 11 | 12 | --- Registry housekeeping. 13 | -- This module contains functions used for housekeeping of subscriptions, 14 | -- publishers, and services. They should not be used directly. 15 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 16 | -- @release Released under BSD license 17 | module("roslua.registry", package.seeall) 18 | 19 | require("roslua") 20 | 21 | subscribers = {} 22 | publishers = {} 23 | services = {} 24 | timers = {} 25 | 26 | --- Register subscriber. 27 | -- As a side effect registers the subscriber with the master. 28 | -- @param topic topic to register subscriber for 29 | -- @param type type of topic 30 | -- @param subscriber Subscriber instance to register 31 | -- @see Subscriber 32 | function register_subscriber(topic, type, subscriber) 33 | assert(not roslua.subscribers[topic], "Subscriber has already been registerd for " 34 | .. topic .. " (" .. type .. ")") 35 | 36 | roslua.subscribers[topic] = { type=type, subscriber=subscriber } 37 | 38 | local ok, pubs_err = pcall(roslua.master.registerSubscriber, roslua.master, topic, type) 39 | if not ok then 40 | error("Cannot connect to ROS master: " .. pubs_err) 41 | end 42 | subscriber:update_publishers(pubs_err, true) 43 | end 44 | 45 | --- Register publisher. 46 | -- As a side effect registers the publisher with the master. 47 | -- @param topic topic to register publisher for 48 | -- @param type type of topic 49 | -- @param publisher Publisher instance to register 50 | -- @see Publisher 51 | function register_publisher(topic, type, publisher) 52 | assert(not roslua.publishers[topic], "Publisher has already been registerd for " 53 | .. topic .. " (" .. type .. ")") 54 | 55 | local ok, subs_err = pcall(roslua.master.registerPublisher, roslua.master, topic, type) 56 | if not ok then 57 | error("Cannot connect to ROS master: " .. subs_err) 58 | end 59 | roslua.publishers[topic] = { type=type, publisher=publisher } 60 | end 61 | 62 | --- Register service provider. 63 | -- As a side effect registers the service provider with the master. 64 | -- @param topic topic to register service provider for 65 | -- @param type type of topic 66 | -- @param provider Service instance to register 67 | -- @see Service 68 | function register_service(service, type, provider) 69 | assert(not roslua.services[service], "Service already provided") 70 | 71 | local ok = pcall(roslua.master.registerService, roslua.master, service, provider:uri()) 72 | if not ok then 73 | error("Cannot connect to ROS master: " .. subs_err) 74 | end 75 | roslua.services[service] = { type=type, provider=provider } 76 | end 77 | 78 | --- Unregister subscriber. 79 | -- As a side effect unregisters the subscriber with the master. 80 | -- @param topic topic to register subscriber for 81 | -- @param type type of topic 82 | -- @param subscriber Subscriber instance to unregister 83 | -- @see Subscriber 84 | function unregister_subscriber(topic, type, subscriber) 85 | assert(roslua.subscribers[topic], "Topic " .. topic .. " has not been subscribed") 86 | assert(roslua.subscribers[topic].type == type, "Conflicting type for topic " .. topic 87 | .. " while unregistering subscriber (" .. roslua.subscribers[topic].type 88 | .. " vs. " .. type .. ")") 89 | assert(roslua.subscribers[topic].subscriber == subscriber, 90 | "Different subscribers for topic " .. topic .. " on unregistering subscriber") 91 | 92 | roslua.master:unregisterSubscriber(topic) 93 | roslua.subscribers[topic] = nil 94 | end 95 | 96 | --- Unregister publisher. 97 | -- As a side effect unregisters the publisher with the master. 98 | -- @param topic topic to unregister publisher for 99 | -- @param type type of topic 100 | -- @param publisher Publisher instance to unregister 101 | -- @see Publisher 102 | function unregister_publisher(topic, type, publisher) 103 | assert(roslua.publishers[topic], "Topic " .. topic .. " is not published") 104 | assert(roslua.publishers[topic].type == type, "Conflicting type for topic " .. topic 105 | .. " while unregistering publisher (" .. roslua.publishers[topic].type 106 | .. " vs. " .. type .. ")") 107 | assert(roslua.publishers[topic].publisher == publisher, 108 | "Different publishers for topic " .. topic .. " on unregistering publisher") 109 | 110 | roslua.master:unregisterPublisher(topic) 111 | roslua.publishers[topic] = nil 112 | end 113 | 114 | --- Unregister service provider. 115 | -- As a side effect unregisters the service provider with the master. 116 | -- @param topic topic to unregister service provider for 117 | -- @param type type of topic 118 | -- @param provider Service instance to unregister 119 | -- @see Service 120 | function unregister_service(service, type, provider) 121 | assert(roslua.services[service], "Service " .. service .. " is not provided") 122 | assert(roslua.services[service].type == type, "Conflicting type for service " .. service 123 | .. " while unregistering provider (" .. roslua.services[service].type 124 | .. " vs. " .. type .. ")") 125 | assert(roslua.services[service].provider == provider, 126 | "Different providers for service " .. service .. " on unregistering provider") 127 | 128 | roslua.master:unregisterService(service, roslua.services[service].provider:uri()) 129 | roslua.services[service] = nil 130 | end 131 | 132 | 133 | --- Register timer. 134 | -- @param timer timer to register 135 | -- @see Timer 136 | function register_timer(timer) 137 | assert(not roslua.timers[timer], "Timer has already been registered") 138 | 139 | roslua.timers[timer] = timer 140 | end 141 | 142 | 143 | --- Unregister timer 144 | -- @param timer timer to unregister 145 | -- @see Timer 146 | function unregister_timer(timer) 147 | assert(roslua.timers[timer], "Timer has not been registered") 148 | 149 | roslua.timers[timer] = nil 150 | end 151 | -------------------------------------------------------------------------------- /src/roslua/service.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- service.lua - Service provider 4 | -- 5 | -- Created: Thu Jul 29 14:43:45 2010 (at Intel Labs Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010-2011 Tim Niemueller [www.niemueller.de] 8 | -- 2010-2011 Carnegie Mellon University 9 | -- 2010 Intel Labs Pittsburgh 10 | -- 2011 SRI International 11 | ---------------------------------------------------------------------------- 12 | 13 | --- Service provider. 14 | -- This module contains the Service class to provide services to other ROS 15 | -- nodes. It is created using the function roslua.service(). 16 | --

17 | -- The service needs a handler to which incoming requests are dispatched. 18 | -- A handler is either a function or a class instance with a service_call() 19 | -- method. On a connection, the request message is called with the fields 20 | -- of the message passed as positional arguments. Sub-messages (i.e. 21 | -- non-builtin complex types) are themselves passed as arrays with the 22 | -- entries being the sub-message fields. This is done recursively for 23 | -- larger hierarchies of parameters. 24 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 25 | -- @release Released under BSD license 26 | module("roslua.service", package.seeall) 27 | 28 | require("roslua") 29 | require("roslua.srv_spec") 30 | require("roslua.utils") 31 | 32 | require("struct") 33 | require("socket") 34 | 35 | Service = {DEBUG=false, 36 | CLSTATE_CONNECTED = 1, 37 | CLSTATE_HEADER_SENT = 2, 38 | CLSTATE_HEADER_RECEIVED = 3, 39 | CLSTATE_COMMUNICATING = 4, 40 | CLSTATE_FAILED = 5, 41 | CLSTATE_DISCONNECTED = 6, 42 | 43 | CLSTATE_TO_STR = { "CLSTATE_CONNECTED", 44 | "CLSTATE_HEADER_SENT", 45 | "CLSTATE_HEADER_RECEIVED", 46 | "CLSTATE_COMMUNICATING", 47 | "CLSTATE_FAILED", "CLSTATE_DISCONNECTED" } 48 | } 49 | 50 | --- Constructor. 51 | -- Create a new service provider instance. 52 | -- @param service name of the provided service 53 | -- @param type type of the service 54 | -- @param handler handler function or class instance 55 | function Service:new(service, srvtype, handler) 56 | local o = {} 57 | setmetatable(o, self) 58 | self.__index = self 59 | 60 | o.service = roslua.resolve(service) 61 | o.handler = handler 62 | if roslua.srv_spec.is_srvspec(srvtype) then 63 | o.type = srvtype.type 64 | o.srvspec = srvtype 65 | else 66 | o.type = srvtype 67 | o.srvspec = roslua.get_srvspec(srvtype) 68 | end 69 | assert(o.service, "Service name is missing") 70 | assert(o.type, "Service type is missing") 71 | assert(o.handler, "No service handler given") 72 | assert(type(handler) == "function" or 73 | (type(handler) == "table" and handler.service_call), 74 | "Service handler must be function or class") 75 | 76 | o.clients = {} 77 | o.num_calls = 0 78 | o.waiting_clients = 0 79 | o.failed_clients = 0 80 | 81 | o.is_complex = false 82 | for _, f in ipairs(o.srvspec.reqspec.fields) do 83 | if f.is_array or not f.is_builtin then 84 | o.is_complex = true 85 | end 86 | end 87 | 88 | -- connect to all publishers 89 | o:start_server() 90 | 91 | return o 92 | end 93 | 94 | 95 | --- Finalize instance. 96 | function Service:finalize() 97 | for uri, c in pairs(self.clients) do 98 | c.connection:close() 99 | end 100 | self.subscribers = {} 101 | end 102 | 103 | --- Start the internal TCP server to accept ROS RPC connections. 104 | function Service:start_server() 105 | self.server = roslua.tcpros.TcpRosServiceProviderConnection:new() 106 | self.server.srvspec = self.srvspec 107 | self.server:bind() 108 | _, self.port = self.server:get_ip_port() 109 | self.address = socket.dns.gethostname() 110 | end 111 | 112 | 113 | -- (internal) Called by spin() to accept new connections. 114 | function Service:accept_connections() 115 | local conns = self.server:accept() 116 | for _, c in ipairs(conns) do 117 | table.insert(self.clients, {connection = c, state = self.CLSTATE_CONNECTED}) 118 | c.srvspec = self.srvspec 119 | end 120 | self.waiting_clients = self.waiting_clients + #conns 121 | end 122 | 123 | 124 | -- (internal) Called by spin to process waiting clients. 125 | function Service:process_clients() 126 | for _, c in ipairs(self.clients) do 127 | if c.state < self.CLSTATE_COMMUNICATING then 128 | if c.state == self.CLSTATE_CONNECTED then 129 | c.md5sum = self.srvspec:md5() 130 | c.connection:send_header{callerid=roslua.node_name, 131 | service=self.service, 132 | type=self.type, 133 | md5sum=c.md5sum} 134 | 135 | c.header_receive_coroutine = 136 | coroutine.create(function () 137 | return c.connection:receive_header(true) 138 | end) 139 | c.state = self.CLSTATE_HEADER_SENT 140 | 141 | elseif c.state == self.CLSTATE_HEADER_SENT then 142 | local data, err = coroutine.resume(c.header_receive_coroutine) 143 | if not data then 144 | print_warn("Service[%s]: failed to receive header from %s: %s", 145 | self.service, c.uri, err) 146 | c.state = self.CLSTATE_FAILED 147 | elseif coroutine.status(c.header_receive_coroutine) == "dead" then 148 | -- finished 149 | c.header_receive_coroutine = nil 150 | c.state = self.CLSTATE_HEADER_RECEIVED 151 | end 152 | 153 | elseif c.state == self.CLSTATE_HEADER_RECEIVED then 154 | if self.DEBUG then 155 | print_debug("Service[%s]: incoming client connection", 156 | self.service) 157 | end 158 | 159 | if c.connection.header.md5sum ~= "*" and 160 | c.connection.header.md5sum ~= c.md5sum 161 | then 162 | print_warn("Service[%s]: received non-matching MD5 ".. 163 | "(here: %s there: %s) sum from %s, disconnecting and ".. 164 | "ignoring", self.service, c.md5sum, 165 | c.connection.header.md5sum, c.connection.header.callerid) 166 | c.state = self.CLSTATE_FAILED 167 | else 168 | if self.DEBUG then 169 | printf("Service[%s]: accepted connection from %s", 170 | self.service, c.connection.header.callerid) 171 | end 172 | c.callerid = c.connection.header.callerid 173 | c.connection.name = string.format("Service[%s]/%s", 174 | self.service, c.callerid) 175 | c.state = self.CLSTATE_COMMUNICATING 176 | self.waiting_clients = self.waiting_clients - 1 177 | end 178 | end 179 | 180 | if c.state == self.CLSTATE_FAILED then 181 | self.waiting_clients = self.waiting_clients - 1 182 | self.failed_client = self.failed_clients + 1 183 | print_warn("Service[%s]: accepting connection failed", self.service) 184 | c.connection:close() 185 | c.connection = nil 186 | end 187 | end 188 | end 189 | end 190 | 191 | 192 | -- (internal) Called by spin() to cleanup failed clients. 193 | function Service:cleanup_subscribers() 194 | for i=#self.clients, 1, -1 do 195 | if self.clients[i].state == self.CLSTATE_FAILED or 196 | self.clients[i].state == self.CLSTATE_DISCONNECTED 197 | then 198 | if self.DEBUG then 199 | printf("Service[%s]: removing failed/disconnected client %s", 200 | self.service, self.clients[i].callerid) 201 | end 202 | table.remove(self.clients, i) 203 | end 204 | end 205 | self.failed_clients = 0 206 | end 207 | 208 | 209 | 210 | -- (internal) Send response to the given connection 211 | -- @param connection connection to send response with 212 | -- @param msg_or_vals Either message object or value array to send 213 | -- as response. A value array must be given in the same format as the parameters 214 | -- that are passed to the handler. 215 | function Service:send_response(connection, msg_or_vals) 216 | local m 217 | if getmetatable(msg_or_vals) == roslua.Message then 218 | m = message 219 | else 220 | -- value array or nil, pack it first 221 | m = self.srvspec.respspec:instantiate() 222 | if msg_or_vals then m:set_from_array(msg_or_vals) end 223 | end 224 | local s = struct.pack(" 0 then 320 | self:process_clients() 321 | end 322 | 323 | self:process_calls() 324 | 325 | if self.failed_clients > 0 then 326 | self:cleanup_clients() 327 | end 328 | end 329 | -------------------------------------------------------------------------------- /src/roslua/slave_proxy.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- slave_proxy.lua - Slave XML-RPC proxy 4 | -- 5 | -- Created: Mon Jul 26 11:58:27 2010 (at Intel Research, Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 8 | -- 2010 Carnegie Mellon University 9 | -- 2010 Intel Research Pittsburgh 10 | ---------------------------------------------------------------------------- 11 | 12 | --- Slave XML-RPC API proxy. 13 | -- This module contains the SlaveProxy class to call methods provided via 14 | -- XML-RPC by ROS slaves. 15 | --

16 | -- The user should not have to directly interact with the slave. It is used 17 | -- to initiate topic connections and get information about the slave. 18 | -- It can also be used to remotely shutdown a slave. 19 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 20 | -- @release Released under BSD license 21 | module("roslua.slave_proxy", package.seeall) 22 | 23 | require("xmlrpc") 24 | require("xmlrpc.http") 25 | assert(xmlrpc._VERSION_MAJOR and 26 | (xmlrpc._VERSION_MAJOR > 1 or 27 | xmlrpc._VERSION_MAJOR == 1 and xmlrpc._VERSION_MINOR >= 2), 28 | "You must use version 1.2 or newer of lua-xmlrpc") 29 | require("roslua.xmlrpc_post") 30 | 31 | __DEBUG = false 32 | 33 | SlaveProxy = { slave_uri = nil, node_name = nil } 34 | 35 | --- Constructor. 36 | -- @param slave_uri XML-RPC HTTP slave URI 37 | -- @param node_name name of this node 38 | function SlaveProxy:new(slave_uri, node_name) 39 | local o = {} 40 | setmetatable(o, self) 41 | self.__index = self 42 | 43 | o.slave_uri = slave_uri 44 | o.node_name = node_name 45 | 46 | return o 47 | end 48 | 49 | -- (internal) execute XML-RPC call 50 | -- Will always prefix the arguments with the caller ID. 51 | -- @param method_name name of the method to execute 52 | -- @param ... Arguments depending on the method call 53 | function SlaveProxy:do_call(method_name, ...) 54 | local ok, res = xmlrpc.http.call(self.slave_uri, 55 | method_name, self.node_name, ...) 56 | assert(ok, string.format("XML-RPC call %s failed on client: %s", method_name, tostring(res))) 57 | assert(res[1] == 1, string.format("XML-RPC call %s failed on server: %s", 58 | method_name, tostring(res[2]))) 59 | 60 | if __DEBUG then 61 | print(string.format("Ok: %s Code: %d Error: %s arrlen: %i", 62 | tostring(ok), tostring(res[1]), tostring(res[2]), #res)) 63 | end 64 | 65 | return res 66 | end 67 | 68 | 69 | --- Get bus stats. 70 | -- @return bus stats 71 | function SlaveProxy:getBusStats() 72 | local res = self:do_call("getBusStats") 73 | 74 | return res[3] 75 | end 76 | 77 | 78 | --- Get bus info. 79 | -- @return bus info 80 | function SlaveProxy:getBusInfo() 81 | local res = self:do_call("getBusInfo") 82 | 83 | return res[3] 84 | end 85 | 86 | 87 | --- Get slaves master URI. 88 | -- @return slaves master URI 89 | function SlaveProxy:getMasterUri() 90 | local res = self:do_call("getMasterUri") 91 | 92 | return res[3] 93 | end 94 | 95 | --- Shutdown remote node. 96 | -- @param msg shutdown message 97 | function SlaveProxy:shutdown(msg) 98 | local res = self:do_call("shutdown", msg or "") 99 | end 100 | 101 | --- Get PID of remote slave. 102 | -- Can be used to "ping" the remote node. 103 | function SlaveProxy:getPid() 104 | local res = self:do_call("getPid") 105 | 106 | return res[3] 107 | end 108 | 109 | --- Get all subscriptions of remote node. 110 | -- @return list of subscriptions 111 | function SlaveProxy:getSubscriptions() 112 | local res = self:do_call("getSubscriptions") 113 | 114 | return res[3] 115 | end 116 | 117 | --- Get all publications of remote node. 118 | -- @return list of publications 119 | function SlaveProxy:getPublications() 120 | local res = self:do_call("getPublications") 121 | 122 | return res[3] 123 | end 124 | 125 | 126 | function SlaveProxy:connection_params() 127 | local protocols = {} 128 | local tcpros = {"TCPROS"} 129 | table.insert(protocols, xmlrpc.newTypedValue(tcpros, xmlrpc.newArray())) 130 | return xmlrpc.newTypedValue(protocols, xmlrpc.newArray("array")) 131 | end 132 | 133 | --- Request a TCPROS connection for a specific topic. 134 | -- @param topic name of topic 135 | -- @return TCPROS communication parameters 136 | function SlaveProxy:requestTopic(topic) 137 | local res = self:do_call("requestTopic", topic, self:connection_params()) 138 | 139 | return res[3] 140 | end 141 | 142 | 143 | --- Start a topic request. 144 | -- This starts a concurrent execution of requestTopic(). 145 | -- @param topic topic to request 146 | -- @return XmlRpcRequest handle for the started request 147 | function SlaveProxy:requestTopic_conc(topic) 148 | return roslua.xmlrpc_post.XmlRpcRequest:new(self.slave_uri, "requestTopic", 149 | self.node_name, topic, 150 | self:connection_params()) 151 | end 152 | 153 | -------------------------------------------------------------------------------- /src/roslua/srv_spec.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- srv_spec.lua - Service specification wrapper 4 | -- 5 | -- Created: Thu Jul 29 11:04:13 2010 (at Intel Research, Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 8 | -- 2010 Carnegie Mellon University 9 | -- 2010 Intel Research Pittsburgh 10 | ---------------------------------------------------------------------------- 11 | 12 | --- Service specification. 13 | -- This module contains the SrvSpec class to read and represent ROS service 14 | -- specification (YAML files). Service specifications should be obtained by 15 | -- using the get_srvspec() function, which is aliased for 16 | -- convenience as roslua.get_srvspec(). 17 | --

18 | -- The service files are read on the fly, no offline code generation is 19 | -- necessary. This avoids the need to write yet another code generator. After 20 | -- reading the service specifications contains two fields, the reqspec field 21 | -- contains the request message specification, the respspec field contains the 22 | -- response message specification. 23 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 24 | -- @release Released under BSD license 25 | module("roslua.srv_spec", package.seeall) 26 | 27 | require("roslua.msg_spec") 28 | require("md5") 29 | 30 | local MsgSpec = roslua.msg_spec.MsgSpec 31 | 32 | local srvspec_cache = {} 33 | 34 | --- Get service specification. 35 | -- It is recommended to use the aliased version roslua.get_srvspec(). 36 | -- @param srv_type service type (e.g. std_msgs/String). The name must include 37 | -- the package. 38 | function get_srvspec(srv_type) 39 | roslua.utils.assert_rospack() 40 | 41 | if not srvspec_cache[srv_type] then 42 | srvspec_cache[srv_type] = SrvSpec:new{type=srv_type} 43 | end 44 | 45 | return srvspec_cache[srv_type] 46 | end 47 | 48 | --- Check if the given object is a message spec. 49 | -- @param testobj object to test 50 | -- @return true if testobj is a message spec, false otherwise 51 | function is_srvspec(testobj) 52 | if type(testobj) == "table" then 53 | if getmetatable(testobj) == SrvSpec then 54 | return true 55 | end 56 | end 57 | return false 58 | end 59 | 60 | 61 | SrvSpec = { request = nil, response = nil } 62 | 63 | --- Constructor. 64 | -- @param o Object initializer, must contain a field type with the string 65 | -- representation of the type name. 66 | function SrvSpec:new(o) 67 | setmetatable(o, self) 68 | self.__index = self 69 | 70 | assert(o.type, "Service type is missing") 71 | 72 | o.package = "roslib" 73 | o.short_type = o.type 74 | 75 | local slashpos = o.type:find("/") 76 | if slashpos then 77 | o.package = o.type:sub(1, slashpos - 1) 78 | o.short_type = o.type:sub(slashpos + 1) 79 | end 80 | 81 | o:load() 82 | 83 | return o 84 | end 85 | 86 | -- (internal) load from iterator 87 | -- @param iterator iterator that returns one line of the specification at a time 88 | function SrvSpec:load_from_iterator(iterator) 89 | self.fields = {} 90 | self.constants = {} 91 | 92 | local request = "" 93 | local response = "" 94 | 95 | local is_request = true 96 | 97 | -- extract the request and response message descriptions 98 | for line in iterator do 99 | if line == "---" then 100 | is_request = false 101 | elseif is_request then 102 | request = request .. line .. "\n" 103 | else 104 | response = response .. line .. "\n" 105 | end 106 | end 107 | 108 | self.reqspec = MsgSpec:new{type=self.type .. "_Request", 109 | specstr = request} 110 | self.respspec = MsgSpec:new{type=self.type .. "_Response", 111 | specstr = response} 112 | end 113 | 114 | --- Load specification from string. 115 | -- @param s string containing the service specification 116 | function SrvSpec:load_from_string(s) 117 | return self:load_from_iterator(s:gmatch("(.-)\n")) 118 | end 119 | 120 | --- Load service specification from file. 121 | -- Will search for the appropriate service specification file (using rospack) 122 | -- and will then read and parse the file. 123 | function SrvSpec:load() 124 | local package_path = roslua.utils.find_rospack(self.package) 125 | self.file = package_path .. "/srv/" .. self.short_type .. ".srv" 126 | 127 | return self:load_from_iterator(io.lines(self.file)) 128 | end 129 | 130 | -- (internal) Calculate MD5 sum. 131 | -- Generates the MD5 sum for this message type. 132 | -- @return MD5 sum as text 133 | function SrvSpec:calc_md5() 134 | local s = 135 | self.reqspec:generate_hashtext() .. self.respspec:generate_hashtext() 136 | 137 | self.md5sum = md5.sumhexa(s) 138 | return self.md5sum 139 | end 140 | 141 | --- Get MD5 sum of type specification. 142 | -- This will create a text representation of the service specification and 143 | -- generate the MD5 sum for it. The value is cached so concurrent calls will 144 | -- cause the cached value to be returned 145 | -- @return MD5 sum of message specification 146 | function SrvSpec:md5() 147 | return self.md5sum or self:calc_md5() 148 | end 149 | 150 | --- Print specification. 151 | -- @param indent string (normally spaces) to put before every line of output 152 | function SrvSpec:print() 153 | print("Service " .. self.type) 154 | print("MD5: " .. self:md5()) 155 | print("Messages:") 156 | self.reqspec:print(" ") 157 | print() 158 | self.respspec:print(" ") 159 | end 160 | -------------------------------------------------------------------------------- /src/roslua/timer.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- timer.lua - Timer 4 | -- 5 | -- Created: Fri Apr 15 12:07:33 2011 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010-2011 Tim Niemueller [www.niemueller.de] 8 | -- 2010-2011 Carnegie Mellon University 9 | -- 2010-2011 Intel Labs Pittsburgh 10 | -- 2011 SRI International 11 | ---------------------------------------------------------------------------- 12 | 13 | --- Timer. 14 | -- This module contains the Timer class for periodical execution of a 15 | -- function. A time period is given, in which the function should be 16 | -- executed. Due to the nature of Lua, especially because it is inherently 17 | -- single-threaded, the times cannot be guaranteed, rather, a minimum time 18 | -- between calls to the function is defined. 19 | --

20 | -- During spinning the all timers are evaluated and executed if the minimum 21 | -- time has gone by. Make sure that timer callbacks are functions that run 22 | -- quickly and have a very short duration as not to influence the overall 23 | -- system performance negatively. 24 | --

25 | -- The rate at which the spinning function is called defines the minimum 26 | -- period for which timers can be called somewhat accurately. For 27 | -- example, if the roslua.spin() function is called once every 30ms, then 28 | -- these 30ms are the very minimum duration of a timer, a shorter time is 29 | -- not possible. You will see increasing offsets between the 30 | -- current_expected and current_real times which will periodically get 31 | -- small once the offset approaches half the spinning time. 32 | --

33 | -- The callback is invoked with a table as parameter of the following 34 | -- entries: 35 | -- * last_expected Time when the last callback should have happened 36 | -- * last_real Time when the last callback actually happened 37 | -- * current_expected Time when the current callback should have happened 38 | -- * current_real Time at the start of the current execution 39 | -- * last_duration Time in seconds the last callback ran 40 | -- 41 | -- @copyright Tim Niemueller, SRI International, Carnegie Mellon University, 42 | -- Intel Labs Pittsburgh 43 | -- @release Released under BSD license 44 | module("roslua.timer", package.seeall) 45 | 46 | require("roslua") 47 | 48 | Timer = {DEBUG = false} 49 | 50 | 51 | --- Constructor. 52 | -- Create a new Timer instance. 53 | -- @param period minimum time between invocations, i.e. the desired 54 | -- time interval between invocations. Either a number, which is considered 55 | -- as time in seconds, or an instance of Duration. 56 | -- @param callback function to execute when the timer is due 57 | function Timer:new(period, callback) 58 | local o = {} 59 | setmetatable(o, self) 60 | self.__index = self 61 | 62 | if roslua.Duration.is_instance(inverval) then 63 | o.period = period:to_sec() 64 | elseif type(period) == "number" then 65 | o.period = period 66 | else 67 | error("Period must be a number (time in seconds) or Duration") 68 | end 69 | o.callback = callback 70 | assert(o.callback, "Callback is missing") 71 | assert(type(o.callback) == "function", "Callback must be a function") 72 | 73 | local now = roslua.Time.now() 74 | o.event = { last_expected = now, 75 | last_real = now, 76 | current_expected = now + period, 77 | current_real = nil, 78 | last_duration = 0 79 | } 80 | 81 | return o 82 | end 83 | 84 | --- Finalize instance. 85 | function Timer:finalize() 86 | -- Subs, pubs etc. also do not auto-unregister, maybe later 87 | -- if roslua.registry.timers[self] then 88 | -- roslua.registry.unregister_timer(self) 89 | --end 90 | end 91 | 92 | --- Check if given table is an instance of Timer. 93 | -- @param t instance to check 94 | -- @return true if given object t is an instance of Timer, false otherwise 95 | function Timer.is_instance(t) 96 | return getmetatable(t) == Timer 97 | end 98 | 99 | --- Default run function. 100 | -- This function calls a registered callback function with the event 101 | -- table as the only parameter. 102 | function Timer:run() 103 | self.callback(self.event) 104 | end 105 | 106 | --- Check time and execute callback if due. 107 | function Timer:spin() 108 | local now = roslua.Time.now() 109 | if now >= self.event.current_expected then 110 | self.event.current_real = now 111 | self:run() 112 | local after = roslua.Time.now() 113 | self.event.last_expected = self.event.current_expected 114 | self.event.last_real = self.event.current_real 115 | self.event.last_duration = (after - now):to_sec() 116 | self.event.current_expected = self.event.last_expected + self.period 117 | end 118 | end 119 | -------------------------------------------------------------------------------- /src/roslua/utils.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- utils.lua - Utilities used in the code 4 | -- 5 | -- Created: Thu Jul 29 10:59:22 2010 (at Intel Research, Pittsburgh) 6 | -- License: BSD, cf. LICENSE file of roslua 7 | -- Copyright 2010-2011 Tim Niemueller [www.niemueller.de] 8 | -- 2010-2011 Carnegie Mellon University 9 | -- 2010-2011 Intel Research Pittsburgh 10 | -- 2011 SRI International 11 | ---------------------------------------------------------------------------- 12 | 13 | --- General roslua utilities. 14 | -- This module contains useful functions used in roslua. 15 | -- @copyright Tim Niemueller, Carnegie Mellon University, Intel Research Pittsburgh 16 | -- @release Released under BSD license 17 | module("roslua.utils", package.seeall) 18 | 19 | local asserted_rospack = false 20 | --- Assert availability of rospack. 21 | -- Throws an error if rospack cannot be executed, for example because ROS is 22 | -- not installed or the binary is not in the PATH. 23 | function assert_rospack() 24 | if not asserted_rospack then 25 | local rv = os.execute("rospack 2>/dev/null") 26 | assert(rv == 0, "Cannot find rospack command, must be in PATH") 27 | asserted_rospack = true 28 | end 29 | end 30 | 31 | local rospack_path_cache = {} 32 | 33 | 34 | local ros_version_major = nil 35 | local ros_version_minor = nil 36 | local ros_version_micro = nil 37 | local ros_version_codename = nil 38 | 39 | --- Get ROS version. 40 | -- @return four values, first value is version code name, second value is 41 | -- major version number, third is minor version number, and fourth and last is 42 | -- micro version number. For example, for ROS 1.4.6 it would return the 43 | -- four values "diamondback", 1, 4, 6. 44 | function rosversion() 45 | if ros_version_major == nil then 46 | assert_rospack() 47 | local p = io.popen("rosversion ros 2>/dev/null") 48 | local version = p:read("*a") 49 | p:close() 50 | if not version or version == "" then 51 | local p = io.popen("rosversion roslaunch 2>/dev/null") 52 | version = p:read("*a") 53 | p:close() 54 | end 55 | if not version or version == "" then 56 | error("Cannot determine ROS version") 57 | end 58 | 59 | local t = split(version, ".") 60 | ros_version_major = tonumber(t[1]) 61 | ros_version_minor = tonumber(t[2]) 62 | ros_version_micro = tonumber(t[3]) 63 | 64 | ros_version_codename = "unknown" 65 | if ros_version_major == 1 then 66 | if ros_version_minor == 0 then 67 | ros_version_codename = "boxturtle" 68 | elseif ros_version_minor == 2 then 69 | ros_version_codename = "cturtle" 70 | elseif ros_version_minor == 4 then 71 | ros_version_codename = "diamondback" 72 | end 73 | end 74 | end 75 | 76 | return ros_version_codename, 77 | ros_version_major, ros_version_minor, ros_version_micro 78 | end 79 | 80 | --- Get path for a package. 81 | -- Uses rospack to find the path to a certain package. The path is cached so 82 | -- that consecutive calls will not trigger another rospack execution, but are 83 | -- rather handled directly from the cache. An error is thrown if the package 84 | -- cannot be found. 85 | -- @return path to give package 86 | function find_rospack(package) 87 | if not rospack_path_cache[package] then 88 | local p = io.popen("rospack find " .. package .. " 2>/dev/null") 89 | local path = p:read("*a") 90 | -- strip trailing newline 91 | rospack_path_cache[package] = string.gsub(path, "^(.+)\n$", "%1") 92 | p:close() 93 | end 94 | 95 | assert(rospack_path_cache[package], "Package path could not be found for " .. package) 96 | assert(rospack_path_cache[package] ~= "", "Package path could not be found for " .. package) 97 | return rospack_path_cache[package] 98 | end 99 | 100 | --- Split string. 101 | -- Splits a string at a given separator and returns the parts in a table. 102 | -- @param s string to split 103 | -- @param sep separator to split at 104 | -- @return table with splitted parts 105 | function split(s, sep) 106 | local sep, fields = sep or ":", {} 107 | local pattern = string.format("([^%s]+)", sep) 108 | string.gsub(s, pattern, function(c) fields[#fields+1] = c end) 109 | return fields 110 | end 111 | 112 | --- Package loader to find Lua modules in ROS packages. 113 | -- This will use the first part of the module name and assume it to 114 | -- be the name of a ROS package. It will then try to determine the path using 115 | -- rospack and if found try to load the module in the package directory. 116 | -- Additionally it appends the string "_lua" to the package name, thus 117 | -- allowing a module named my_module in the ROS package my_module_lua. This 118 | -- is done to allow to mark Lua ROS packages, but avoid having to have 119 | -- the _lua suffix in module names. The suffixed version takes precedence. 120 | -- @param module module name as given to require() 121 | -- @return function of loaded code if module was found, nil otherwise 122 | function package_loader(module) 123 | local package = string.match(module, "^[^%.]+") 124 | local modname = string.match(module, "[^%.]+$") 125 | if not package or not modname then return end 126 | 127 | local try_paths = { "%s/src/%s.lua", "%s/src/%s/%s.lua", "%s/src/%s/init.lua", 128 | "%s/src/lua/%s.lua", "%s/src/lua/%s/%s.lua", "%s/src/lua/%s/init.lua" } 129 | local try_packages = { package .. "_lua", package } 130 | local errmsg = "" 131 | 132 | for _, package in ipairs(try_packages) do 133 | local ok, packpath = pcall(find_rospack, package) 134 | if ok then 135 | errmsg = errmsg .. string.format("\n\tFound matching ROS package %s at s (ROS Lua loader)", 136 | package, packpath) 137 | 138 | for _, tp in ipairs(try_paths) do 139 | local modulepath = string.gsub(module, "%.", "/") 140 | local filename = string.format(tp, packpath, modulepath, modname) 141 | local file = io.open(filename, "rb") 142 | if file then 143 | -- Compile and return the module 144 | if _G.add_watchfile then _G.add_watchfile(filename) end 145 | local chunk, errmsg = loadstring(assert(file:read("*a")), filename) 146 | if chunk then 147 | return chunk 148 | else 149 | error("Failed loading " .. filename .. ": " .. errmsg) 150 | end 151 | end 152 | errmsg = errmsg .. string.format("\n\tno file %s (ROS Lua loader)", filename) 153 | end 154 | else 155 | errmsg = errmsg .. "\n\tno ROS package '" .. package .. "' found (ROS Lua loader)" 156 | end 157 | end 158 | 159 | return errmsg 160 | end 161 | 162 | 163 | --- Package loader to find Lua modules written in C in ROS packages. 164 | -- This will use the first part of the module name and assume it to 165 | -- be the name of a ROS package. It will then try to determine the path using 166 | -- rospack and if found try to load the module in the package directory. 167 | -- Additionally it appends the string "_lua" to the package name, thus 168 | -- allowing a module named my_module in the ROS package my_module_lua. This 169 | -- is done to allow to mark Lua ROS packages, but avoid having to have 170 | -- the _lua suffix in module names. The suffixed version takes precedence. 171 | -- @param module module name as given to require() 172 | -- @return function of loaded code if module was found, nil otherwise 173 | function c_package_loader(module) 174 | local package_name = string.match(module, "^[^%.]+") 175 | local submod = string.sub(module, #package_name + 2) 176 | 177 | local try_packages = { package_name .. "_lua", package_name } 178 | local errmsg = "" 179 | 180 | for _, tpackage in ipairs(try_packages) do 181 | local ok, packpath = pcall(find_rospack, tpackage) 182 | if ok then 183 | errmsg = errmsg .. string.format("\n\tFound matching ROS package %s at %s (ROS C loader)", 184 | tpackage, packpath) 185 | 186 | local try_paths = {{string.format("%s/lib/%s.luaso", packpath, package_name), string.gsub(module, "%.", "_")}, 187 | {string.format("%s/lib/%s_lua.luaso", packpath, package_name), string.gsub(module, "%.", "_")}} 188 | if submod ~= nil or submod ~= "" then 189 | table.insert(try_paths, {string.format("%s/lib/%s.luaso", packpath, submod), 190 | string.gsub(submod, "%.", "_")}) 191 | end 192 | 193 | for _, pathinfo in ipairs(try_paths) do 194 | local symbolname = string.gsub(module, "%.", "_") 195 | local file = io.open(pathinfo[1], "rb") 196 | if file then 197 | file:close() 198 | -- Load and return the module loader 199 | if _G.add_watchfile then _G.add_watchfile(pathinfo[1]) end 200 | local loader, msg = package.loadlib(pathinfo[1], "luaopen_"..pathinfo[2]) 201 | if not loader then 202 | error("error loading module '" .. module .. "' from file '".. pathinfo[1] .."':\n\t" .. msg, 3) 203 | end 204 | return loader 205 | end 206 | errmsg = errmsg .. "\n\tno file '" .. pathinfo[1] .. "' (ROS C loader)" 207 | end 208 | else 209 | errmsg = errmsg .. "\n\tno ROS package '" .. tpackage .. "' found (ROS C loader)" 210 | end 211 | end 212 | 213 | return errmsg 214 | end 215 | 216 | 217 | function socket_send(socket, data) 218 | local sent_bytes = 0 219 | while sent_bytes < #data do 220 | local index, error, err_index = 221 | socket:send(data, sent_bytes + 1, #data) 222 | if index == nil then 223 | if error ~= "timeout" then 224 | return nil, error 225 | else 226 | --printscr("Sending: index %d <= %d", err_index, #data) 227 | sent_bytes = err_index 228 | end 229 | else 230 | sent_bytes = index 231 | end 232 | end 233 | 234 | return sent_bytes 235 | end 236 | 237 | function socket_recv(socket, num_bytes, yield_on_timeout) 238 | local result = "" 239 | local read_bytes = 0 240 | socket:settimeout(0) 241 | while read_bytes < num_bytes do 242 | local data, error, chunk = socket:receive(num_bytes - read_bytes) 243 | if not data then 244 | if error ~= "timeout" then 245 | return nil, error 246 | else 247 | read_bytes = read_bytes + #chunk 248 | result = result .. chunk 249 | if yield_on_timeout then 250 | coroutine.yield(read_bytes) 251 | end 252 | end 253 | elseif data then 254 | return data 255 | end 256 | end 257 | end 258 | 259 | 260 | function socket_recvline(socket, yield_on_timeout) 261 | local line = "" 262 | local d 263 | repeat 264 | d = socket_recv(socket, 1, yield_on_timeout) 265 | if d ~= "\n" and d ~= "\r" then 266 | line = line .. d 267 | end 268 | until d == "\n" 269 | 270 | return line 271 | end 272 | -------------------------------------------------------------------------------- /src/test/logtest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- subscriber.lua - subscriber implementation test 4 | -- 5 | -- Created: Mon Jul 27 15:37:01 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | 14 | -- the following require is only for test program to ensure that we wait for 15 | -- the rosout publisher, do not do this in "normal" programs! 16 | require("roslua.logging.rosout") 17 | 18 | roslua.init_node{master_uri=os.getenv("ROS_MASTER_URI"), 19 | node_name="/logtest"} 20 | 21 | roslua.logging.rosout.pub_rosout:wait_for_subscriber() 22 | 23 | printf("This is a %s test", "printf") 24 | print_debug("Printing DEBUG") 25 | print_info("Printing INFO") 26 | print_warn("Printing WARN") 27 | print_error("Printing ERROR") 28 | print_fatal("Printing FATAL") 29 | -------------------------------------------------------------------------------- /src/test/masterquery.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- masterquery.lua - little test program to query data from master 4 | -- 5 | -- Created: Fri Jul 16 18:12:18 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | 14 | roslua.init_node(os.getenv("ROS_MASTER_URI"), "/roslua_masterquery") 15 | 16 | local master = roslua.master 17 | local parmserv = roslua.parameter_server 18 | 19 | print("Getting system state...") 20 | local publishers, subscribers, services = master:getSystemState() 21 | 22 | print("Publishers") 23 | for topic, pubs in pairs(publishers) do 24 | print(" " .. topic) 25 | for _, p in ipairs(pubs) do 26 | print(" " .. p) 27 | end 28 | end 29 | 30 | print("Subscribers") 31 | for topic, subs in pairs(subscribers) do 32 | print(" " .. topic) 33 | for _, s in ipairs(subs) do 34 | print(" " .. s) 35 | end 36 | end 37 | 38 | print("Services") 39 | for service, prvs in pairs(services) do 40 | print(" " .. service) 41 | for _, p in ipairs(prvs) do 42 | print(" " .. p) 43 | end 44 | end 45 | 46 | 47 | print() 48 | print("Looking up node /talker...") 49 | 50 | local uri = master:lookupNode("/talker") 51 | print(string.format("URI for /talker is %s", uri)) 52 | 53 | 54 | print() 55 | print("Listing topics") 56 | local topics = master:getPublishedTopics() 57 | for i,t in ipairs(topics) do 58 | print(i, t[1], t[2]) 59 | end 60 | 61 | 62 | print() 63 | print("Getting master URI") 64 | local master_uri = master:getUri() 65 | print("Master Uri", master_uri) 66 | 67 | 68 | print() 69 | print("Looking up service /rosout/get_loggers") 70 | local service_uri = master:lookupService("/rosout/get_loggers") 71 | print("Service URI", service_uri) 72 | 73 | 74 | print() 75 | print("Registering dummy service /masterquery") 76 | master:registerService("/masterquery", "rosrpc://localhost:12345", "http://localhost:12346") 77 | 78 | print() 79 | print("UNregistering dummy service /masterquery") 80 | master:unregisterService("/masterquery", "rosrpc://localhost:12345", "http://localhost:12346") 81 | 82 | --print() 83 | --print("Registering as subscriber for /chatter") 84 | --master:registerSubscriber("/chatter", "rosrpc://localhost:12345", "http://localhost:12346") 85 | 86 | print() 87 | print("Listing parameter names") 88 | local param_names = parmserv:get_param_names() 89 | for _,n in ipairs(param_names) do 90 | local param_value = parmserv:get_param(n) 91 | print("", n,"=", param_value) 92 | end 93 | 94 | print() 95 | print("Checking for parameter /run_id") 96 | local has_param = parmserv:has_param("/run_id") 97 | if has_param then 98 | print("", "YES") 99 | else 100 | print("", "NO") 101 | end 102 | 103 | 104 | print() 105 | print("Custom value test with /masterquery") 106 | parmserv:set_param("/masterquery", 1234) 107 | local set_ok = parmserv:has_param("/masterquery") 108 | if set_ok then 109 | print("setting worked, fetching") 110 | local val = parmserv:get_param("/masterquery") 111 | print("Value", val) 112 | 113 | print("Deleting value") 114 | parmserv:delete_param("/masterquery") 115 | local del_ok = parmserv:has_param("/masterquery") 116 | if del_ok then 117 | print("Failed to delete value") 118 | else 119 | print("Delete succeeded") 120 | end 121 | else 122 | print("Setting parameter failed") 123 | end 124 | 125 | print() 126 | print("Searching bogus key") 127 | local ok, fkey = pcall(parmserv.search_param, parmserv, "/bogus") 128 | if ok then 129 | print("WTF, our bogus search found something!?", fkey) 130 | else 131 | print("Nothing, as expected") 132 | end 133 | 134 | 135 | print() 136 | print("Searching run_id key") 137 | local fkey = parmserv:search_param("run_id") 138 | print("Found", fkey) 139 | 140 | -------------------------------------------------------------------------------- /src/test/msgstest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- msgstest.lua - Message specification parser test 4 | -- 5 | -- Created: Mon Jul 26 15:48:49 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | require("roslua.utils") 14 | 15 | print("std_msgs path: ", roslua.utils.find_rospack("std_msgs")) 16 | 17 | print() 18 | print("Message spec tests") 19 | 20 | print() 21 | local msgspec = roslua.msg_spec.get_msgspec("std_msgs/String") 22 | msgspec:print() 23 | 24 | print() 25 | local msgspec = roslua.msg_spec.get_msgspec("roslib/Log") 26 | msgspec:print() 27 | 28 | print() 29 | local msgspec = roslua.msg_spec.get_msgspec("gazebo_plugins/ModelJointsState") 30 | msgspec:print() 31 | 32 | print() 33 | local msgspec = roslua.msg_spec.get_msgspec("geometry_msgs/Pose") 34 | msgspec:print() 35 | 36 | print() 37 | local msgspec = roslua.msg_spec.get_msgspec("geometry_msgs/Point") 38 | msgspec:print() 39 | -------------------------------------------------------------------------------- /src/test/publishertest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- publisher.lua - publisher implementation test 4 | -- 5 | -- Created: Tue Jul 28 10:40:33 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | 14 | roslua.init_node{master_uri=os.getenv("ROS_MASTER_URI"), 15 | node_name="/talkerpub"} 16 | 17 | local topic = "/chatter" 18 | local msgtype = "std_msgs/String" 19 | local msgspec = roslua.get_msgspec(msgtype) 20 | 21 | local p = roslua.publisher(topic, msgtype) 22 | 23 | while not roslua.quit do 24 | roslua.spin() 25 | 26 | local m = msgspec:instantiate() 27 | m.values.data = "hello world " .. os.date() 28 | p:publish(m) 29 | end 30 | roslua.finalize() 31 | -------------------------------------------------------------------------------- /src/test/serializetest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- serializetest.lua - serialization test 4 | -- 5 | -- Created: Mon Jul 27 19:16:35 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | 14 | roslua.init_node{master_uri = os.getenv("ROS_MASTER_URI"), 15 | node_name = "/serializetest"} 16 | 17 | local ms = roslua.get_msgspec("roslib/Log") 18 | ms:print() 19 | local m = ms:instantiate() 20 | 21 | local hms = roslua.get_msgspec("roslib/Header") 22 | local hm = hms:instantiate() 23 | 24 | hm.values.seq = 1024 25 | hm.values.stamp = {1, 2} 26 | hm.values.frame_id = "my_frameid" 27 | 28 | m.values.header = hm 29 | m.values.level = 2 30 | m.values.topics = {"/topic1", "/topic2", "/topic3"} 31 | 32 | local s, format, arr = m:serialize() 33 | 34 | local function print_table_rec(t, indent) 35 | local indent = indent or "" 36 | for k,v in pairs(t) do 37 | if type(v) == "table" then 38 | print(indent .. "Recursing into table " .. k) 39 | print_table_rec(v, indent .. " ") 40 | else 41 | print(indent .. k .. "=" .. tostring(v) .. " (" .. type(v) .. ")") 42 | end 43 | end 44 | end 45 | print("Format", format) 46 | print_table_rec(arr) 47 | 48 | print("Writing serialized string to serializetest.dat") 49 | local f = io.open("serializetest.dat", "w") 50 | f:write(s) 51 | f:close() 52 | 53 | -------------------------------------------------------------------------------- /src/test/serviceclienttest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- serviceclienttest.lua - service client implementation test 4 | -- 5 | -- Created: Fri Jul 30 10:58:59 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | 14 | roslua.init_node{master_uri=os.getenv("ROS_MASTER_URI"), 15 | node_name="/serviceclient"} 16 | 17 | local service = "/add_two_ints" 18 | local srvtype = "rospy_tutorials/AddTwoInts" 19 | local srvspec = roslua.get_srvspec(srvtype) 20 | 21 | local function run_test(s) 22 | math.randomseed(os.time()) 23 | local a, b = math.random(1000), math.random(1000) 24 | local res = s{a, b} 25 | 26 | local result_ok = (a + b) == res 27 | print(a .. " + " .. b .. " = " .. res .. " (result ok: " .. tostring(result_ok) .. ")") 28 | end 29 | 30 | 31 | print("Running NON-persistent tests") 32 | local s = roslua.service_client(service, srvtype, false) 33 | run_test(s) 34 | run_test(s) 35 | run_test(s) 36 | 37 | print("Running persistent test") 38 | local s = roslua.service_client(service, srvtype, true) 39 | run_test(s) 40 | run_test(s) 41 | run_test(s) 42 | 43 | roslua.finalize() 44 | -------------------------------------------------------------------------------- /src/test/serviceprovidertest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- serviceprovidertest.lua - service provider implementation test 4 | -- 5 | -- Created: Thu Jul 29 15:55:38 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | 14 | roslua.init_node{master_uri=os.getenv("ROS_MASTER_URI"), 15 | node_name="/serviceprovider"} 16 | 17 | local service = "/add_two_ints" 18 | local srvtype = "rospy_tutorials/AddTwoInts" 19 | local srvspec = roslua.get_srvspec(srvtype) 20 | 21 | function add_two_ints(a, b) 22 | print(a .. " + " .. b .. " = " .. a+b) 23 | return { a+b } 24 | end 25 | 26 | local p = roslua.service(service, srvtype, add_two_ints) 27 | 28 | while not roslua.quit do 29 | roslua.spin() 30 | end 31 | roslua.finalize() 32 | -------------------------------------------------------------------------------- /src/test/srvtest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- srvspec.lua - Service specification parser test 4 | -- 5 | -- Created: Thu Jul 29 11:47:56 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("roslua") 13 | 14 | print() 15 | print("Service spec tests") 16 | 17 | print() 18 | local srvspec = roslua.srv_spec.get_srvspec("std_srvs/Empty") 19 | srvspec:print() 20 | 21 | print() 22 | local srvspec = roslua.srv_spec.get_srvspec("roscpp/SetLoggerLevel") 23 | srvspec:print() 24 | 25 | print() 26 | local srvspec = roslua.srv_spec.get_srvspec("roscpp/GetLoggers") 27 | srvspec:print() 28 | 29 | 30 | print() 31 | local srvspec = roslua.srv_spec.get_srvspec("rospy_tutorials/AddTwoInts") 32 | srvspec:print() 33 | 34 | --[[ 35 | print() 36 | local srvspec = roslua.srv_spec.get_srvspec("geometry_srvs/Point") 37 | srvspec:print() 38 | --]] 39 | -------------------------------------------------------------------------------- /src/test/subscribertest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- subscriber.lua - subscriber implementation test 4 | -- 5 | -- Created: Mon Jul 27 15:37:01 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | --package.path = ";;/homes/timn/ros/local/roslua/src/?/init.lua;/homes/timn/ros/local/roslua/src/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/share/lua/5.1/?.lua" 13 | --package.cpath = package.cpath .. ";/homes/timn/ros/local/roslua/src/roslua/?.luaso;something?;/usr/lib/lua/5.1/?.so" 14 | 15 | require("roslua") 16 | 17 | roslua.init_node{master_uri=os.getenv("ROS_MASTER_URI"), 18 | node_name="/talkersub"} 19 | 20 | --local topic = "/rosout" 21 | --local msgtype = "roslib/Log" 22 | local topic = "/chatter" 23 | local msgtype = "std_msgs/String" 24 | 25 | local s = roslua.subscriber(topic, msgtype) 26 | s:add_listener(function (message) 27 | message:print() 28 | end) 29 | 30 | while not roslua.quit do 31 | roslua.spin() 32 | end 33 | roslua.finalize() 34 | -------------------------------------------------------------------------------- /src/test/talkertest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- talkertest.lua - Initial test of opening a connection 4 | -- 5 | -- Created: Mon Jul 26 11:05:22 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | 12 | require("struct") 13 | 14 | require("roslua") 15 | require("roslua.slave_proxy") 16 | require("roslua.tcpros") 17 | require("roslua.msg_spec") 18 | 19 | --StringMessage = { md5sum = "992ce8a1687cec8c8bd883ec73ca41d1" } 20 | 21 | --function StringMessage:new() 22 | -- local o = {} 23 | -- setmetatable(o, self) 24 | -- self.__index = self 25 | -- return o 26 | --end 27 | 28 | 29 | --[[ 30 | 1 Subscriber starts. 31 | It reads its command-line remapping arguments to resolve which topic name 32 | it will use. (Remapping Arguments) 33 | 2 Publisher starts. 34 | It reads its command-line remapping arguments to resolve which topic name 35 | it will use. (Remapping Arguments) 36 | 3 Subscriber registers with the Master. (XMLRPC) 37 | 4 Publisher registers with the Master. (XMLRPC) 38 | 5 Master informs Subscriber of new Publisher. (XMLRPC) 39 | 6 Subscriber contacts Publisher to request a topic connection and negotiate 40 | the transport protocol. (XMLRPC) 41 | 7 Publish sends Subscriber the settings for the selected transport 42 | protocol. (XMLRPC) 43 | 8 Subscriber connects to Publisher using the selected transport protocol. 44 | (TCPROS, etc...) 45 | --]] 46 | 47 | roslua.init_node("http://irpwkst00-l:13476/", "/talkertest") 48 | 49 | --[[ 50 | local remote_node = "/talker" 51 | local topic = "/chatter" 52 | local msgtype = "std_msgs/String" 53 | --]] 54 | local remote_node = "/talker" 55 | local topic = "/rosout" 56 | local msgtype = "roslib/Log" 57 | 58 | local uri = roslua.master:lookupNode(remote_node) 59 | print("Slave URI", uri) 60 | local slave = roslua.slave_proxy.SlaveProxy:new(uri, "/talkertest") 61 | 62 | local pid = slave:getPid() 63 | print("PID", pid) 64 | 65 | print("Requesting topic") 66 | local proto = slave:requestTopic(topic) 67 | local function print_table_rec(t, indent) 68 | local indent = indent or "" 69 | for k,v in pairs(t) do 70 | if type(v) == "table" then 71 | print(indent .. "Recursing into table " .. k) 72 | print_table_rec(v, indent .. " ") 73 | else 74 | print(indent .. k .. "=" .. tostring(v)) 75 | end 76 | end 77 | end 78 | print_table_rec(proto) 79 | 80 | function sleep(n) 81 | os.execute("sleep " .. tonumber(n)) 82 | end 83 | 84 | --print("Sleeping, fire up your wireshark") 85 | --sleep(15) 86 | 87 | local tcpconn = roslua.tcpros.TcpRosConnection:new() 88 | tcpconn:connect(proto[2], proto[3]) 89 | 90 | local msgspec = roslua.msg_spec.get_msgspec(msgtype) 91 | 92 | tcpconn:send_header{callerid="/talkertest", 93 | topic=topic, 94 | type=msgspec.type, 95 | md5sum=msgspec:md5()} 96 | local header = tcpconn:receive_header() 97 | print_table_rec(header, "HEADER ") 98 | 99 | while true do 100 | tcpconn:spin() 101 | if tcpconn:data_received() then 102 | --print("Received:", tcpconn.payload) 103 | tcpconn.message:print() 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /src/test/timetest.lua: -------------------------------------------------------------------------------- 1 | 2 | ---------------------------------------------------------------------------- 3 | -- timetest.lua - time test 4 | -- 5 | -- Created: Mon Aug 09 14:29:06 2010 (at Intel Research, Pittsburgh) 6 | -- Copyright 2010 Tim Niemueller [www.niemueller.de] 7 | -- 8 | ---------------------------------------------------------------------------- 9 | 10 | -- Licensed under BSD license 11 | require("roslua") 12 | require("roslua.time") 13 | 14 | local Time = roslua.time.Time 15 | 16 | local t = Time:new() 17 | print(tostring(t)) 18 | 19 | t:stamp() 20 | print(tostring(t)) 21 | 22 | 23 | local t1 = Time:new(1, 0) 24 | local t2 = Time:new(3, 0) 25 | local t3 = t1 + t2 26 | local t4 = t2 - t1 27 | 28 | print("t1", t1) 29 | print("t2", t2) 30 | print("t3 = t1 + t2", t3) 31 | print("t4 = t2 - t1", t4) 32 | 33 | print("t1 < t2?", tostring(t1 < t2)) 34 | print("t1 > t2?", tostring(t1 > t2)) 35 | print("t1 == t2?", tostring(t1 == t2)) 36 | local t5 = t1:clone() 37 | print("t1 == t5?", tostring(t1 == t5)) 38 | --------------------------------------------------------------------------------