This is an old revision of the document!


Adding new designators

Disclaimer: Designators are Common Lisp objects for describing various parameters in the CRAM Plan Language. This tutorial only serves the purpose to show how a designator is practically built-in, the theoretical should be taken from this doc cram_designators.

Syntax

(defun pour (&key
               ((:object ?object-designator))
               ((:object-name  ?object-name))
               ((:object-type ?object-type))
               ((:arms ?arms))
               ((:grasp ?grasp))
               ((:left-approach-poses ?left-approach-poses))
               ((:right-approach-poses ?right-approach-poses))
               ((:left-tilt-poses ?left-tilt-poses))
               ((:right-tilt-poses ?right-tilt-poses))
               ((:collision-mode ?collision-mode))
	       ((:context ?context))
             &allow-other-keys)
  "Object already in hand, approach 2nd object, tilt 100degree, tilt back"
 
  (roslisp:ros-info (cut-pour pour) "Approaching")
  (cpl:with-failure-handling
      ((common-fail:manipulation-low-level-failure (e)
         (roslisp:ros-warn (cut-and-pour-plans pour)
                           "Manipulation messed up: ~a~%Ignoring."
                           e)
         ;; (return)
         ))
    (exe:perform
     (desig:an action
               (type approaching)
               (left-poses ?left-approach-poses)
               (right-poses ?right-approach-poses)
               (desig:when ?collision-mode
                 (collision-mode ?collision-mode)))))
    (cpl:sleep 2)
 
    (roslisp:ros-info (cut-pour pour) "Tilting")
    (cpl:with-failure-handling
        ((common-fail:manipulation-low-level-failure (e)
           (roslisp:ros-warn (cut-and-pour-plans pour)
                             "Manipulation messed up: ~a~%Ignoring."
                             e)))
      (exe:perform
       (desig:an action
                 (type tilting)
                 (left-poses ?left-tilt-poses)
                 (right-poses ?right-tilt-poses)
                 (desig:when ?collision-mode
                   (collision-mode ?collision-mode)))))
 
  (cpl:sleep 2)
  (if (eq ?context :pancake-making)
      (and 
       (roslisp:ros-info (cut-pour pour) "Squeeze")
       (exe:perform
	(desig:an action
		  (type setting-gripper)
		  (gripper ?arms)
		  (position 0.018)))
 
 
       (exe:perform
	(desig:an action
		  (type setting-gripper)
		  (gripper ?arms)
		  (position 0.1)))))
 
  (if (eq ?context :pouring)
      (and 
       (cpl:with-failure-handling
	   ((common-fail:manipulation-low-level-failure (e)
	      (roslisp:ros-warn (cut-and-pour-plans pour)
				"Manipulation messed up: ~a~%Ignoring."
				e)))
	 (exe:perform
	  (desig:an action
		    (type approaching)
		    (left-poses ?left-approach-poses)
		    (right-poses ?right-approach-poses)
		    (desig:when ?collision-mode
		      (collision-mode ?collision-mode))))))))
(<- (desig:action-grounding ?action-designator (pour ?resolved-action-designator))
    (spec:property ?action-designator (:type :pouring))
    ;; extract info from ?action-designator
    (spec:property ?action-designator (:object ?object-designator))
    (desig:current-designator ?object-designator ?current-object-desig)
    (spec:property ?current-object-desig (:type ?object-type))
    (spec:property ?current-object-desig (:name ?object-name))
     (-> (spec:property ?action-designator (:arms ?arms))
        (true)
        (and (man-int:robot-free-hand ?_ ?arm)
             (equal ?arms (?arm))))
     (lisp-fun man-int:get-object-transform ?current-object-desig ?object-transform)
 
     ;; infer missing information like ?grasp type, gripping ?maximum-effort, manipulation poses
     (lisp-fun man-int:calculate-object-faces ?object-transform (?facing-robot-face ?bottom-face))
     (-> (man-int:object-rotationally-symmetric ?object-type)
	 (equal ?rotationally-symmetric t)
	 (equal ?rotationally-symmetric nil))
     (-> (spec:property ?action-designator (:grasp ?grasp))
	 (true)
	 (and (member ?arm ?arms)
	      (lisp-fun man-int:get-action-grasps ?object-type ?arm ?object-transform ?grasps)
	      (member ?grasp ?grasps)))
     (lisp-fun man-int:get-action-gripping-effort ?object-type ?effort)
     (lisp-fun man-int:get-action-gripper-opening ?object-type ?gripper-opening)
 
     (-> (spec:property ?action-designator (:context ?context))
	 (true)
	 (format t "WARNING: pouring is only legit with context"))
 
     ;; calculate trajectory
     (equal ?objects (?current-object-desig))
     (-> (member :left ?arms)
	 (and
	  (-> (equal ?context :pouring)
	      (lisp-fun man-int:get-action-trajectory :pouring :left ?grasp T
			?objects :tilt-angle 100 
			?left-pouring-pose)
	      (lisp-fun man-int:get-action-trajectory :pouring :left ?grasp T
			?objects :tilt-angle 160
			?left-pouring-pose))
	  (lisp-fun man-int:get-traj-poses-by-label ?left-pouring-pose :approach
		    ?left-approach-poses)
	  (lisp-fun man-int:get-traj-poses-by-label ?left-pouring-pose :tilting
		    ?left-tilt-poses))
 
        (and (equal ?left-approach-poses NIL)
             (equal ?left-tilt-poses NIL)))
 
     (-> (member :right ?arms)
	 (and
	  (-> (equal ?context :pouring)
	      (lisp-fun man-int:get-action-trajectory :pouring :right ?grasp T
			?objects :tilt-angle 100
			?right-pouring-pose)
	      (lisp-fun man-int:get-action-trajectory :pouring :right ?grasp T
			?objects :tilt-angle 160
                       ?right-pouring-pose))
             (lisp-fun man-int:get-traj-poses-by-label ?right-pouring-pose :approach
                       ?right-approach-poses)
             (lisp-fun man-int:get-traj-poses-by-label ?right-pouring-pose :tilting
                       ?right-tilt-poses))
 
        (and (equal ?right-approach-poses NIL)
             (equal ?right-tilt-poses NIL)))
 
     (-> (desig:desig-prop ?action-designator (:collision-mode ?collision-mode))
        (true)
        (equal ?collision-mode nil))
 
     (-> (desig:desig-prop ?action-designator (:context ?context))
	 (true)
	 (format t "WARNING: pouring action need a context"))
 
 
     ;; put together resulting action designator
    (desig:designator :action ((:type :pouring)
                               (:object ?current-object-desig)
                               (:object-type ?object-type)
                               (:object-name  ?object-name)
                               (:arms ?arms)
                               (:grasp ?grasp)
                               (:left-approach-poses ?left-approach-poses)
                               (:right-approach-poses ?right-approach-poses)
                               (:left-tilt-poses ?left-tilt-poses)
                               (:right-tilt-poses ?right-tilt-poses)
                               (:collision-mode ?collision-mode)
			       (:context ?context))
                      ?resolved-action-designator))
;;get pouring trajectory workes like picking-up it will get the 
;;object-type-to-gripper-tilt-approch-transform und makes a traj-segment out of it
;;here we have only the approach pose, followed by that is the titing pose (above)
(defmethod man-int:get-action-trajectory :heuristics 20 ((action-type (eql :pouring))
                                                         arm
                                                         grasp
                                                         location
                                                         objects-acted-on
                                                         &key tilt-angle)
  (let* ((object
           (car objects-acted-on))
         (object-name
           (desig:desig-prop-value object :name))
         (object-type
           (desig:desig-prop-value object :type))
         (bTo
           (man-int:get-object-transform object))
         ;; The first part of the btb-offset transform encodes the
         ;; translation difference between the gripper and the
         ;; object. The static defined orientation of bTb-offset
         ;; describes how the gripper should be orientated to approach
         ;; the object in which something should be poured into. This
         ;; depends mostly on the defined coordinate frame of the
         ;; object and how objects should be rotated to pour something
         ;; out of them.
         (bTb-offset
           (man-int::get-object-type-robot-frame-tilt-approach-transform
            object-type arm grasp))
         ;; Since the grippers orientation should not depend on the
         ;; orientation of the object it is omitted here.
         (oTg-std
           (cram-tf:copy-transform-stamped
            (man-int:get-object-type-to-gripper-transform
             object-type object-name arm grasp)
            :rotation (cl-tf:make-identity-rotation)))
         (approach-pose
           (cl-tf:copy-pose-stamped 
            (man-int:calculate-gripper-pose-in-base
              (cram-tf:apply-transform
               (cram-tf:copy-transform-stamped 
                bTb-offset
                :rotation (cl-tf:make-identity-rotation))
               bTo)
              arm oTg-std)
            :orientation 
            (cl-tf:rotation bTb-offset)))
         (tilting-poses
           (get-tilting-poses grasp (list approach-pose) (cram-math:degrees->radians tilt-angle))))
    (mapcar (lambda (label poses-in-base)
              (man-int:make-traj-segment
               :label label
               :poses (mapcar 
                       (lambda (pose-in-base)
                         (let ((mTb (cram-tf:pose->transform-stamped
                                     cram-tf:*fixed-frame*
                                     cram-tf:*robot-base-frame*
                                     0.0
                                     (btr:pose (btr:get-robot-object))))
                               (bTg-std
                                 (cram-tf:pose-stamped->transform-stamped
                                  pose-in-base
                                  (cl-tf:child-frame-id bTo))))
                           (cl-tf:ensure-pose-stamped
                            (cram-tf:apply-transform mTb bTg-std))))
                       poses-in-base)))
            '(:approach
              :tilting)
            `((,approach-pose)
              ,tilting-poses))))
(defun translate-pose-in-base (bTg &key (x-offset 0.0) (y-offset 0.0) (z-offset 0.0))
  (cram-tf:translate-transform-stamped bTg
                                       :x-offset x-offset
                                       :y-offset y-offset
                                       :z-offset z-offset))
 
(defun calculate-init-slicing-pose (object arm bTg)
  (let* ((x-gripper-position-offset
           (/(cl-transforms:y
              (cl-bullet::bounding-box-dimensions
               (btr:aabb object)))
             2))
         (y-gripper-position-offset
           (/(cl-transforms:x
              (cl-bullet::bounding-box-dimensions
               (btr:aabb object)))
             2)))
    (translate-pose-in-base 
     bTg
     :x-offset (- x-gripper-position-offset)
     :y-offset (if (eq arm :right)
                   (- y-gripper-position-offset)
                   y-gripper-position-offset))))
(defun get-tilting-poses (grasp approach-poses &optional angle)
  (mapcar (lambda (?approach-pose)
            ;;depending on the grasp the angle to tilt is different
            (case grasp
              (:front (rotate-once-pose ?approach-pose (+ angle) :y))
              (:top-front (rotate-once-pose ?approach-pose (+ angle) :y))
              (:left-side (rotate-once-pose ?approach-pose (+ angle) :x))
              (:top-left (rotate-once-pose ?approach-pose (+ angle) :x))
              (:right-side (rotate-once-pose ?approach-pose (- angle) :x))
              (:top-right (rotate-once-pose ?approach-pose (- angle) :x))
              (:back (rotate-once-pose ?approach-pose (- angle) :y))
              (:top (rotate-once-pose ?approach-pose (- angle) :y))
              (t (error "can only pour from :side, back or :front :top :top-side"))))
          approach-poses))
;;helper function for tilting
;;rotate the pose around the axis in an angle
(defun rotate-once-pose (pose angle axis)
  (cl-transforms-stamped:copy-pose-stamped
   pose
   :orientation (let ((pose-orientation (cl-transforms:orientation pose)))
                  (cl-tf:normalize
                   (cl-transforms:q*
                    (cl-transforms:axis-angle->quaternion
                     (case axis
                       (:x (cl-transforms:make-3d-vector 1 0 0))
                       (:y (cl-transforms:make-3d-vector 0 1 0))
                       (:z (cl-transforms:make-3d-vector 0 0 1))
                       (t (error "in ROTATE-ONCE-POSE forgot to specify axis properly: ~a" axis)))
                     angle)
                    pose-orientation)))))
;;;;;;;;;;;;;; CUP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
(defmethod man-int:get-object-type-robot-frame-tilt-approach-transform 
    ((object-type (eql :cup))
     arm
     (grasp (eql :left-side)))
  '((0.0 0.085 0.065)(0 0 -0.707 0.707)))
 
(defmethod man-int:get-object-type-robot-frame-tilt-approach-transform
    ((object-type (eql :cup))
     arm
     (grasp (eql :right-side)))
  '((0.0 -0.085 0.065)(0 0 0.707 0.707)))
 
(defmethod man-int:get-object-type-robot-frame-tilt-approach-transform
    ((object-type (eql :cup))
     arm
     (grasp (eql :front)))
  '((-0.085 0.0 0.065)(0 0 0 1)))
 
(defmethod man-int:get-object-type-robot-frame-tilt-approach-transform 
    ((object-type (eql :cup))
     arm
     (grasp (eql :back)))
  '((0.085 0.0 0.065)(0 0 1 0)))