====== Solutions to Exercises from Zero prerequisites demo tutorial: Simple fetch and place ====== ==== Exercise 1 ==== ;; Simple solution involves adding some hardcoded base poses to search the bottle ;; Then nesting the find object with another failure handling that iterates different hardcoded ;; base poses to find the object. ;; Solution to exercise 1 with static poses (defparameter *base-pose-near-table-towards-island* (make-pose "map" '((-1.447d0 0.150d0 0.0d0) (0.0d0 0.0d0 0.7071d0 0.7071d0)))) (defparameter *base-pose-near-sink-surface* (make-pose "map" '((0.700000 0.650000 0.00000) (0.00000 0.00000 0 1)))) (defun move-bottle (bottle-spawn-pose) (spawn-object bottle-spawn-pose) (with-simulated-robot (let ((?navigation-goal *base-pose-near-table*)) (cpl:par ;; Moving the robot near the table. (perform (an action (type going) (target (a location (pose ?navigation-goal))))) (perform (a motion (type moving-torso) (joint-angle 0.3))) (park-arms))) (let ((?perceived-bottle (let ((?possible-base-poses `(,*base-pose-near-table-towards-island* ,*base-pose-near-sink-surface*)) (?current-base-pose *base-pose-near-table*)) (handle-failure (or object-nowhere-to-be-found object-unreachable) ((find-object :bottle)) (when (first ?possible-base-poses) (print "Changing the base to a new location to try finding the object") (setf ?current-base-pose (first ?possible-base-poses)) (setf ?possible-base-poses (rest ?possible-base-poses)) (perform (an action (type going) (target (a location (pose ?current-base-pose))))) (cpl:retry)) (print "Exhausted all the locations to search. Cannot find the object") (cpl:fail 'object-unreachable)))) (?grasping-arm :right)) ;; We update the value of ?grasping-arm according to what the method used (setf ?grasping-arm (pick-up-object ?perceived-bottle ?grasping-arm)) (park-arm ?grasping-arm) ;; Moving the robot near the counter. (let ((?nav-goal *base-pose-near-counter*)) (perform (an action (type going) (target (a location (pose ?nav-goal)))))) ;; Setting the object down on the counter (let ((?drop-pose *final-object-destination*)) (perform (an action (type placing) (arm ?grasping-arm) (object ?perceived-bottle) (target (a location (pose ?drop-pose)))))) (park-arm ?grasping-arm)))) ==== Exercise 2 ==== ;; Solution for choosing the arm based on the position of the robot (defun get-preferred-arm (?perceived-object) (let* ((obj-name (get-obj-name ?perceived-object)) (obj-pose (get-current-pose-of-object obj-name)) (robot-transformation (get-robot-transformation)) (inverse-robot-transform (inverse-transformation robot-transformation)) ;; Position of the object relative to the robot (obj-in-robot-frame (apply-transformation inverse-robot-transform obj-pose)) (x (get-x-of-pose obj-in-robot-frame)) (y (get-y-of-pose obj-in-robot-frame))) ;; If the object is in front of the robot (if (> x 0) ;; if the object is on positive y-axis in front of the robot ;; then left, else right (if (> y 0) :left :right) ;; If the object is on positive y-axis while behind the robot ;; then right, else left (if (> y 0) :right :left)))) ==== Exercise 3 ==== ;; Modified find-object which changes torso link during perception failure (defun find-object (?object-type) (let* ((possible-look-directions `(,*downward-look-coordinate* ,*left-downward-look-coordinate* ,*right-downward-look-coordinate*)) (?looking-direction (first possible-look-directions)) (possible-torso-link-positions '(0.1 0.2)) (?current-torso-link-position 0.3)) (setf possible-look-directions (rest possible-look-directions)) ;; Look towards the first direction (perform (an action (type looking) (target (a location (pose ?looking-direction))))) ;; Set the first torso link angle (perform (a motion (type moving-torso) (joint-angle ?current-torso-link-position))) ;; perception-object-not-found is the error that we get when the robot cannot find the object. ;; Now we're wrapping it in a failure handling clause to handle it (handle-failure object-nowhere-to-be-found ((handle-failure perception-object-not-found ;; Try the action ((perform (an action (type detecting) (object (an object (type ?object-type)))))) ;; If the action fails, try the following: ;; try different look directions until there is none left. (when possible-look-directions (print "Perception error happened! Turning head.") ;; Resetting the head to look forward before turning again (perform (an action (type looking) (direction forward))) (setf ?looking-direction (first possible-look-directions)) (setf possible-look-directions (rest possible-look-directions)) (perform (a motion (type looking) (target (a location (pose ?looking-direction))))) ;; This statement retries the action again (cpl:retry)) ;; If everything else fails, error out ;; Reset the neck before erroring out (perform (an action (type looking) (direction forward))) (cpl:fail 'object-nowhere-to-be-found))) (when possible-torso-link-positions (print "Perception error happened! Changing torso link position") (setf ?current-torso-link-position (first possible-torso-link-positions)) (setf possible-torso-link-positions (rest possible-torso-link-positions)) (setf possible-look-directions `(,*downward-look-coordinate* ,*left-downward-look-coordinate* ,*right-downward-look-coordinate*)) (setf ?looking-direction (first possible-look-directions)) (perform (a motion (type moving-torso) (joint-angle ?current-torso-link-position))) (cpl:retry)) (print "All Torso link positions exhausted :(") (cpl:fail 'object-nowhere-to-be-found))))