jsk-ros-pkg / jsk_roseus

ROS EusLisp Client
http://wiki.ros.org/roseus/Tutorials
17 stars 56 forks source link

crash on subscribe messages including properties with type name 'Object' #574

Open furushchev opened 6 years ago

furushchev commented 6 years ago

Currently, roseus crashes on subscribing messages which have properties of the type name is Object.

For example, jsk_recognition_msgs now has Object and ObjectArray messages.

#!/usr/bin/env roseus
(ros::load-ros-manifest "jsk_recognition_msgs")

(ros::roseus "test_crash")

(defun callback (msg) (print msg))

(ros::subscribe "foo" jsk_recognition_msgs::ObjectArray #'callback)

(ros::spin)
rostopic pub foo jsk_recognition_msgs/ObjectArray '<any content>'

After the command above, roseus crashes on deserialization:

5.irteusgl$ (ros::spin)
Call Stack (max depth: 20):
  0: at (send #:inst729 :init)
  1: at (let ((#:inst729 (instantiate object))) (send #:inst729 :init) #:inst729)
  2: at (instance object :init)
  3: at (cons (instance object :init) ros::r)
  4: at (setq ros::r (cons (instance object :init) ros::r))
  5: at (setf ros::r (cons (instance object :init) ros::r))
  6: at (push (instance object :init) ros::r)
  7: at (while (< ros::i #:dotimes728) (push (instance object :init) ros::r) (setq ros::i (1+ ros::i)))
  8: at (let ((ros::i 0) (#:dotimes728 ros::n)) (declare (integer ros::i #:dotimes728)) (while (< ros::i #:dotimes728) (push (instance object :init) ros:\
:r) (setq ros::i (1+ ros::i))) nil)
  9: at (dotimes (ros::i ros::n) (push (instance object :init) ros::r))
  10: at (let (ros::r) (dotimes (ros::i ros::n) (push (instance object :init) ros::r)) ros::r)
  11: at (setq ros::_objects (let (ros::r) (dotimes (ros::i ros::n) (push (instance object :init) ros::r)) ros::r))
  12: at (let (ros::n) (setq ros::n (system:peek ros::buf ros::ptr- :integer)) (incf ros::ptr- 4) (setq ros::_objects (let (ros::r) (dotimes (ros::i ros:\
:n) (push (instance object :init) ros::r)) ros::r)) (dolist (ros::elem- ros::_objects) (send ros::elem- :deserialize ros::buf ros::ptr-) (incf ros::ptr- \
(send ros::elem- :serialization-length))))
  13: at (ros::spin)
  14: at #<compiled-code #X5e559a0>
/home/furushchev/ros/indigo_parent/devel/share/euslisp/jskeus/eus/Linux64/bin/irteusgl 0 error: cannot find method :init in (send #:inst729 :init)

FYI: I misunderstood with the issue https://github.com/jsk-ros-pkg/jsk_roseus/issues/508 ?

furushchev commented 6 years ago

I investigated a bit by testing simple version:

(make-package "HOGE")

(shadow 'Object (find-package "HOGE"))

(make-package "HOGE::OBJECT")

(in-package "ROS")

(defclass hoge::Object
  :super ros::object
  :slots ())

(defmethod hoge::Object
  (:init ()
    (send-super :init)))

;;                                                                                                                                                        
(make-package "HOGE::OBJECTARRAY")

(defclass hoge::ObjectArray
  :super ros::object
  :slots (_obj))

(defmethod hoge::ObjectArray
  (:init ()
    (send-super :init))
  (:deserialize ()
    (setq _obj (instance hoge::Object :init))))

;;                                                                                                                                                        
(in-package "USER")

(setq obj (instance hoge::ObjectArray :init))
(send obj :deserialize)

And this code runs without any problem. The difference from the code with error might be whether :deserialize method is called from eus or C (C++).

Affonso-Gui commented 5 years ago

Actually this is a quite tricky one.

What is happening here is:

  1. ObjectArray.l gets loaded before Object.l during load-ros-manifest
  2. jsk_recognition_msgs::Object becomes lisp::object, since the symbol is still not defined in the jsk_recognition_msgs package and exists in the lisp package (which is used by default).
  3. (instance lisp::object :init) leads to the no such method error.

There are a few possible solutions for this: