00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 import sys
00044 import os
00045 import traceback
00046 import re
00047
00048 import roslib.msgs
00049 import roslib.srvs
00050 import roslib.packages
00051 import roslib.gentools
00052 from roslib.msgs import MsgSpec
00053 from roslib.srvs import SrvSpec
00054
00055 try:
00056 from cStringIO import StringIO
00057 except ImportError:
00058 from io import StringIO
00059
00060
00061
00062
00063
00064 def is_fixnum(t):
00065 return t in ['int8', 'uint8', 'int16', 'uint16']
00066
00067 def is_integer(t):
00068 return is_fixnum(t) or t in ['byte', 'char', 'int32', 'uint32', 'int64', 'uint64']
00069
00070 def is_signed_int(t):
00071 return t in ['int8', 'int16', 'int32', 'int64']
00072
00073 def is_unsigned_int(t):
00074 return t in ['uint8', 'uint16', 'uint32', 'uint64']
00075
00076 def is_bool(t):
00077 return t == 'bool'
00078
00079 def is_string(t):
00080 return t == 'string'
00081
00082 def is_float(t):
00083 return t in ['float16', 'float32', 'float64']
00084
00085 def is_time(t):
00086 return t in ['time', 'duration']
00087
00088 def field_type(f):
00089 if f.is_builtin:
00090 elt_type = lisp_type(f.base_type)
00091 else:
00092 elt_type = msg_type(f)
00093 if f.is_array:
00094 return '(cl:vector %s)'%elt_type
00095 else:
00096 return elt_type
00097
00098 def parse_msg_type(f):
00099 if f.base_type == 'Header':
00100 return ('std_msgs', 'Header')
00101 else:
00102 return f.base_type.split('/')
00103
00104
00105 def msg_type(f):
00106 (pkg, msg) = parse_msg_type(f)
00107 return '%s-msg:%s'%(pkg, msg)
00108
00109 def lisp_type(t):
00110 if is_fixnum(t):
00111 return 'cl:fixnum'
00112 elif is_integer(t):
00113 return 'cl:integer'
00114 elif is_bool(t):
00115 return 'cl:boolean'
00116 elif is_float(t):
00117 return 'cl:float'
00118 elif is_time(t):
00119 return 'cl:real'
00120 elif is_string(t):
00121 return 'cl:string'
00122 else:
00123 raise ValueError('%s is not a recognized primitive type'%t)
00124
00125 def field_initform(f):
00126 if f.is_builtin:
00127 initform = lisp_initform(f.base_type)
00128 elt_type = lisp_type(f.base_type)
00129 else:
00130 initform = '(cl:make-instance \'%s)'%msg_type(f)
00131 elt_type = msg_type(f)
00132 if f.is_array:
00133 len = f.array_len or 0
00134 return '(cl:make-array %s :element-type \'%s :initial-element %s)'%(len, elt_type, initform)
00135 else:
00136 return initform
00137
00138 def lisp_initform(t):
00139 if is_integer(t):
00140 return '0'
00141 elif is_bool(t):
00142 return 'cl:nil'
00143 elif is_float(t):
00144 return '0.0'
00145 elif is_time(t):
00146 return 0
00147 elif is_string(t):
00148 return '\"\"'
00149 else:
00150 raise ValueError('%s is not a recognized primitive type'%t)
00151
00152 NUM_BYTES = {'int8': 1, 'int16': 2, 'int32': 4, 'int64': 8,
00153 'uint8': 1, 'uint16': 2, 'uint32': 4, 'uint64': 8}
00154
00155
00156
00157
00158
00159
00160
00161 class IndentedWriter():
00162
00163 def __init__(self, s):
00164 self.str = s
00165 self.indentation = 0
00166 self.block_indent = False
00167
00168 def write(self, s, indent=True, newline=True):
00169 if not indent:
00170 newline = False
00171 if self.block_indent:
00172 self.block_indent = False
00173 else:
00174 if newline:
00175 self.str.write('\n')
00176 if indent:
00177 for i in range(self.indentation):
00178 self.str.write(' ')
00179 self.str.write(s)
00180
00181 def newline(self):
00182 self.str.write('\n')
00183
00184 def inc_indent(self, inc=2):
00185 self.indentation += inc
00186
00187 def dec_indent(self, dec=2):
00188 self.indentation -= dec
00189
00190 def reset_indent(self):
00191 self.indentation = 0
00192
00193 def block_next_indent(self):
00194 self.block_indent = True
00195
00196 class Indent():
00197
00198 def __init__(self, w, inc=2, indent_first=True):
00199 self.writer = w
00200 self.inc = inc
00201 self.indent_first = indent_first
00202
00203 def __enter__(self):
00204 self.writer.inc_indent(self.inc)
00205 if not self.indent_first:
00206 self.writer.block_next_indent()
00207
00208 def __exit__(self, type, val, traceback):
00209 self.writer.dec_indent(self.inc)
00210
00211
00212
00213 def write_begin(s, spec, path, is_service=False):
00214 "Writes the beginning of the file: a comment saying it's auto-generated and the in-package form"
00215
00216 s.write('; Auto-generated. Do not edit!\n\n\n', newline=False)
00217 suffix = 'srv' if is_service else 'msg'
00218 s.write('(cl:in-package %s-%s)\n\n\n'%(spec.package, suffix), newline=False)
00219
00220 def write_html_include(s, spec, is_srv=False):
00221
00222 s.write(';//! \\htmlinclude %s.msg.html\n'%spec.actual_name, newline=False)
00223
00224 def write_slot_definition(s, field):
00225 "Write the definition of a slot corresponding to a single message field"
00226
00227 s.write('(%s'%field.name)
00228 with Indent(s, 1):
00229 s.write(':reader %s'%field.name)
00230 s.write(':initarg :%s'%field.name)
00231 s.write(':type %s'%field_type(field))
00232 i = 0 if field.is_array else 1
00233 with Indent(s, i):
00234 s.write(':initform %s)'%field_initform(field))
00235
00236 def write_deprecated_readers(s, spec):
00237 suffix = 'srv' if spec.component_type == 'service' else 'msg'
00238 for field in spec.parsed_fields():
00239 s.newline()
00240 s.write('(cl:ensure-generic-function \'%s-val :lambda-list \'(m))' % field.name)
00241 s.write('(cl:defmethod %s-val ((m %s))'%(field.name, message_class(spec)))
00242 with Indent(s):
00243 s.write('(roslisp-msg-protocol:msg-deprecation-warning "Using old-style slot reader %s-%s:%s-val is deprecated. Use %s-%s:%s instead.")'%(spec.package, suffix, field.name, spec.package, suffix, field.name))
00244 s.write('(%s m))'%field.name)
00245
00246
00247
00248 def write_defclass(s, spec):
00249 "Writes the defclass that defines the message type"
00250 cl = message_class(spec)
00251 new_cl = new_message_class(spec)
00252 suffix = 'srv' if spec.component_type == 'service' else 'msg'
00253 s.write('(cl:defclass %s (roslisp-msg-protocol:ros-message)'%cl)
00254 with Indent(s):
00255 s.write('(')
00256 with Indent(s, inc=1, indent_first=False):
00257 for field in spec.parsed_fields():
00258 write_slot_definition(s, field)
00259 s.write(')', indent=False)
00260 s.write(')')
00261 s.newline()
00262 s.write('(cl:defclass %s (%s)'%(new_cl, cl))
00263 with Indent(s):
00264 s.write('())')
00265 s.newline()
00266 s.write('(cl:defmethod cl:initialize-instance :after ((m %s) cl:&rest args)'%cl)
00267 with Indent(s):
00268 s.write('(cl:declare (cl:ignorable args))')
00269 s.write('(cl:unless (cl:typep m \'%s)'%new_cl)
00270 with Indent(s):
00271 s.write('(roslisp-msg-protocol:msg-deprecation-warning "using old message class name %s-%s:%s is deprecated: use %s-%s:%s instead.")))'%(spec.package, suffix, cl, spec.package, suffix, new_cl))
00272
00273
00274
00275 def message_class(spec):
00276 """
00277 Return the CLOS class name for this message type
00278 """
00279 return '<%s>'%spec.actual_name
00280
00281 def new_message_class(spec):
00282 return spec.actual_name
00283
00284
00285 def write_serialize_length(s, v, is_array=False):
00286
00287 var = '__ros_arr_len' if is_array else '__ros_str_len'
00288
00289 s.write('(cl:let ((%s (cl:length %s)))'%(var, v))
00290 with Indent(s):
00291 for x in range(0, 32, 8):
00292 s.write('(cl:write-byte (cl:ldb (cl:byte 8 %s) %s) ostream)'%(x, var))
00293 s.write(')', indent=False)
00294
00295
00296 def write_serialize_bits(s, v, num_bytes):
00297 for x in range(0, num_bytes*8, 8):
00298 s.write('(cl:write-byte (cl:ldb (cl:byte 8 %s) %s) ostream)'%(x, v))
00299
00300 def write_serialize_bits_signed(s, v, num_bytes):
00301 num_bits = num_bytes*8
00302 s.write('(cl:let* ((signed %s) (unsigned (cl:if (cl:< signed 0) (cl:+ signed %s) signed)))'%(v, 2**num_bits))
00303 with Indent(s):
00304 write_serialize_bits(s, 'unsigned', num_bytes)
00305 s.write(')')
00306
00307
00308
00309
00310 def write_serialize_builtin(s, f, var='msg', lookup_slot=True):
00311 v = '(cl:slot-value %s \'%s)'%(var, f.name) if lookup_slot else var
00312 if f.base_type == 'string':
00313 write_serialize_length(s, v)
00314 s.write('(cl:map cl:nil #\'(cl:lambda (c) (cl:write-byte (cl:char-code c) ostream)) %s)'%v)
00315 elif f.base_type == 'float32':
00316 s.write('(cl:let ((bits %s))'%'(roslisp-utils:encode-single-float-bits %s)'%v)
00317 with Indent(s):
00318 write_serialize_bits(s, 'bits', 4)
00319 s.write(')', False)
00320 elif f.base_type == 'float64':
00321 s.write('(cl:let ((bits %s))'%'(roslisp-utils:encode-double-float-bits %s)'%v)
00322 with Indent(s):
00323 write_serialize_bits(s, 'bits', 8)
00324 s.write(')', False)
00325 elif f.base_type == 'bool':
00326 s.write('(cl:write-byte (cl:ldb (cl:byte 8 0) (cl:if %s 1 0)) ostream)'%v)
00327 elif f.base_type in ['byte', 'char']:
00328 s.write('(cl:write-byte (cl:ldb (cl:byte 8 0) %s) ostream)'%v)
00329 elif f.base_type in ['duration', 'time']:
00330 s.write('(cl:let ((__sec (cl:floor %s))'%v)
00331 s.write(' (__nsec (cl:round (cl:* 1e9 (cl:- %s (cl:floor %s))))))'%(v,v))
00332 with Indent(s):
00333 write_serialize_bits(s, '__sec', 4)
00334 write_serialize_bits(s, '__nsec', 4)
00335 s.write(')', False)
00336 elif is_signed_int(f.base_type):
00337 write_serialize_bits_signed(s, v, NUM_BYTES[f.base_type])
00338 elif is_unsigned_int(f.base_type):
00339 write_serialize_bits(s, v, NUM_BYTES[f.base_type])
00340 else:
00341 raise ValueError('Unknown type: %s', f.base_type)
00342
00343 def write_serialize_field(s, f):
00344 slot = '(cl:slot-value msg \'%s)'%f.name
00345 if f.is_array:
00346 if not f.array_len:
00347 write_serialize_length(s, slot, True)
00348 s.write('(cl:map cl:nil #\'(cl:lambda (ele) ')
00349 var = 'ele'
00350 s.block_next_indent()
00351 lookup_slot = False
00352 else:
00353 var='msg'
00354 lookup_slot = True
00355
00356 if f.is_builtin:
00357 write_serialize_builtin(s, f, var, lookup_slot=lookup_slot)
00358 else:
00359 to_write = slot if lookup_slot else var
00360 s.write('(roslisp-msg-protocol:serialize %s ostream)'%to_write)
00361
00362 if f.is_array:
00363 s.write(')', False)
00364 s.write(' %s)'%slot)
00365
00366 def write_serialize(s, spec):
00367 """
00368 Write the serialize method
00369 """
00370 s.write('(cl:defmethod roslisp-msg-protocol:serialize ((msg %s) ostream)'%message_class(spec))
00371 with Indent(s):
00372 s.write('"Serializes a message object of type \'%s"'%message_class(spec))
00373 for f in spec.parsed_fields():
00374 write_serialize_field(s, f)
00375 s.write(')')
00376
00377
00378
00379 def write_deserialize_length(s, is_array=False):
00380 var = '__ros_arr_len' if is_array else '__ros_str_len'
00381 s.write('(cl:let ((%s 0))'%var)
00382 with Indent(s):
00383 for x in range(0, 32, 8):
00384 s.write('(cl:setf (cl:ldb (cl:byte 8 %s) %s) (cl:read-byte istream))'%(x, var))
00385
00386 def write_deserialize_bits(s, v, num_bytes):
00387 for x in range(0, num_bytes*8, 8):
00388 s.write('(cl:setf (cl:ldb (cl:byte 8 %s) %s) (cl:read-byte istream))'%(x, v))
00389
00390 def write_deserialize_bits_signed(s, v, num_bytes):
00391 s.write('(cl:let ((unsigned 0))')
00392 num_bits = 8*num_bytes
00393 with Indent(s):
00394 write_deserialize_bits(s, 'unsigned', num_bytes)
00395 s.write('(cl:setf %s (cl:if (cl:< unsigned %s) unsigned (cl:- unsigned %s))))'%(v, 2**(num_bits-1), 2**num_bits))
00396
00397
00398
00399 def write_deserialize_builtin(s, f, v):
00400 if f.base_type == 'string':
00401 write_deserialize_length(s)
00402 with Indent(s):
00403 s.write('(cl:setf %s (cl:make-string __ros_str_len))'%v)
00404 s.write('(cl:dotimes (__ros_str_idx __ros_str_len msg)')
00405 with Indent(s):
00406 s.write('(cl:setf (cl:char %s __ros_str_idx) (cl:code-char (cl:read-byte istream)))))'%v)
00407 elif f.base_type == 'float32':
00408 s.write('(cl:let ((bits 0))')
00409 with Indent(s):
00410 write_deserialize_bits(s, 'bits', 4)
00411 s.write('(cl:setf %s (roslisp-utils:decode-single-float-bits bits)))'%v)
00412 elif f.base_type == 'float64':
00413 s.write('(cl:let ((bits 0))')
00414 with Indent(s):
00415 write_deserialize_bits(s, 'bits', 8)
00416 s.write('(cl:setf %s (roslisp-utils:decode-double-float-bits bits)))'%v)
00417 elif f.base_type == 'bool':
00418 s.write('(cl:setf %s (cl:not (cl:zerop (cl:read-byte istream))))'%v)
00419 elif f.base_type in ['byte', 'char']:
00420 s.write('(cl:setf (cl:ldb (cl:byte 8 0) %s) (cl:read-byte istream))'%v)
00421 elif f.base_type in ['duration', 'time']:
00422 s.write('(cl:let ((__sec 0) (__nsec 0))')
00423 with Indent(s):
00424 write_deserialize_bits(s, '__sec', 4)
00425 write_deserialize_bits(s, '__nsec', 4)
00426 s.write('(cl:setf %s (cl:+ (cl:coerce __sec \'cl:double-float) (cl:/ __nsec 1e9))))'%v)
00427 elif is_signed_int(f.base_type):
00428 write_deserialize_bits_signed(s, v, NUM_BYTES[f.base_type])
00429 elif is_unsigned_int(f.base_type):
00430 write_deserialize_bits(s, v, NUM_BYTES[f.base_type])
00431 else:
00432 raise ValueError('%s unknown'%f.base_type)
00433
00434
00435 def write_deserialize_field(s, f, pkg):
00436 slot = '(cl:slot-value msg \'%s)'%f.name
00437 var = slot
00438 if f.is_array:
00439 if not f.array_len:
00440 write_deserialize_length(s, True)
00441 length = '__ros_arr_len'
00442 else:
00443 length = '%s'%f.array_len
00444
00445 s.write('(cl:setf %s (cl:make-array %s))'%(slot, length))
00446 s.write('(cl:let ((vals %s))'%slot)
00447 var = '(cl:aref vals i)'
00448 with Indent(s):
00449 s.write('(cl:dotimes (i %s)'%length)
00450
00451 if f.is_builtin:
00452 with Indent(s):
00453 write_deserialize_builtin(s, f, var)
00454 else:
00455 if f.is_array:
00456 with Indent(s):
00457 s.write('(cl:setf %s (cl:make-instance \'%s))'%(var, msg_type(f)))
00458 s.write('(roslisp-msg-protocol:deserialize %s istream)'%var)
00459
00460 if f.is_array:
00461 s.write('))', False)
00462 if not f.array_len:
00463 s.write(')', False)
00464
00465
00466 def write_deserialize(s, spec):
00467 """
00468 Write the deserialize method
00469 """
00470 s.write('(cl:defmethod roslisp-msg-protocol:deserialize ((msg %s) istream)'%message_class(spec))
00471 with Indent(s):
00472 s.write('"Deserializes a message object of type \'%s"'%message_class(spec))
00473 for f in spec.parsed_fields():
00474 write_deserialize_field(s, f, spec.package)
00475 s.write('msg')
00476 s.write(')')
00477
00478 def write_class_exports(s, pkg):
00479 "Write the _package.lisp file"
00480 s.write('(cl:defpackage %s-msg'%pkg, False)
00481 with Indent(s):
00482 s.write('(:use )')
00483 s.write('(:export')
00484 with Indent(s, inc=1):
00485 for spec in roslib.msgs.get_pkg_msg_specs(pkg)[0]:
00486 (p, msg_type) = spec[0].split('/')
00487 msg_class = '<%s>'%msg_type
00488 s.write('"%s"'%msg_class.upper())
00489 s.write('"%s"'%msg_type.upper())
00490 s.write('))\n\n')
00491
00492 def write_srv_exports(s, pkg):
00493 "Write the _package.lisp file for a service directory"
00494 s.write('(cl:defpackage %s-srv'%pkg, False)
00495 with Indent(s):
00496 s.write('(:use )')
00497 s.write('(:export')
00498 with Indent(s, inc=1):
00499 for spec in roslib.srvs.get_pkg_srv_specs(pkg)[0]:
00500 (_, srv_type) = spec[0].split('/')
00501 s.write('"%s"'%srv_type.upper())
00502 s.write('"<%s-REQUEST>"'%srv_type.upper())
00503 s.write('"%s-REQUEST"'%srv_type.upper())
00504 s.write('"<%s-RESPONSE>"'%srv_type.upper())
00505 s.write('"%s-RESPONSE"'%srv_type.upper())
00506 s.write('))\n\n')
00507
00508
00509 def write_asd_deps(s, deps, msgs):
00510 with Indent(s):
00511 s.write(':depends-on (:roslisp-msg-protocol :roslisp-utils ')
00512 with Indent(s, inc=13, indent_first=False):
00513 for d in sorted(deps):
00514 s.write(':%s-msg'%d)
00515 s.write(')')
00516 with Indent(s):
00517 s.write(':components ((:file "_package")')
00518 with Indent(s):
00519 for (full_name, _) in msgs:
00520 (_, name) = full_name.split('/')
00521 s.write('(:file "%s" :depends-on ("_package_%s"))'%(name, name))
00522 s.write('(:file "_package_%s" :depends-on ("_package"))'%name)
00523 s.write('))')
00524
00525
00526
00527 def write_srv_asd(s, pkg):
00528 s.write('(cl:in-package :asdf)')
00529 s.newline()
00530 s.write('(defsystem "%s-srv"'%pkg)
00531 services = roslib.srvs.get_pkg_srv_specs(pkg)[0]
00532
00533
00534 deps = set()
00535 for (_, spec) in services:
00536 for f in spec.request.parsed_fields():
00537 if not f.is_builtin:
00538 (p, _) = parse_msg_type(f)
00539 deps.add(p)
00540 for f in spec.response.parsed_fields():
00541 if not f.is_builtin:
00542 (p, _) = parse_msg_type(f)
00543 deps.add(p)
00544
00545 write_asd_deps(s, deps, services)
00546
00547
00548 def write_asd(s, pkg):
00549 s.write('(cl:in-package :asdf)')
00550 s.newline()
00551 s.write('(defsystem "%s-msg"'%pkg)
00552 msgs = roslib.msgs.get_pkg_msg_specs(pkg)[0]
00553
00554
00555 deps = set()
00556 for (_, spec) in msgs:
00557 for f in spec.parsed_fields():
00558 if not f.is_builtin:
00559 (p, _) = parse_msg_type(f)
00560 deps.add(p)
00561 if pkg in deps:
00562 deps.remove(pkg)
00563 write_asd_deps(s, deps, msgs)
00564
00565 def write_accessor_exports(s, spec):
00566 "Write the package exports for this message/service"
00567 is_srv = isinstance(spec, SrvSpec)
00568 suffix = 'srv' if is_srv else 'msg'
00569 s.write('(cl:in-package %s-%s)'%(spec.package, suffix), indent=False)
00570 s.write('(cl:export \'(')
00571 if is_srv:
00572 fields = spec.request.parsed_fields()[:]
00573 fields.extend(spec.response.parsed_fields())
00574 else:
00575 fields = spec.parsed_fields()
00576
00577 with Indent(s, inc=10, indent_first=False):
00578 for f in fields:
00579 accessor = '%s-val'%f.name
00580 s.write('%s'%accessor.upper())
00581 s.write('%s'%f.name.upper())
00582 s.write('))')
00583
00584
00585 def write_ros_datatype(s, spec):
00586 for c in (message_class(spec), new_message_class(spec)):
00587 s.write('(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql \'%s)))'%c)
00588 with Indent(s):
00589 s.write('"Returns string type for a %s object of type \'%s"'%(spec.component_type, c))
00590 s.write('"%s")'%spec.full_name)
00591
00592 def write_md5sum(s, spec, parent=None):
00593 if parent is None:
00594 parent = spec
00595 gendeps_dict = roslib.gentools.get_dependencies(parent, spec.package,
00596 compute_files=False)
00597 md5sum = roslib.gentools.compute_md5(gendeps_dict)
00598 for c in (message_class(spec), new_message_class(spec)):
00599 s.write('(cl:defmethod roslisp-msg-protocol:md5sum ((type (cl:eql \'%s)))'%c)
00600 with Indent(s):
00601
00602 s.write('"Returns md5sum for a message object of type \'%s"'%c)
00603 s.write('"%s")'%md5sum)
00604
00605 def write_message_definition(s, spec):
00606 for c in (message_class(spec), new_message_class(spec)):
00607 s.write('(cl:defmethod roslisp-msg-protocol:message-definition ((type (cl:eql \'%s)))'%c)
00608 with Indent(s):
00609 s.write('"Returns full string definition for message of type \'%s"'%c)
00610 s.write('(cl:format cl:nil "')
00611 gendeps_dict = roslib.gentools.get_dependencies(spec, spec.package, compute_files=False)
00612 definition = roslib.gentools.compute_full_text(gendeps_dict)
00613 lines = definition.split('\n')
00614 for line in lines:
00615 l = line.replace('\\', '\\\\')
00616 l = l.replace('"', '\\"')
00617 s.write('%s~%%'%l, indent=False)
00618 s.write('~%', indent=False)
00619 s.write('"))', indent=False)
00620
00621 def write_builtin_length(s, f, var='msg'):
00622 if f.base_type in ['int8', 'uint8']:
00623 s.write('1')
00624 elif f.base_type in ['int16', 'uint16']:
00625 s.write('2')
00626 elif f.base_type in ['int32', 'uint32', 'float32']:
00627 s.write('4')
00628 elif f.base_type in ['int64', 'uint64', 'float64', 'duration', 'time']:
00629 s.write('8')
00630 elif f.base_type == 'string':
00631 s.write('4 (cl:length %s)'%var)
00632 elif f.base_type in ['bool', 'byte', 'char']:
00633 s.write('1')
00634 else:
00635 raise ValueError('Unknown: %s', f.base_type)
00636
00637 def write_serialization_length(s, spec):
00638 c = message_class(spec)
00639 s.write('(cl:defmethod roslisp-msg-protocol:serialization-length ((msg %s))'%c)
00640 with Indent(s):
00641 s.write('(cl:+ 0')
00642 with Indent(s, 3):
00643 for field in spec.parsed_fields():
00644 slot = '(cl:slot-value msg \'%s)'%field.name
00645 if field.is_array:
00646 l = '0' if field.array_len else '4'
00647 s.write('%s (cl:reduce #\'cl:+ %s :key #\'(cl:lambda (ele) (cl:declare (cl:ignorable ele)) (cl:+ '%(l, slot))
00648 var = 'ele'
00649 s.block_next_indent()
00650 else:
00651 var = slot
00652
00653 if field.is_builtin:
00654 write_builtin_length(s, field, var)
00655 else:
00656 s.write('(roslisp-msg-protocol:serialization-length %s)'%var)
00657
00658 if field.is_array:
00659 s.write(')))', False)
00660 s.write('))')
00661
00662
00663 def write_list_converter(s, spec):
00664 c = message_class(spec)
00665 s.write('(cl:defmethod roslisp-msg-protocol:ros-message-to-list ((msg %s))'%c)
00666 with Indent(s):
00667 s.write('"Converts a ROS message object to a list"')
00668 s.write('(cl:list \'%s'%new_message_class(spec))
00669 with Indent(s):
00670 for f in spec.parsed_fields():
00671 s.write('(cl:cons \':%s (%s msg))'%(f.name, f.name))
00672 s.write('))')
00673
00674 def write_constants(s, spec):
00675 if spec.constants:
00676 for cls in (message_class(spec), new_message_class(spec)):
00677 s.write('(cl:defmethod roslisp-msg-protocol:symbol-codes ((msg-type (cl:eql \'%s)))'%cls)
00678 with Indent(s):
00679 s.write(' "Constants for message type \'%s"'%cls)
00680 s.write('\'(')
00681 with Indent(s, indent_first=False):
00682 for c in spec.constants:
00683 s.write('(:%s . %s)'%(c.name.upper(), c.val))
00684 s.write(')', False)
00685 s.write(')')
00686
00687
00688 def write_srv_component(s, spec, parent):
00689 spec.component_type='service'
00690 write_html_include(s, spec)
00691 write_defclass(s, spec)
00692 write_deprecated_readers(s, spec)
00693 write_constants(s, spec)
00694 write_serialize(s, spec)
00695 write_deserialize(s, spec)
00696 write_ros_datatype(s, spec)
00697 write_md5sum(s, spec, parent)
00698 write_message_definition(s, spec)
00699 write_serialization_length(s, spec)
00700 write_list_converter(s, spec)
00701
00702
00703 def write_service_specific_methods(s, spec):
00704 spec.actual_name=spec.short_name
00705 s.write('(cl:defmethod roslisp-msg-protocol:service-request-type ((msg (cl:eql \'%s)))'%spec.short_name)
00706 with Indent(s):
00707 s.write('\'%s)'%new_message_class(spec.request))
00708 s.write('(cl:defmethod roslisp-msg-protocol:service-response-type ((msg (cl:eql \'%s)))'%spec.short_name)
00709 with Indent(s):
00710 s.write('\'%s)'%new_message_class(spec.response))
00711 s.write('(cl:defmethod roslisp-msg-protocol:ros-datatype ((msg (cl:eql \'%s)))'%spec.short_name)
00712 with Indent(s):
00713 s.write('"Returns string type for a service object of type \'%s"'%message_class(spec))
00714 s.write('"%s")'%spec.full_name)
00715
00716
00717 def generate_msg(msg_path):
00718 """
00719 Generate a message
00720
00721 @param msg_path: The path to the .msg file
00722 @type msg_path: str
00723 """
00724 (package_dir, package) = roslib.packages.get_dir_pkg(msg_path)
00725 (_, spec) = roslib.msgs.load_from_file(msg_path, package)
00726 spec.actual_name=spec.short_name
00727 spec.component_type='message'
00728
00729
00730
00731
00732
00733 io = StringIO()
00734 s = IndentedWriter(io)
00735 write_begin(s, spec, msg_path)
00736 write_html_include(s, spec)
00737 write_defclass(s, spec)
00738 write_deprecated_readers(s, spec)
00739 write_constants(s, spec)
00740 write_serialize(s, spec)
00741 write_deserialize(s, spec)
00742 write_ros_datatype(s, spec)
00743 write_md5sum(s, spec)
00744 write_message_definition(s, spec)
00745 write_serialization_length(s, spec)
00746 write_list_converter(s, spec)
00747
00748 output_dir = '%s/msg_gen/lisp'%package_dir
00749 if (not os.path.exists(output_dir)):
00750
00751
00752 try:
00753 os.makedirs(output_dir)
00754 except OSError as e:
00755 pass
00756
00757 with open('%s/%s.lisp'%(output_dir, spec.short_name), 'w') as f:
00758 f.write(io.getvalue() + "\n")
00759 io.close()
00760
00761
00762
00763
00764
00765
00766 io = StringIO()
00767 s = IndentedWriter(io)
00768 write_accessor_exports(s, spec)
00769 with open('%s/_package_%s.lisp'%(output_dir, spec.short_name), 'w') as f:
00770 f.write(io.getvalue())
00771 io.close()
00772
00773
00774
00775
00776
00777
00778
00779 io = StringIO()
00780 s = IndentedWriter(io)
00781 write_class_exports(s, package)
00782 with open('%s/_package.lisp'%output_dir, 'w') as f:
00783 f.write(io.getvalue())
00784 io.close()
00785
00786
00787
00788
00789
00790
00791
00792 io = StringIO()
00793 s = IndentedWriter(io)
00794 write_asd(s, package)
00795 with open('%s/%s-msg.asd'%(output_dir, package), 'w') as f:
00796 f.write(io.getvalue())
00797 io.close()
00798
00799
00800 def generate_srv(srv_path):
00801 "Generate code from .srv file"
00802 (pkg_dir, pkg) = roslib.packages.get_dir_pkg(srv_path)
00803 (_, spec) = roslib.srvs.load_from_file(srv_path, pkg)
00804 output_dir = '%s/srv_gen/lisp'%pkg_dir
00805 if (not os.path.exists(output_dir)):
00806
00807
00808 try:
00809 os.makedirs(output_dir)
00810 except OSError as e:
00811 pass
00812
00813
00814
00815
00816
00817 io = StringIO()
00818 s = IndentedWriter(io)
00819 write_begin(s, spec, srv_path, True)
00820 spec.request.actual_name='%s-request'%spec.short_name
00821 spec.response.actual_name='%s-response'%spec.short_name
00822 write_srv_component(s, spec.request, spec)
00823 s.newline()
00824 write_srv_component(s, spec.response, spec)
00825 write_service_specific_methods(s, spec)
00826
00827 with open('%s/%s.lisp'%(output_dir, spec.short_name), 'w') as f:
00828 f.write(io.getvalue())
00829 io.close()
00830
00831
00832
00833
00834
00835
00836 io = StringIO()
00837 s = IndentedWriter(io)
00838 write_accessor_exports(s, spec)
00839 with open('%s/_package_%s.lisp'%(output_dir, spec.short_name), 'w') as f:
00840 f.write(io.getvalue())
00841 io.close()
00842
00843
00844
00845
00846
00847 io = StringIO()
00848 s = IndentedWriter(io)
00849 write_srv_exports(s, pkg)
00850 with open('%s/_package.lisp'%output_dir, 'w') as f:
00851 f.write(io.getvalue())
00852 io.close()
00853
00854
00855
00856
00857
00858 io = StringIO()
00859 s = IndentedWriter(io)
00860 write_srv_asd(s, pkg)
00861 with open('%s/%s-srv.asd'%(output_dir, pkg), 'w') as f:
00862 f.write(io.getvalue())
00863 io.close()
00864
00865
00866
00867
00868 if __name__ == "__main__":
00869 roslib.msgs.set_verbose(False)
00870 if sys.argv[1].endswith('.msg'):
00871 generate_msg(sys.argv[1])
00872 elif sys.argv[1].endswith('.srv'):
00873 generate_srv(sys.argv[1])
00874 else:
00875 raise ValueError('Invalid filename %s'%sys.argv[1])