diff --git a/cram_3d_world/cl_bullet_vis/cl-bullet-vis.asd b/cram_3d_world/cl_bullet_vis/cl-bullet-vis.asd index 845be5bf77..a179ffa542 100644 --- a/cram_3d_world/cl_bullet_vis/cl-bullet-vis.asd +++ b/cram_3d_world/cl_bullet_vis/cl-bullet-vis.asd @@ -41,7 +41,8 @@ cl-glx trivial-garbage alexandria - cram-physics-utils) + cram-physics-utils + cram-math) :components ((:module "src" :components diff --git a/cram_3d_world/cl_bullet_vis/src/bullet-world-window.lisp b/cram_3d_world/cl_bullet_vis/src/bullet-world-window.lisp index 718a05fc60..cda3b6632e 100644 --- a/cram_3d_world/cl_bullet_vis/src/bullet-world-window.lisp +++ b/cram_3d_world/cl_bullet_vis/src/bullet-world-window.lisp @@ -69,6 +69,104 @@ (when (frame-rate w) (glut:enable-tick w (truncate (* (/ (frame-rate w)) 1000))))) +(defvar *draw-ui* nil) +(defvar *draw-textured-number* nil) +(defvar *text-to-draw* "") + +(defun draw-ui (window) + (when *draw-ui* + (gl:disable :lighting) + (gl:with-pushed-matrix + (let ((text-point (cl-transforms:transform-point + (camera-transform window) + (cl-transforms:make-3d-vector 3.0 0 1.3)))) + (gl:translate (cl-transforms:x text-point) + (cl-transforms:y text-point) + (cl-transforms:z text-point))) + (gl:color 1 0 0 1.0) + (%gl:raster-pos-3f 0.0 0.0 0.0) + (glut:bitmap-string glut:+bitmap-times-roman-24+ *text-to-draw*) + (glut:bitmap-string glut:+bitmap-times-roman-24+ "Red") + (when *draw-textured-number* + ;; (print (gl:get* :current-raster-position)) + ;; (print (gl:get* :current-raster-position-valid)) + (let ((text-pose (cl-transforms:transform-pose + (camera-transform window) + (cl-transforms:make-pose + (cl-transforms:make-3d-vector 3.0 0 1.3) + (cl-transforms:make-identity-rotation))))) + ;; (gl:translate (cl-transforms:x (cl-transforms:origin text-pose)) + ;; (cl-transforms:y (cl-transforms:origin text-pose)) + ;; (cl-transforms:z (cl-transforms:origin text-pose))) + (gl:translate 0.5 0 0) + (multiple-value-bind (axis angle) + (cl-transforms:quaternion->axis-angle (cl-transforms:orientation text-pose)) + (gl:rotate (cma:radians->degrees angle) + (cl-transforms:x axis) (cl-transforms:y axis) (cl-transforms:z axis)) + (gl:rotate 90 0 1 0) + (gl:rotate -90 0 0 1))) + (gl:enable :lighting) + (gl:color 1 0 0 1.0) + (gl:scale 0.1 0.1 0.1) + ;; (glut:solid-cube 2.0) + (gl:with-pushed-attrib (:texture-bit :enable-bit) + (multiple-value-bind (texture-handle new?) + (cl-bullet-vis:get-texture-handle window (gensym)) + (gl:bind-texture :texture-2d texture-handle) + ;; (print new?) + (when new? + (gl:tex-env :texture-env :texture-env-mode :modulate) + (gl:tex-parameter :texture-2d :texture-min-filter :linear-mipmap-linear) + (gl:tex-parameter :texture-2d :texture-mag-filter :linear) + (gl:tex-parameter :texture-2d :texture-wrap-s :repeat) + (gl:tex-parameter :texture-2d :texture-wrap-t :repeat) + (glu:build-2d-mipmaps + :texture-2d 4 16 16 :rgba :float + (texture-str->bitmap + (concatenate + 'string + "xxxxxxxxxxxxxxxx" + "x x" + "x xx x" + "x x x x" + "x x x x" + "x x x x" + "x x x" + "x x x" + "x x x" + "x x x" + "x x x" + "x x x" + "x xxxxxxx x" + "x x" + "x x" + "xxxxxxxxxxxxxxxx") + #\o #\Space #\x '(1 1 1 1))))) + (gl:enable :texture-2d) + (gl:disable :cull-face) + (gl:disable :lighting) + (gl:with-primitive :quads + (gl:normal 0 0 1) + (gl:tex-coord 0.0 0.0) + (gl:vertex -0.5 -0.5) + (gl:tex-coord 1.0 0.0) + (gl:vertex 0.5 -0.5) + (gl:tex-coord 1.0 1.0) + (gl:vertex 0.5 0.5) + (gl:tex-coord 0.0 1.0) + (gl:vertex -0.5 0.5))))) + (gl:with-pushed-matrix + (let ((text-point (cl-transforms:transform-point + (camera-transform window) + (cl-transforms:make-3d-vector 3.0 -0.2 1.3)))) + (gl:translate (cl-transforms:x text-point) + (cl-transforms:y text-point) + (cl-transforms:z text-point))) + (gl:color 0 1 0 1.0) + (%gl:raster-pos-3f 0.0 0.0 0.0) + (glut:bitmap-string glut:+bitmap-times-roman-24+ "Green")) + (gl:enable :lighting))) + (defmethod glut:display ((window bullet-world-window)) (with-rendering-lock (gl:matrix-mode :projection) @@ -98,6 +196,8 @@ (dolist (obj transparent-objects) (draw window obj)) (%gl:depth-mask t))) + ;; Draw UI texts + (draw-ui window) ;; When we are moving around, draw a little yellow disk similar to ;; that one RVIZ draws. (when (or (eq (motion-mode window) :rotate) diff --git a/cram_3d_world/cl_bullet_vis/src/math-function-visualization.lisp b/cram_3d_world/cl_bullet_vis/src/math-function-visualization.lisp index b2c76c7f96..6c3e64f65d 100644 --- a/cram_3d_world/cl_bullet_vis/src/math-function-visualization.lisp +++ b/cram_3d_world/cl_bullet_vis/src/math-function-visualization.lisp @@ -1,20 +1,20 @@ ;;; ;;; Copyright (c) 2010, Lorenz Moesenlechner ;;; All rights reserved. -;;; +;;; ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions are met: -;;; +;;; ;;; * Redistributions of source code must retain the above copyright ;;; notice, this list of conditions and the following disclaimer. ;;; * Redistributions in binary form must reproduce the above copyright ;;; notice, this list of conditions and the following disclaimer in the ;;; documentation and/or other materials provided with the distribution. ;;; * Neither the name of the Intelligent Autonomous Systems Group/ -;;; Technische Universitaet Muenchen nor the names of its contributors -;;; may be used to endorse or promote products derived from this software +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software ;;; without specific prior written permission. -;;; +;;; ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -38,6 +38,7 @@ (cl-transforms:make-3d-vector 0 0 0) (cl-transforms:make-quaternion 0 0 0 1))) (fun :initarg :function :reader fun) + (height-fun :initarg :height-function :reader height-fun :initform (constantly 0.0)) (alpha :initarg :alpha :reader alpha :initform 1.0) (color-fun :initarg :color-fun :reader color-fun :initform (constantly (list 0.0 0.0 0.6))))) @@ -45,26 +46,35 @@ (< (alpha obj) 1.0)) (defmethod draw ((context gl-context) (obj math-function-object)) - (let ((points (make-hash-table :test 'equal)) + (let ((value-points (make-hash-table :test 'equal)) + (heights (make-hash-table :test 'equal)) (colors (make-hash-table :test 'equal))) - (flet ((get-point (x y) + (flet ((get-value (x y) (with-slots (fun) obj (multiple-value-bind (old-value found?) - (gethash (list x y) points) + (gethash (list x y) value-points) (if found? old-value (let ((new-value (funcall fun x y))) - (setf (gethash (list x y) points) + (setf (gethash (list x y) value-points) + (when (numberp new-value) + new-value))))))) + (get-height (x y) + (with-slots (height-fun) obj + (multiple-value-bind (old-value found?) + (gethash (list x y) heights) + (if found? + old-value + (let ((new-value (funcall height-fun x y))) + (setf (gethash (list x y) heights) (when (numberp new-value) - (cl-transforms:make-3d-vector x y new-value)))))))) - (get-color (vec) - (let ((x (cl-transforms:x vec)) - (y (cl-transforms:y vec))) - (with-slots (color-fun) obj - (or (gethash (list x y) colors) - (setf (gethash (list x y) colors) - (append (subseq (funcall color-fun vec) 0 3) - (list (alpha obj)))))))) + new-value))))))) + (get-color (x y value) + (with-slots (color-fun) obj + (or (gethash (list x y) colors) + (setf (gethash (list x y) colors) + (append (subseq (funcall color-fun value) 0 3) + (list (alpha obj))))))) (vertex (vec &optional normal) (let ((normal (cl-transforms:v* normal @@ -86,34 +96,39 @@ (gl:mult-matrix (pose->gl-matrix pose)) (loop for x from (- (/ width 2)) to (- (/ width 2) step-size) by step-size do (loop for y from (- (/ height 2)) to (- (/ height 2) step-size) by step-size do - (let ((middle-pt (get-point (+ x (/ step-size 2)) - (+ y (/ step-size 2))))) - (when middle-pt - (let* ((value (cl-transforms:z middle-pt)) - (pt-1 (cl-transforms:make-3d-vector - x y value)) - (pt-2 (cl-transforms:make-3d-vector - (+ x step-size) y value)) - (pt-3 (cl-transforms:make-3d-vector - x (+ y step-size) value)) - (pt-4 (cl-transforms:make-3d-vector - (+ x step-size) (+ y step-size) value)) - (n-1 (cl-transforms:cross-product - (cl-transforms:v- pt-2 pt-1) - (cl-transforms:v- pt-4 pt-1))) - (n-2 (cl-transforms:cross-product - (cl-transforms:v- pt-4 pt-1) - (cl-transforms:v- pt-3 pt-1)))) + (let* ((pt-middle-x (+ x (/ step-size 2))) + (pt-middle-y (+ y (/ step-size 2))) + (value (get-value pt-middle-x pt-middle-y))) + (when value + (let* ((color + (get-color pt-middle-x pt-middle-y value)) + (height + (get-height pt-middle-x pt-middle-y)) + (pt-1 + (cl-transforms:make-3d-vector + x y height)) + (pt-2 + (cl-transforms:make-3d-vector + (+ x step-size) y height)) + (pt-3 + (cl-transforms:make-3d-vector + x (+ y step-size) height)) + (pt-4 + (cl-transforms:make-3d-vector + (+ x step-size) (+ y step-size) height)) + (n-1 + (cl-transforms:cross-product + (cl-transforms:v- pt-2 pt-1) + (cl-transforms:v- pt-4 pt-1))) + (n-2 + (cl-transforms:cross-product + (cl-transforms:v- pt-4 pt-1) + (cl-transforms:v- pt-3 pt-1)))) (gl:with-primitive :triangles - (apply #'gl:color (get-color pt-1)) + (apply #'gl:color color) (vertex pt-1 n-1) - (apply #'gl:color (get-color pt-2)) (vertex pt-2 n-1) - (apply #'gl:color (get-color pt-4)) (vertex pt-4 n-1) - (apply #'gl:color (get-color pt-1)) (vertex pt-1 n-2) - (apply #'gl:color (get-color pt-4)) (vertex pt-4 n-2) - (apply #'gl:color (get-color pt-3)) (vertex pt-3 n-2))))))))))))) diff --git a/cram_3d_world/cram_btr_spatial_relations_costmap/cram-btr-spatial-relations-costmap-tests.asd b/cram_3d_world/cram_btr_spatial_relations_costmap/cram-btr-spatial-relations-costmap-tests.asd new file mode 100644 index 0000000000..83282fd786 --- /dev/null +++ b/cram_3d_world/cram_btr_spatial_relations_costmap/cram-btr-spatial-relations-costmap-tests.asd @@ -0,0 +1,68 @@ +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(defsystem cram-btr-spatial-relations-costmap-tests + :author "Amar Fayaz" + :license "BSD" + :depends-on (roslisp + lisp-unit + + cram-language + cram-executive + cram-designators + cram-prolog + cram-projection + cram-occasions-events + + cram-common-failures + cram-mobile-pick-place-plans + cram-object-knowledge + + cram-physics-utils ; for reading "package://" paths + cl-bullet ; for handling BOUNDING-BOX datastructures + cram-bullet-reasoning + cram-bullet-reasoning-belief-state + cram-bullet-reasoning-utilities + + cram-location-costmap + cram-btr-visibility-costmap + cram-btr-spatial-relations-costmap + cram-robot-pose-gaussian-costmap + cram-occupancy-grid-costmap + + cram-urdf-projection ; for with-simulated-robot + cram-urdf-projection-reasoning ; to set projection reasoning to T + cram-fetch-deliver-plans + cram-urdf-environment-manipulation + + cram-pr2-description) + :components + ((:module "tests" + :components + ((:file "package") + (:file "orientation-tests" :depends-on ("package")))))) diff --git a/cram_3d_world/cram_btr_spatial_relations_costmap/src/cost-functions.lisp b/cram_3d_world/cram_btr_spatial_relations_costmap/src/cost-functions.lisp index 095655b133..5613e35c41 100644 --- a/cram_3d_world/cram_btr_spatial_relations_costmap/src/cost-functions.lisp +++ b/cram_3d_world/cram_btr_spatial_relations_costmap/src/cost-functions.lisp @@ -31,18 +31,21 @@ (in-package :btr-spatial-cm) +(defparameter *potential-field-threshold* 0.2 + "Costmap grid cells that have value below the threshold will be set to 0.") + ;;;;;;;;;;;;;;;;;;;;;;;;;;; NEAR and FAR calculations (defun get-aabb-min-length (object) - (let ((dims (btr:calculate-bb-dims object))) + (let ((dims (btr:calculate-bb-dims object :initial-pose t))) (min (cl-transforms:x dims) (cl-transforms:y dims)))) (defun get-aabb-circle-diameter (object) - (cl-transforms:x (btr:calculate-bb-dims object))) + (cl-transforms:x (btr:calculate-bb-dims object :initial-pose t))) (defun get-aabb-oval-diameter (object) "We assume the radius of the oval is the max of its two radia" - (let ((dims (btr:calculate-bb-dims object))) + (let ((dims (btr:calculate-bb-dims object :initial-pose t))) (max (cl-transforms:x dims) (cl-transforms:y dims)))) (defun calculate-near-costmap-min-radius (ref-obj-size for-obj-size @@ -129,29 +132,11 @@ ref-sz/2 + ref-padding + max-padding + max-sz + max-padding + for-padding + for- ;;;;;;;;;;;;;;;;;;;; Level Calculations ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun find-levels-under-link (parent-link) - "Finds all the child links under the parent link with the name -board or level or shelf in them" - (let ((levels-found)) - (labels ((find-levels (link) - (let* ((child-joints (cl-urdf:to-joints link)) - (child-links (mapcar #'cl-urdf:child child-joints))) - (mapcar (lambda (child-link) - (let ((child-name (cl-urdf:name child-link))) - (if (or (search "board" child-name) - (search "level" child-name) - (search "shelf" child-name)) - (push child-link levels-found) - (find-levels child-link)))) - child-links)))) - (find-levels parent-link)) - levels-found)) - (defun get-level-links-in-container (btr-environment container-name) (when (symbolp container-name) (setf container-name (roslisp-utilities:rosify-underscores-lisp-name container-name))) - (find-levels-under-link + (btr:find-levels-under-link (gethash container-name (cl-urdf:links (btr:urdf btr-environment))))) (defun choose-level (btr-environment level-links tag &key (invert nil)) @@ -179,50 +164,70 @@ reverse sort it" ;;;;;;;;;;;;;;;;;;;;;;;; COSTMAPS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun make-object-bounding-box-costmap-generator (object) +(defun make-object-bounding-box-costmap-generator (object &key (invert nil) + (padding 0.0d0)) "This cost function assumes that one of the planes of the object is aligned with the horizontal plane, i.e. the object is lying flatly on the horizontal surface." - (let* ((bounding-box-dims - (btr:calculate-bb-dims object)) - (dimensions-x/2 - (/ (cl-transforms:x bounding-box-dims) 2)) - (dimensions-y/2 - (/ (cl-transforms:y bounding-box-dims) 2)) - (angle-around-map-z - (cram-tf:angle-around-map-z (cl-transforms:orientation (btr:pose object)))) - (object-position - (cl-transforms:origin (btr:pose object))) - (center-x - (cl-transforms:x object-position)) - (center-y - (cl-transforms:y object-position))) - + (let* ((objects + (if (listp object) + (cut:force-ll object) + (list object))) + (centerx-centery-dimx/2-dimy/2-anglez-lists + (loop for object in objects + collecting + (let* ((bounding-box-dims + (btr:calculate-bb-dims object)) + (dimensions-x/2 + (+ (/ (cl-transforms:x bounding-box-dims) 2) padding)) + (dimensions-y/2 + (+ (/ (cl-transforms:y bounding-box-dims) 2) padding)) + (angle-around-map-z + (cram-tf:angle-around-map-z (cl-transforms:orientation + (btr:pose object)))) + (object-position + (cl-transforms:origin (btr:pose object))) + (center-x + (cl-transforms:x object-position)) + (center-y + (cl-transforms:y object-position))) + (list center-x center-y dimensions-x/2 dimensions-y/2 + angle-around-map-z))))) (lambda (x y) - (let* ((point-in-bb-frame-identity-orientation - (btr::make-3d-vector - (- x center-x) - (- y center-y) - 0)) - (point-in-bb-frame-bb-orientation - (cl-transforms:rotate - (cl-transforms:axis-angle->quaternion - (cl-transforms:make-3d-vector 0 0 1) - (- angle-around-map-z)) - point-in-bb-frame-identity-orientation)) - (point-in-map-frame - (cl-transforms:v+ - point-in-bb-frame-bb-orientation - (cl-transforms:make-3d-vector center-x center-y 0))) - (new-x (cl-transforms:x point-in-map-frame)) - (new-y (cl-transforms:y point-in-map-frame))) - (if (and - (<= new-x (+ center-x dimensions-x/2)) - (>= new-x (- center-x dimensions-x/2)) - (< new-y (+ center-y dimensions-y/2)) - (> new-y (- center-y dimensions-y/2))) - 1.0 - 0.0))))) + (block nil + (dolist (centerx-centery-dimx/2-dimy/2-anglez-list + centerx-centery-dimx/2-dimy/2-anglez-lists + ;; if we reach the end of the list, we return the default 0.0 + ;; (or if invert then 1.0), because there was no object + ;; within the bounding boxes of which the costmap sample lies + (if invert 1.0d0 0.0d0)) + (destructuring-bind (center-x center-y dimensions-x/2 dimensions-y/2 + angle-around-map-z) + centerx-centery-dimx/2-dimy/2-anglez-list + (let* ((point-in-bb-frame-identity-orientation + (btr::make-3d-vector + (- x center-x) + (- y center-y) + 0)) + (point-in-bb-frame-bb-orientation + (cl-transforms:rotate + (cl-transforms:axis-angle->quaternion + (cl-transforms:make-3d-vector 0 0 1) + (- angle-around-map-z)) + point-in-bb-frame-identity-orientation)) + (point-in-map-frame + (cl-transforms:v+ + point-in-bb-frame-bb-orientation + (cl-transforms:make-3d-vector center-x center-y 0))) + (new-x (cl-transforms:x point-in-map-frame)) + (new-y (cl-transforms:y point-in-map-frame))) + ;; if the sample lies within the bounding box of at least one object + ;; we can break the loop and return 1.0 + (when (and (<= new-x (+ center-x dimensions-x/2)) + (>= new-x (- center-x dimensions-x/2)) + (< new-y (+ center-y dimensions-y/2)) + (> new-y (- center-y dimensions-y/2))) + (return (if invert 0.0 1.0)))))))))) (defun make-object-in-object-bounding-box-costmap-generator (container-object inner-object) "Returns a costmap generator, which for any point within @@ -349,7 +354,8 @@ The function returns one of the following keys: :front, :back, :left, :right." :front :right)))))) (defun make-potential-field-cost-function (axis ref-pose supp-pose pred - &optional (threshold 0.2d0)) + &optional (threshold + *potential-field-threshold*)) "This function is used for resolving spatial relations such as left-of, behind etc. Returns a lambda function which for any (x y) gives a value in [0; 1]. `axis' is either :x (for relations in-front-of and behind) or :y (for left and right). @@ -558,15 +564,22 @@ The function returns one of the following keys: :front, :back, :left, :right." "Returns a lambda function which for each (x y) gives 1.0 if it is on the sign side of the axis. " (when obj - (let* ((pose-origin (cl-transforms:origin (btr:pose obj))) - (bb-x (cl-transforms:x pose-origin)) - (bb-y (cl-transforms:y pose-origin))) + (let* ((map-T-obj (cl-transforms:reference-transform (btr:pose obj))) + (obj-T-map (cl-transforms:transform-inv map-T-obj))) (lambda (x y) - (if (case axis - (:x (funcall sign x bb-x)) - (:y (funcall sign y bb-y))) - 1.0 - 0.0))))) + (let* ((map-T-cm-sample + (cl-transforms:make-pose + (cl-transforms:make-3d-vector x y 0.0) + (cl-transforms:make-identity-rotation))) + (obj-T-cm-sample + (cl-transforms:transform obj-T-map map-T-cm-sample)) + (obj-T-cm-sample-origin + (cl-transforms:origin obj-T-cm-sample))) + (if (case axis + (:x (funcall sign (cl-transforms:x obj-T-cm-sample-origin) 0)) + (:y (funcall sign (cl-transforms:y obj-T-cm-sample-origin) 0))) + 1.0 + 0.0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; HEIGHT GENERATORS ;;;;;;;;;;;;;;;;;;;;;;; @@ -614,7 +627,7 @@ if it is on the sign side of the axis. " environment-objects (list environment-objects))))) (for-object-height - (cl-transforms:z (btr:calculate-bb-dims for-object))) + (cl-transforms:z (btr:calculate-bb-dims for-object :initial-pose t))) (for-object-z (+ environment-object-top (/ for-object-height 2)))) (constantly @@ -648,11 +661,7 @@ if it is on the sign side of the axis. " ;; This is only correct if supp-obj is rotated only around Z axis, i.e. ;; it is parallel to the floor (supp-angle - (* 2 (acos (cl-transforms:w (cl-transforms:orientation supp-obj-pose)))))) - ;; acos only gives values between 0 and pi - ;; checks the sign of the cos to see what sign the angle should have - (when (< (cl-transforms:z (cl-transforms:orientation supp-obj-pose)) 0) - (setf supp-angle (- (* 2 pi) supp-angle))) + (cram-tf:angle-around-map-z (cl-transforms:orientation supp-obj-pose)))) (+ supp-angle angle-in-supp))) (defun make-supporting-obj-aligned-orientations-generator (supp-obj-dims supp-obj-pose diff --git a/cram_3d_world/cram_btr_spatial_relations_costmap/src/designator-integration.lisp b/cram_3d_world/cram_btr_spatial_relations_costmap/src/designator-integration.lisp index c83d75fa68..9e134aa99a 100644 --- a/cram_3d_world/cram_btr_spatial_relations_costmap/src/designator-integration.lisp +++ b/cram_3d_world/cram_btr_spatial_relations_costmap/src/designator-integration.lisp @@ -81,7 +81,7 @@ have the highest values, so we put a threshold on the solution values.") (let ((for-prop-value (desig:desig-prop-value desig :for))) (if (and for-prop-value (prolog `(and - (btr-belief:object-designator-name ,for-prop-value ?object-name) + (object-designator-from-name-or-type ,for-prop-value ?object-name) (btr:item-type ?world ?object-name ?_))) (costmap::get-cached-costmap desig)) (if (prolog `(desig-solution-not-in-collision ,desig ,for-prop-value ,pose)) diff --git a/cram_3d_world/cram_btr_spatial_relations_costmap/src/knowledge.lisp b/cram_3d_world/cram_btr_spatial_relations_costmap/src/knowledge.lisp index 121217487d..1cdbf5429d 100644 --- a/cram_3d_world/cram_btr_spatial_relations_costmap/src/knowledge.lisp +++ b/cram_3d_world/cram_btr_spatial_relations_costmap/src/knowledge.lisp @@ -48,8 +48,10 @@ (<- (%item-type-shape :mug :complex)) (<- (%item-type-shape :plate :circle)) (<- (%item-type-shape :fork :rectangle)) + (<- (%item-type-shape :spoon :rectangle)) (<- (%item-type-shape :knife :rectangle)) (<- (%item-type-shape :pancake-maker :circle)) + (<- (%item-type-shape :cup :circle)) (<- (%item-type-shape :spatula :rectangle)) ;; (<- (item-type-shape ?type ?shape) @@ -83,7 +85,7 @@ (<- (object-type-padding-size :knife 0.005d0)) (<- (object-type-padding-size :pancake-maker 0.018d0)) (<- (object-type-padding-size :spatula 0.01d0)) - (<- (object-type-padding-size :cup 0.1d0)) + (<- (object-type-padding-size :cup 0.0d0)) ;; (<- (padding-size ?world ?object-name ?padding) (btr:item-type ?world ?object-name ?object-type) @@ -118,7 +120,7 @@ (<- (%paddings-list :sink-area-surface :table-setting (0.03d0 0.03d0 0.03d0 0.03d0))) (<- (%paddings-list :dining-area-jokkmokk-table-main :table-setting - (0.1d0 0.1d0 0.1d0 0.1d0))) + (0.03d0 0.03d0 0.03d0 0.03d0))) (<- (paddings-list ?environment-object-name :table-setting ?paddings-list) (setof ?object-name (%paddings-list ?object-name :table-setting ?_) ?defined-paddings-list-objects) diff --git a/cram_3d_world/cram_btr_spatial_relations_costmap/src/prolog.lisp b/cram_3d_world/cram_btr_spatial_relations_costmap/src/prolog.lisp index f8a7f0bbb0..2579a1b206 100644 --- a/cram_3d_world/cram_btr_spatial_relations_costmap/src/prolog.lisp +++ b/cram_3d_world/cram_btr_spatial_relations_costmap/src/prolog.lisp @@ -167,7 +167,7 @@ (costmap:costmap-padding ?robot-name ?padding) (costmap:costmap-add-function environment-free-space - (make-aabbs-costmap-generator + (make-object-bounding-box-costmap-generator ?rigid-bodies :invert t :padding ?padding) ?costmap) ;; Locations to see and to reach are on the floor, so we can use a @@ -268,14 +268,6 @@ ;;;;;;;;;;;;; LEFT-OF etc. for bullet objects or locations ;;;;;;;;;;;;;;;;;; ;; uses make-potential-field-cost-function to resolve the designator - (<- (potential-field-costmap ?edge ?relation ?reference-pose ?supp-obj-pose ?costmap) - (relation-axis-and-pred ?edge ?relation ?axis ?pred) - (instance-of field-generator ?field-generator-id) - (costmap:costmap-add-function - ?field-generator-id - (make-potential-field-cost-function ?axis ?reference-pose ?supp-obj-pose ?pred) - ?costmap)) - ;; (<- (costmap:desig-costmap ?designator ?costmap) (or (desig:desig-prop ?designator (:left-of ?ref-designator)) (desig:desig-prop ?designator (:right-of ?ref-designator)) @@ -311,7 +303,16 @@ (lisp-fun get-closest-edge ?reference-pose ?supp-obj-pose ?supp-obj-dims ?edge)) (and (equal ?edge :front) (lisp-fun cl-transforms:make-identity-pose ?supp-obj-pose))))) - (potential-field-costmap ?edge ?relation ?reference-pose ?supp-obj-pose ?costmap) + ;; position + (once (or (desig:desig-prop ?designator (:threshold ?threshold)) + (symbol-value *potential-field-threshold* ?threshold))) + (relation-axis-and-pred ?edge ?relation ?axis ?pred) + (instance-of field-generator ?field-generator-id) + (costmap:costmap-add-function + ?field-generator-id + (make-potential-field-cost-function ?axis ?reference-pose ?supp-obj-pose ?pred ?threshold) + ?costmap) + ;; orientation (once (or (desig:desig-prop ?designator (:orientation ?orientation-type)) (equal ?orientation-type :random))) (generate-orientations ?orientation-type ?supporting-rigid-body ?reference-pose ?costmap)) @@ -371,7 +372,9 @@ (and (object-designator-from-name-or-type ?for-obj ?for-obj-name) (btr:object ?world ?for-obj-name) (btr:%object ?world ?for-obj-name ?for-object-instance) - (lisp-fun btr:calculate-bb-dims ?for-object-instance ?dimensions) + (lisp-fun btr:calculate-bb-dims ?for-object-instance + :initial-pose t + ?dimensions) (lisp-fun cl-transforms:z ?dimensions ?height) (lisp-fun / ?height 2 ?offset) (lisp-fun + ?highest-z ?offset ?resulting-z)) @@ -523,6 +526,7 @@ ?link-rigid-body) (lisp-pred identity ?link-rigid-body) (equal ?height-calculation-tag ?original-tag))))) + ;; ;; the costmap (<- (costmap:desig-costmap ?designator ?costmap) (or (and (desig:desig-prop ?designator (:in ?object)) @@ -541,6 +545,7 @@ ?height-calculation-tag) (lisp-pred identity ?environment-link) (costmap:costmap ?costmap) + ;; differentiate between locations FOR an object and without the FOR (once (or (and (desig:desig-prop ?designator (:for ?for-object)) (object-designator-from-name-or-type ?for-object ?for-object-name) (btr:%object ?world ?for-object-name ?for-object-instance) @@ -607,64 +612,88 @@ ?costmap)) ;; ;;;;;;;;;;;;;;;;;;;;; SIDE and RANGE relations for ON, IN or ABOVE ;;;;;;;;; + (<- (rigid-body-of-location-designator-reference-object ?designator ?rigid-body) + (once + (or + (desig:desig-prop ?designator (:on ?object-designator)) + (desig:desig-prop ?designator (:in ?object-designator)) + (desig:desig-prop ?designator (:above ?object-designator)))) + (btr:bullet-world ?world) + (once + (or + (and (desig:desig-prop ?object-designator (:level ?level)) + (desig:desig-prop ?object-designator (:urdf-name ?urdf-name)) + (desig:desig-prop ?object-designator (:part-of ?environment-name)) + (btr:%object ?world ?environment-name ?environment-object) + (level-rigid-body ?environment-object ?urdf-name ?level nil ?rigid-body) + (lisp-pred identity ?rigid-body)) + (and (desig:desig-prop ?object-designator (:level-invert ?level)) + (desig:desig-prop ?object-designator (:urdf-name ?urdf-name)) + (desig:desig-prop ?object-designator (:part-of ?environment-name)) + (btr:%object ?world ?environment-name ?environment-object) + (level-rigid-body ?environment-object ?urdf-name ?level t ?rigid-body) + (lisp-pred identity ?rigid-body)) + (and (desig:desig-prop ?object-designator (:urdf-name ?urdf-name)) + (desig:desig-prop ?object-designator (:part-of ?environment-name)) + (btr:%object ?world ?environment-name ?environment-object) + (lisp-fun get-link-rigid-body ?environment-object ?urdf-name ?rigid-body) + (lisp-pred identity ?rigid-body)) + (and (object-designator-from-name-or-type ?object-designator ?object-instance-name) + (btr:item-type ?world ?object-instance-name ?_) + (btr:%object ?world ?object-instance-name ?rigid-body) + (lisp-pred identity ?rigid-body))))) + ;; + ;; SIDE relations (<- (costmap:desig-costmap ?designator ?costmap) - (or (and (desig:desig-prop ?designator (:side ?relation)) - (member ?relation (:left :right :front :back))) - (desig:desig-prop ?designator (:range ?range)) - (desig:desig-prop ?designator (:range-invert ?range-invert))) - (or (desig:desig-prop ?designator (:on ?on-object)) - (desig:desig-prop ?designator (:in ?on-object)) - (desig:desig-prop ?designator (:above ?on-object))) + (desig:desig-prop ?designator (:side ?relations)) + (-> (lisp-type ?relations list) + (equal ?relations (?relation1 ?relation2)) + (equal (?relations nil) (?relation1 ?relation2))) + (member ?relation1 (:left :right :front :back)) + (member ?relation2 (:left :right :front :back nil)) (not (desig:desig-prop ?designator (:attachment ?_))) (not (desig:desig-prop ?designator (:attachments ?_))) - (costmap:costmap ?costmap) - (btr:bullet-world ?world) - (once - (or (and (desig:desig-prop ?on-object (:level ?level)) - (desig:desig-prop ?on-object (:urdf-name ?urdf-name)) - (desig:desig-prop ?on-object (:part-of ?environment-name)) - (btr:%object ?world ?environment-name ?environment-object) - (level-rigid-body ?environment-object ?urdf-name ?level nil - ?rigid-body) - (lisp-pred identity ?link-rigid-body)) - (and (desig:desig-prop ?on-object (:level-invert ?level)) - (desig:desig-prop ?on-object (:urdf-name ?urdf-name)) - (desig:desig-prop ?on-object (:part-of ?environment-name)) - (btr:%object ?world ?environment-name ?environment-object) - (level-rigid-body ?environment-object ?urdf-name ?level t - ?rigid-body) - (lisp-pred identity ?link-rigid-body)) - (and (desig:desig-prop ?on-object (:urdf-name ?urdf-name)) - (desig:desig-prop ?on-object (:part-of ?environment-name)) - (btr:%object ?world ?environment-name ?environment-object) - (lisp-fun get-link-rigid-body ?environment-object ?urdf-name - ?rigid-body) - (lisp-pred identity ?rigid-body)) - (and (object-designator-from-name-or-type ?on-object ?object-instance-name) - (btr:item-type ?world ?object-instance-name ?_) - (btr:%object ?world ?object-instance-name ?rigid-body) - (lisp-pred identity ?rigid-body)))) + (rigid-body-of-location-designator-reference-object ?designator ?rigid-body) (lisp-fun btr:pose ?rigid-body ?object-pose) - (-> (desig:desig-prop ?designator (:side ?relation)) - (and (relation-axis-and-pred ?relation :in-front-of ?axis ?sign) - (instance-of side-generator ?side-generator-id) - (costmap:costmap-add-function - ?side-generator-id - (make-side-costmap-generator ?rigid-body ?axis ?sign) - ?costmap)) - (true)) - (-> (desig:desig-prop ?designator (:range ?range)) - (and (instance-of range-generator ?range-generator-id) - (costmap:costmap-add-function - ?range-generator-id - (costmap:make-range-cost-function ?object-pose ?range :invert nil) - ?costmap)) - (true)) - (-> (desig:desig-prop ?designator (:range-invert ?range-invert)) - (and (instance-of range-generator ?range-generator-another-id) + (costmap:costmap ?costmap) + (relation-axis-and-pred ?relation1 :in-front-of ?axis ?sign) + (instance-of side-generator ?side-generator-id) + (costmap:costmap-add-function + ?side-generator-id + (make-side-costmap-generator ?rigid-body ?axis ?sign) + ?costmap) + (-> (lisp-pred identity ?relation2) + (and (relation-axis-and-pred ?relation2 :in-front-of ?axis2 ?sign2) + (instance-of side-generator ?side-generator-id2) (costmap:costmap-add-function - ?range-generator-another-id - (costmap:make-range-cost-function ?object-pose ?range-invert :invert t) + ?side-generator-id2 + (make-side-costmap-generator ?rigid-body ?axis2 ?sign2) ?costmap)) - (true)))) + (true))) + ;; RANGE relation + (<- (costmap:desig-costmap ?designator ?costmap) + (desig:desig-prop ?designator (:range ?range)) + (not (desig:desig-prop ?designator (:attachment ?_))) + (not (desig:desig-prop ?designator (:attachments ?_))) + (rigid-body-of-location-designator-reference-object ?designator ?rigid-body) + (lisp-fun btr:pose ?rigid-body ?object-pose) + (costmap:costmap ?costmap) + (instance-of range-generator ?range-generator-id) + (costmap:costmap-add-function + ?range-generator-id + (costmap:make-range-cost-function ?object-pose ?range :invert nil) + ?costmap)) + ;; RANGE-INVERT relation + (<- (costmap:desig-costmap ?designator ?costmap) + (desig:desig-prop ?designator (:range-invert ?range-invert)) + (not (desig:desig-prop ?designator (:attachment ?_))) + (not (desig:desig-prop ?designator (:attachments ?_))) + (rigid-body-of-location-designator-reference-object ?designator ?rigid-body) + (lisp-fun btr:pose ?rigid-body ?object-pose) + (costmap:costmap ?costmap) + (instance-of range-generator ?range-invert-generator-id) + (costmap:costmap-add-function + ?range-invert-generator-id + (costmap:make-range-cost-function ?object-pose ?range-invert :invert t) + ?costmap))) diff --git a/cram_3d_world/cram_btr_spatial_relations_costmap/tests/orientation-tests.lisp b/cram_3d_world/cram_btr_spatial_relations_costmap/tests/orientation-tests.lisp new file mode 100644 index 0000000000..f4a0e6cea4 --- /dev/null +++ b/cram_3d_world/cram_btr_spatial_relations_costmap/tests/orientation-tests.lisp @@ -0,0 +1,99 @@ +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :spatial-cm-tests) + +(defun setup-test () + (roslisp-utilities:startup-ros) + (coe:clear-belief) + (setf cram-tf:*tf-default-timeout* 2.0) + (setf prolog:*break-on-lisp-errors* t) + (setf proj-reasoning::*projection-reasoning-enabled* nil) + + (btr-utils:kill-all-objects) + (btr:add-objects-to-mesh-list "cram_pr2_pick_place_demo")) + +(defun spawn-object (pose object-type) + (btr-utils:spawn-object + (intern (format nil "~a-1" object-type) :keyword) + object-type + :pose pose + :mass 0.0) + (btr:simulate btr:*current-bullet-world* 100)) + +(defun make-pose-stamped (pose-list) + (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (apply #'cl-transforms:make-3d-vector (first pose-list)) + (apply #'cl-transforms:make-quaternion (second pose-list)))) + + +(define-test check-spoon-orientation-and-height-on-dining-table + (setup-test) + ;; bowl pose is on the dining table + (let ((bowl-pose (make-pose-stamped '((-3.368202972412109d0 + -0.15089993476867675d0 + 0.7991479237874349d0) + (3.7803240502398694d-6 + -5.186260023037903d-5 + 0.9513682126998901d0 + 0.30805596709251404d0)))) + ;; Spoon just needs to exist, the pose doesn't matter + (spoon-pose (make-pose-stamped '((0 0 0) (0 0 0 1))))) + (spawn-object bowl-pose :bowl) + (spawn-object spoon-pose :spoon) + (let* ((?other-object-designator + (desig:an object + (type bowl) + (location (desig:a location + (on (desig:an object + (type counter-top) + (urdf-name dining-area-jokkmokk-table-main) + (part-of iai-kitchen))) + (for (desig:an object (type bowl))) + (side right) + (context table-setting) + (object-count 2))))) + (location-right-of-bowl (desig:reference (desig:a location + (right-of ?other-object-designator) + (near ?other-object-designator) + (for (desig:an object (type spoon))) + (orientation support-aligned)))) + (angle-for-spoon (cram-tf:angle-around-map-z + (cl-transforms:orientation location-right-of-bowl))) + (height-for-spoon (cl-transforms:z (cl-transforms:origin location-right-of-bowl))) + (height-of-dining-table (btr-spatial-cm::get-rigid-body-aabb-top-z + (btr:rigid-body + (btr:object btr:*current-bullet-world* :iai-kitchen) + (btr::make-rigid-body-name + (string-upcase :iai-kitchen) + (roslisp-utilities:rosify-underscores-lisp-name + 'dining-area-jokkmokk-table-main)))))) + + (assert-true (< (- height-for-spoon height-of-dining-table) 0.05)) + (assert-true (< (abs (- 1.5708 angle-for-spoon)) 0.02))))) ;; ~1 degrees diff --git a/cram_3d_world/cram_btr_spatial_relations_costmap/tests/package.lisp b/cram_3d_world/cram_btr_spatial_relations_costmap/tests/package.lisp new file mode 100644 index 0000000000..32d3ada2ed --- /dev/null +++ b/cram_3d_world/cram_btr_spatial_relations_costmap/tests/package.lisp @@ -0,0 +1,34 @@ +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :cl-user) + +(defpackage :cram-btr-spatial-relations-costmap-tests + (:nicknames :spatial-cm-tests) + (:use #:common-lisp #:lisp-unit #:btr) + (:export)) diff --git a/cram_3d_world/cram_btr_visibility_costmap/src/visibility-costmap.lisp b/cram_3d_world/cram_btr_visibility_costmap/src/visibility-costmap.lisp index 66615b090f..28452ea221 100644 --- a/cram_3d_world/cram_btr_visibility_costmap/src/visibility-costmap.lisp +++ b/cram_3d_world/cram_btr_visibility_costmap/src/visibility-costmap.lisp @@ -127,7 +127,7 @@ void main(void) ;; (/ (row-major-aref depth-image i) ;; max-value) ;; 1.0d0))) - ;; (to-png-image width height normalized :gray))) + ;; (btr:to-png-image width height normalized :gray))) ;; (format nil "/tmp/foo-~a.png" i)) ))))) diff --git a/cram_3d_world/cram_bullet_reasoning/cram-bullet-reasoning.asd b/cram_3d_world/cram_bullet_reasoning/cram-bullet-reasoning.asd index 63675a4a74..15c85e4d1c 100644 --- a/cram_3d_world/cram_bullet_reasoning/cram-bullet-reasoning.asd +++ b/cram_3d_world/cram_bullet_reasoning/cram-bullet-reasoning.asd @@ -29,86 +29,88 @@ ;;; (defsystem cram-bullet-reasoning - :author "Lorenz Moesenlechner" - :license "BSD" + :author "Lorenz Moesenlechner" + :license "BSD" - :depends-on (alexandria - cram-prolog - cl-bullet - cl-bullet-vis - cl-urdf - cl-transforms-stamped - cl-transforms - roslisp - moveit_msgs-srv - moveit_msgs-msg - sensor_msgs-msg - ;; household_objects_database_msgs-msg - ;; household_objects_database_msgs-srv - cram-location-costmap - cram-designators - roslisp-utilities - cram-semantic-map-utils - cram-robot-interfaces - cram-occasions-events - cram-utilities ; lazy in pose-generators and with-file-cache - cram-occasions-events ; for temporal reasoning - cram-tf - cram-physics-utils) + :depends-on (alexandria + png ; used in png-rendering for writing png images + cram-prolog + cl-bullet + cl-bullet-vis + cl-urdf + cl-transforms-stamped + cl-transforms + roslisp + moveit_msgs-srv + moveit_msgs-msg + sensor_msgs-msg + cram-location-costmap + cram-designators + roslisp-utilities + cram-semantic-map-utils + cram-robot-interfaces + cram-occasions-events + cram-utilities ; lazy in pose-generators and with-file-cache + cram-occasions-events ; for temporal reasoning + cram-tf + cram-physics-utils) + :components + ((:module + "src" :components - ((:module - "src" - :components - ((:file "package") - (:file "reasoning-world" :depends-on ("package")) - (:file "textures" :depends-on ("package")) - (:file "utils" :depends-on ("package")) + ((:file "package") + (:file "reasoning-world" :depends-on ("package")) + (:file "textures" :depends-on ("package")) + (:file "utils" :depends-on ("package")) - (:file "objects" :depends-on ("package" "utils" "reasoning-world" "textures")) - (:file "robot-model" :depends-on ("package" "objects" "utils" - "reasoning-world")) - (:file "robot-model-utils" :depends-on ("package" "robot-model")) - (:file "robot-model-facts" :depends-on ("package" "world-facts" - "prolog-handlers" - "robot-model" - "robot-model-utils")) - (:file "items" :depends-on ("package" "objects" "utils" "aabb")) + (:file "objects" :depends-on ("package" "utils" "reasoning-world" "textures")) + (:file "robot-model" :depends-on ("package" "objects" "utils" + "reasoning-world")) + (:file "robot-model-utils" :depends-on ("package" "robot-model")) + (:file "robot-model-facts" :depends-on ("package" "world-facts" + "prolog-handlers" + "robot-model" + "robot-model-utils")) + (:file "items" :depends-on ("package" "objects" "utils" "aabb")) - (:file "aabb" :depends-on ("package" "objects")) + (:file "aabb" :depends-on ("package" "objects")) - (:file "debug-window" :depends-on ("package")) - (:file "gl-scenes" :depends-on ("package" "debug-window")) - (:file "visibility-reasoning" :depends-on ("package" "gl-scenes")) - (:file "visibility-facts" :depends-on ("package" "world-facts" - "visibility-reasoning" - "robot-model-facts")) + (:file "debug-window" :depends-on ("package")) + (:file "gl-scenes" :depends-on ("package" "debug-window")) + (:file "visibility-reasoning" :depends-on ("package" "gl-scenes")) + (:file "visibility-facts" :depends-on ("package" "world-facts" + "visibility-reasoning" + "robot-model-facts")) + (:file "png-rendering" :depends-on ("package" + "gl-scenes" + "visibility-reasoning")) - (:file "world-utils" :depends-on ("package" "reasoning-world" "objects")) - (:file "world-facts" :depends-on ("package" "reasoning-world" "items" - "objects" "debug-window" - "world-utils")) - (:file "prolog-handlers" :depends-on ("package" "reasoning-world" - "world-facts")) + (:file "world-utils" :depends-on ("package" "reasoning-world" "objects")) + (:file "world-facts" :depends-on ("package" "reasoning-world" "items" + "objects" "debug-window" + "world-utils")) + (:file "prolog-handlers" :depends-on ("package" "reasoning-world" + "world-facts")) - (:file "pose-generators" :depends-on ("package" "utils" "aabb" "world-facts")) - (:file "pose-sampling-facts" :depends-on ("package" "world-facts" - "pose-generators")) - (:file "pose-facts" :depends-on ("package" "aabb" "world-utils" - "pose-generators" "objects" - "world-facts")) + (:file "pose-generators" :depends-on ("package" "utils" "aabb" "world-facts")) + (:file "pose-sampling-facts" :depends-on ("package" "world-facts" + "pose-generators")) + (:file "pose-facts" :depends-on ("package" "aabb" "world-utils" + "pose-generators" "objects" + "world-facts")) - (:file "semantic-map" :depends-on ("package" "objects" "utils")) - (:file "simple-semantic-map" :depends-on ("package" "semantic-map")) - (:file "urdf-semantic-map" :depends-on ("package" "reasoning-world" - "semantic-map" - "robot-model")) - (:file "semantic-map-facts" :depends-on ("package" "semantic-map" - "urdf-semantic-map" - "world-facts")) - (:file "articulated-objects" :depends-on ("package" "semantic-map")) + (:file "semantic-map" :depends-on ("package" "objects" "utils")) + (:file "simple-semantic-map" :depends-on ("package" "semantic-map")) + (:file "urdf-semantic-map" :depends-on ("package" "reasoning-world" + "semantic-map" + "robot-model")) + (:file "semantic-map-facts" :depends-on ("package" "semantic-map" + "urdf-semantic-map" + "world-facts")) + (:file "articulated-objects" :depends-on ("package" "semantic-map")) - (:module "temporal-reasoning" :depends-on ("package" "reasoning-world" - "world-facts" "utils") - :components ((:file "events") - (:file "timeline" :depends-on ("events")) - (:file "prolog"))))))) + (:module "temporal-reasoning" :depends-on ("package" "reasoning-world" + "world-facts" "utils") + :components ((:file "events") + (:file "timeline" :depends-on ("events")) + (:file "prolog"))))))) diff --git a/cram_3d_world/cram_bullet_reasoning/package.xml b/cram_3d_world/cram_bullet_reasoning/package.xml index eb65e7af80..fe5d1a7400 100644 --- a/cram_3d_world/cram_bullet_reasoning/package.xml +++ b/cram_3d_world/cram_bullet_reasoning/package.xml @@ -15,6 +15,7 @@ catkin alexandria + cl_png cram_prolog cl_bullet cl_bullet_vis @@ -34,5 +35,4 @@ cram_tf cram_physics_utils - diff --git a/cram_3d_world/cram_bullet_reasoning/resource/bowl_round.stl b/cram_3d_world/cram_bullet_reasoning/resource/bowl_round.stl index 069c4b25fa..12047f5e6f 100644 Binary files a/cram_3d_world/cram_bullet_reasoning/resource/bowl_round.stl and b/cram_3d_world/cram_bullet_reasoning/resource/bowl_round.stl differ diff --git a/cram_3d_world/cram_bullet_reasoning/resource/mug.stl b/cram_3d_world/cram_bullet_reasoning/resource/mug.stl index 87813c72f1..c89c115c8d 100644 Binary files a/cram_3d_world/cram_bullet_reasoning/resource/mug.stl and b/cram_3d_world/cram_bullet_reasoning/resource/mug.stl differ diff --git a/cram_3d_world/cram_bullet_reasoning/resource/mug_old_origin.stl b/cram_3d_world/cram_bullet_reasoning/resource/mug_old_origin.stl new file mode 100644 index 0000000000..87813c72f1 Binary files /dev/null and b/cram_3d_world/cram_bullet_reasoning/resource/mug_old_origin.stl differ diff --git a/cram_3d_world/cram_bullet_reasoning/resource/pot-ww.stl b/cram_3d_world/cram_bullet_reasoning/resource/pot-ww.stl index 1e3b1a2e94..8534a856df 100644 Binary files a/cram_3d_world/cram_bullet_reasoning/resource/pot-ww.stl and b/cram_3d_world/cram_bullet_reasoning/resource/pot-ww.stl differ diff --git a/cram_3d_world/cram_bullet_reasoning/resource/shoe.stl b/cram_3d_world/cram_bullet_reasoning/resource/shoe.stl index 3b87f34367..5f6c925a89 100644 Binary files a/cram_3d_world/cram_bullet_reasoning/resource/shoe.stl and b/cram_3d_world/cram_bullet_reasoning/resource/shoe.stl differ diff --git a/cram_3d_world/cram_bullet_reasoning/resource/spatula.stl b/cram_3d_world/cram_bullet_reasoning/resource/spatula.stl index da8c867d4a..292a843c28 100644 Binary files a/cram_3d_world/cram_bullet_reasoning/resource/spatula.stl and b/cram_3d_world/cram_bullet_reasoning/resource/spatula.stl differ diff --git a/cram_3d_world/cram_bullet_reasoning/src/aabb.lisp b/cram_3d_world/cram_bullet_reasoning/src/aabb.lisp index d98d79c6fc..0141e8bec4 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/aabb.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/aabb.lisp @@ -77,7 +77,7 @@ (bounding-box-dimensions bounding-box)) 2)))))) -(defun calculate-bb-dims (bullet-object) +(defun calculate-bb-dims (bullet-object &key initial-pose) "Calculates bounding box dimensions, putting the object down flatly, i.e. if the object has an angle with respect to the horizontal plane, i.e. an angle around the X or/and Y of the fixed map frame, @@ -90,8 +90,10 @@ with one of its sides." (setf (pose bullet-object) (cl-transforms:make-pose (cl-transforms:make-identity-vector) - (cram-tf:map-axis-aligned-orientation - (cl-transforms:orientation (pose bullet-object))))) + (if initial-pose + (cl-transforms:make-identity-rotation) + (cram-tf:map-axis-aligned-orientation + (cl-transforms:orientation (pose bullet-object)))))) (setf aabb (cl-bullet:aabb bullet-object))) (setf (pose bullet-object) old-pose)) (cl-bullet:bounding-box-dimensions aabb))) diff --git a/cram_3d_world/cram_bullet_reasoning/src/debug-window.lisp b/cram_3d_world/cram_bullet_reasoning/src/debug-window.lisp index 1012815295..0204dd01fa 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/debug-window.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/debug-window.lisp @@ -1,20 +1,20 @@ ;;; ;;; Copyright (c) 2010, Lorenz Moesenlechner ;;; All rights reserved. -;;; +;;; ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions are met: -;;; +;;; ;;; * Redistributions of source code must retain the above copyright ;;; notice, this list of conditions and the following disclaimer. ;;; * Redistributions in binary form must reproduce the above copyright ;;; notice, this list of conditions and the following disclaimer in the ;;; documentation and/or other materials provided with the distribution. ;;; * Neither the name of the Intelligent Autonomous Systems Group/ -;;; Technische Universitaet Muenchen nor the names of its contributors -;;; may be used to endorse or promote products derived from this software +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software ;;; without specific prior written permission. -;;; +;;; ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -36,8 +36,15 @@ (defvar *current-costmap-sample* nil "A red sphere for visualizing costmap samples.") (defvar *vis-axes* nil "An associative list of ((ID . (X Y Z)) ...) couples, storing axes of a coordinate frame for visualizing poses.") -(defparameter *costmap-z* 0.0) +(defparameter *vis-axis-width* 0.01 "In meters") +(defparameter *vis-axis-length* 0.3 "In meters") +(defparameter *vis-axis-alpha* 1.0 "Color alpha value of frame visualization.") +(defparameter *costmap-z* 0.005) (defparameter *costmap-tilt* (cl-transforms:make-quaternion 0 0 0 1)) +(defparameter *costmap-sample-dims* + (cl-transforms:make-3d-vector + 0.02 0.02 0.02) + "Half extents in meters.") (defun add-debug-window (world) (sb-thread:with-mutex (*debug-window-lock*) @@ -59,30 +66,29 @@ storing axes of a coordinate frame for visualizing poses.") (when (hidden *debug-window*) (show-window *debug-window*)))) -(defun costmap-color-fun (vec) - (let ((val (cl-transforms:z vec))) - (let ((segment (* val 4))) - (cond ((< segment 1.0) - (list 0.0 (* val 4) 1.0)) - ((< segment 2.0) - (list 0.0 1.0 (- 1.0 (* (- val 0.25) 4)))) - ((< segment 3.0) - (list (* (- val 0.5) 4) 1.0 0.0)) - ((< segment 4.0) - (list 1.0 (- 1.0 (* (- val 0.75) 4)) 0.0)) - (t (list 1.0 0.0 0.0)))))) - -(defun clear-costmap-vis-object () +(defun costmap-color-fun (val) + (let ((segment (* val 4))) + (cond ((< segment 1.0) + (list 0.0 (* val 4) 1.0)) + ((< segment 2.0) + (list 0.0 1.0 (- 1.0 (* (- val 0.25) 4)))) + ((< segment 3.0) + (list (* (- val 0.5) 4) 1.0 0.0)) + ((< segment 4.0) + (list 1.0 (- 1.0 (* (- val 0.75) 4)) 0.0)) + (t (list 1.0 0.0 0.0))))) + +(defun clear-costmap-vis-object (&key (costmap t) (sample t) (axes t)) (sb-thread:with-mutex (*debug-window-lock*) - (when (and *current-costmap-function* *debug-window*) + (when (and costmap *current-costmap-function* *debug-window*) (setf (gl-objects *debug-window*) (remove *current-costmap-function* (gl-objects *debug-window*))) (setf *current-costmap-function* nil)) - (when (and *current-costmap-sample* *debug-window*) + (when (and sample *current-costmap-sample* *debug-window*) (setf (gl-objects *debug-window*) (remove *current-costmap-sample* (gl-objects *debug-window*))) (setf *current-costmap-sample* nil)) - (when (and *vis-axes* *debug-window*) + (when (and axes *vis-axes* *debug-window*) (mapcar (lambda (id-axes-pair) (setf (gl-objects *debug-window*) (reduce (lambda (gl-objects-list axis-object) @@ -100,30 +106,35 @@ storing axes of a coordinate frame for visualizing poses.") (setf (gl-objects *debug-window*) (remove *current-costmap-function* (gl-objects *debug-window*)))) (when costmap - (let* ((map-array (location-costmap:get-cost-map costmap)) + (let* ((map-array (costmap:get-cost-map costmap)) (max-val (loop for y from 0 below (array-dimension map-array 0) maximizing (loop for x from 0 below (array-dimension map-array 1) maximizing (aref map-array y x))))) (declare (type cma:double-matrix map-array)) (flet ((costmap-function (x y) - (let ((val (/ (location-costmap:get-map-value costmap x y) max-val))) - (when (> val location-costmap:*costmap-valid-solution-threshold*) - val)))) + (let ((val (/ (costmap:get-map-value costmap x y) max-val))) + (when (> val costmap:*costmap-valid-solution-threshold*) + val))) + (costmap-height-function (x y) + (let ((val (costmap:generate-height costmap x y))) + (+ val *costmap-z*)))) (setf *current-costmap-function* (make-instance 'math-function-object - :width (location-costmap:grid-width costmap) - :height (location-costmap:grid-height costmap) - :alpha 0.5 :color-fun #'costmap-color-fun + :width (costmap:grid-width costmap) + :height (costmap:grid-height costmap) + :alpha 0.5 + :color-fun #'costmap-color-fun :pose (cl-transforms:make-pose (cl-transforms:make-3d-vector - (+ (location-costmap:origin-x costmap) - (/ (location-costmap:grid-width costmap) 2)) - (+ (location-costmap:origin-y costmap) - (/ (location-costmap:grid-height costmap) 2)) + (+ (costmap:origin-x costmap) + (/ (costmap:grid-width costmap) 2)) + (+ (costmap:origin-y costmap) + (/ (costmap:grid-height costmap) 2)) *costmap-z*) *costmap-tilt*) :function #'costmap-function - :step-size (location-costmap:resolution costmap))))) + :height-function #'costmap-height-function + :step-size (costmap:resolution costmap))))) (when *debug-window* (push *current-costmap-function* (gl-objects *debug-window*)))))) @@ -139,25 +150,27 @@ storing axes of a coordinate frame for visualizing poses.") :pose (cl-transforms:make-pose point (cl-transforms:make-identity-rotation)) - :collision-shape (make-instance 'colored-sphere-shape - :radius 0.05 + :collision-shape (make-instance 'colored-box-shape + :half-extents *costmap-sample-dims* :color '(1.0 0.0 0.0 0.5)))) (when *debug-window* (push *current-costmap-sample* (gl-objects *debug-window*)))))) -(defgeneric add-vis-axis-object (object-or-pose &key length id) +(defgeneric add-vis-axis-object (object-or-pose &key length width id) (:documentation "Spawn a coordinate frame at a given pose or at btr:object origin. It is built from 3 rigid bodies of primitive box shape. `Length' specified the length of a single axis. `Id' can be used if one wants to visualize multiple frames at the same time.") - (:method ((object-name symbol) &key (length 0.30) (id 0)) + (:method ((object-name symbol) + &key (length *vis-axis-length*) (width *vis-axis-width*) (id 0)) (add-vis-axis-object (pose (btr:object *current-bullet-world* object-name)) - :length length :id id)) + :length length :width width :id id)) - (:method ((pose cl-transforms:pose) &key (length 0.30) (id 0)) + (:method ((pose cl-transforms:pose) + &key (length *vis-axis-length*) (width *vis-axis-width*) (id 0)) (sb-thread:with-mutex (*debug-window-lock*) (when (and *vis-axes* *debug-window* (assoc id *vis-axes*)) (setf (gl-objects *debug-window*) @@ -167,6 +180,7 @@ It is built from 3 rigid bodies of primitive box shape. :initial-value (gl-objects *debug-window*)))) (let ((length/2 (/ length 2)) + (width/2 (/ width 2)) (object-transform (cl-transforms:pose->transform pose))) ;; spawn the objects @@ -188,16 +202,16 @@ It is built from 3 rigid bodies of primitive box shape. (let ((new-axes-list (list (make-axis-rigid-body `(,length/2 0 0) - `(,length/2 0.01 0.01) - '(0.5 0 0 0.5)) + `(,length/2 ,width/2 ,width/2) + `(0.5 0 0 ,*vis-axis-alpha*)) (make-axis-rigid-body `(0 ,length/2 0) - `(0.01 ,length/2 0.01) - '(0 0.5 0 0.5)) + `(,width/2 ,length/2 ,width/2) + `(0 0.5 0 ,*vis-axis-alpha*)) (make-axis-rigid-body `(0 0 ,length/2) - `(0.01 0.01 ,length/2) - '(0 0 0.5 0.5))))) + `(,width/2 ,width/2 ,length/2) + `(0 0 0.5 ,*vis-axis-alpha*))))) (if (assoc id *vis-axes*) (rplacd (assoc id *vis-axes*) new-axes-list) (push (cons id new-axes-list) *vis-axes*)))) diff --git a/cram_3d_world/cram_bullet_reasoning/src/gl-scenes.lisp b/cram_3d_world/cram_bullet_reasoning/src/gl-scenes.lisp index 216c49d502..03dcb74794 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/gl-scenes.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/gl-scenes.lisp @@ -172,15 +172,3 @@ (mirror-buffer (width camera) (height camera) gl-buffer 1) gl-buffer))) -(defun to-png-image (width height buffer &optional (color-mode :rgb)) - (let ((channels (ecase color-mode - (:rgb 3) - (:gray 1)))) - (let* ((result (make-array `(,height ,width ,channels) - :element-type '(unsigned-byte 8) - :displaced-to (make-array (* height width channels) - :element-type (list 'unsigned-byte 8))))) - (dotimes (i (array-total-size buffer) result) - (setf (row-major-aref result i) - (truncate (* (row-major-aref buffer i) #xff))))))) - diff --git a/cram_3d_world/cram_bullet_reasoning/src/items.lisp b/cram_3d_world/cram_bullet_reasoning/src/items.lisp index 1d58a7fbd3..7411d911f4 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/items.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/items.lisp @@ -33,7 +33,9 @@ (in-package :btr) -(defparameter *mesh-files* +(defvar *item-model-alpha* 1.0) + +(defvar *mesh-files* '((:mug "package://cram_bullet_reasoning/resource/mug.stl" t) (:mug-compound "package://cram_bullet_reasoning/resource/mug_compound.dae" t) (:plate "package://cram_bullet_reasoning/resource/plate.stl" nil) @@ -128,16 +130,14 @@ The name in the list is a keyword that is created by lispifying the filename." ;;;;;;;;;;;;;;;;;;;;;;;;;; ATTACHMENTS ;;;;;;;;;;;;;;;;;;;;;;;;;; (defmethod attach-object ((other-object item) (object item) - &key attachment-type loose - skip-removing-loose link grasp) + &key attachment-type loose link grasp) "Attaches `object' to `other-object': adds an attachment to the attached-objects lists of each other. `attachment-type' is a keyword that specifies the type of attachment. `loose' specifies if the attachment is bidirectional (nil) or unidirectional (t). In bidirectional attachments both objects are attached to each other. In unidirectional/loose attachments, one object is properly attached, and the other one is -loosely attached. `skip-removing-loose' should be T for attaching more objects -unidirectional. See `attach-object' above." +loosely attached." (declare (ignore link grasp)) ;; used in robot-model.lisp (when (equal (name object) (name other-object)) (warn "Cannot attach an object to itself: ~a" (name object)) @@ -163,11 +163,9 @@ unidirectional. See `attach-object' above." Deleting old attachment." (name object) (name other-object)) (btr:detach-object other-object object)))))) - (unless skip-removing-loose - (remove-loose-attachment-for object)) (let ((object-collision-information ;; Since robot objects are not in the attached-objects - ;; list of items, this has to be copied manuelly: + ;; list of items, this has to be copied manually: (if (and (get-robot-object) (object-attached (get-robot-object) object)) (get-collision-information object (get-robot-object)) @@ -190,17 +188,14 @@ unidirectional. See `attach-object' above." (defmethod attach-object ((other-objects list) (object item) &key attachment-type loose) "Will be used if an attachment should be made from one item to more -than one item. If `loose' T the other attachments have to be made with -`skip-removing-loose' as T to prevent removing loose attachments between -the element before in `other-objects' and `object'." +than one item." (if other-objects (progn (attach-object (first other-objects) object :attachment-type attachment-type :loose loose) (mapcar (lambda (obj) (attach-object obj object - :attachment-type attachment-type :loose loose - :skip-removing-loose T)) + :attachment-type attachment-type :loose loose)) (cdr other-objects))) (warn "Trying to attach an object to a NIL."))) @@ -208,7 +203,7 @@ the element before in `other-objects' and `object'." "Removes item names from the given arguments in the corresponding `attached-objects' lists of the given items." (when (equal (name object) (name other-object)) - (warn "Cannot attach an object to itself: ~a" (name object)) + (warn "Cannot detach an object from itself: ~a" (name object)) (return-from detach-object)) (flet ((get-attachment-object (elem) (attachment-object (car (second elem))))) @@ -265,6 +260,42 @@ it is possible to change the pose of its attachments when its pose changes." (setf already-moved '())))) (call-next-method)))) +(defmethod object-attached ((object item) (other-object item) + &key checked-attached-objects-of) + (flet ((object-directly-attached-p (object other-object) + (with-slots (attached-objects) object + (find (btr:name other-object) + (mapcar #'car attached-objects) + :test #'equalp)))) + (with-slots (attached-objects) object + (cond + ;; If `other-object' is directly attached to `object', return T. + ((object-directly-attached-p object other-object) + (return-from object-attached T)) + ;; Otherwise, it will be checked if `other-object' is + ;; attached to any attached object of `object' meaning + ;; that an indirect attachment might exist e.g.: + ;; `object' <-> another-object <-> `other-object' + (t + (let ((checked-all-attachments T)) + (loop for attachment in attached-objects do + (unless (find (car attachment) + checked-attached-objects-of + :test #'equalp) + (setf checked-all-attachments NIL) + (when (object-attached + (btr:object btr:*current-bullet-world* (car attachment)) + other-object + :checked-attached-objects-of + (append checked-attached-objects-of + (list (btr:name object)))) + (return-from object-attached T)))) + ;; If all attached objects were checked and no indirect + ;; attachment from `other-object' to `object' were found, + ;; return NIL. + (when checked-all-attachments + (return-from object-attached NIL)))))))) + ;;;;;;;;;;;;;;;;;;;;; SPAWNING MESH AND PRIMITIVE-SHAPED ITEMS ;;;;;;;;;;;; (defmethod add-object ((world bt-world) (type (eql :mesh)) name pose @@ -278,7 +309,7 @@ it is possible to change the pose of its attachments when its pose changes." (make-instance 'convex-hull-mesh-shape :points (physics-utils:3d-model-vertices scaled-mesh) :faces (physics-utils:3d-model-faces scaled-mesh) - :color color + :color (apply-alpha-value color *item-model-alpha*) :disable-face-culling disable-face-culling))) ((or string symbol) diff --git a/cram_3d_world/cram_bullet_reasoning/src/objects.lisp b/cram_3d_world/cram_bullet_reasoning/src/objects.lisp index 64cd9ba3c5..70a587738c 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/objects.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/objects.lisp @@ -225,7 +225,8 @@ :color color)))))) (defmethod add-object ((world bt-world) (type (eql :static-plane)) name pose - &key normal constant (collision-mask '(:default-filter))) + &key normal constant (collision-mask '(:default-filter)) + texture-str texture-size) (destructuring-bind (normal-x normal-y normal-z) normal (make-object world name (list @@ -242,12 +243,12 @@ ;; :width 16 :height 16 ;; :texture (texture-str->bitmap ;; *static-plane-texture* #\Space) - :width 32 :height 32 + :width (or texture-size 32) + :height (or texture-size 32) :texture (texture-str->bitmap - *static-plane-gray-texture* - #\Space - nil - #\g + (or texture-str + *static-plane-gray-texture*) + #\Space nil #\x '(0.6 0.6 0.6 1.0)))))))) (defmethod add-object ((world bt-world) (type (eql :sphere)) name pose @@ -460,8 +461,12 @@ of the object should _not_ be updated. `grasp' is the type of grasp orientation. (defgeneric detach-all-objects (object) (:documentation "Removes all attachments form the list of attached objects of `object'.")) +(defgeneric object-attached (object other-object &key &allow-other-keys) + (:documentation "Returns something if `other-object' is attached to + `object', otherwise NIL.")) + (defmethod attach-object ((object-to-attach-to-name symbol) (object-name symbol) - &key attachment-type loose skip-removing-loose link grasp) + &key attachment-type loose link grasp) "Attaches object named `object-name' to another object named `object-to-attach-to-name'." (multiple-value-bind (obj obj-found) (btr:object *current-bullet-world* object-name) @@ -471,11 +476,10 @@ of the object should _not_ be updated. `grasp' is the type of grasp orientation. (attach-object other-obj obj ;; merged keywords from items.lisp and robot-model.lisp :attachment-type attachment-type :loose loose - :skip-removing-loose skip-removing-loose :link link - :grasp grasp))))) + :link link :grasp grasp))))) (defmethod attach-object ((object-to-attach-to-names list) (object-name symbol) - &key attachment-type loose skip-removing-loose link grasp) + &key attachment-type loose link grasp) "Attaches object named `object-name' to other objects, the names of which are in `object-to-attach-names'." (multiple-value-bind (obj obj-found) @@ -487,8 +491,7 @@ the names of which are in `object-to-attach-names'." object-to-attach-to-names)) obj :attachment-type attachment-type :loose loose - :skip-removing-loose skip-removing-loose :link link - :grasp grasp)))) + :link link :grasp grasp)))) (defmethod detach-object ((object-to-detach-from-name symbol) (object-name symbol) &key) "Detaches object named `object-name' from another object named `object-to-detach-from-name'." diff --git a/cram_3d_world/cram_bullet_reasoning/src/package.lisp b/cram_3d_world/cram_bullet_reasoning/src/package.lisp index 3a20f7b1ec..385a5db3e5 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/package.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/package.lisp @@ -39,7 +39,7 @@ (:shadowing-import-from #:cl-bullet points pose) (:shadow copy-object) (:export *current-bullet-world* *current-timeline* *visibility-threshold* - *all-meshes-as-compound* + *all-meshes-as-compound* *robot-model-alpha* merge-bounding-boxes aabb calculate-bb-dims with-stored-world *debug-window* add-debug-window add-costmap-function-object add-vis-axis-object @@ -48,7 +48,8 @@ height fov-y z-near z-far pose gl-execute-with-camera camera-transform look-at-object-rotation with-rendering-to-framebuffer render-to-framebuffer - get-rendering-context read-pixelbuffer read-depthbuffer to-png-image + get-rendering-context read-pixelbuffer read-depthbuffer + to-png-image png-from-camera-view add-object generic-cup item mesh remove-object object object-type item-type item-types name rigid-bodies @@ -86,11 +87,12 @@ ;; reach-pose-ik reach-object-ik point-reachable-p reach-point-ik ;; object-reachable-p pose-reachable-p calculate-orientation-in-robot ;; calculate-object-tool-length - init-ros-object-database clear-bullet-world - ros-household-object execute open close ;; reach-ik-solution + clear-bullet-world + execute open close ;; reach-ik-solution attached attached-objects object-attached attach-object detach-object detach-all-objects detach-all-from-link - get-loose-attached-objects + get-loose-attached-objects remove-loose-attachment-for + link-attached-object-names object-name-attached-links item-dimensions add-objects-to-mesh-list open-object close-object @@ -108,9 +110,16 @@ #:get-robot-object #:get-environment-object #:robot-colliding-objects-without-attached #:robot-attached-objects-in-collision + #:find-levels-under-link ;; temporal-reasoning event make-event timeline timeline-init timeline-advance timeline-current-world-state timeline-lookup holds-in-world with-timeline ;; simple-sem-map - #:*mesh-path-whitelist*)) + #:*mesh-path-whitelist* + ;; textures + #:*static-plane-texture* + #:*static-plane-gray-texture* + #:*static-plane-gray-thin-texture* + #:*static-plane-black-inverted-texture* + #:*static-plane-texture-64x64)) diff --git a/cram_3d_world/cram_bullet_reasoning/src/png-rendering.lisp b/cram_3d_world/cram_bullet_reasoning/src/png-rendering.lisp new file mode 100644 index 0000000000..8dd1cb5b6c --- /dev/null +++ b/cram_3d_world/cram_bullet_reasoning/src/png-rendering.lisp @@ -0,0 +1,104 @@ +;;; +;;; Copyright (c) 2010, Lorenz Moesenlechner +;;; 2022, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen, nor the name of the Institute for +;;; Artificial Intelligence / University of Bremen, nor the names of their +;;; contributors may be used to endorse or promote products derived from +;;; this software without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. +;;; + +(in-package :btr) + +(defun to-png-image (width height buffer &optional (color-mode :rgb)) + (let ((channels (ecase color-mode + (:rgb 3) + (:gray 1)))) + (let* ((result (png:make-image height width channels))) + ;; `result' is an image array of size height x width x channels + ;; `buffer' is a vector of length height*width*channels + (dotimes (row height result) + (dotimes (col width) + (dotimes (rgb channels) + (setf (aref result row (- width col 1) rgb) + (truncate (* (aref buffer (+ (* row width channels) + (* col channels) + (* rgb))) + #xff))))))))) + +(defun png-from-camera-view (&key + (png-path "/tmp/scene.png") + (png-width 1000) + (png-height 1000) + (robot-camera-view t) + (camera-pose (cl-transforms:make-pose + (cl-transforms:make-3d-vector -1 0.7 9) + (cl-transforms:matrix->quaternion + (make-array '(3 3) + :initial-contents + '(( 0 -1 0) + (-1 0 0) + ( 0 0 -1))))))) + (let ((rendering-context + (btr:get-rendering-context png-width png-height))) + (when robot-camera-view + (setf camera-pose + (cut:var-value + '?camera-pose + (car (prolog:prolog + `(and (rob-int:robot ?robot) + (rob-int:camera-frame ?robot ?camera-frame) + (btr:link-pose ?robot ?camera-frame ?camera-pose))))))) + (cl-bullet-vis:with-gl-context rendering-context + (gl:with-pushed-attrib (:enable-bit :color-buffer-bit :depth-buffer-bit :texture-bit) + (gl:matrix-mode :modelview) + (gl:enable :light0 :lighting :cull-face :depth-test :color-material :blend :rescale-normal) + (apply #'gl:clear-color cl-bullet-vis:*background-color*) + (gl:clear :color-buffer :depth-buffer) + (gl:light-model :light-model-ambient #(0.5 0.5 0.5 1.0)) + (gl:light :light0 :diffuse #(0.8 0.8 0.8 1)) + (gl:light :light0 :specular #(0.8 0.8 0.8 1)) + (gl:load-identity) + (gl:rotate 90 1 0 0) + (gl:rotate -90 0 0 1) + (gl:rotate 180 1 0 0) + (gl:depth-func :lequal) + (gl:shade-model :smooth) + (gl:blend-func :src-alpha :one-minus-src-alpha) + (gl:hint :perspective-correction-hint :nicest) + (btr:with-rendering-to-framebuffer (png-width png-height) + (png::encode-file + (btr:to-png-image + png-width png-height + (car (btr:render-to-framebuffer + rendering-context + (btr:make-drawable-list + :drawables + (bt-vis:gl-objects btr:*debug-window*)) + (make-instance 'btr:camera + :pose camera-pose + :width png-width :height png-height)))) + png-path))))) + png-path) diff --git a/cram_3d_world/cram_bullet_reasoning/src/robot-model-facts.lisp b/cram_3d_world/cram_bullet_reasoning/src/robot-model-facts.lisp index bbdff172b0..467deaf0ba 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/robot-model-facts.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/robot-model-facts.lisp @@ -68,13 +68,24 @@ (%link-pose ?robot ?name ?pose)) (<- (head-pointing-at ?w ?robot-name ?pose) - (cram-robot-interfaces:robot ?robot-name) - (cram-robot-interfaces:robot-neck-links ?robot-name ?pan-link ?tilt-link) - (cram-robot-interfaces:robot-neck-joints ?robot-name ?pan-joint ?tilt-joint) + (rob-int:robot ?robot-name) + (rob-int:robot-neck-links ?robot-name ?pan-link ?tilt-link) + (rob-int:robot-neck-joints ?robot-name ?pan-joint ?tilt-joint) + (rob-int:robot-neck-pan-joint-forward-facing-axis-sign + ?robot-name ?pan-axis ?pan-sign) + (rob-int:robot-neck-tilt-joint-forward-facing-axis-sign + ?robot-name ?tilt-axis ?tilt-sign) + (rob-int:joint-lower-limit ?robot-name ?pan-joint ?pan-lower-limit) + (rob-int:joint-upper-limit ?robot-name ?pan-joint ?pan-upper-limit) + (rob-int:joint-lower-limit ?robot-name ?tilt-joint ?tilt-lower-limit) + (rob-int:joint-upper-limit ?robot-name ?tilt-joint ?tilt-upper-limit) (bullet-world ?w) (%object ?w ?robot-name ?robot) (lisp-fun calculate-pan-tilt ?robot ?pan-link ?tilt-link ?pose + ?pan-axis ?pan-sign ?tilt-axis ?tilt-sign + ?pan-lower-limit ?pan-upper-limit + ?tilt-lower-limit ?tilt-upper-limit (?pan-pos ?tilt-pos)) (lisp-fun set-joint-state ?robot ?pan-joint ?pan-pos ?_) (lisp-fun set-joint-state ?robot ?tilt-joint ?tilt-pos ?_)) diff --git a/cram_3d_world/cram_bullet_reasoning/src/robot-model-utils.lisp b/cram_3d_world/cram_bullet_reasoning/src/robot-model-utils.lisp index a5c7a70287..628a9a8b32 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/robot-model-utils.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/robot-model-utils.lisp @@ -117,56 +117,148 @@ :element-type 'float :initial-element 0.0))) -(defun calculate-pan-tilt (robot pan-link tilt-link pose) - "Calculates values for the pan and tilt joints so that they pose on - `pose'. Returns (LIST PAN-VALUE TILT-VALUE) -Used in desig-check-to-see of btr-visibility-costmap. -Should it be taken out and made PR2-specific?" - (let* ((pan-transform - (cl-transforms:reference-transform (link-pose robot pan-link))) - (tilt-transform - (cl-transforms:reference-transform (link-pose robot tilt-link))) - (pose-trans - (etypecase pose - (cl-transforms:3d-vector - (cl-transforms:make-transform - pose (cl-transforms:make-quaternion 0 0 0 1))) - (cl-transforms:pose (cl-transforms:reference-transform pose)) - (cl-transforms:transform pose))) - (pose-in-pan - (cl-transforms:transform* - (cl-transforms:transform-inv pan-transform) - pose-trans)) - (pose-in-tilt - (cl-transforms:transform* - (cl-transforms:transform-inv tilt-transform) - pose-trans)) - (pan-joint - (cl-urdf:from-joint (gethash pan-link (cl-urdf:links (urdf robot))))) - (pan-joint-name - (cl-urdf:name pan-joint)) - (pan-joint-axis-sign - (cl-transforms:z (cl-urdf:axis pan-joint))) - (tilt-joint - (cl-urdf:from-joint (gethash tilt-link (cl-urdf:links (urdf robot))))) - (tilt-joint-name - (cl-urdf:name tilt-joint)) - (tilt-joint-axis-sign - (cl-transforms:y (cl-urdf:axis tilt-joint)))) - (list - (* pan-joint-axis-sign - (+ (joint-state robot pan-joint-name) - (if (= (cl-transforms:x (cl-transforms:translation pose-in-pan)) 0) - 0.0 - (atan (cl-transforms:y (cl-transforms:translation pose-in-pan)) - (cl-transforms:x (cl-transforms:translation pose-in-pan)))))) - (* tilt-joint-axis-sign - (+ (joint-state robot tilt-joint-name) - (if (= (cl-transforms:x (cl-transforms:translation pose-in-tilt)) 0) - 0.0 - (atan (- (cl-transforms:z (cl-transforms:translation pose-in-tilt))) - (+ (expt (cl-transforms:y (cl-transforms:translation pose-in-tilt)) 2) - (expt (cl-transforms:x (cl-transforms:translation pose-in-tilt)) 2))))))))) +(defun calculate-pan-tilt (robot pan-link tilt-link pose + &optional + (pan-forward-axis 'cl-transforms:x) + (pan-forward-sign +1) + (tilt-forward-axis 'cl-transforms:x) + (tilt-forward-sign -1) + (pan-lower-limit nil) (pan-upper-limit nil) + (tilt-lower-limit nil) (tilt-upper-limit nil)) + "Calculates values for the pan and tilt joints so that they point at `pose'. +Returns a list: (pan-angle tilt-angle). +Used in visibility costmap calculations and in projection." + (flet ((non-zero-unit-vector (3d-vector) + (cond ((/= (cl-transforms:x 3d-vector) 0) + 'cl-transforms:x) + ((/= (cl-transforms:y 3d-vector) 0) + 'cl-transforms:y) + ((/= (cl-transforms:z 3d-vector) 0) + 'cl-transforms:z)))) + (let* ((map-T-pan-link + (cl-transforms:reference-transform (link-pose robot pan-link))) + (map-T-tilt-link + (cl-transforms:reference-transform (link-pose robot tilt-link))) + (map-T-look-pose + (etypecase pose + (cl-transforms:3d-vector + (cl-transforms:make-transform + pose (cl-transforms:make-quaternion 0 0 0 1))) + (cl-transforms:pose + (cl-transforms:reference-transform pose)) + (cl-transforms:transform + pose))) + (pan-link-T-look-pose ; pan-link-T-map * map-T-look-pose + (cl-transforms:transform* + (cl-transforms:transform-inv map-T-pan-link) + map-T-look-pose)) + (tilt-link-T-look-pose ; tilt-link-T-map * map-T-look-pose + (cl-transforms:transform* + (cl-transforms:transform-inv map-T-tilt-link) + map-T-look-pose)) + + (pan-joint + (cl-urdf:from-joint + (gethash pan-link (cl-urdf:links (urdf robot))))) + (pan-joint-name + (cl-urdf:name pan-joint)) + (pan-joint-axis + (cl-urdf:axis pan-joint)) + (pan-joint-rotational-axis + (non-zero-unit-vector pan-joint-axis)) + (pan-joint-forward-facing-axis + pan-forward-axis) + (pan-joint-forward-facing-sign + pan-forward-sign) + (pan-joint-other-axis + (car + (remove pan-joint-forward-facing-axis + (remove pan-joint-rotational-axis + (list 'cl-transforms:x + 'cl-transforms:y + 'cl-transforms:z))))) + (pan-joint-axis-sign + (funcall pan-joint-rotational-axis pan-joint-axis)) + + (tilt-joint + (cl-urdf:from-joint + (gethash tilt-link (cl-urdf:links (urdf robot))))) + (tilt-joint-name + (cl-urdf:name tilt-joint)) + (tilt-joint-axis + (cl-urdf:axis tilt-joint)) + (tilt-joint-rotational-axis + (non-zero-unit-vector tilt-joint-axis)) + (tilt-joint-forward-facing-axis + tilt-forward-axis) + (tilt-joint-forward-facing-sign + tilt-forward-sign) + (tilt-joint-other-axis + (car + (remove tilt-joint-forward-facing-axis + (remove tilt-joint-rotational-axis + (list 'cl-transforms:x + 'cl-transforms:y + 'cl-transforms:z))))) + (tilt-joint-axis-sign + (funcall tilt-joint-rotational-axis tilt-joint-axis)) + + (pan-link-T-look-pose-translation + (cl-transforms:translation pan-link-T-look-pose)) + (pan-link-T-look-pose-forward-facing-axis + (funcall pan-joint-forward-facing-axis + pan-link-T-look-pose-translation)) + (pan-link-T-look-pose-other-axis + (funcall pan-joint-other-axis + pan-link-T-look-pose-translation)) + + (tilt-link-T-look-pose-translation + (cl-transforms:translation tilt-link-T-look-pose)) + (tilt-link-T-look-pose-forward-facing-axis + (funcall tilt-joint-forward-facing-axis + tilt-link-T-look-pose-translation)) + (tilt-link-T-look-pose-other-axis + (funcall tilt-joint-other-axis + tilt-link-T-look-pose-translation)) + (tilt-link-T-look-pose-rotational-axis + (funcall tilt-joint-rotational-axis + tilt-link-T-look-pose-translation)) + + (pan-angle + (cl-transforms:normalize-angle + (+ (joint-state robot pan-joint-name) + (atan (* pan-joint-axis-sign + pan-joint-forward-facing-sign + pan-link-T-look-pose-other-axis) + pan-link-T-look-pose-forward-facing-axis)))) + (tilt-angle + (cl-transforms:normalize-angle + (+ (joint-state robot tilt-joint-name) + (atan (* tilt-joint-axis-sign + tilt-joint-forward-facing-sign + tilt-link-T-look-pose-other-axis) + (+ (expt tilt-link-T-look-pose-rotational-axis 2) + (expt tilt-link-T-look-pose-forward-facing-axis 2)))))) + + (cropped-pan-angle + (if (and pan-lower-limit pan-upper-limit) + (if (< pan-angle pan-lower-limit) + pan-lower-limit + (if (> pan-angle pan-upper-limit) + pan-upper-limit + pan-angle)) + pan-angle)) + (cropped-tilt-angle + (if (and tilt-lower-limit tilt-upper-limit) + (if (< tilt-angle tilt-lower-limit) + tilt-lower-limit + (if (> tilt-angle tilt-upper-limit) + tilt-upper-limit + tilt-angle)) + tilt-angle))) + + (values (list cropped-pan-angle cropped-tilt-angle) + (list pan-angle tilt-angle))))) (defun looking-in-direction-p (robot camera-frame angle-horizontal angle-vertical @@ -273,6 +365,38 @@ or other objects to which current object is attached." (find this-object-name (btr:attached-objects object) :key #'car))) - colliding-objects-without-robot))) - colliding-objects-without-robot-and-attached-objects)) + colliding-objects-without-robot)) + ;; remove all items which are indirectly + ;; attached between each other + (colliding-objects-without-robot-and-indirect-attached-objects + (remove-if + (lambda (object) + (some (lambda (attachment) + (btr:object-attached + (btr:object btr:*current-bullet-world* (car attachment)) + object)) + (btr:attached-objects object))) + colliding-objects-without-robot-and-attached-objects))) + colliding-objects-without-robot-and-indirect-attached-objects)) (attached-objects (get-robot-object))))) + + +(defun find-levels-under-link (parent-link) + (declare (type cl-urdf:link parent-link)) + "Finds all the child links under the parent link with the name +board or level or shelf in them" + (let ((levels-found)) + (labels ((find-levels (link) + (let* ((child-joints (cl-urdf:to-joints link)) + (child-links (mapcar #'cl-urdf:child child-joints))) + (mapcar (lambda (child-link) + (let ((child-name (cl-urdf:name child-link))) + (if (or (search "_board" child-name) + (search "_level" child-name) + (search "_shelf" child-name) + (search "Floor" child-name)) + (push child-link levels-found) + (find-levels child-link)))) + child-links)))) + (find-levels parent-link)) + levels-found)) diff --git a/cram_3d_world/cram_bullet_reasoning/src/robot-model.lisp b/cram_3d_world/cram_bullet_reasoning/src/robot-model.lisp index 5e6df396dc..4009b4e608 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/robot-model.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/robot-model.lisp @@ -33,7 +33,7 @@ (in-package :btr) -(defvar *robot-model-alpha* nil) +(defvar *robot-model-alpha* 0.7) (defgeneric urdf-make-collision-shape (geometry &optional color compound)) @@ -43,7 +43,7 @@ (make-instance 'colored-box-shape :half-extents (cl-transforms:v* (cl-urdf:size box) 0.5) - :color (apply-alpha-value color))) + :color (apply-alpha-value color *robot-model-alpha*))) (defmethod urdf-make-collision-shape ((cylinder cl-urdf:cylinder) &optional (color '(0.8 0.8 0.8 1.0)) (compound nil)) @@ -53,13 +53,13 @@ (cl-urdf:radius cylinder) (cl-urdf:radius cylinder) (* 0.5 (cl-urdf:cylinder-length cylinder))) - :color (apply-alpha-value color))) + :color (apply-alpha-value color *robot-model-alpha*))) (defmethod urdf-make-collision-shape ((sphere cl-urdf:sphere) &optional (color '(0.8 0.8 0.8 1.0)) (compound nil)) (declare (ignore compound)) (make-instance 'colored-sphere-shape :radius (cl-urdf:radius sphere) - :color (apply-alpha-value color))) + :color (apply-alpha-value color *robot-model-alpha*))) (defmethod urdf-make-collision-shape ((mesh cl-urdf:mesh) &optional (color '(0.8 0.8 0.8 1.0)) (compound nil)) @@ -139,16 +139,27 @@ (defgeneric (setf link-pose) (new-value robot-object name) (:documentation "Sets the pose of a link and all its children")) - -(defgeneric object-attached (robot-object object) - (:documentation "Returns the list of links `object' has been - attached to.") - (:method ((robot-object robot-object) (object object)) - (with-slots (attached-objects) robot-object - (values (mapcar #'attachment-link (car (cdr (assoc (name object) attached-objects - :test #'equal)))) - (mapcar #'attachment-grasp (car (cdr (assoc (name object) attached-objects - :test #'equal)))))))) +(defmethod object-attached ((object robot-object) (other-object object) &key loose) + "Returns the list of links `other-object' has been attached to." + (with-slots (attached-objects) object + (values (mapcar #'attachment-link (remove-if-not + (if loose + #'attachment-loose + #'identity) + (car (cdr (assoc (name other-object) attached-objects + :test #'equal))))) + (mapcar #'attachment-grasp (remove-if-not + (if loose + #'attachment-loose + #'identity) + (car (cdr (assoc (name other-object) attached-objects + :test #'equal)))))))) + +(defmethod object-attached ((object object) (other-object robot-object) &key) + "Robot objects cannot be attached to anything. +Things get attached to robot objects, not the other way around. +So this function just returns NIL." + NIL) (defmethod attach-object ((robot-object robot-object) (obj object) &key link loose grasp &allow-other-keys) @@ -218,14 +229,16 @@ Otherwise, the attachment is only used as information but does not affect the wo (defmethod detach-all-from-link ((robot-object robot-object) link) "Removes all objects form the given `link' of `robot-object'." (with-slots (attached-objects) robot-object - (dolist (attachment attached-objects) - (let* ((object-name (car attachment)) - (object-instance (object *current-bullet-world* object-name))) - (if object-instance - (let ((attached-to-links (object-attached robot-object object-instance))) - (when (find link attached-to-links :test #'equalp) - (detach-object robot-object object-instance :link link))) - (setf attached-objects (remove object-name attached-objects :key #'car))))))) + (dolist (attachment attached-objects) + (let* ((object-name (car attachment)) + (object-instance (object *current-bullet-world* object-name))) + (if object-instance + (let ((attached-to-links + (object-attached robot-object object-instance))) + (when (find link attached-to-links :test #'equalp) + (detach-object robot-object object-instance :link link))) + (setf attached-objects + (remove object-name attached-objects :key #'car))))))) (defmethod detach-all-objects ((robot-object robot-object)) "Removes all objects form the list of attached objects." @@ -233,8 +246,10 @@ Otherwise, the attachment is only used as information but does not affect the wo (dolist (attached-object attached-objects) (let ((object-name (car attached-object))) (if (object *current-bullet-world* object-name) - (detach-object robot-object (object *current-bullet-world* object-name)) - (setf attached-objects (remove object-name attached-objects :key #'car))))))) + (detach-object robot-object + (object *current-bullet-world* object-name)) + (setf attached-objects + (remove object-name attached-objects :key #'car))))))) (defgeneric gc-attached-objects (robot-object) (:documentation "Removes all attached objects with an invalid world @@ -268,6 +283,27 @@ Otherwise, the attachment is only used as information but does not affect the wo (detach-object robot-object obj)) (attach-object robot-object obj :link link-name))))) +(defun link-attached-object-names (robot-object link) + (declare (type robot-object robot-object) + (type string link)) + (remove-if #'null + (mapcar (lambda (attachment) + (let ((attachment-of-link + (find link + (second attachment) + :key #'attachment-link + :test #'string-equal))) + (when attachment-of-link + (attachment-object attachment-of-link)))) + (attached-objects robot-object)))) + +(defun object-name-attached-links (robot-object object-name) + (declare (type robot-object robot-object) + (type symbol object-name)) + (mapcar #'attachment-link + (second + (find object-name (attached-objects robot-object) :key #'car)))) + (defmethod initialize-instance :after ((robot-object robot-object) &key color name pose (collision-group :character-filter) @@ -309,7 +345,8 @@ Otherwise, the attachment is only used as information but does not affect the wo (cl-urdf:visual link)))) (let ((some-gray (/ (+ (random 5) 3) 10.0))) (list some-gray some-gray some-gray - (or *robot-model-alpha* 1.0))))) + (or *robot-model-alpha* 1.0)))) + *robot-model-alpha*) compound) :collision-flags :cf-default :group collision-group @@ -640,31 +677,38 @@ inverse joint transform of parent's from-joint and try again." (with-slots (urdf links joint-states) obj (let* ((joint (gethash joint-name (cl-urdf:joints urdf))) (parent (and joint (cl-urdf:parent joint)))) - (cond ((and parent (gethash (cl-urdf:name parent) links)) - (cl-transforms:transform->pose - (cl-transforms:transform* - (cl-transforms:reference-transform current-pose) - (cl-transforms:reference-transform (pose (gethash (cl-urdf:name parent) links)))))) - ((and parent (cl-urdf:from-joint parent)) - ;; walk the tree up - (let* ((parent-joint (cl-urdf:from-joint parent)) - (parent-joint-name (cl-urdf:name parent-joint))) - (find-parent-pose - obj parent-joint-name - (cl-transforms:transform->pose - (cl-transforms:transform* - (cl-transforms:reference-transform - (cl-urdf:origin parent-joint)) - (joint-transform - parent-joint - (or (joint-state obj parent-joint-name) - 0.0)) - (cl-transforms:reference-transform current-pose)))))) - (t ;; We are at the root. Return the object's inverse pose - ;; multiplied with current-pose + (cond + ;; parent has a physical link + ((and parent (gethash (cl-urdf:name parent) links)) + (cl-transforms:transform->pose + ;; map-T-parent = map-T-grandparent * grandparent-T-parent + (cl-transforms:transform* + (cl-transforms:reference-transform (pose (gethash (cl-urdf:name parent) links))) + (cl-transforms:reference-transform current-pose)))) + ;; parent has no physical link but there is a grandparent + ((and parent (cl-urdf:from-joint parent)) + ;; walk the tree up + (let* ((parent-joint (cl-urdf:from-joint parent)) + (parent-joint-name (cl-urdf:name parent-joint))) + (find-parent-pose + obj parent-joint-name + ;; grandpa-link-T-pa-link = + ;; grandpa-link-T-pa-joint * joint-state * pa-joint-T-pa-link + (cl-transforms:transform->pose (cl-transforms:transform* - (cl-transforms:reference-transform (pose obj)) - (cl-transforms:reference-transform current-pose))))))) + (cl-transforms:reference-transform + (cl-urdf:origin parent-joint)) + (joint-transform + parent-joint + (or (joint-state obj parent-joint-name) + 0.0)) + (cl-transforms:reference-transform current-pose)))))) + ;; We are at the root. Return the object's inverse pose + ;; multiplied with current-pose + (t + (cl-transforms:transform* + (cl-transforms:reference-transform (pose obj)) + (cl-transforms:reference-transform current-pose))))))) (defmethod link-pose ((obj robot-object) name) ;; We need to handle two different cases here. One is when we have a @@ -727,16 +771,3 @@ Only one joint state changes in this situation, so only one joint state is updat (with-slots (urdf) obj (setf (link-pose obj (cl-urdf:name (cl-urdf:root-link urdf))) new-value))) - -(defmacro with-alpha (alpha &body body) - `(let ((*robot-model-alpha* ,alpha)) - ,@body)) - -(defun apply-alpha-value (color) - (if (= (length color) 4) - (destructuring-bind (r g b a) color - (list r g b (or *robot-model-alpha* a))) - (if (= (length color) 3) - (destructuring-bind (r g b) color - (list r g b (or *robot-model-alpha* 1.0))) - (error "Color of an object has to be a list of 3 or 4 values")))) diff --git a/cram_3d_world/cram_bullet_reasoning/src/textures.lisp b/cram_3d_world/cram_bullet_reasoning/src/textures.lisp index 5d32334c82..c65733c7c4 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/textures.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/textures.lisp @@ -1,20 +1,20 @@ ;;; ;;; Copyright (c) 2010, Lorenz Moesenlechner ;;; All rights reserved. -;;; +;;; ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions are met: -;;; +;;; ;;; * Redistributions of source code must retain the above copyright ;;; notice, this list of conditions and the following disclaimer. ;;; * Redistributions in binary form must reproduce the above copyright ;;; notice, this list of conditions and the following disclaimer in the ;;; documentation and/or other materials provided with the distribution. ;;; * Neither the name of the Intelligent Autonomous Systems Group/ -;;; Technische Universitaet Muenchen nor the names of its contributors -;;; may be used to endorse or promote products derived from this software +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software ;;; without specific prior written permission. -;;; +;;; ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -54,35 +54,178 @@ (defparameter *static-plane-gray-texture* (concatenate 'string - "gggggggggggggggggggggggggggggggg" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "g g" - "gggggggggggggggggggggggggggggggg")) + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "x x" + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")) + + +(defparameter *static-plane-gray-thin-texture* + (concatenate + 'string + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x ")) + + + +(defparameter *static-plane-black-inverted-texture* + (concatenate + 'string + " " + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")) + +(defparameter *static-plane-texture-64x64 + (concatenate + 'string + "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x " + "x ")) diff --git a/cram_3d_world/cram_bullet_reasoning/src/utils.lisp b/cram_3d_world/cram_bullet_reasoning/src/utils.lisp index 5b0260d9f9..34dbb9af66 100644 --- a/cram_3d_world/cram_bullet_reasoning/src/utils.lisp +++ b/cram_3d_world/cram_bullet_reasoning/src/utils.lisp @@ -77,3 +77,15 @@ destructively modify the list." (t (iterate list (cdr list) count) list)))) +(defmacro with-alpha (alpha &body body) + `(let ((*robot-model-alpha* ,alpha)) + ,@body)) + +(defun apply-alpha-value (color alpha) + (if (= (length color) 4) + (destructuring-bind (r g b a) color + (list r g b (or alpha a))) + (if (= (length color) 3) + (destructuring-bind (r g b) color + (list r g b (or alpha 1.0))) + (error "Color of an object has to be a list of 3 or 4 values")))) diff --git a/cram_3d_world/cram_bullet_reasoning/tests/items-tests.lisp b/cram_3d_world/cram_bullet_reasoning/tests/items-tests.lisp index 2ea14c7817..71d3ce7c96 100644 --- a/cram_3d_world/cram_bullet_reasoning/tests/items-tests.lisp +++ b/cram_3d_world/cram_bullet_reasoning/tests/items-tests.lisp @@ -1006,9 +1006,7 @@ (btr:attach-object 'oo1 'oo2 :loose T) (btr:attach-object 'oo2 'oo3) (btr:attach-object 'oo2 'oo4) - (btr:attach-object 'oo5 'oo2 :loose T :skip-removing-loose T) - ;; the :skip-removing-loose key is used so the loose attachement - ;; between 'oo2 and 'oo1 won't get removed + (btr:attach-object 'oo5 'oo2 :loose T) (let ((loose-attached-obj-names (btr::get-loose-attached-objects (btr:object btr:*current-bullet-world* 'oo2)))) @@ -1050,9 +1048,7 @@ (btr:attach-object 'oo1 'oo2 :loose T) (btr:attach-object 'oo2 'oo3) (btr:attach-object 'oo2 'oo4) - (btr:attach-object 'oo5 'oo2 :loose T :skip-removing-loose T) - ;; the :skip-removing-loose key is used so the loose attachement - ;; between 'oo2 and 'oo1 won't get removed + (btr:attach-object 'oo5 'oo2 :loose T) (btr::remove-loose-attachment-for (btr:object btr:*current-bullet-world* 'oo2)) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/cram-bullet-reasoning-belief-state-tests.asd b/cram_3d_world/cram_bullet_reasoning_belief_state/cram-bullet-reasoning-belief-state-tests.asd new file mode 100644 index 0000000000..ad95577b45 --- /dev/null +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/cram-bullet-reasoning-belief-state-tests.asd @@ -0,0 +1,36 @@ +;;; +;;; Copyright (c) 2019, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(defsystem cram-bullet-reasoning-belief-state-tests + :depends-on (cram-bullet-reasoning-belief-state + lisp-unit) + :components ((:module "tests" + :components + ((:file "package") + (:file "event-handlers-tests" :depends-on ("package")))))) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/cram-bullet-reasoning-belief-state.asd b/cram_3d_world/cram_bullet_reasoning_belief_state/cram-bullet-reasoning-belief-state.asd index 25d63d5a26..e9f687c6ba 100644 --- a/cram_3d_world/cram_bullet_reasoning_belief_state/cram-bullet-reasoning-belief-state.asd +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/cram-bullet-reasoning-belief-state.asd @@ -71,6 +71,8 @@ (:file "object-perceptions" :depends-on ("package")) (:file "occasions" :depends-on ("package" "object-perceptions")) (:file "world-state-detecting" :depends-on ("package")) + (:file "consistency-checking" :depends-on ("package")) (:file "event-handlers" :depends-on ("package" "object-perceptions" + "consistency-checking" "world-state-detecting")))))) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/src/belief-state.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/src/belief-state.lisp index b2b30055b9..9be00a8c57 100644 --- a/cram_3d_world/cram_bullet_reasoning_belief_state/src/belief-state.lisp +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/src/belief-state.lisp @@ -31,7 +31,51 @@ (defparameter *spawn-debug-window* t "If the debug window should be spawned when belief state is set up.") -(defun average (min max) (+ min (/ (- max min) 2))) +(defun spawn-world () + ;; sunset blue sky color + (setf bt-vis:*background-color* (list (/ 203 255) (/ 216 255) (/ 223 255) 1)) + (assert + (cut:force-ll + (prolog `(and + (btr:bullet-world ?w) + ,@(when *spawn-debug-window* + '((btr:debug-window ?w))) + (btr:assert ?w (btr:object :static-plane + :floor ((0 0 0) (0 0 0 1)) + :normal (0 0 1) :constant 0 + :collision-mask (:default-filter) + :texture-str ,btr:*static-plane-texture-64x64 + :texture-size 64)) + (-> (rob-int:environment-name ?environment-name) + (btr:assert ?w (btr:object :urdf ?environment-name + ((0 0 0) (0 0 0 1)) + :collision-group :static-filter + :collision-mask (:default-filter + :character-filter) + ,@(when rob-int:*environment-urdf* + `(:urdf ,rob-int:*environment-urdf*)) + :compound T)) + (warn "ROB-INT:ENVIRONMENT-NAME was not defined. ~ + Have you loaded an environment knowledge package?")) + (-> (rob-int:robot ?robot) + (and (btr:assert ?w (btr:object :urdf ?robot ((0 0 0) (0 0 0 1)) + ;; :color (0.9 0.9 0.9 1.0) + :urdf ,rob-int:*robot-urdf*)) + (-> (rob-int:robot-joint-states ?robot :arm :left :park ?left-joint-states) + (assert (btr:joint-state ?world ?robot ?left-joint-states)) + (true)) + (-> (rob-int:robot-joint-states ?robot :arm :right :park ?right-joint-states) + (assert (btr:joint-state ?world ?robot ?right-joint-states)) + (true)) + (rob-int:robot-torso-link-joint ?robot ?_ ?torso-joint) + (rob-int:joint-lower-limit ?robot ?torso-joint ?lower-limit) + (rob-int:joint-upper-limit ?robot ?torso-joint ?upper-limit) + (lisp-fun cma:average ?lower-limit ?upper-limit ?average-joint-value) + (assert (btr:joint-state ?world ?robot + ((?torso-joint ?average-joint-value))))) + (warn "ROB-INT:ROBOT was not defined. ~ + Have you loaded a robot package?"))))))) + (defun setup-world-database () ;; make a clean world instance (setf btr:*current-bullet-world* (make-instance 'btr:bt-reasoning-world)) @@ -79,45 +123,16 @@ :origin origin-transform))) collision)))) + ;; get rid of Boxy's stupid limit boxes + (dolist (to-remove-collision-of-link '("limit_box" "limit_box2")) + (when (gethash to-remove-collision-of-link (cl-urdf:links rob-int:*robot-urdf*)) + (setf (slot-value (gethash to-remove-collision-of-link + (cl-urdf:links rob-int:*robot-urdf*)) + 'cl-urdf:collision) + nil))) + ;; spawn the floor, the robot and the environment - (assert - (cut:force-ll - (prolog `(and - (btr:bullet-world ?w) - ,@(when *spawn-debug-window* - '((btr:debug-window ?w))) - (btr:assert ?w (btr:object :static-plane :floor ((0 0 0) (0 0 0 1)) - :normal (0 0 1) :constant 0 - :collision-mask (:default-filter))) - (-> (rob-int:environment-name ?environment-name) - (btr:assert ?w (btr:object :urdf ?environment-name - ((0 0 0) (0 0 0 1)) - :collision-group :static-filter - :collision-mask (:default-filter - :character-filter) - ,@(when rob-int:*environment-urdf* - `(:urdf ,rob-int:*environment-urdf*)) - :compound T)) - (warn "ROB-INT:ENVIRONMENT-NAME was not defined. ~ - Have you loaded an environment knowledge package?")) - (-> (rob-int:robot ?robot) - (and (btr:assert ?w (btr:object :urdf ?robot ((0 0 0) (0 0 0 1)) - ;; :color (0.9 0.9 0.9 1.0) - :urdf ,rob-int:*robot-urdf*)) - (-> (rob-int:robot-joint-states ?robot :arm :left :park ?left-joint-states) - (assert (btr:joint-state ?world ?robot ?left-joint-states)) - (true)) - (-> (rob-int:robot-joint-states ?robot :arm :right :park ?right-joint-states) - (assert (btr:joint-state ?world ?robot ?right-joint-states)) - (true)) - (rob-int:robot-torso-link-joint ?robot ?_ ?torso-joint) - (rob-int:joint-lower-limit ?robot ?torso-joint ?lower-limit) - (rob-int:joint-upper-limit ?robot ?torso-joint ?upper-limit) - (lisp-fun average ?lower-limit ?upper-limit ?average-joint-value) - (assert (btr:joint-state ?world ?robot - ((?torso-joint ?average-joint-value))))) - (warn "ROB-INT:ROBOT was not defined. ~ - Have you loaded a robot package?")))))) + (spawn-world) ;; update robot from TF in case we have a real robot (let ((robot-object (btr:get-robot-object))) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/src/consistency-checking.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/src/consistency-checking.lisp new file mode 100644 index 0000000000..5653cb760f --- /dev/null +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/src/consistency-checking.lisp @@ -0,0 +1,135 @@ +;;; +;;; Copyright (c) 2019, Amar Fayaz +;;; 2020, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :cram-bullet-reasoning-belief-state) + +(defparameter *artificial-perception-noise-factor* 0.0 + "Gives the maximum distance in meters of simulated perception noise. +Eg. A value 0.1 means the perceived object can be moved around up to 0.1 meters +when simulated perception noise is applied. 0 means no artificial noise.") + +(defparameter *perception-instability-threshold* 0.07 + "The distance threshold in meters, +in which the simulation is expected to safely correct the perceived object pose. +Anything beyond this distance will cause a correction method to be triggered +to try and correct the unstable object. +If this threshold is NIL, no correction will happen.") + +(defparameter *perception-noise-correction-offset* 0.01 + "First distance in meters, with which the unstable perceived object will be +counter-moved when it falls down upon simulation.") + +(defparameter *perception-noise-correction-iterations* 5 + "Number of distances to try the correction approach with. In times.") + +(defparameter *perception-noise-correction-step* 0.01 + "The step in meters that each iteration of the correction approach differs +from the correction offset.") + +(defparameter *perception-noise-simulation-timeout* 3 + "In secs. How many seconds to simulate to compare initial vs simulated pose.") + + +(defun add-artificial-perception-noise (object-name object-pose) + "Randomly moves around the object to simulate the errors in perception. +The range at which the object is moved is determined by +*artificial-perception-noise-factor* and setting it to zero will disable noise." + (when (> *artificial-perception-noise-factor* 0.0) + (let* ((offset-direction (nth (random 3) '(:x :y :z))) + (offset-distance (- (random (* 2 *artificial-perception-noise-factor*)) + *artificial-perception-noise-factor*)) + (new-pose (cram-tf:translate-pose object-pose offset-direction offset-distance))) + (setf (btr:pose (btr:object btr:*current-bullet-world* object-name)) + new-pose)))) + +(defun calculate-perception-pose-correction (initial-pose simulated-pose) + "Returns correction info to counteract the perception noise. +The correction only happens if the distance between the poses is larger than +*perception-instability-threshold*. +Returns a list of ((:axis-1 sign-1) (:axis-2 sign-2)...)." + (loop with dist = (cl-transforms:v- (cl-transforms:origin initial-pose) + (cl-transforms:origin simulated-pose)) + with dist-list = (cram-tf:3d-vector->list dist) + with correction + for distance in dist-list + for axis in '(:x :y :z) + do (when (> (abs distance) *perception-instability-threshold*) + (push (/ distance (abs distance)) correction) + (push axis correction)) + finally (return correction))) + +(defun apply-bullet-object-pose (btr-world object-name object-new-pose) + "Moves the object to the new pose and erases old velocity." + ;; apply new pose + (setf (btr:pose (btr:object btr-world object-name)) + object-new-pose) + ;; erase object velocity from previous simulation + (mapcar (lambda (body) + (setf (cl-bullet:linear-velocity body) + (cl-transforms:make-identity-vector) + (cl-bullet:angular-velocity body) + (cl-transforms:make-identity-vector)) + (cl-bullet:clear-forces body)) + (btr:rigid-bodies (btr:object btr-world object-name)))) + +(defun stabilize-perceived-object-pose (btr-world object-name object-pose) + (when *perception-instability-threshold* + (apply-bullet-object-pose btr-world object-name object-pose) + (btr:simulate btr-world *perception-noise-simulation-timeout*) + (let* ((object-simulated-pose + (btr:pose (btr:object btr-world object-name))) + (object-pose-correction + (calculate-perception-pose-correction object-pose object-simulated-pose))) + (when object-pose-correction + (loop for offset = *perception-noise-correction-offset* + then (+ offset *perception-noise-correction-step*) + for iteration from 1 to *perception-noise-correction-iterations* + do (let* ((scaled-correction + (mapcar (lambda (x) (if (numberp x) (* x offset) x)) + object-pose-correction)) + (object-corrected-pose + (apply #'cram-tf:translate-pose object-pose scaled-correction))) + (apply-bullet-object-pose btr-world object-name object-corrected-pose) + (btr:simulate btr-world 10) + (let ((object-second-simulated-pose + (btr:pose (btr:object btr-world object-name)))) + (if (> (cl-transforms:v-dist + (cl-transforms:origin object-corrected-pose) + (cl-transforms:origin object-second-simulated-pose)) + *perception-instability-threshold*) + ;; if the correction did not make the object stable, + ;; reset the pose back and continue with the loop + (apply-bullet-object-pose btr-world object-name object-pose) + ;; if the correction helped, exit the loop + (return))))))))) + + + + diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/src/event-handlers.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/src/event-handlers.lisp index 08389bcca7..3359d25516 100644 --- a/cram_3d_world/cram_bullet_reasoning_belief_state/src/event-handlers.lisp +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/src/event-handlers.lisp @@ -12,8 +12,8 @@ ;;; notice, this list of conditions and the following disclaimer in the ;;; documentation and/or other materials provided with the distribution. ;;; * Neither the name of the Intelligent Autonomous Systems Group/ -;;; Technische Universitaet Muenchen nor the names of its contributors -;;; may be used to endorse or promote products derived from this software +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software ;;; without specific prior written permission. ;;; ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" @@ -69,29 +69,65 @@ and renames POSE into OLD-POSE." (defmethod cram-occasions-events:on-event object-perceived 2 ((event cpoe:object-perceived-event)) - (if cram-projection:*projection-environment* - ;; if in projection, only add the object name to perceived designators list - (let ((object-data (desig:reference (cpoe:event-object-designator event)))) - (or - (gethash (desig:object-identifier object-data) - *object-identifier-to-instance-mappings*) - (setf (gethash (desig:object-identifier object-data) - *object-identifier-to-instance-mappings*) - (desig:object-identifier object-data)))) - ;; otherwise, spawn a new object in the bullet world - (progn + (let* ((object-data (desig:reference (cpoe:event-object-designator event))) + (object-name (desig:object-identifier object-data)) + (object-pose (desig:object-pose object-data))) + (if cram-projection:*projection-environment* + ;; if in projection, add noise and add the object name to perceived designators list + (progn + (add-artificial-perception-noise object-name object-pose) + (or (gethash (desig:object-identifier object-data) + *object-identifier-to-instance-mappings*) + (setf (gethash (desig:object-identifier object-data) + *object-identifier-to-instance-mappings*) + (desig:object-identifier object-data)))) + ;; otherwise, spawn a new object in the bullet world (register-object-designator-data - (desig:reference (cpoe:event-object-designator event)) - :type (desig:desig-prop-value (cpoe:event-object-designator event) :type)) - ;; after having spawned the object, update the designator to get the - ;; new simulated pose - (desig:equate - (cpoe:event-object-designator event) - (detect-new-object-pose-from-btr (cpoe:event-object-designator event)))))) + object-data + :type (desig:desig-prop-value (cpoe:event-object-designator event) :type))) + ;; after having spawned the object, + ;; correct noise through world state consistency reasoning + (stabilize-perceived-object-pose btr:*current-bullet-world* object-name object-pose) + ;; simulate world + (btr:simulate btr:*current-bullet-world* 100) + ;; update the designator to get the new simulated pose + (desig:equate + (cpoe:event-object-designator event) + (detect-new-object-pose-from-btr (cpoe:event-object-designator event))))) (defmethod cram-occasions-events:on-event btr-belief ((event cpoe:object-location-changed)) + ;; Remove loose attachment between robot and object, + ;; if the object was placed somewhere else, e. g.: + ;; the robot has been placing an object on itself + ;; and now picked up and placed the object on the table. + (when (btr:attached-objects (btr:get-robot-object)) + (let* ((object-desig + (cpoe:event-object-designator event)) + (object-name + (desig:desig-prop-value object-desig :name)) + (btr-object + (btr:object btr:*current-bullet-world* object-name)) + (target-desig + (cpoe:event-location-designator event)) + (target-on-desig + (or (desig:desig-prop-value target-desig :on) + (desig:desig-prop-value target-desig :in))) + (urdf-name + (desig:desig-prop-value target-on-desig :urdf-name)) + (object-loose-attached-at-robot-links + (btr:object-attached (btr:get-robot-object) btr-object :loose T))) + ;; If the object is loosely attached to some robot links and the + ;; target location is not one of these robot links, the + ;; loose attachment between the robot and the object will be removed. + (when (and object-loose-attached-at-robot-links + (not (find (roslisp-utilities:rosify-underscores-lisp-name + urdf-name) + object-loose-attached-at-robot-links + :test #'equalp))) + (btr:detach-object (btr:get-robot-object) btr-object)))) + ;; update the designator to get the new location (update-object-designator-location (cpoe:event-object-designator event) @@ -111,6 +147,36 @@ and renames POSE into OLD-POSE." + +(defun snap-object-onto-robot (object-type object-name arm grasp) + (cut:with-vars-strictly-bound (?ee-frame ?ee-P-tcp ?std-gripper-T-gripper) + + (cut:lazy-car + (prolog:prolog + `(and + (rob-int:robot ?robot) + (rob-int:end-effector-link ?robot ,arm ?ee-frame) + (rob-int:tcp-in-ee-pose ?robot ?ee-P-tcp) + (rob-int:standard<-particular-gripper-transform ?robot ?std-gripper-T-gripper)))) + + (let* ((map-T-ee + (cl-transforms:reference-transform + (btr:link-pose (btr:get-robot-object) ?ee-frame))) + (ee-T-gripper + (cl-transforms:reference-transform ?ee-P-tcp)) + (gripper-T-std-gripper + (cl-transforms:transform-inv ?std-gripper-T-gripper)) + (obj-T-std-gripper + (man-int:get-object-type-to-gripper-transform + object-type object-name arm grasp)) + (std-gripper-T-obj + (cl-transforms:transform-inv obj-T-std-gripper)) + (map-T-obj + (cl-transforms:transform* + map-T-ee ee-T-gripper gripper-T-std-gripper std-gripper-T-obj))) + (setf (btr:pose (btr:object btr:*current-bullet-world* object-name)) + (cl-transforms:transform->pose map-T-obj))))) + (defmethod cram-occasions-events:on-event btr-attach-object 2 ((event cpoe:object-attached-robot)) "2 means this method has to be ordered based on integer qualifiers. It could have been 1 but 1 is reserved in case somebody has to be even more urgently @@ -146,10 +212,7 @@ If there is no other method with 1 as qualifier, this method will be executed al ;; with the supporting objects. do not destroy the normal attachments, ;; as those are attachments to the supported objects and we want the ;; supported objects to still stay with our grasped object - (mapcar (lambda (other-object-name) - (btr:detach-object - btr-object (btr:object btr:*current-bullet-world* other-object-name))) - (btr:get-loose-attached-objects btr-object)) + (btr:remove-loose-attachment-for btr-object) ;; now attach to the robot-object (when btr-object ;; if the object is already attached to some other robot link @@ -165,6 +228,13 @@ If there is no other method with 1 as qualifier, this method will be executed al :loose t :grasp grasp)) links grasps))) + ;; This is not really necessary, as the object and the gripper should + ;; already be perfectly aligned. But if one wanted to test something out + ;; without bothering to move the robot, this could be useful. + ;; In that case please call the function yourself directly. + ;; For environment objects, which are also robot objects, + ;; the grasp transform is not defined, so this only works for robot robots. + ;; (snap-object-onto-robot (car (btr:item-types btr-object)) btr-object-name arm grasp) ;; attach (btr:attach-object robot-object btr-object :link link :loose nil :grasp grasp) ;; invalidate the pose in the designator @@ -188,13 +258,14 @@ If there is no other method with 1 as qualifier, this method will be executed al (cpoe:event-link event) (error "[BTR-BELIEF OBJECT-DETACHED] either link or arm ~ in object-attached-robot even had to be given..."))))) - (when (cut:is-var link) (error "[BTR-BELIEF OBJECT-DETACHED] Couldn't find robot's EE link.")) + (when (cut:is-var link) + (error "[BTR-BELIEF OBJECT-DETACHED] Couldn't find robot's EE link.")) (if btr-object-name ;; if btr-object-name was given, detach it from the robot link (let ((btr-object (btr:object btr:*current-bullet-world* btr-object-name))) (when btr-object (btr:detach-object robot-object btr-object :link link) - (btr:simulate btr:*current-bullet-world* 10) + (btr:simulate btr:*current-bullet-world* 100) ;; find the links and items that support the object ;; and attach the object to them. ;; links get proper attachments and items loose attachments @@ -214,22 +285,30 @@ If there is no other method with 1 as qualifier, this method will be executed al (contacting-items (remove-if-not (lambda (c) (typep c 'btr:item)) - (btr:find-objects-in-contact btr:*current-bullet-world* btr-object)))) - ;; If a link contacting btr-object was found, btr-object - ;; will be attached to it - ;; also, if btr-object is in contact with an item, + (btr:find-objects-in-contact + btr:*current-bullet-world* btr-object)))) + ;; If btr-object is in contact with an item, ;; it will be attached loose. - (mapcar (lambda (link-name) - (btr:attach-object environment-object btr-object :link link-name)) - contacting-links) - (mapcar (lambda (item-object) - (when item-object - (btr:attach-object item-object btr-object :loose T))) - contacting-items)))) + ;; Otherwise, if a link contacting btr-object was found, + ;; btr-object will be attached to it. + (or (mapcar (lambda (item-object) + (when item-object + (btr:attach-object item-object btr-object :loose T))) + contacting-items) + (mapcar (lambda (link-name) + (btr:attach-object + environment-object btr-object :link link-name)) + contacting-links) + (roslisp:ros-warn (btr-belief btr-detach-object) + "Object ~a was detached from robot, + but after falling down it + is in no contact with the + environment or another object." + btr-object-name))))) ;; if btr-object-name was not given, detach all objects from the robot link (progn (btr:detach-all-from-link robot-object link) - (btr:simulate btr:*current-bullet-world* 10))))) + (btr:simulate btr:*current-bullet-world* 100))))) (defmethod cram-occasions-events:on-event btr-attach-two-objs ((event cpoe:object-attached-object)) (let* ((btr-object-name (cpoe:event-object-name event)) @@ -301,12 +380,12 @@ If there is no other method with 1 as qualifier, this method will be executed al ,new-joint-angle-rounded)) object))) -(defmethod cram-occasions-events:on-event open-container ((event cpoe:container-opening-event)) +(defmethod cram-occasions-events:on-event open-container 2 ((event cpoe:container-opening-event)) (move-joint-by-event event :open) (unless cram-projection:*projection-environment* (publish-environment-joint-state (btr:joint-states (cpoe:environment-event-object event))))) -(defmethod cram-occasions-events:on-event close-container ((event cpoe:container-closing-event)) +(defmethod cram-occasions-events:on-event close-container 2 ((event cpoe:container-closing-event)) (move-joint-by-event event :close) (unless cram-projection:*projection-environment* (publish-environment-joint-state (btr:joint-states (cpoe:environment-event-object event))))) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/src/object-perceptions.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/src/object-perceptions.lisp index fd48a0ab8f..6edff145f5 100644 --- a/cram_3d_world/cram_bullet_reasoning_belief_state/src/object-perceptions.lisp +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/src/object-perceptions.lisp @@ -108,9 +108,7 @@ just updated. Otherwise a new instance is created.")) ;; :disable-face-culling t :color ,(if (slot-boundp data 'desig::color) (desig:object-color data) - '(0.5 0.5 0.5))))))) - ;; simulate world - (btr:simulate btr:*current-bullet-world* 10))) + '(0.5 0.5 0.5))))))))) (defmethod register-object-designator-data ((data cram-physics-utils:object-shape-data-mixin) &key type) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/src/occasions.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/src/occasions.lisp index 0f6701d41f..6040b6692b 100644 --- a/cram_3d_world/cram_bullet_reasoning_belief_state/src/occasions.lisp +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/src/occasions.lisp @@ -40,6 +40,7 @@ (def-fact-group occasions (cpoe:object-in-hand cpoe:object-at-location + cpoe:object-placed cpoe:robot-at-location cpoe:torso-at cpoe:gripper-joint-at @@ -68,12 +69,16 @@ ;; if we only want to know the link and don't care about the arm ;; it can be that the arm is not even given in the attachments ;; so we need a bit of copy paste here... - (<- (cpoe:object-in-hand ?object ?_ ?grasp ?link) + (<- (cpoe:object-in-hand ?object ?arm ?grasp ?link) (btr:bullet-world ?world) (rob-int:robot ?robot) (btr:attached ?world ?robot ?link ?object-name ?grasp) (once (and (object-designator-name ?object ?object-name) - (desig:obj-desig? ?object)))) + (desig:obj-desig? ?object))) + (-> (bound ?arm) + (rob-int:end-effector-link ?robot ?arm ?link) + (once (or (rob-int:end-effector-link ?robot ?arm ?link) + (true))))) ;; (<- (cpoe:object-in-hand ?object ?arm) (cpoe:object-in-hand ?object ?arm ?_)) @@ -97,6 +102,10 @@ (object-designator-name ?object ?object-name) (%object-at-location ?_ ?object-name ?location)) + (<- (cpoe:object-placed ?object ?location) + (cpoe:object-at-location ?object ?location) + (not (cpoe:object-in-hand ?object))) + (<- (cpoe:torso-at ?joint-state) (symbol-value *torso-convergence-delta* ?torso-delta) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/src/package.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/src/package.lisp index f972f24d87..e9220a211d 100644 --- a/cram_3d_world/cram_bullet_reasoning_belief_state/src/package.lisp +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/src/package.lisp @@ -41,9 +41,19 @@ #:update-bullet-transforms ;; occasions #:object-designator-name + ;; event-handlers + #:snap-object-onto-robot ;; belief-state #:*spawn-debug-window* #:setup-world-database + #:spawn-world #:vary-kitchen-urdf ;; world-state-detecting - #:world-state-detecting-pm)) + #:world-state-detecting-pm + ;; consistency-checking + #:*artificial-perception-noise-factor* + #:*perception-instability-threshold* + #:*perception-noise-correction-offset* + #:*perception-noise-correction-iterations* + #:*perception-noise-correction-step* + #:*perception-noise-simulation-timeout*)) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/src/world-state-detecting.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/src/world-state-detecting.lisp index d6d944a9dc..efcbf340fb 100644 --- a/cram_3d_world/cram_bullet_reasoning_belief_state/src/world-state-detecting.lisp +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/src/world-state-detecting.lisp @@ -28,10 +28,6 @@ (in-package :btr-belief) -(def-fact-group world-state-matching-pms (cpm:matching-process-module) - (<- (cpm:matching-process-module ?motion-designator world-state-detecting-pm) - (desig:desig-prop ?motion-designator (:type :world-state-detecting)))) - (cpm:def-process-module world-state-detecting-pm (motion-designator) (destructuring-bind (command object-designator) (desig:reference motion-designator) @@ -39,6 +35,16 @@ (cram-common-designators:world-state-detect (world-state-detecting object-designator))))) + +(def-fact-group world-state-matching-pms (cpm:matching-process-module + cpm:available-process-module) + + (<- (cpm:matching-process-module ?motion-designator world-state-detecting-pm) + (desig:desig-prop ?motion-designator (:type :world-state-detecting))) + + (<- (cpm:available-process-module world-state-detecting-pm))) + + (defun world-state-detecting (object-designator) (declare (type desig:object-designator object-designator)) "Creates a new object designator with pose corresponding to current robot pose. @@ -97,7 +103,7 @@ the old object-designator description is enough to create a new one." (let* ((map-T-base (cram-tf:pose->transform-stamped cram-tf:*fixed-frame* cram-tf:*robot-base-frame* 0.0 - (cram-tf:robot-current-pose))) + (btr:pose (btr:get-robot-object)))) (base-T-map (cram-tf:transform-stamped-inv map-T-base)) (base-T-obj diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/tests/event-handlers-tests.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/tests/event-handlers-tests.lisp new file mode 100644 index 0000000000..132e5c9d2b --- /dev/null +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/tests/event-handlers-tests.lisp @@ -0,0 +1,320 @@ +;;; +;;; Copyright (c) 2019, Amar Fayaz +;;; Arthur Niedzwiecki +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :btr-belief-tests) + +(defparameter *kitchen-changed* t) + +(defun init-env () + "Resets the world. Only resets kitchen if it changed." + (when *kitchen-changed* + (let ((kitchen-urdf + (cl-urdf:parse-urdf + (roslisp:get-param "kitchen_description")))) + (prolog:prolog + `(and (btr:bullet-world ?world) + (assert (btr:object ?world + :urdf + :iai-kitchen ((0 0 0) (0 0 0 1)) + :urdf ,kitchen-urdf + :collision-group :static-filter + :collision-mask (:default-filter + :character-filter) + :compound T))))) + (setf *kitchen-changed* nil)) + (btr:prolog-?w + `(btr:item-type ?w ?obj ?type) + `(btr:retract (btr:object ?w ?obj))) + (btr:add-objects-to-mesh-list "cram_pr2_pick_place_demo")) + + +(define-test sink-counter-stable-position-test + (let* ((obj-name 'bowl-1) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector 1.4 0.8 0.9) + (cl-transforms:make-identity-rotation)))) + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + (btr:simulate btr:*current-bullet-world* 100) + (assert-true (< (cl-transforms:v-dist + (cl-transforms:origin spawn-pose) + (cl-transforms:origin + (btr:pose (btr:object btr:*current-bullet-world* obj-name)))) + 0.1)))) + +(define-test sink-counter-unstable-position-test + (let* ((obj-name 'bowl-1) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector 1.4 0.8 1.9) + (cl-transforms:make-identity-rotation)))) + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + (btr:simulate btr:*current-bullet-world* 100) + (assert-true (> (cl-transforms:v-dist + (cl-transforms:origin spawn-pose) + (cl-transforms:origin + (btr:pose (btr:object btr:*current-bullet-world* obj-name)))) + 0.1)))) + +(define-test a-case-that-our-approach-cannot-correct-but-would-still-be-fine-test + (let* ((obj-name 'bowl-1) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector 1.53 1.25 0.9) + (cl-transforms:make-identity-rotation)))) + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + ;; assert that although the object is unstable, + ;; the distance is not high enough to correct + (assert-false (btr:stable-p (btr:object btr:*current-bullet-world* obj-name))) + (btr:simulate btr:*current-bullet-world* 100) + (assert-true (< (cl-transforms:v-dist + (cl-transforms:origin spawn-pose) + (cl-transforms:origin (btr:pose (btr:object + btr:*current-bullet-world* + obj-name)))) + btr-belief:*perception-instability-threshold*)) + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + (btr-belief::stabilize-perceived-object-pose + btr:*current-bullet-world* obj-name spawn-pose) + (assert-true (< (cl-transforms:v-dist + (cl-transforms:origin spawn-pose) + (cl-transforms:origin (btr:pose (btr:object + btr:*current-bullet-world* + obj-name)))) + btr-belief:*perception-instability-threshold*)))) + + +(define-test bowl-on-edge-falling-stabilize-test + "Spawns bowl on the edge of the sink area surface, about to fall. +Tests if the bowl is stable after correction." + (let* ((?obj-name 'bowl-1) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector 1.27 0.8 0.9) + (cl-transforms:make-identity-rotation))) + (bowl-desig (desig:an object (type bowl) (name ?obj-name)))) + ;; Prepare the object designator to be fired in the perceive event. + (setf (slot-value bowl-desig 'desig:data) + (make-instance 'desig:object-designator-data + :object-identifier ?obj-name + :pose spawn-pose)) + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,?obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + ;; Verify that object is unstable. + (btr:simulate btr:*current-bullet-world* 10) + (assert-false (btr:stable-p (btr:object btr:*current-bullet-world* ?obj-name))) + ;; reset object + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,?obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + ;; Fire event + (cram-occasions-events:on-event + (make-instance 'cram-plan-occasions-events:object-perceived-event + :object-designator bowl-desig + :perception-source :whatever)) + ;; Verify object is stable. + (btr:simulate btr:*current-bullet-world* 10) + (assert-true (btr:stable-p (btr:object btr:*current-bullet-world* ?obj-name))))) + + +(define-test bowl-on-other-side-falling-stabilize-test + "Spawns bowl on the edge of the sink area surface, about to fall. +Tests if the bowl is stable after correction." + (let* ((?obj-name 'bowl-1) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector -0.6607 1.2022 0.89) + (cl-transforms:make-identity-rotation))) + (bowl-desig (desig:an object (type bowl) (name ?obj-name)))) + ;; Prepare the object designator to be fired in the perceive event. + (setf (slot-value bowl-desig 'desig:data) + (make-instance 'desig:object-designator-data + :object-identifier ?obj-name + :pose spawn-pose)) + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,?obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + ;; Verify that object is unstable. + (btr:simulate btr:*current-bullet-world* 10) + (assert-false (btr:stable-p (btr:object btr:*current-bullet-world* ?obj-name))) + ;; reset object + (init-env) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,?obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + ;; Fire event + (cram-occasions-events:on-event + (make-instance 'cram-plan-occasions-events:object-perceived-event + :object-designator bowl-desig + :perception-source :whatever)) + ;; Verify object is stable. + (btr:simulate btr:*current-bullet-world* 10) + (assert-true (btr:stable-p (btr:object btr:*current-bullet-world* ?obj-name))))) + + +(define-test spoon-falling-through-drawer-test + (unwind-protect + (let* ((?obj-name 'spoon-1) + (?obj-type :spoon) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector 1.05 0.87 0.71) + (cl-transforms:make-identity-rotation))) + (desig (desig:an object (type ?obj-type) (name ?obj-name)))) + (setf (slot-value desig 'desig:data) + (make-instance 'desig:object-designator-data + :object-identifier ?obj-name + :pose spawn-pose)) + + (init-env) + (setf (btr:joint-state (btr:get-environment-object) + "sink_area_left_upper_drawer_main_joint") 0.4) + (setf *kitchen-changed* t) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,?obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh ,?obj-type)))) + + (cram-occasions-events:on-event + (make-instance 'cram-plan-occasions-events:object-perceived-event + :object-designator desig + :perception-source :whatever)) + + (btr:simulate btr:*current-bullet-world* 10) + (assert-true (> (cl-transforms:z + (cl-transforms:origin + (btr:pose (btr:object btr:*current-bullet-world* ?obj-name)))) + 0.5))) + (setf (btr:joint-state (btr:get-environment-object) + "sink_area_left_upper_drawer_main_joint") 0.0))) + + +(define-test milk-in-fridge-door-test + (unwind-protect + (let* ((?obj-name 'milk-1) + (?obj-type :milk) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector 0.95 -1.14 0.66) + (cl-transforms:make-identity-rotation))) + (desig (desig:an object (type ?obj-type) (name ?obj-name)))) + (setf (slot-value desig 'desig:data) + (make-instance 'desig:object-designator-data + :object-identifier ?obj-name + :pose spawn-pose)) + + (init-env) + (setf (btr:joint-state (btr:get-environment-object) + "iai_fridge_door_joint") 1.57) + (setf *kitchen-changed* t) + (prolog:prolog `(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh ,?obj-name + ,(cram-tf:pose->list spawn-pose) + :mass 0.2 :color (1 0 0) :mesh ,?obj-type)))) + + (cram-occasions-events:on-event + (make-instance 'cram-plan-occasions-events:object-perceived-event + :object-designator desig + :perception-source :whatever)) + + (btr:simulate btr:*current-bullet-world* 10) + (assert-true (> (cl-transforms:z + (cl-transforms:origin + (btr:pose (btr:object btr:*current-bullet-world* ?obj-name)))) + 0.5))) + (setf (btr:joint-state (btr:get-environment-object) + "iai_fridge_door_joint") 0.0))) + + +#+This-test-has-some-bug-that-needs-to-be-fixed-Commenting-until-it-is-checked +(define-test kitchen-island-counted-edge-unstable-with-recovery-test + (let* ((obj-name :bowl-1) + (spawn-pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms:make-3d-vector -0.6607 1.2022 0.822) + (cl-transforms:make-identity-rotation)))) + (let ((kitchen-urdf + (cl-urdf:parse-urdf + (roslisp:get-param "kitchen_description")))) + (prolog:prolog + `(and (btr:bullet-world ?world) + (assert (btr:object ?world + :urdf + :kitchen ((0 0 0) (0 0 0 1)) + :urdf ,kitchen-urdf + :collision-group :static-filter + :collision-mask (:default-filter + :character-filter) + :compound T))))) + (btr:prolog-?w + `(btr:item-type ?w ?obj ?type) + `(btr:retract (btr:object ?w ?obj))) + (btr:add-objects-to-mesh-list "cram_pr2_pick_place_demo") + (prolog:prolog '(and (btr:bullet-world ?world) + (assert (btr:object ?world :mesh :bowl-1 ((-0.6607 1.2022 0.822) (0 0 0 1)) + :mass 0.2 :color (1 0 0) :mesh :bowl)))) + (btr:simulate btr:*current-bullet-world* 100) + (assert-true (> (cl-transforms:v-dist + (cl-transforms:origin spawn-pose) + (cl-transforms:origin (btr:pose (btr:object + btr:*current-bullet-world* + obj-name)))) + btr-belief::*perception-instability-threshold*)) + (btr-belief::check-and-correct-perception-instability :bowl-1 spawn-pose) + (assert-true (< (cl-transforms:v-dist + (cl-transforms:origin spawn-pose) + (cl-transforms:origin (btr:pose (btr:object + btr:*current-bullet-world* + obj-name)))) + btr-belief::*perception-instability-threshold*)))) diff --git a/cram_3d_world/cram_bullet_reasoning_belief_state/tests/package.lisp b/cram_3d_world/cram_bullet_reasoning_belief_state/tests/package.lisp new file mode 100644 index 0000000000..d9f0e0e47d --- /dev/null +++ b/cram_3d_world/cram_bullet_reasoning_belief_state/tests/package.lisp @@ -0,0 +1,32 @@ +;;; +;;; Copyright (c) 2019, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(defpackage :cram-bullet-reasoning-belief-state-tests + (:nicknames :btr-belief-tests) + (:use :common-lisp :lisp-unit)) diff --git a/cram_3d_world/cram_bullet_reasoning_utilities/src/objects-database.lisp b/cram_3d_world/cram_bullet_reasoning_utilities/src/objects-database.lisp index a9e5cc5c7b..8495529709 100644 --- a/cram_3d_world/cram_bullet_reasoning_utilities/src/objects-database.lisp +++ b/cram_3d_world/cram_bullet_reasoning_utilities/src/objects-database.lisp @@ -49,17 +49,25 @@ ;; Colors for different object types the same for all scenarios. (<- (%scenario-object-color :plate (0.8 0.58 0.35))) - (<- (%scenario-object-color :fork (0.2 0.1 0.3))) + ;; (<- (%scenario-object-color :fork (0.2 0.1 0.3))) (<- (%scenario-object-color :knife (0.5 0 0))) (<- (%scenario-object-color :mug (0.8 0.3 0))) (<- (%scenario-object-color :cup (1.0 0.64 0.293))) - (<- (%scenario-object-color :pot (0.1 0.2 0.3))) + ;; (<- (%scenario-object-color :pot (0.1 0.2 0.3))) + (<- (%scenario-object-color :pot (0.2 0.2 0.2))) (<- (%scenario-object-color :bowl (0.61 0.17 0.06))) (<- (%scenario-object-color :mondamin (0.5 0.1 0))) (<- (%scenario-object-color :spatula (0.1 0.1 0.1))) (<- (%scenario-object-color :pancake-maker (0.15 0.15 0.15))) (<- (%scenario-object-color :breakfast-cereal (0.5 0.5 0.21))) + (<- (%scenario-object-color :milk (0.12 0.22 0.42))) (<- (%scenario-object-color :visualization-box (1.0 0.0 0.0 0.5))) + (<- (%scenario-object-color :bowl-round (0.15 0.24 0.35))) + (<- (%scenario-object-color :denkmit-entkalker (0.96 0.89 0.3))) + (<- (%scenario-object-color :heitmann-citronensaeure (0.92 0.92 0.92))) + (<- (%scenario-object-color :kuehne-essig-essenz (0.06 0.39 0.26 0.3))) + (<- (%scenario-object-color :domestos-allzweckreiniger (0.06 0.24 0.48))) + (<- (%scenario-object-color :shoe (0.34 0.32 0.18))) ;; Object type shapes (<- (scenario-object-shape ?object-type ?shape) diff --git a/cram_3d_world/cram_fetch_deliver_plans/cram-fetch-deliver-plans-tests.asd b/cram_3d_world/cram_fetch_deliver_plans/cram-fetch-deliver-plans-tests.asd new file mode 100644 index 0000000000..b3840955bf --- /dev/null +++ b/cram_3d_world/cram_fetch_deliver_plans/cram-fetch-deliver-plans-tests.asd @@ -0,0 +1,74 @@ +;;; +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(defsystem cram-fetch-deliver-plans-tests + :author "Amar Fayaz" + :license "BSD" + + :depends-on (roslisp + lisp-unit + + cram-language + cram-executive + cram-designators + cram-prolog + cram-projection + cram-occasions-events + + cram-common-failures + cram-mobile-pick-place-plans + cram-object-knowledge + + cram-physics-utils ; for reading "package://" paths + cl-bullet ; for handling BOUNDING-BOX datastructures + cram-bullet-reasoning + cram-bullet-reasoning-belief-state + cram-bullet-reasoning-utilities + + cram-location-costmap + cram-btr-visibility-costmap + cram-btr-spatial-relations-costmap + cram-robot-pose-gaussian-costmap + cram-occupancy-grid-costmap + + cram-urdf-projection ; for with-simulated-robot + cram-urdf-projection-reasoning ; to set projection reasoning to T + cram-fetch-deliver-plans + cram-urdf-environment-manipulation + + cram-pr2-description) + + :components + ((:module "tests" + :components + ((:file "package") + (:file "utils" :depends-on ("package")) + (:file "searching-tests" :depends-on ("package" "utils")) + (:file "fetching-tests" :depends-on ("package" "utils")) + (:file "delivering-tests" :depends-on ("package" "utils")))))) diff --git a/cram_3d_world/cram_fetch_deliver_plans/package.xml b/cram_3d_world/cram_fetch_deliver_plans/package.xml index 13b90008e0..88346b4948 100644 --- a/cram_3d_world/cram_fetch_deliver_plans/package.xml +++ b/cram_3d_world/cram_fetch_deliver_plans/package.xml @@ -25,4 +25,23 @@ cram_manipulation_interfaces cram_urdf_projection_reasoning cram_urdf_environment_manipulation + + + + + + + + + + + + + + + + + + + diff --git a/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-designators.lisp b/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-designators.lisp index b650c55715..b3ace8727a 100644 --- a/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-designators.lisp +++ b/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-designators.lisp @@ -77,13 +77,16 @@ the `look-pose-stamped'." (desig:current-designator ?some-location-designator ?location-designator) ;; robot-location (-> (man-int:location-always-reachable ?location-designator) - (lisp-fun cram-tf:robot-current-pose ?robot-rotated-pose) - (lisp-fun calculate-robot-navigation-goal-towards-target ?location-designator - ?robot-rotated-pose)) + (and (lisp-fun cram-tf:robot-current-pose ?robot-rotated-pose) + (equal ?target-always-reachable T)) + (and (lisp-fun calculate-robot-navigation-goal-towards-target ?location-designator + ?robot-rotated-pose) + (equal ?target-always-reachable NIL))) (desig:designator :location ((:pose ?robot-rotated-pose)) ?robot-location) (desig:designator :action ((:type :turning-towards) (:target ?location-designator) - (:robot-location ?robot-location)) + (:robot-location ?robot-location) + (:target-always-reachable ?target-always-reachable)) ?resolved-action-designator)) @@ -103,15 +106,10 @@ the `look-pose-stamped'." ;; location of the object that we are trying to access (once (or (spec:property ?object-designator (:location ?object-location-desig)) (equal ?object-location-desig nil))) - ;; arm - (-> (spec:property ?action-designator (:arm ?arm)) + ;; arms + (-> (spec:property ?action-designator (:arms ?arms)) (true) - (man-int:robot-free-hand ?robot ?arm) - ;; (and (man-int:robot-free-hand ?robot ?arm) - ;; (-> (spec:property ?object-designator (:type :fridge)) - ;; (equal ?arm :right) - ;; (equal ?arm :left))) - ) + (setof ?arm (man-int:robot-free-hand ?robot ?arm) ?arms)) ;; distance (once (or (spec:property ?action-designator (:distance ?distance)) (equal ?distance NIL))) @@ -120,13 +118,13 @@ the `look-pose-stamped'." ?some-robot-location)) (desig:current-designator ?robot-location ?robot-location)) (desig:designator :location ((:reachable-for ?robot) - (:arm ?arm) + ;; (:arm ?arm) (:object ?object-designator)) ?robot-location))) (desig:designator :action ((:type ?action-type) (:object ?object-designator) (:object-location ?object-location-desig) - (:arm ?arm) + (:arms ?arms) (:distance ?distance) (:robot-location ?robot-location)) ?resolved-action-designator)) @@ -185,7 +183,6 @@ the `look-pose-stamped'." ;; arms (-> (spec:property ?action-designator (:arms ?arms)) (true) - ;; (equal ?arms NIL) (setof ?arm (man-int:robot-free-hand ?robot ?arm) ?arms)) ;; grasps (-> (spec:property ?action-designator (:grasps ?grasps)) @@ -203,7 +200,11 @@ the `look-pose-stamped'." (desig:designator :location ((:reachable-for ?robot) ;; ?arm is not available because we're sampling ;; (:arm ?arm) - (:object ?object-designator)) + (:object ?object-designator) + ;; have to add the visibility + ;; constraint as he reperceives + ;; each time before grasping + (:visible-for ?robot)) ?robot-location-designator))) ;; if the object is in the hand or its reference object is in the hand ;; we need to bring the hand closer to the other hand, e.g., bring to front diff --git a/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-plans.lisp b/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-plans.lisp index f4ce5bb2ab..a5b695e6b6 100644 --- a/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-plans.lisp +++ b/cram_3d_world/cram_fetch_deliver_plans/src/fetch-and-deliver-plans.lisp @@ -57,6 +57,7 @@ if yes, perform GOING action while ignoring failures." (defun turn-towards (&key ((:target ?look-target)) ((:robot-location ?robot-location)) + target-always-reachable &allow-other-keys) (declare (type desig:location-designator ?look-target ?robot-location)) "Perform a LOOKING action, if looking target twists the neck, @@ -81,9 +82,10 @@ turn the robot base such that it looks in the direction of target and look again (roslisp:ros-warn (pp-plans turn-towards) "~a~%Turning around." e) (cpl:do-retry turn-around-retries (cpl:par - (exe:perform (desig:an action - (type navigating) - (location ?robot-location))) + (unless target-always-reachable + (exe:perform (desig:an action + (type navigating) + (location ?robot-location)))) (let ((?goal `(cpoe:looking-at :forward))) (exe:perform (desig:an action (type looking) @@ -91,7 +93,9 @@ turn the robot base such that it looks in the direction of target and look again (goal ?goal))))) (cpl:retry)) (roslisp:ros-warn (pp-plans turn-towards) "Turning around didn't work :'(~%") - (cpl:fail 'common-fail:looking-high-level-failure))) + (roslisp:ros-warn (pp-plans turn-towards) "Ignoring the failure, not propagating up.") + ;; (cpl:fail 'common-fail:looking-high-level-failure) + (return))) (let (;; (?goal `(cpoe:looking-at ,?look-target)) ) (exe:perform (desig:an action @@ -105,11 +109,12 @@ turn the robot base such that it looks in the direction of target and look again ((:type action-type)) ((:object ?object-to-manipulate)) ((:object-location ?object-location)) - ((:arm ?arm)) + ((:arms all-arms)) ((:distance ?distance)) ((:robot-location ?manipulate-robot-location)) &allow-other-keys) - (declare (type keyword action-type ?arm) + (declare (type keyword action-type) + (type list all-arms) (type desig:object-designator ?object-to-manipulate) (type (or desig:location-designator null) ?object-location) (type (or number null) ?distance) @@ -135,61 +140,97 @@ if yes, relocate and retry, if no collisions, open or close container." (cpl:fail 'common-fail:environment-manipulation-impossible :description "Some designator could not be resolved."))) - (cpl:with-retry-counters ((relocation-retries 50)) - (cpl:with-failure-handling - (((or common-fail:navigation-goal-in-collision - common-fail:environment-unreachable - common-fail:gripper-low-level-failure - common-fail:manipulation-low-level-failure) (e) - (common-fail:retry-with-loc-designator-solutions - ?manipulate-robot-location - relocation-retries - (:error-object-or-string e - :warning-namespace (fd-plans environment) - :rethrow-failure 'common-fail:environment-manipulation-impossible) - (let ((?goal `(cpoe:gripper-opened (:left :right)))) + (let* ((?arms all-arms) + (?arm (cut:lazy-car ?arms)) + ;; TODO: THIS LET IS A HACK because I'm lazy to make a subaction for accessing + (?manipulate-robot-location-with-arm + (desig:copy-designator ?manipulate-robot-location + :new-description `((:arm ,?arm))))) + + ;; if opening- / closing-container fails, relocate + (cpl:with-retry-counters ((relocation-retries 50)) + (cpl:with-failure-handling + (((or common-fail:environment-unreachable) (e) + (common-fail:retry-with-loc-designator-solutions + ?manipulate-robot-location-with-arm + relocation-retries + (:error-object-or-string e + :warning-namespace (fd-plans environment) + :reset-designators (list ?manipulate-robot-location-with-arm) + :rethrow-failure 'common-fail:environment-manipulation-impossible) + ;; TODO: what if the another arm is holding an object! (exe:perform (desig:an action - (type opening-gripper) - (gripper (left right)) - (goal ?goal)))) - (roslisp:ros-info (fd-plans environment) "Relocating...")))) - - ;; navigate, open / close - (exe:perform (desig:an action - (type navigating) - (location ?manipulate-robot-location))) - - (let ((manipulation-action - (ecase action-type - (:accessing - (let ((?goal - (if ?distance - `(cpoe:container-state ,?object-to-manipulate ,?distance) - `(cpoe:container-state ,?object-to-manipulate :open)))) - (desig:an action - (type opening) - (arm ?arm) - (object ?object-to-manipulate) - (desig:when ?distance - (distance ?distance)) - (goal ?goal)))) - (:sealing - (let ((?goal - (if ?distance - `(cpoe:container-state ,?object-to-manipulate ,?distance) - `(cpoe:container-state ,?object-to-manipulate :closed)))) - (desig:an action - (type closing) - (arm ?arm) - (object ?object-to-manipulate) - (desig:when ?distance - (distance ?distance)) - (goal ?goal))))))) - - (proj-reasoning:check-environment-manipulation-collisions manipulation-action) - (setf manipulation-action (desig:current-desig manipulation-action)) - - (exe:perform manipulation-action))))) + (type releasing))) + (setf ?arms + all-arms) + (setf ?arm + (cut:lazy-car ?arms)) + (setf (cadr (find :arm (desig:description ?manipulate-robot-location-with-arm) + :key #'car)) + ?arm) + (roslisp:ros-info (fd-plans environment) "Relocating...")))) + + ;; if opening- / closing-container fails with this arm, try another arm + (cpl:with-retry-counters ((arm-retries 1)) + (cpl:with-failure-handling + (((or common-fail:navigation-goal-in-collision + common-fail:environment-unreachable + common-fail:gripper-low-level-failure + common-fail:manipulation-low-level-failure + desig:designator-error) (e) + (common-fail:retry-with-list-solutions + ?arms + arm-retries + (:error-object-or-string + (format NIL "Manipulation failed: ~a.~%Next." e) + :warning-namespace (fd-plans environment) + :rethrow-failure 'common-fail:environment-unreachable) + ;; TODO: what if the another arm is holding an object! + (exe:perform (desig:an action + (type releasing))) + (setf ?arm + (cut:lazy-car ?arms)) + (setf (cadr (find :arm (desig:description ?manipulate-robot-location-with-arm) + :key #'car)) + ?arm) + (desig:reset ?manipulate-robot-location-with-arm)))) + + ;; navigate, open / close + (exe:perform (desig:an action + (type navigating) + (location ?manipulate-robot-location-with-arm))) + + (let ((manipulation-action + (ecase action-type + (:accessing + (let ((?goal + (if ?distance + `(cpoe:container-state ,?object-to-manipulate ,?distance) + `(cpoe:container-state ,?object-to-manipulate :open)))) + (desig:an action + (type opening) + (arm ?arm) + (object ?object-to-manipulate) + (desig:when ?distance + (distance ?distance)) + (goal ?goal)))) + (:sealing + (let ((?goal + (if ?distance + `(cpoe:container-state ,?object-to-manipulate ,?distance) + `(cpoe:container-state ,?object-to-manipulate :closed)))) + (desig:an action + (type closing) + (arm ?arm) + (object ?object-to-manipulate) + (desig:when ?distance + (distance ?distance)) + (goal ?goal))))))) + + (proj-reasoning:check-environment-manipulation-collisions manipulation-action) + (setf manipulation-action (desig:current-desig manipulation-action)) + + (exe:perform manipulation-action)))))))) ;; Seal the object containing location after sealing the object (when (and ?object-location @@ -214,97 +255,108 @@ if yes, relocate and retry, if no collisions, open or close container." If the object is not there or navigation location is unreachable, retries with different search location or robot base location." - (cpl:with-failure-handling - ((desig:designator-error (e) - (roslisp:ros-warn (fd-plans search-for-object) - "Desig ~a could not be resolved: ~a~%Propagating up." - ?search-location e) - (cpl:fail 'common-fail:searching-failed - :description "Search location designator could not be resolved."))) - - ;; take new `?search-location' sample if a failure happens and retry - (cpl:with-retry-counters ((outer-search-location-retries 3)) - (cpl:with-failure-handling - ((common-fail:object-nowhere-to-be-found (e) - (common-fail:retry-with-loc-designator-solutions - ?search-location - outer-search-location-retries - (:error-object-or-string e - :warning-namespace (fd-plans search-for-object) - :reset-designators (list ?robot-location) - :rethrow-failure 'common-fail:searching-failed - :distance-threshold 0.1) - (roslisp:ros-warn (fd-plans search-for-object) - "Search is about to give up. Retrying~%")))) - - ;; if the going action fails, pick another `?robot-location' sample and retry - (cpl:with-retry-counters ((robot-location-retries 4)) - (cpl:with-failure-handling - (((or common-fail:navigation-goal-in-collision - common-fail:looking-high-level-failure - common-fail:perception-low-level-failure) (e) - (costmap:reset-costmap-cache) - (common-fail:retry-with-loc-designator-solutions - ?robot-location - robot-location-retries - (:error-object-or-string e - :warning-namespace (fd-plans search-for-object) - :reset-designators (list ?search-location ?robot-location) - :rethrow-failure 'common-fail:object-nowhere-to-be-found) - ;; go up with torso to look from higher up - (let ((?goal `(cpoe:torso-at :upper-limit))) - (exe:perform (desig:an action - (type moving-torso) - (joint-angle upper-limit) - (goal ?goal))))))) + (setf ?search-location (desig:reset ?search-location)) + (setf ?robot-location (desig:reset ?robot-location)) - ;; navigate - (exe:perform (desig:an action - (type navigating) - (location ?robot-location))) - - (cpl:with-retry-counters ((move-torso-retries 1)) - (cpl:with-failure-handling - ((common-fail:perception-low-level-failure (e) - (cpl:do-retry move-torso-retries - (roslisp:ros-warn (pick-and-place perceive) "~a" e) - ;; if a failure happens, try to go with the torso a bit more down - (let ((?goal `(cpoe:torso-at :middle))) - (exe:perform (desig:an action - (type moving-torso) - (joint-angle middle) - (goal ?goal)))) - (cpl:retry)))) - - ;; if perception action fails, try another `?search-location' and retry - (cpl:with-retry-counters ((search-location-retries 1)) - (cpl:with-failure-handling - (((or common-fail:perception-low-level-failure - common-fail:looking-high-level-failure) (e) - (common-fail:retry-with-loc-designator-solutions - ?search-location - search-location-retries - (:error-object-or-string e - :warning-namespace (fd-plans search-for-object) - :reset-designators (list ?robot-location))))) - - (let (;; (?goal `(cpoe:looking-at ,?search-location)) - ) + (cpl:with-retry-counters ((designator-broke-retries 1)) + (cpl:with-failure-handling + ((desig:designator-error (e) + (cpl:do-retry designator-broke-retries + (roslisp:ros-warn (fd-plans search-for-object) + "Desig ~a could not be resolved: ~a~%Retrying." + ?search-location e) + (setf ?search-location (desig:reset ?search-location)) + (cpl:retry)) + (roslisp:ros-warn (fd-plans search-for-object) + "Desig ~a could not be resolved: ~a~%Propagating up." + ?search-location e) + (cpl:fail 'common-fail:searching-failed + :description "Search location designator could not be resolved."))) + + ;; take new `?search-location' sample if a failure happens and retry + (cpl:with-retry-counters ((outer-search-location-retries 3)) + (cpl:with-failure-handling + (((or common-fail:object-nowhere-to-be-found + desig:designator-error) (e) + (common-fail:retry-with-loc-designator-solutions + ?search-location + outer-search-location-retries + (:error-object-or-string e + :warning-namespace (fd-plans search-for-object) + :reset-designators (list ?robot-location) + :rethrow-failure 'common-fail:searching-failed + :distance-threshold 0.1) + (roslisp:ros-warn (fd-plans search-for-object) + "Search is about to give up. Retrying~%")))) + + ;; if the going action fails, pick another `?robot-location' sample and retry + (cpl:with-retry-counters ((robot-location-retries 5)) + (cpl:with-failure-handling + (((or common-fail:navigation-goal-in-collision + common-fail:looking-high-level-failure + common-fail:perception-low-level-failure) (e) + (costmap:reset-costmap-cache) + (common-fail:retry-with-loc-designator-solutions + ?robot-location + robot-location-retries + (:error-object-or-string e + :warning-namespace (fd-plans search-for-object) + :reset-designators (list ?search-location ?robot-location) + :rethrow-failure 'common-fail:object-nowhere-to-be-found) + ;; go up with torso to look from higher up + (let ((?goal `(cpoe:torso-at :upper-limit))) + (exe:perform (desig:an action + (type moving-torso) + (joint-angle upper-limit) + (goal ?goal))))))) + + ;; navigate + (exe:perform (desig:an action + (type navigating) + (location ?robot-location))) + + (cpl:with-retry-counters ((move-torso-retries 1)) + (cpl:with-failure-handling + ((common-fail:perception-low-level-failure (e) + (cpl:do-retry move-torso-retries + (roslisp:ros-warn (pick-and-place perceive) "~a" e) + ;; if a failure happens, try to go with the torso a bit more down + (let ((?goal `(cpoe:torso-at :middle))) + (exe:perform (desig:an action + (type moving-torso) + (joint-angle middle) + (goal ?goal)))) + (cpl:retry)))) + + ;; if perception action fails, try another `?search-location' and retry + (cpl:with-retry-counters ((search-location-retries 2)) + (cpl:with-failure-handling + (((or common-fail:perception-low-level-failure + common-fail:looking-high-level-failure) (e) + (common-fail:retry-with-loc-designator-solutions + ?search-location + search-location-retries + (:error-object-or-string e + :warning-namespace (fd-plans search-for-object) + :reset-designators (list ?robot-location))))) + + (let ( ;; (?goal `(cpoe:looking-at ,?search-location)) + ) + (exe:perform (desig:an action + (type turning-towards) + (target ?search-location) + ;; (goal ?goal) + ))) (exe:perform (desig:an action - (type turning-towards) - (target ?search-location) - ;; (goal ?goal) - ))) - (exe:perform (desig:an action - (type perceiving) - (object ?object-designator))))))))))))) + (type perceiving) + (object ?object-designator)))))))))))))) (defun fetch (&key ((:object ?object-designator)) - ((:arms ?arms)) - ((:grasps ?grasps)) + ((:arms ?all-arms)) + ((:grasps ?all-grasps)) ((:robot-location ?pick-up-robot-location)) ((:look-location ?look-location)) pick-up-action @@ -312,7 +364,7 @@ retries with different search location or robot base location." object-hand &allow-other-keys) (declare (type desig:object-designator ?object-designator) - (type list ?arms ?grasps) + (type list ?all-arms ?all-grasps) ;; ?pick-up-robot-location should not be NULL at the beginning ;; but can become NULL during execution of the plan (type (or desig:location-designator null) ?pick-up-robot-location) @@ -322,6 +374,9 @@ one of arms in the `?arms' lazy list (if not NIL) and one of grasps in `?grasps' while standing at `?pick-up-robot-location' and using the grasp and arm specified in `pick-up-action' (if not NIL)." + (setf ?look-location (desig:reset ?look-location)) + (setf ?pick-up-robot-location (desig:reset ?pick-up-robot-location)) + (cpl:with-failure-handling ((desig:designator-error (e) (roslisp:ros-warn (fd-plans fetch) "~a~%Propagating up." e) @@ -336,7 +391,11 @@ and using the grasp and arm specified in `pick-up-action' (if not NIL)." common-fail:looking-high-level-failure common-fail:perception-low-level-failure common-fail:object-unreachable - common-fail:manipulation-low-level-failure) (e) + common-fail:manipulation-low-level-failure + desig:designator-error) (e) + (setf ?pick-up-robot-location + (desig:reset ?pick-up-robot-location)) + (desig:reference ?pick-up-robot-location) (common-fail:retry-with-loc-designator-solutions ?pick-up-robot-location relocation-for-ik-retries @@ -367,7 +426,7 @@ and using the grasp and arm specified in `pick-up-action' (if not NIL)." (desig:when (eql object-hand :right) (right-configuration hand-over)) (goal ?goal))) - (desig:reset ?look-location))) + (setf ?look-location (desig:reset ?look-location)))) (let (;; (?goal `(cpoe:looking-at ,?look-location)) ) @@ -377,16 +436,13 @@ and using the grasp and arm specified in `pick-up-action' (if not NIL)." ;; (goal ?goal) ))) - (cpl:with-retry-counters ((regrasping-retries 1)) + (cpl:with-retry-counters ((regrasping-retries 2)) (cpl:with-failure-handling ((common-fail:gripper-low-level-failure (e) (roslisp:ros-warn (fd-plans fetch) "Misgrasp happened: ~a~%" e) + ;; TODO: what if the another arm is holding an object! (exe:perform (desig:an action - (type releasing) - (gripper left))) - (exe:perform (desig:an action - (type releasing) - (gripper right))) + (type releasing))) (cpl:do-retry regrasping-retries (roslisp:ros-info (fd-plans fetch) "Reperceiving and repicking...") (cpl:retry)) @@ -400,7 +456,8 @@ and using the grasp and arm specified in `pick-up-action' (if not NIL)." (object ?object-designator))))) - (let ((?arm (cut:lazy-car ?arms))) + (let* ((?arms ?all-arms) + (?arm (cut:lazy-car ?arms))) ;; if picking up fails, try another arm (cpl:with-retry-counters ((arm-retries 1)) (cpl:with-failure-handling @@ -416,9 +473,10 @@ and using the grasp and arm specified in `pick-up-action' (if not NIL)." :rethrow-failure 'common-fail:object-unreachable) (setf ?arm (cut:lazy-car ?arms))))) - (let ((?grasp (cut:lazy-car ?grasps))) + (let* ((?grasps ?all-grasps) + (?grasp (cut:lazy-car ?grasps))) ;; if picking up fails, try another grasp orientation - (cpl:with-retry-counters ((grasp-retries 4)) + (cpl:with-retry-counters ((grasp-retries 5)) (cpl:with-failure-handling (((or common-fail:manipulation-low-level-failure common-fail:object-unreachable @@ -498,6 +556,9 @@ and using the grasp and arm specified in `pick-up-action' (if not NIL)." and the robot should stand at `?target-robot-location' when placing the object. If a failure happens, try a different `?target-location' or `?target-robot-location'." + (setf ?target-location (desig:reset ?target-location)) + (setf ?target-robot-location (desig:reset ?target-robot-location)) + ;; Reference the `?target-location' to see if that works at all ;; If not, delivering is impossible so throw a OBJECT-UNDERLIVERABLE failure (cpl:with-failure-handling @@ -523,7 +584,7 @@ If a failure happens, try a different `?target-location' or `?target-robot-locat :rethrow-failure 'common-fail:delivering-failed)))) ;; take a new `?target-robot-location' sample if a failure happens - (cpl:with-retry-counters ((relocation-for-ik-retries 10)) + (cpl:with-retry-counters ((relocation-for-ik-retries 15)) (cpl:with-failure-handling (((or common-fail:navigation-goal-in-collision common-fail:object-undeliverable @@ -546,91 +607,99 @@ If a failure happens, try a different `?target-location' or `?target-robot-locat (location ?target-robot-location))) ;; take a new `?target-location' sample if a failure happens - (cpl:with-retry-counters ((target-location-retries 2)) - (cpl:with-failure-handling - (((or common-fail:looking-high-level-failure - common-fail:object-unreachable - common-fail:high-level-failure) (e) - (common-fail:retry-with-loc-designator-solutions - ?target-location - target-location-retries - (:error-object-or-string (format NIL "Placing failed: ~a" e) - :warning-namespace (fd-plans deliver) - :reset-designators (list ?target-robot-location) - :rethrow-failure 'common-fail:object-undeliverable) + (let ((?reachable-target-location + (desig:copy-designator ?target-location + :new-description '((:reachable-from :robot))))) + (cpl:with-retry-counters ((target-location-retries 4)) + (cpl:with-failure-handling + (((or common-fail:looking-high-level-failure + common-fail:object-unreachable + common-fail:high-level-failure) (e) (roslisp:ros-warn (fd-plans deliver) - "Retrying with new placing location ...~%")))) - - ;; if target is in hand, we have a handover, - ;; so move target hand closer - (when target-in-hand - (let ((?goal - (case target-hand - (:left `(cpoe:arms-positioned-at :hand-over nil)) - (:right `(cpoe:arms-positioned-at nil :hand-over)) - (t `(cpoe:arms-positioned-at nil nil))))) - (exe:perform - (desig:an action - (type positioning-arm) - (desig:when (eql target-hand :left) - (left-configuration hand-over)) - (desig:when (eql target-hand :right) - (right-configuration hand-over)) - (goal ?goal))) - (desig:reset ?target-location))) - - ;; look - (let (;; (?goal `(cpoe:looking-at ,?target-location)) - ) - (exe:perform (desig:an action - (type turning-towards) - (target ?target-location) - ;; (goal ?goal) - ))) - - ;; place - (let ((place-action - (or (when place-action - (let* ((referenced-action-desig - (desig:reference place-action)) - (?arm - (desig:desig-prop-value referenced-action-desig :arm)) - (?projected-target-location - (desig:desig-prop-value referenced-action-desig :target))) - (let ((?goal `(cpoe:object-at-location - ,?object-designator - ,?projected-target-location))) - (desig:an action - (type placing) - (arm ?arm) - (object ?object-designator) - (target ?projected-target-location) - (goal ?goal))))) - (let ((?goal `(cpoe:object-at-location - ,?object-designator - ,?target-location))) - (desig:an action - (type placing) - (desig:when ?arm - (arm ?arm)) - (object ?object-designator) - (target ?target-location) - (goal ?goal)))))) - - ;; test if the placing trajectory is reachable and not colliding - (setf place-action (desig:current-desig place-action)) - (proj-reasoning:check-placing-collisions place-action) - (setf place-action (desig:current-desig place-action)) - - ;; test if the placing pose is a good one -- not falling on the floor - ;; test function throws a high-level-failure if not good pose - (unless target-stable - (proj-reasoning:check-placing-pose-stability - ?object-designator ?target-location)) - - (exe:perform place-action) - - (desig:current-desig ?object-designator)))))))))) + "target-location-retries ~A~%" + (cpl:get-counter target-location-retries)) + (common-fail:retry-with-loc-designator-solutions + ?reachable-target-location + target-location-retries + (:error-object-or-string (format NIL "Placing failed: ~a" e) + :warning-namespace (fd-plans deliver) + :reset-designators (list ?target-robot-location) + :rethrow-failure 'common-fail:object-undeliverable) + (roslisp:ros-warn (fd-plans deliver) + "Retrying with new placing location ...~%")))) + + ;; if target is in hand, we have a handover, + ;; so move target hand closer + (when target-in-hand + (let ((?goal + (case target-hand + (:left `(cpoe:arms-positioned-at :hand-over nil)) + (:right `(cpoe:arms-positioned-at nil :hand-over)) + (t `(cpoe:arms-positioned-at nil nil))))) + (exe:perform + (desig:an action + (type positioning-arm) + (desig:when (eql target-hand :left) + (left-configuration hand-over)) + (desig:when (eql target-hand :right) + (right-configuration hand-over)) + (goal ?goal))) + (setf ?reachable-target-location + (desig:reset ?reachable-target-location)))) + + ;; look + (let ( ;; (?goal `(cpoe:looking-at ,?target-location)) + ) + (exe:perform (desig:an action + (type turning-towards) + (target ?reachable-target-location) + ;; (goal ?goal) + ))) + + ;; place + (let ((place-action + (or (when place-action + (let* ((referenced-action-desig + (desig:reference place-action)) + (?arm + (desig:desig-prop-value referenced-action-desig :arm)) + (?projected-target-location + (desig:desig-prop-value referenced-action-desig :target))) + (let ((?goal `(cpoe:object-placed + ,?object-designator + ,?projected-target-location))) + (desig:an action + (type placing) + (arm ?arm) + (object ?object-designator) + (target ?projected-target-location) + (goal ?goal))))) + + (let ((?goal `(cpoe:object-placed + ,?object-designator + ,?reachable-target-location))) + (desig:an action + (type placing) + (desig:when ?arm + (arm ?arm)) + (object ?object-designator) + (target ?reachable-target-location) + (goal ?goal)))))) + + ;; test if the placing trajectory is reachable and not colliding + (setf place-action (desig:current-desig place-action)) + (proj-reasoning:check-placing-collisions place-action) + (setf place-action (desig:current-desig place-action)) + + ;; test if the placing pose is a good one -- not falling on the floor + ;; test function throws a high-level-failure if not good pose + (unless target-stable + (proj-reasoning:check-placing-pose-stability + ?object-designator ?reachable-target-location)) + + (exe:perform place-action) + + (desig:current-desig ?object-designator))))))))))) diff --git a/cram_3d_world/cram_fetch_deliver_plans/tests/delivering-tests.lisp b/cram_3d_world/cram_fetch_deliver_plans/tests/delivering-tests.lisp new file mode 100644 index 0000000000..d2ed94158b --- /dev/null +++ b/cram_3d_world/cram_fetch_deliver_plans/tests/delivering-tests.lisp @@ -0,0 +1,290 @@ +;;; +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :fd-plans-tests) + +(defparameter *delivering-tests* '(object-can-be-delivered-no-errors-deliver-test + object-delivery-location-unreachable-deliver-test + delivery-attempt-with-wrong-arm-deliver-test + object-delivery-location-unreachable-from-2-robot-locations-deliver-test + object-reachable-on-2nd-robot-location-deliver-test + object-reachable-on-2nd-target-location-deliver-test + first-deliver-location-designator-error-deliver-test)) + + +(define-test object-can-be-delivered-no-errors-deliver-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + ;; Deterministic Fetch + (let ((?fetched-object)) + (urdf-proj:with-simulated-robot + (setf ?fetched-object + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses + (*valid-location-on-island*)))))) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*)))))))) + (sleep 0.5) + (urdf-proj:with-simulated-robot + (perform (an action + (type delivering) + (target (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object ?fetched-object) + (robot-location (a location + (poses + (*valid-robot-pose-towards-sink-area-surface*)))))))) + (assert-nil (get-total-error-count))) + + +(define-test object-delivery-location-unreachable-deliver-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + ;; Deterministic Fetch + (let ((?fetched-object)) + (urdf-proj:with-simulated-robot + (setf ?fetched-object + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses + (*valid-location-on-island*)))))) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*)))))))) + (sleep 0.5) + (assert-nil (get-total-error-count)) + (assert-error + 'common-fail:delivering-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type delivering) + (target (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object ?fetched-object) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*))))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:delivering-failed)) + (assert-equal 2 (get-error-count-for-error 'common-fail:object-undeliverable)) + (assert-equal 1 (get-error-count-for-error 'common-fail:manipulation-low-level-failure)) + (assert-equal 1 (get-error-count-for-error 'common-fail:object-unreachable))) + + +(define-test delivery-attempt-with-wrong-arm-deliver-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + ;; Deterministic Fetch + (let ((?fetched-object)) + (urdf-proj:with-simulated-robot + (setf ?fetched-object + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island*)))) + (arm (right)) + (object (an object + (type bowl) + (location (a location + (poses + (*valid-location-on-island*)))))) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*)))))))) + (sleep 0.5) + (assert-error + 'common-fail:delivering-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type delivering) + (target (a location + (poses (*valid-location-on-sink-area-surface*)))) + (arm left) + (object ?fetched-object) + (robot-location (a location + (poses + (*valid-robot-pose-towards-sink-area-surface*))))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:delivering-failed)) + (assert-equal 2 (get-error-count-for-error 'common-fail:object-undeliverable)) + (assert-equal 1 (get-error-count-for-error 'common-fail:object-unreachable))) + + +(define-test object-delivery-location-unreachable-from-2-robot-locations-deliver-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + ;; Deterministic Fetch + (let ((?fetched-object)) + (urdf-proj:with-simulated-robot + (setf ?fetched-object + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses + (*valid-location-on-island*)))))) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*)))))))) + (sleep 0.5) + (assert-error + 'common-fail:delivering-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type delivering) + (target (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object ?fetched-object) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island* + *valid-robot-pose-towards-island-near-wall*))))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:delivering-failed)) + (assert-equal 12 (get-error-count-for-error 'common-fail:object-undeliverable)) + (assert-equal 21 (get-error-count-for-error 'common-fail:manipulation-low-level-failure)) + (assert-equal 21 (get-error-count-for-error 'common-fail:object-unreachable))) + + +(define-test object-reachable-on-2nd-robot-location-deliver-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + ;; Deterministic Fetch + (let ((?fetched-object)) + (urdf-proj:with-simulated-robot + (setf ?fetched-object + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses + (*valid-location-on-island*)))))) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*)))))))) + (sleep 0.5) + (urdf-proj:with-simulated-robot + (perform (an action + (type delivering) + (target (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object ?fetched-object) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island* + *valid-robot-pose-towards-sink-area-surface*)))))))) + (assert-equal 0 (get-error-count-for-error 'common-fail:delivering-failed)) + (assert-equal 1 (get-error-count-for-error 'common-fail:object-undeliverable)) + (assert-equal 1 (get-error-count-for-error 'common-fail:manipulation-low-level-failure)) + (assert-equal 1 (get-error-count-for-error 'common-fail:object-unreachable))) + + +(define-test object-reachable-on-2nd-target-location-deliver-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + ;; Deterministic Fetch + (let ((?fetched-object)) + (urdf-proj:with-simulated-robot + (setf ?fetched-object + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses + (*valid-location-on-island*)))))) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*)))))))) + (sleep 0.5) + (urdf-proj:with-simulated-robot + (perform (an action + (type delivering) + (target (a location + (poses (*valid-location-on-sink-area-surface* + *valid-location-on-island*)))) + (object ?fetched-object) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island* + )))))))) + (assert-equal 0 (get-error-count-for-error 'common-fail:delivering-failed)) + (assert-equal 0 (get-error-count-for-error 'common-fail:object-undeliverable)) + (assert-equal 1 (get-error-count-for-error 'common-fail:manipulation-low-level-failure)) + (assert-equal 0 (get-error-count-for-error 'common-fail:object-unreachable))) + +(define-test first-deliver-location-designator-error-deliver-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + ;; Deterministic Fetch + (let ((?fetched-object)) + (urdf-proj:with-simulated-robot + (setf ?fetched-object + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses + (*valid-location-on-island*)))))) + (robot-location (a location + (poses + (*valid-robot-pose-towards-island*)))))))) + (sleep 0.5) + (assert-nil (get-total-error-count)) + (urdf-proj:with-simulated-robot + (perform (an action + (type delivering) + (target (a location + (poses (*invalid-location-outside-map* + *valid-location-on-island*)))) + (object ?fetched-object))))) + (assert-equal 0 (get-error-count-for-error 'common-fail:delivering-failed)) + (assert-equal 0 (get-error-count-for-error 'common-fail:object-undeliverable)) + (assert-equal 0 (get-error-count-for-error 'common-fail:manipulation-low-level-failure)) + (assert-equal 0 (get-error-count-for-error 'common-fail:object-unreachable))) diff --git a/cram_3d_world/cram_fetch_deliver_plans/tests/fetching-tests.lisp b/cram_3d_world/cram_fetch_deliver_plans/tests/fetching-tests.lisp new file mode 100644 index 0000000000..f2358d3e04 --- /dev/null +++ b/cram_3d_world/cram_fetch_deliver_plans/tests/fetching-tests.lisp @@ -0,0 +1,240 @@ +;;; +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :fd-plans-tests) + +(defparameter *fetch-tests* '(object-can-be-fetched-no-errors-fetch-test + object-cannot-be-reached-but-seen-fetch-test + object-cannot-be-seen-fetch-test + object-reached-on-second-robot-location-fetch-test + object-unreachable-with-first-arm-fetch-test + object-unreachable-with-only-unreachable-arm-fetch-test + object-seen-on-second-search-location-fetch-test + navigation-pose-invalid-before-perception-fetch-test + perception-pose-valid-fetch-pose-invalid-fetch-test)) + + +(define-test object-can-be-fetched-no-errors-fetch-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))))) + (robot-location (a location (poses (*valid-robot-pose-towards-island*))))))) + (assert-nil (get-total-error-count))) + + +(define-test object-cannot-be-reached-but-seen-fetch-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + (assert-error + 'common-fail:fetching-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))))) + (robot-location (a location + (poses (*valid-robot-pose-towards-island-near-wall*)))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:fetching-failed)) + (assert-equal 3 (get-error-count-for-error 'common-fail:object-unreachable)) + (assert-equal 8 (get-error-count-for-error 'common-fail:manipulation-low-level-failure))) + + +(define-test object-cannot-be-seen-fetch-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface-near-oven* :bowl) + (assert-error + 'common-fail:fetching-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))))) + (robot-location (a location + (poses (*valid-robot-pose-towards-island-near-wall*)))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:fetching-failed)) + (assert-equal 2 (get-error-count-for-error 'common-fail:perception-object-not-found))) + + +(define-test object-reached-on-second-robot-location-fetch-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))))) + (robot-location (a location + (poses (*valid-robot-pose-towards-island-near-wall* + *valid-robot-pose-towards-island*))))))) + (assert-equal 0 (get-error-count-for-error 'common-fail:fetching-failed)) + (assert-equal 3 (get-error-count-for-error 'common-fail:object-unreachable)) + (assert-equal 8 (get-error-count-for-error 'common-fail:manipulation-low-level-failure))) + + +(define-test object-unreachable-with-first-arm-fetch-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface-near-oven* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (arms (right left)) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))))) + (robot-location (a location + (poses (*valid-robot-pose-towards-sink-area-surface*))))))) + (assert-equal 0 (get-error-count-for-error 'common-fail:fetching-failed)) + (assert-equal 1 (get-error-count-for-error 'common-fail:object-unreachable)) + (assert-equal 5 (get-error-count-for-error 'common-fail:manipulation-goal-in-collision))) + + +(define-test object-unreachable-with-only-unreachable-arm-fetch-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface-near-oven* :bowl) + (assert-error + 'common-fail:fetching-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (arms (right)) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))))) + (robot-location (a location + (poses (*valid-robot-pose-towards-sink-area-surface*)))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:fetching-failed)) + (assert-equal 2 (get-error-count-for-error 'common-fail:object-unreachable)) + (assert-equal 4 (get-error-count-for-error 'common-fail:manipulation-goal-in-collision))) + + +(define-test object-seen-on-second-search-location-fetch-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface-near-oven* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (arms (left)) + (location (a location + (poses (*valid-location-on-sink-area-surface* + *valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-sink-area-surface* + *valid-location-on-island*)))))) + (robot-location (a location + (poses (*valid-robot-pose-towards-island-near-wall* + *valid-robot-pose-towards-sink-area-surface*))))))) + ;; Can't find in the first location + (assert-equal 2 (get-error-count-for-error 'common-fail:perception-object-not-found))) + + +(define-test navigation-pose-invalid-before-perception-fetch-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface* :bowl) + (assert-error + 'common-fail:fetching-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (arms (left)) + (location (a location + (poses (*valid-location-on-sink-area-surface* + *valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-sink-area-surface* + *valid-location-on-island*)))))) + (robot-location (a location + (poses (*invalid-robot-pose-towards-sink-area-surface*)))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:fetching-failed)) + (assert-equal 1 (get-error-count-for-error 'common-fail:navigation-goal-in-collision)) + (assert-equal 1 (get-error-count-for-error 'common-fail:navigation-pose-unreachable))) + + +(define-test perception-pose-valid-fetch-pose-invalid-fetch-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface* :bowl) + (assert-error + 'common-fail:fetching-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type fetching) + (arms (left)) + (location (a location + (poses (*valid-location-on-sink-area-surface* + *valid-location-on-island*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-sink-area-surface* + *valid-location-on-island*)))))) + (robot-location (a location + (poses (*valid-robot-pose-towards-island* + *invalid-robot-pose-towards-sink-area-surface*)))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:fetching-failed)) + (assert-equal 4 (get-error-count-for-error 'common-fail:manipulation-low-level-failure)) + (assert-equal 2 (get-error-count-for-error 'common-fail:object-unreachable)) + (assert-equal 50 (get-error-count-for-error 'common-fail:navigation-goal-in-collision)) + (assert-equal 50 (get-error-count-for-error 'common-fail:navigation-pose-unreachable))) diff --git a/cram_3d_world/cram_fetch_deliver_plans/tests/package.lisp b/cram_3d_world/cram_fetch_deliver_plans/tests/package.lisp new file mode 100644 index 0000000000..a2002d71a3 --- /dev/null +++ b/cram_3d_world/cram_fetch_deliver_plans/tests/package.lisp @@ -0,0 +1,38 @@ +;;; +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :cl-user) + +(defpackage cram-fetch-deliver-plans-tests + (:nicknames #:fd-plans-tests) + (:use #:common-lisp + #:lisp-unit + #:cram-prolog + #:desig #:exe) + (:export)) diff --git a/cram_3d_world/cram_fetch_deliver_plans/tests/searching-tests.lisp b/cram_3d_world/cram_fetch_deliver_plans/tests/searching-tests.lisp new file mode 100644 index 0000000000..0bc8cdcaa5 --- /dev/null +++ b/cram_3d_world/cram_fetch_deliver_plans/tests/searching-tests.lisp @@ -0,0 +1,147 @@ +;;; +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :fd-plans-tests) + +(defparameter *searching-tests* '(object-can-be-found-no-errors-search-test + object-can-be-found-in-second-try-search-test + object-occluded-from-view-search-test + unreachable-location-search-test + initially-unreachable-location-search-test + object-can-be-found-after-visibility-designator-error-search-test)) + +(define-test object-can-be-found-no-errors-search-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type searching) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))))) + (robot-location (a location (poses (*valid-robot-pose-towards-island*))))))) + (assert-nil (get-total-error-count))) + +(define-test object-can-be-found-in-second-try-search-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface-near-oven* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type searching) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))))) + (robot-location (a location (poses (*valid-robot-pose-towards-island*))))))) + (assert-equal 0 (get-error-count-for-error 'common-fail:searching-failed)) + (assert-equal 0 (get-error-count-for-error 'common-fail:object-nowhere-to-be-found)) + (assert-equal 2 (get-error-count-for-error 'common-fail:perception-object-not-found))) + + +(define-test object-occluded-from-view-search-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface-near-oven* :bowl) + (assert-error + 'common-fail:searching-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type searching) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-island* + *valid-location-on-sink-area-surface*)))))) + (robot-location (a location (poses (*valid-robot-pose-towards-island-near-wall* + *valid-robot-pose-towards-island*)))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:searching-failed)) + (assert-equal 1 (get-error-count-for-error 'common-fail:object-nowhere-to-be-found))) + + +(define-test unreachable-location-search-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface* :bowl) + (assert-error + 'common-fail:searching-failed + (urdf-proj:with-simulated-robot + (perform (an action + (type searching) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))))) + (robot-location (a location (poses (*invalid-robot-pose-towards-sink-area-surface*)))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:searching-failed)) + (assert-equal 1 (get-error-count-for-error 'common-fail:object-nowhere-to-be-found)) + (assert-equal 1 (get-error-count-for-error 'common-fail:navigation-goal-in-collision)) + (assert-equal 1 (get-error-count-for-error 'common-fail:navigation-pose-unreachable))) + + +(define-test initially-unreachable-location-search-test + (init-projection) + (spawn-object *valid-location-on-sink-area-surface* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type searching) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-on-sink-area-surface*)))))) + (robot-location (a location (poses (*invalid-robot-pose-towards-sink-area-surface* + *valid-robot-pose-towards-sink-area-surface*))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:navigation-pose-unreachable))) + + +(define-test object-can-be-found-after-visibility-designator-error-search-test + (init-projection) + (spawn-object *valid-location-on-island* :bowl) + (urdf-proj:with-simulated-robot + (perform (an action + (type searching) + (object (an object + (type bowl) + (location (a location + (poses (*valid-location-inside-fridge* + *valid-location-on-island*))))))))) + (assert-equal 1 (get-error-count-for-error 'common-fail:navigation-goal-in-collision))) diff --git a/cram_3d_world/cram_fetch_deliver_plans/tests/utils.lisp b/cram_3d_world/cram_fetch_deliver_plans/tests/utils.lisp new file mode 100644 index 0000000000..893f901793 --- /dev/null +++ b/cram_3d_world/cram_fetch_deliver_plans/tests/utils.lisp @@ -0,0 +1,172 @@ +;;; +;;; Copyright (c) 2020, Amar Fayaz +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :fd-plans-tests) + +(defparameter *error-counter-look-up* '()) + +(defmethod cpl:fail :before (&rest args) + (when (and (not (null args)) (typep (first args) 'symbol)) + (add-error-count-for-error (first args)))) + + +(defun init-test-env () + (coe:clear-belief) + (setf cram-tf:*tf-default-timeout* 2.0) + (setf prolog:*break-on-lisp-errors* t) + (setf proj-reasoning::*projection-reasoning-enabled* nil)) + +(roslisp-utilities:register-ros-init-function init-test-env) + +(defun init-projection () + (btr:clear-costmap-vis-object) + (btr:add-objects-to-mesh-list "cram_pr2_pick_place_demo") + (btr-utils:kill-all-objects) + (setf (btr:pose (btr:get-robot-object)) (cl-transforms:make-identity-pose)) + (reset-error-counter)) + +(defun make-pose-stamped (pose-list) + (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (apply #'cl-transforms:make-3d-vector (first pose-list)) + (apply #'cl-transforms:make-quaternion (second pose-list)))) + +(defun make-pose (pose-list) + (cl-transforms:make-pose + (apply #'cl-transforms:make-3d-vector (first pose-list)) + (apply #'cl-transforms:make-quaternion (second pose-list)))) + +(defun spawn-object (pose object-type) + (btr-utils:kill-all-objects) + (btr:add-objects-to-mesh-list "cram_pr2_pick_place_demo") + (btr:detach-all-objects (btr:get-robot-object)) + (btr-utils:spawn-object + (intern (format nil "~a-1" object-type) :keyword) + object-type + :pose pose + :mass 0.0) + (btr:simulate btr:*current-bullet-world* 100)) + +(defun error-type-to-keyword (error-type) + (intern (format nil "~a" error-type) :keyword)) + +(defun reset-error-counter () + (setf *error-counter-look-up* '())) + +(defun get-total-error-count () + (unless (null *error-counter-look-up*) + (reduce (lambda (count1 count2) + (+ count1 count2)) + *error-counter-look-up* + :key #'cdr))) + +(defun add-error-count-for-error (error-type) + (let ((error-keyword (error-type-to-keyword error-type))) + (if (null (assoc error-keyword *error-counter-look-up*)) + (setf *error-counter-look-up* (cons (cons error-keyword 0) + *error-counter-look-up*))) + (incf (cdr (assoc error-keyword *error-counter-look-up*))))) + +(defun get-error-count-for-error (error-type) + (let ((error-keyword (error-type-to-keyword error-type))) + (if (null (assoc error-keyword *error-counter-look-up*)) + 0 + (cdr (assoc error-keyword *error-counter-look-up*))))) + +(defun make-restricted-area-cost-function () + (lambda (x y) + (if (> x 1.2) + 0.0 + (if (and (> x 0.5) (> y -1.5) (< y 2.0)) + 1.0 + (if (and (> x 0.0) (> y -1.5) (< y 1.0)) + 1.0 + (if (and (> x -1.5) (> y -1.5) (< y 2.5)) + 1.0 + (if (and (> x -4.0) (> y -1.0) (< y 1.0)) + 1.0 + 0.0))))))) + +(defmethod location-costmap:costmap-generator-name->score ((name (eql 'restricted-area))) 5) + +(def-fact-group demo-costmap (location-costmap:desig-costmap) + (<- (location-costmap:desig-costmap ?designator ?costmap) + (or (rob-int:visibility-designator ?designator) + (rob-int:reachability-designator ?designator)) + ;; make sure that the location is not on the robot itself + ;; if it is, don't generate a costmap + (once (or (and (desig:desig-prop ?designator (:object ?some-object)) + (desig:current-designator ?some-object ?object) + (lisp-fun man-int:get-object-pose-in-map ?object ?to-reach-pose) + (lisp-pred identity ?to-reach-pose) + (-> (desig:desig-prop ?object (:location ?loc)) + (not (man-int:location-always-reachable ?loc)) + (true))) + (and (desig:desig-prop ?designator (:location ?some-location)) + (desig:current-designator ?some-location ?location) + ;; if the location is on the robot itself, + ;; don't use the costmap + (not (man-int:location-always-reachable ?location))))) + (location-costmap:costmap ?costmap) + (location-costmap:costmap-add-function + restricted-area + (make-restricted-area-cost-function) + ?costmap))) + +;;;;;;;;;;;; Object Poses ;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *valid-location-on-island* + (make-pose-stamped '((-0.8 0.76 0.9) (0 0 0 1)))) + +(defparameter *valid-location-on-sink-area-surface* + (make-pose-stamped '((1.48 0.96 0.9) (0 0 0 1)))) + + +(defparameter *valid-location-on-sink-area-surface-near-oven* + (make-pose-stamped '((1.54 1.1 0.9) (0 0 0 1)))) + +(defparameter *valid-location-inside-fridge* + (make-pose-stamped '((1.48 -1.16 0.55) (0 0 0 1)))) + +(defparameter *invalid-location-outside-map* + (make-pose-stamped '((2.8 0.71 0.9) (0 0 0 1)))) + +;;;;;;;;;;;;; Robot Poses ;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *valid-robot-pose-towards-island* + (make-pose-stamped '((-0.1 0.74 0) (0 0 1 0)))) + +(defparameter *valid-robot-pose-towards-island-near-wall* + (make-pose-stamped '((-0.1 2.2 0) (0 0 1 0)))) + +(defparameter *valid-robot-pose-towards-sink-area-surface* + (make-pose-stamped '((0.8 0.7 0) (0 0 0 1)))) + +(defparameter *invalid-robot-pose-towards-sink-area-surface* + (make-pose-stamped '((1.0 0.7 0) (0 0 0 1)))) diff --git a/cram_3d_world/cram_physics_utils/cram-physics-utils.asd b/cram_3d_world/cram_physics_utils/cram-physics-utils.asd index 55b272962d..272bee48b8 100644 --- a/cram_3d_world/cram_physics_utils/cram-physics-utils.asd +++ b/cram_3d_world/cram_physics_utils/cram-physics-utils.asd @@ -28,17 +28,23 @@ ;;; POSSIBILITY OF SUCH DAMAGE. ;;; -(cl:eval-when (:load-toplevel :execute) - (asdf:operate 'asdf:load-op 'cffi-ros-utils)) - ;; We need to use g++ instead of cc here because assimp doesn't ;; typedef its structs which causes compilation to fail. -(setf cffi-grovel::*cc* "g++") +(cl:eval-when (:load-toplevel :execute) + (asdf:operate 'asdf:load-op 'cffi-ros-utils)) +(defmethod asdf:perform :after ((op asdf:prepare-op) (component asdf/component:module)) + (if (string-equal (asdf/component:component-name component) + "cram-physics-utils") + (setf cffi-toolchain:*cc* "g++"))) +(defmethod asdf:perform :after ((op asdf:compile-op) (component asdf/component:module)) + (if (string-equal (asdf/component:component-name component) + "cram-physics-utils") + (setf cffi-toolchain:*cc* "cc"))) (defsystem cram-physics-utils :author "Lorenz Moesenlechner" :license "BSD" - + :depends-on (cl-transforms cffi cffi-ros-utils cram-tf ros-load-manifest roslisp geometry_msgs-msg shape_msgs-msg) diff --git a/cram_3d_world/cram_urdf_environment_manipulation/src/action-designators.lisp b/cram_3d_world/cram_urdf_environment_manipulation/src/action-designators.lisp index 3f3c35e9ee..7167e3f2f7 100644 --- a/cram_3d_world/cram_urdf_environment_manipulation/src/action-designators.lisp +++ b/cram_3d_world/cram_urdf_environment_manipulation/src/action-designators.lisp @@ -43,9 +43,10 @@ (-> (spec:property ?container-designator (:handle-axis ?handle-axis)) (true) (lisp-fun get-handle-axis ?container-designator ?handle-axis)) + (rob-int:robot ?robot) (-> (spec:property ?action-designator (:arm ?arm)) (true) - (man-int:robot-free-hand ?_ ?arm)) + (man-int:robot-free-hand ?robot ?arm)) (lisp-fun get-container-link ?container-name ?btr-environment ?container-link) (lisp-fun get-connecting-joint ?container-link ?connecting-joint) @@ -86,6 +87,11 @@ (lisp-fun btr:object ?world ?btr-environment ?environment-object) (lisp-fun btr:name ?environment-object ?environment-name) + (btr:joint-state ?world ?environment-name ?joint-name ?current-state) + (-> (equal ?action-type :opening) + (lisp-fun + ?current-state ?clipped-distance ?absolute-distance) + (lisp-fun - ?current-state ?clipped-distance ?absolute-distance)) + ;; infer missing information like ?gripper-opening, opening trajectory (lisp-fun man-int:get-action-gripper-opening ?container-type ?gripper-opening) @@ -152,11 +158,22 @@ (or (lisp-pred identity ?left-trajectory) (lisp-pred identity ?right-trajectory)) + (-> (lisp-pred identity ?left-reach-poses) + (equal ?left-reach-poses (?look-pose . ?_)) + (equal ?right-reach-poses (?look-pose . ?_))) + + (-> (man-int:robot-arm-is-also-a-neck ?robot ?arm) + (equal ?robot-arm-is-also-a-neck T) + (equal ?robot-arm-is-also-a-neck NIL)) + ;; make new action designator (desig:designator :action ((:type ?action-type) (:arm ?arm) (:gripper-opening ?gripper-opening) (:distance ?clipped-distance) + (:absolute-distance ?absolute-distance) + (:look-pose ?look-pose) + (:robot-arm-is-also-a-neck ?robot-arm-is-also-a-neck) (:left-reach-poses ?left-reach-poses) (:right-reach-poses ?right-reach-poses) (:left-grasp-poses ?left-grasp-poses) diff --git a/cram_3d_world/cram_urdf_environment_manipulation/src/costmaps.lisp b/cram_3d_world/cram_urdf_environment_manipulation/src/costmaps.lisp index 76a254fdf0..b6de91d659 100644 --- a/cram_3d_world/cram_urdf_environment_manipulation/src/costmaps.lisp +++ b/cram_3d_world/cram_urdf_environment_manipulation/src/costmaps.lisp @@ -39,13 +39,13 @@ environment, in which it can be found, respectively." container-name btr-environment)) (neutral-handle-pose - (get-manipulated-pose + (get-manipulated-pose-by-setting-joint (cl-urdf:name handle-link) 0 btr-environment :relative T)) (manipulated-handle-pose - (get-manipulated-pose + (get-manipulated-pose-by-setting-joint (cl-urdf:name handle-link) 1 btr-environment @@ -176,53 +176,55 @@ ARM has to be either :left or :right." 1.0 0.0)))))) -(defun make-opened-door-cost-function (container-name btr-environment - &optional (padding 0.2)) - "Resolve the relation according to the pose of the door hinge joint and the -handles neutral and manipulated poses. Diregard any samples inside the door's -opening arc. -CONTAINER-NAME and BTR-ENVIRONMENT are the names of the container and the -environment, in which it can be found, respectively." - (let* ((handle-link - (get-handle-link container-name btr-environment)) - (manipulated-handle-pose - (get-manipulated-pose - (cl-urdf:name handle-link) - 1 - btr-environment - :relative T)) - (man-handle-pos-2d - (cl-transforms:make-3d-vector - (cl-transforms:x - (cl-transforms:origin manipulated-handle-pose)) - (cl-transforms:y - (cl-transforms:origin manipulated-handle-pose)) - 0)) - (joint-name - (cl-urdf:name - (cl-urdf:child (get-connecting-joint handle-link)))) - (joint-pose - (get-urdf-link-pose joint-name btr-environment)) - (joint-pos-2d - (cl-transforms:make-3d-vector - (cl-transforms:x - (cl-transforms:origin joint-pose)) - (cl-transforms:y - (cl-transforms:origin joint-pose)) - 0)) - (v2 - (cl-transforms:v- man-handle-pos-2d joint-pos-2d)) - (v2-length - (sqrt (cl-transforms:dot-product v2 v2)))) - - (lambda (x y) - (let* ((vP (cl-transforms:v- (cl-transforms:make-3d-vector x y 0) - joint-pos-2d)) - (vP-length (sqrt (cl-transforms:dot-product vP vP)))) - (if (and (< vP-length (+ v2-length padding)) - T) - 0 - 1))))) +;; (defun make-opened-door-cost-function (container-name btr-environment +;; &optional (padding 0.2)) +;; "Resolve the relation according to the pose of the door hinge joint and the +;; handles neutral and manipulated poses. Diregard any samples inside the door's +;; opening arc. +;; CONTAINER-NAME and BTR-ENVIRONMENT are the names of the container and the +;; environment, in which it can be found, respectively." +;; (let* ((handle-link +;; (get-handle-link container-name btr-environment)) +;; (manipulated-handle-pose +;; (get-manipulated-pose +;; (cl-urdf:name handle-link) +;; 1 +;; btr-environment +;; :relative T)) +;; (man-handle-pos-2d +;; (cl-transforms:make-3d-vector +;; (cl-transforms:x +;; (cl-transforms:origin manipulated-handle-pose)) +;; (cl-transforms:y +;; (cl-transforms:origin manipulated-handle-pose)) +;; 0)) +;; (joint-name +;; (cl-urdf:name +;; (cl-urdf:child (get-connecting-joint handle-link)))) +;; (joint-pose +;; (get-urdf-link-pose joint-name btr-environment)) +;; (joint-pos-2d +;; (cl-transforms:make-3d-vector +;; (cl-transforms:x +;; (cl-transforms:origin joint-pose)) +;; (cl-transforms:y +;; (cl-transforms:origin joint-pose)) +;; 0)) +;; (v2 +;; (cl-transforms:v- man-handle-pos-2d joint-pos-2d)) +;; (v2-length +;; ;;(sqrt (cl-transforms:dot-product v2 v2)) +;; (cl-transforms:v-norm v2))) + +;; (lambda (x y) +;; (let* ((vP (cl-transforms:v- (cl-transforms:make-3d-vector x y 0) +;; joint-pos-2d)) +;; ;;(vP-length (sqrt (cl-transforms:dot-product vP vP))) +;; (vP-length (cl-transforms:v-norm vP))) +;; (if (and (< vP-length (+ v2-length padding)) +;; T) +;; 0 +;; 1))))) (defun make-opened-door-for-opposite-arm-cost-function (container-name btr-environment @@ -295,18 +297,34 @@ environment, in which it can be found, respectively." 0 1))))) +(defun make-opened-door-cost-function (container-name btr-environment &optional (padding 0.2)) + (flet ((check-aabb (aabb x y) + (let ((dims (cl-bullet:bounding-box-dimensions aabb)) + (vCP (cl-transforms:v- + (cl-transforms:make-3d-vector x y 0) + (cl-bullet:bounding-box-center aabb)))) + (if (and (<= (abs (cl-transforms:x vCP)) + (+ (/ (cl-transforms:x dims) 2) padding)) + (<= (abs (cl-transforms:y vCP)) + (+ (/ (cl-transforms:y dims) 2) padding))) + 0 + 1)))) + (let ((aabbs (get-aabbs-at-joint-states container-name btr-environment))) + (lambda (x y) + (reduce 'logand + (mapcar + (lambda (aabb) (check-aabb aabb x y)) + aabbs)))))) + (defun point-to-point-direction (x y pos1 pos2) "Takes an X and Y coordinate, but ignores them, and returns a quaternion to face from `pos1' towards `pos2'." (declare (ignore x y)) - (let* ((point1 (etypecase pos1 + (let ((point1 (etypecase pos1 (cl-transforms:pose (cl-transforms:origin pos1)) - (cl-transforms:3d-vector pos1))) - (point2 (etypecase pos2 - (cl-transforms:pose (cl-transforms:origin pos2)) - (cl-transforms:3d-vector pos2))) - (p-rel (cl-transforms:v- point2 point1))) - (atan (cl-transforms:y p-rel) (cl-transforms:x p-rel)))) + (cl-transforms:3d-vector pos1)))) + (costmap:angle-to-point-direction + (cl-transforms:x point1) (cl-transforms:y point1) pos2))) (defun make-point-to-point-generator (pos1 pos2 &key (samples 1) sample-step sample-offset) "Returns a function that takes an X and Y coordinate and returns a lazy-list of @@ -324,8 +342,9 @@ quaternions to face from `pos1' to `pos2'." "Takes an X and Y coordinate and returns a quaternion between the one facing from pos1 to pos2 and the one facing from (X,Y) to target-pos." (let ((pos-direction (point-to-point-direction 0 0 pos1 pos2)) - (target-direction (costmap::angle-to-point-direction x y target-pos))) - (/ (+ pos-direction target-direction) 2))) + (target-direction (costmap:angle-to-point-direction x y target-pos))) + (+ pos-direction + (/ (cl-transforms:normalize-angle (- target-direction pos-direction)) 2)))) (defun make-angle-halfway-to-point-generator (pos1 pos2 target-pos &key (samples 1) sample-step sample-offset) "Returns a function that takes an X and Y coordinate and returns a lazy-list of @@ -372,7 +391,6 @@ Disregarding the orientation (using the pose2's)." (defmethod costmap:costmap-generator-name->score ((name (eql 'opened-door-for-opposite-arm-cost-function))) 10) - (def-fact-group environment-manipulation-costmap (costmap:desig-costmap) (<- (costmap:desig-costmap ?designator ?costmap) (rob-int:reachability-designator ?designator) @@ -466,20 +484,23 @@ Disregarding the orientation (using the pose2's)." ?exclude-generator-id (costmap:make-range-cost-function ?pose ?minimal-distance :invert t) - ?costmap))) + ?costmap) + )) - ;; cutting out door costmap (costmap:costmap-manipulation-padding ?robot-name ?padding) + + ;; cutting out door costmap (costmap:costmap-add-function opened-door-cost-function (make-opened-door-cost-function ?container-name ?btr-environment ?padding) ?costmap) + ;; Commented out for now, since this doesn't work with non-vertical doors ;; cutting out for specific arm - (costmap:costmap-add-function - opened-door-for-opposite-arm-cost-function - (make-opened-door-for-opposite-arm-cost-function ?container-name ?btr-environment ?arm) - ?costmap) + ;; (costmap:costmap-add-function + ;; opened-door-for-opposite-arm-cost-function + ;; (make-opened-door-for-opposite-arm-cost-function ?container-name ?btr-environment ?arm) + ;; ?costmap) ;; orientate towards the door (lisp-fun get-container-link ?container-name ?btr-environment ?link) diff --git a/cram_3d_world/cram_urdf_environment_manipulation/src/environment-occasions.lisp b/cram_3d_world/cram_urdf_environment_manipulation/src/environment-occasions.lisp index 5ee9a16911..5a1fe72dcb 100644 --- a/cram_3d_world/cram_urdf_environment_manipulation/src/environment-occasions.lisp +++ b/cram_3d_world/cram_urdf_environment_manipulation/src/environment-occasions.lisp @@ -46,13 +46,29 @@ (lisp-fun cl-urdf:name ?joint ?joint-name) (btr:joint-state ?world ?btr-environment ?joint-name ?joint-state) (or (and (lisp-type ?distance number) - (lisp-pred cram-tf:values-converged ?joint-state ?distance ?delta)) + (lisp-fun clip-absolute-distance ?container-name ?btr-environment ?distance + ?clipped-distance) + (lisp-pred cram-tf:values-converged ?joint-state ?clipped-distance ?delta)) (and (member ?distance (:open :closed)) (lisp-fun cl-urdf:limits ?joint ?joint-limits) (lisp-fun cl-urdf:lower ?joint-limits ?lower-limit) (lisp-fun cl-urdf:upper ?joint-limits ?upper-limit) (-> (equal ?distance :open) + (not (lisp-pred cram-tf:values-converged + ?joint-state ?lower-limit ?delta)) (lisp-pred cram-tf:values-converged - ?joint-state ?upper-limit ?delta) - (lisp-pred cram-tf:values-converged - ?joint-state ?lower-limit ?delta)))))) + ?joint-state ?lower-limit ?delta)))))) + +(defun clip-absolute-distance (container-name btr-environment distance) + (declare (type (or string symbol) container-name) + (type keyword btr-environment) + (type number distance)) + (let ((joint-limits + (cl-urdf:limits + (get-connecting-joint + (get-container-link container-name btr-environment))))) + (if (< distance (cl-urdf:lower joint-limits)) + (cl-urdf:lower joint-limits) + (if (> distance (cl-urdf:upper joint-limits)) + (cl-urdf:upper joint-limits) + distance)))) diff --git a/cram_3d_world/cram_urdf_environment_manipulation/src/environment.lisp b/cram_3d_world/cram_urdf_environment_manipulation/src/environment.lisp index f72f295e74..9c919477b9 100644 --- a/cram_3d_world/cram_urdf_environment_manipulation/src/environment.lisp +++ b/cram_3d_world/cram_urdf_environment_manipulation/src/environment.lisp @@ -73,6 +73,59 @@ The frame-id will be cram-tf:*robot-base-frame* and the child-frame-id will be t (string-upcase btr-environment) name)))) +(defun get-urdf-link-aabb (name btr-environment) + "Return the axis-aligned bounding box of the object with `name' in `environment'." + (declare (type (or string symbol) name) + (type keyword btr-environment)) + (when (symbolp name) + (setf name + (roslisp-utilities:rosify-underscores-lisp-name name))) + (btr:aabb + (btr:rigid-body + (btr:object btr:*current-bullet-world* + btr-environment) + (btr::make-rigid-body-name + (string-upcase btr-environment) + name)))) + +(defun get-aabb-at-joint-state (name btr-environment joint-state) + "Return the axis-aligned bounding box of the object with `name' in `environment' +at a specific `joint-state'. First the joint is set to the specified state, then +the bounding box is retrieved and finally the joint is reset." + (declare (type (or string symbol) name) + (type keyword btr-environment)) + (let* ((joint (get-connecting-joint + (get-container-link name btr-environment))) + (original-state (get-joint-position + joint + btr-environment))) + (setf (btr:joint-state + (btr:object btr:*current-bullet-world* + btr-environment) + (cl-urdf:name joint)) + joint-state) + (let ((aabb (get-urdf-link-aabb (cl-urdf:name (cl-urdf:child joint)) btr-environment))) + (setf (btr:joint-state + (btr:object btr:*current-bullet-world* + btr-environment) + (cl-urdf:name joint)) + original-state) + aabb))) + +(defun get-aabbs-at-joint-states (name btr-environment) + "Return a list of axis-aligned bounding boxes at minimum, middle and maximum of the joint's +limit." + (declare (type (or string symbol) name) + (type keyword btr-environment)) + (let* ((joint (get-connecting-joint + (get-container-link name btr-environment))) + (limits (cl-urdf:limits joint)) + (middle (+ (cl-urdf:lower limits) (/ (cl-urdf:upper limits) 2)))) + (list + (get-aabb-at-joint-state name btr-environment (cl-urdf:lower limits)) + (get-aabb-at-joint-state name btr-environment middle) + (get-aabb-at-joint-state name btr-environment (cl-urdf:upper limits))))) + (defun get-container-link (container-name btr-environment) "Return the link of the container with `container-name' in the `btr-environment'." (declare (type (or string symbol) container-name) @@ -238,6 +291,42 @@ values, the new pose of the link and the joint object that was changed. (get-urdf-link-pose (cl-urdf:name (cl-urdf:child joint)) btr-environment)))))) joint)))))) +(defun get-manipulated-pose-by-setting-joint (link-name joint-position btr-environment + &key relative) + (declare (type (or string symbol) link-name) + (type number joint-position) + (type keyword btr-environment) + (type boolean relative)) + (when (not (floatp joint-position)) + (setf joint-position (float joint-position))) + (let ((link (get-container-link link-name btr-environment))) + (when (typep link 'cl-urdf:link) + (let ((joint (get-connecting-joint link))) + (when joint + (when relative + (setf joint-position + (+ + (cl-urdf:lower (cl-urdf:limits joint)) + (* joint-position + (- (cl-urdf:upper (cl-urdf:limits joint)) + (cl-urdf:lower (cl-urdf:limits joint))))))) + (values + (let ((original-joint-position (get-joint-position joint btr-environment))) + (setf (btr:joint-state + (btr:object btr:*current-bullet-world* + btr-environment) + (cl-urdf:name joint)) + joint-position) + (let ((manipulated-joint-pose + (get-urdf-link-pose link-name :iai-kitchen))) + (setf (btr:joint-state + (btr:object btr:*current-bullet-world* + btr-environment) + (cl-urdf:name joint)) + original-joint-position) + manipulated-joint-pose)) + joint)))))) + (defun get-handle-axis (container-designator) "Return either a vector with (1 0 0) for horizontal handles or (0 0 1) for vertical handles on the container described by `container-designator'. @@ -254,7 +343,9 @@ this function." ("oven_area_area_left_drawer_main" (cl-transforms:make-3d-vector 0 0 1)) ("oven_area_area_right_drawer_main" - (cl-transforms:make-3d-vector 0 0 1))))) + (cl-transforms:make-3d-vector 0 0 1)) + ("sink_area_dish_washer_main" + (cl-transforms:make-3d-vector 1 0 0))))) (if name-exception name-exception ;; Use prolog to find out which supertype fits. @@ -307,8 +398,10 @@ Using a default (1 0 0)." (:closing (- (- distance state)))))) +;; Important note: This assumes a relative distance, because the trajectory calculations +;; were implemented in a relative manner. (defun clip-distance (container-name btr-environment distance action-type) - "Return a distance that stays inside the joint's limits." + "Return a relative distance that stays inside the joint's limits." (declare (type (or string symbol) container-name) (type keyword btr-environment) (type number distance) diff --git a/cram_3d_world/cram_urdf_environment_manipulation/src/plans.lisp b/cram_3d_world/cram_urdf_environment_manipulation/src/plans.lisp index 5c7e89b874..8bab696f2a 100644 --- a/cram_3d_world/cram_urdf_environment_manipulation/src/plans.lisp +++ b/cram_3d_world/cram_urdf_environment_manipulation/src/plans.lisp @@ -34,6 +34,9 @@ ((:arm ?arm)) ((:gripper-opening ?gripper-opening)) ((:distance ?distance)) + ((:absolute-distance ?absolute-distance)) + ((:look-pose ?look-pose)) + robot-arm-is-also-a-neck ((:left-reach-poses ?left-reach-poses)) ((:right-reach-poses ?right-reach-poses)) ((:left-grasp-poses ?left-grasp-poses)) @@ -60,9 +63,21 @@ (type desig:object-designator ?container-designator)) ;;;;;;;;;;;;;;; OPEN GRIPPER AND REACH ;;;;;;;;;;;;;;;; + (unless robot-arm-is-also-a-neck + (roslisp:ros-info (env-manip plan) "Looking") + (cpl:with-failure-handling + ((common-fail:ptu-low-level-failure (e) + (roslisp:ros-warn (env-manip plan) + "Looking-at had a problem: ~a~%Ignoring." + e) + (return))) + (exe:perform + (desig:an action + (type looking) + (target (desig:a location + (pose ?look-pose))))))) (cpl:par - (roslisp:ros-info (environment-manipulation manipulate-container) - "Opening gripper") + (roslisp:ros-info (env-manip plan) "Opening gripper and reaching") (let ((?goal `(cpoe:gripper-joint-at ,?arm ,?gripper-opening))) (exe:perform (desig:an action @@ -70,44 +85,43 @@ (gripper ?arm) (position ?gripper-opening) (goal ?goal)))) - (roslisp:ros-info (environment-manipulation manipulate-container) - "Reaching") + (cpl:with-retry-counters ((reach-retries 2)) + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (env-plans manipulate) + "Manipulation messed up: ~a~%Failing." + e) + (cpl:do-retry reach-retries + (cpl:retry)))) + (let ((?goal `(cpoe:tool-frames-at ,?left-reach-poses ,?right-reach-poses))) + (exe:perform + (desig:an action + (type reaching) + (left-poses ?left-reach-poses) + (right-poses ?right-reach-poses) + (goal ?goal))))))) + (cpl:with-retry-counters ((grasp-retries 2)) (cpl:with-failure-handling ((common-fail:manipulation-low-level-failure (e) (roslisp:ros-warn (env-plans manipulate) "Manipulation messed up: ~a~%Failing." e) - ;; (return) - )) - (let ((?goal `(cpoe:tool-frames-at ,?left-reach-poses ,?right-reach-poses))) + (cpl:do-retry grasp-retries + (cpl:retry)))) + (let ((?goal `(cpoe:tool-frames-at ,?left-grasp-poses ,?right-grasp-poses))) (exe:perform (desig:an action - (type reaching) - (left-poses ?left-reach-poses) - (right-poses ?right-reach-poses) + (type grasping) + (object (desig:an object + (name ?environment-name))) + (link ?link-name) + (left-poses ?left-grasp-poses) + (right-poses ?right-grasp-poses) (goal ?goal)))))) ;;;;;;;;;;;;;;;;;;;; GRIPPING ;;;;;;;;;;;;;;;;;;;;;;;; (roslisp:ros-info (environment-manipulation manipulate-container) "Gripping") - (cpl:with-failure-handling - ((common-fail:manipulation-low-level-failure (e) - (roslisp:ros-warn (env-plans manipulate) - "Manipulation messed up: ~a~%Failing." - e) - ;; (return) - )) - (let ((?goal `(cpoe:tool-frames-at ,?left-grasp-poses ,?right-grasp-poses))) - (exe:perform - (desig:an action - (type grasping) - (object (desig:an object - (name ?environment-name))) - (link ?link-name) - (left-poses ?left-grasp-poses) - (right-poses ?right-grasp-poses) - (goal ?goal))))) - (when (eq ?type :opening) (exe:perform (desig:an action @@ -117,32 +131,43 @@ ;;;;;;;;;;;;;;;;;;;;;; MANIPULATING ;;;;;;;;;;;;;;;;;;;;;;; (roslisp:ros-info (environment-manipulation manipulate-container) "Manipulating") - (cpl:with-failure-handling - ((common-fail:manipulation-low-level-failure (e) - (roslisp:ros-warn (env-plans manipulate) - "Manipulation messed up: ~a~%Failing." - e) - ;; (return) - )) - (let ((?push-or-pull - (if (eq ?type :opening) - :pulling - :pushing)) - (?goal - `(cpoe:tool-frames-at ,?left-manipulate-poses ,?right-manipulate-poses))) + (cpl:pursue + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (env-plans manipulate) + "Manipulation messed up: ~a~%Failing." + e) + ;; (return) + )) + (let ((?push-or-pull + (if (eq ?type :opening) + :pulling + :pushing)) + (?goal + `(cpoe:tool-frames-at ,?left-manipulate-poses ,?right-manipulate-poses))) + (exe:perform + (desig:an action + (type ?push-or-pull) + (object (desig:an object (name ?environment-name))) + (container-object ?container-designator) + (link ?link-name) + (desig:when ?absolute-distance + (distance ?absolute-distance)) + (desig:when (eq ?arm :left) + (left-poses ?left-manipulate-poses)) + (desig:when (eq ?arm :right) + (right-poses ?right-manipulate-poses)) + (goal ?goal))))) + (cpl:seq (exe:perform (desig:an action - (type ?push-or-pull) - (object (desig:an object (name ?environment-name))) - (container-object ?container-designator) - (link ?link-name) - (desig:when ?distance - (distance ?distance)) - (desig:when (eq ?arm :left) - (left-poses ?left-manipulate-poses)) - (desig:when (eq ?arm :right) - (right-poses ?right-manipulate-poses)) - (goal ?goal))))) + (type monitoring-joint-state) + (gripper ?arm))) + ;; sleep for half a second, + ;; maybe the action is nearly finished, so there is no need to fail + (cpl:sleep 1) + (cpl:fail 'common-fail:gripper-closed-completely + :description "Handle slipped"))) (when (and joint-name) (cram-occasions-events:on-event @@ -175,4 +200,7 @@ (type retracting) (left-poses ?left-retract-poses) (right-poses ?right-retract-poses) - (goal ?goal)))))) + (goal ?goal))))) + (exe:perform + (desig:an action + (type parking-arms)))) diff --git a/cram_3d_world/cram_urdf_environment_manipulation/src/trajectories.lisp b/cram_3d_world/cram_urdf_environment_manipulation/src/trajectories.lisp index 75e4de7527..981fa214cc 100644 --- a/cram_3d_world/cram_urdf_environment_manipulation/src/trajectories.lisp +++ b/cram_3d_world/cram_urdf_environment_manipulation/src/trajectories.lisp @@ -29,9 +29,10 @@ (in-package :env-man) -(defparameter *drawer-handle-grasp-x-offset* 0.0 "in meters") -(defparameter *drawer-handle-pregrasp-x-offset* 0.10 "in meters") -(defparameter *drawer-handle-retract-offset* 0.10 "in meters") +(defparameter *drawer-handle-grasp-x-offset* -0.005 "in meters") +(defparameter *drawer-handle-pregrasp-x-offset-open* 0.05 "in meters") +(defparameter *drawer-handle-pregrasp-x-offset-close* -0.0 "in meters") +(defparameter *drawer-handle-retract-offset* 0.05 "in meters") (defparameter *door-handle-retract-offset* 0.05 "in meters") (defmethod man-int:get-action-trajectory :heuristics 20 ((action-type (eql :opening)) @@ -117,7 +118,8 @@ The parameters are analog to the ones of `get-action-trajectory'." (:container-prismatic (make-prismatic-trajectory object-transform arm action-type grasp-pose opening-distance)) (:container-revolute - (make-revolute-trajectory object-transform arm action-type grasp-pose opening-distance)) + (make-revolute-trajectory object-transform arm action-type grasp-pose opening-distance + (get-revolute-axis object-name object-environment))) (T (error "Unsupported container-type: ~a." object-type))))) @@ -137,26 +139,43 @@ frame of the robot's end effector as the child (eg. `cram-tf:*robot-left-tool-fr (type keyword action-type) (type cl-transforms-stamped:transform-stamped grasp-pose) (type number opening-distance)) + (mapcar - (lambda (label transform) + (lambda (label transforms) (man-int:make-traj-segment :label label - :poses (list (man-int:calculate-gripper-pose-in-map object-transform arm transform)))) + :poses (mapcar (alexandria:curry #'man-int:calculate-gripper-pose-in-map + object-transform arm) + transforms))) `(:reaching :grasping ,action-type :retracting) (list - (cram-tf:translate-transform-stamped - grasp-pose :x-offset *drawer-handle-pregrasp-x-offset*) - grasp-pose - (cram-tf:translate-transform-stamped - grasp-pose :x-offset opening-distance) - (cram-tf:translate-transform-stamped - grasp-pose :x-offset (+ opening-distance *drawer-handle-retract-offset*))))) + (if (eq action-type :closing) + (list (cram-tf:translate-transform-stamped + grasp-pose :x-offset *drawer-handle-pregrasp-x-offset-open*)) + (list (cram-tf:translate-transform-stamped + grasp-pose :x-offset *drawer-handle-pregrasp-x-offset-open*) + (cram-tf:translate-transform-stamped + grasp-pose :x-offset *drawer-handle-pregrasp-x-offset-close*))) + (list grasp-pose) + (list (cram-tf:translate-transform-stamped + grasp-pose :x-offset opening-distance)) + (if (eq action-type :closing) + (list (cram-tf:translate-transform-stamped + grasp-pose :x-offset (+ opening-distance + *drawer-handle-pregrasp-x-offset-close*)) + (cram-tf:translate-transform-stamped + grasp-pose :x-offset (+ opening-distance + *drawer-handle-retract-offset*))) + (list (cram-tf:translate-transform-stamped + grasp-pose :x-offset (+ opening-distance + *drawer-handle-retract-offset*))))))) (defun make-revolute-trajectory (object-transform arm action-type - grasp-pose opening-angle) + grasp-pose opening-angle + axis) "Return a list of `man-int::traj-segment' representing a trajectory to open a container with revolute joints. `object-transform' should have `cram-tf:*robot-base-frame*' @@ -171,7 +190,7 @@ frame of the robot's end effector as the child (eg. `cram-tf:*robot-left-tool-fr (type keyword action-type) (type cl-transforms-stamped:transform-stamped grasp-pose) (type number opening-angle)) - (let* ((traj-poses (get-revolute-traj-poses grasp-pose :angle-max opening-angle)) + (let* ((traj-poses (get-revolute-traj-poses grasp-pose :angle-max opening-angle :axis axis)) (last-traj-pose (car (last traj-poses)))) (mapcar (lambda (label transforms) @@ -185,19 +204,44 @@ frame of the robot's end effector as the child (eg. `cram-tf:*robot-left-tool-fr ,action-type :retracting) (list - (list (cram-tf:translate-transform-stamped - grasp-pose :x-offset *drawer-handle-pregrasp-x-offset*)) + (if (eq action-type :closing) + (list (cram-tf:translate-transform-stamped + grasp-pose :x-offset *drawer-handle-pregrasp-x-offset-open*)) + (list (cram-tf:translate-transform-stamped + grasp-pose :x-offset *drawer-handle-pregrasp-x-offset-open*) + (cram-tf:translate-transform-stamped + grasp-pose :x-offset *drawer-handle-pregrasp-x-offset-close*))) (list grasp-pose) traj-poses (when last-traj-pose - (list (cram-tf:apply-transform - last-traj-pose - (cl-transforms-stamped:make-transform-stamped - (cl-transforms-stamped:child-frame-id last-traj-pose) - (cl-transforms-stamped:child-frame-id last-traj-pose) - (cl-transforms-stamped:stamp last-traj-pose) - (cl-transforms:make-3d-vector 0 0 -0.1) - (cl-transforms:make-identity-rotation))))))))) + (if (eq action-type :closing) + (list (cram-tf:apply-transform + last-traj-pose + (cl-transforms-stamped:make-transform-stamped + (cl-transforms-stamped:child-frame-id last-traj-pose) + (cl-transforms-stamped:child-frame-id last-traj-pose) + (cl-transforms-stamped:stamp last-traj-pose) + (cl-transforms:make-3d-vector + 0 0 *drawer-handle-pregrasp-x-offset-open*) + (cl-transforms:make-identity-rotation))) + (cram-tf:apply-transform + last-traj-pose + (cl-transforms-stamped:make-transform-stamped + (cl-transforms-stamped:child-frame-id last-traj-pose) + (cl-transforms-stamped:child-frame-id last-traj-pose) + (cl-transforms-stamped:stamp last-traj-pose) + (cl-transforms:make-3d-vector + 0 0 (- *door-handle-retract-offset*)) + (cl-transforms:make-identity-rotation)))) + (list (cram-tf:apply-transform + last-traj-pose + (cl-transforms-stamped:make-transform-stamped + (cl-transforms-stamped:child-frame-id last-traj-pose) + (cl-transforms-stamped:child-frame-id last-traj-pose) + (cl-transforms-stamped:stamp last-traj-pose) + (cl-transforms:make-3d-vector + 0 0 (- *door-handle-retract-offset*)) + (cl-transforms:make-identity-rotation)))))))))) (defun 3d-vector->keyparam-list (v) @@ -231,16 +275,8 @@ around `axis' by `angle-max' in steps of 0.1 rad." (cl-transforms-stamped:stamp joint-to-gripper) (cl-transforms:rotate rotation (cl-transforms:translation joint-to-gripper)) - (apply 'cl-transforms:euler->quaternion - (3d-vector->keyparam-list - (cl-transforms:v+ - (apply 'cl-transforms:make-3d-vector - (cl-transforms:quaternion->euler - (cl-transforms:rotation joint-to-gripper) :just-values t)) - (cl-transforms:v* - axis - angle))))))))) - + (cl-transforms:q* rotation (cl-transforms:rotation + joint-to-gripper))))))) (defun get-container-to-gripper-transform (object-name arm @@ -250,7 +286,7 @@ around `axis' by `angle-max' in steps of 0.1 rad." `object-name' is the name of a container in the `btr-environment'. `arm' denotes which arm's gripper should be used (eg. :left or :right). `handle-axis' is the axis on which the handle lies when looked at from the front in form of a vector. -So normally (1 0 0) or (0 0 1). +So normally (0 1 0) or (0 0 1). `btr-environment' is the name of the environment in which the container is located (eg. :KITCHEN)." (declare (type (or string symbol) object-name) (type keyword arm) @@ -312,3 +348,12 @@ So normally (1 0 0) or (0 0 1). -1 0 0)))))) + +(defun get-revolute-axis (object-name object-environment) + (cl-transforms:rotate + (cl-transforms:rotation + (cl-urdf:origin + (cl-urdf:from-joint + (get-handle-link object-name object-environment)))) + (cl-transforms:make-3d-vector 0 0 1))) + diff --git a/cram_3d_world/cram_urdf_projection/src/low-level.lisp b/cram_3d_world/cram_urdf_projection/src/low-level.lisp index d14afac419..1c3d0e8d73 100644 --- a/cram_3d_world/cram_urdf_projection/src/low-level.lisp +++ b/cram_3d_world/cram_urdf_projection/src/low-level.lisp @@ -94,7 +94,7 @@ (defun drive (target) (declare (type cl-transforms-stamped:pose-stamped target)) - (btr:add-vis-axis-object target) + (btr:add-vis-axis-object target :length 0.5) (let ((world-pose-info (btr:get-world-objects-pose-info))) (unwind-protect @@ -177,6 +177,12 @@ (defun look-at-pose-stamped-two-joints (pose-stamped) (declare (type cl-transforms-stamped:pose-stamped pose-stamped)) + (setf pose-stamped + (cram-tf:ensure-pose-in-frame + pose-stamped cram-tf:*fixed-frame* :use-zero-time t)) + + (btr:add-vis-axis-object pose-stamped :length 0.03 :width 0.03) + ;; first look forward, because our IK with 2 joints is buggy... (look-at-joint-angles '(0 0)) @@ -184,7 +190,9 @@ ?tilt-link ?pan-joint ?tilt-joint ?pan-lower-limit ?pan-upper-limit - ?tilt-lower-limit ?tilt-upper-limit) + ?tilt-lower-limit ?tilt-upper-limit + ?pan-forward-axis ?pan-forward-sign + ?tilt-forward-axis ?tilt-forward-sign) (car (prolog:prolog '(and @@ -194,45 +202,45 @@ (rob-int:joint-lower-limit ?robot ?pan-joint ?pan-lower-limit) (rob-int:joint-upper-limit ?robot ?pan-joint ?pan-upper-limit) (rob-int:joint-lower-limit ?robot ?tilt-joint ?tilt-lower-limit) - (rob-int:joint-upper-limit ?robot ?tilt-joint ?tilt-upper-limit)))) - - (let* ((pose-in-world - (cram-tf:ensure-pose-in-frame - pose-stamped - cram-tf:*fixed-frame* - :use-zero-time t)) - (pan-tilt-angles - (btr:calculate-pan-tilt - (btr:get-robot-object) ?pan-link ?tilt-link pose-in-world)) - (pan-angle - (first pan-tilt-angles)) - (tilt-angle - (second pan-tilt-angles)) - (cropped-pan-angle - (if (< pan-angle ?pan-lower-limit) - ?pan-lower-limit - (if (> pan-angle ?pan-upper-limit) - ?pan-upper-limit - pan-angle))) - (cropped-tilt-angle - (if (< tilt-angle ?tilt-lower-limit) - ?tilt-lower-limit - (if (> tilt-angle ?tilt-upper-limit) - ?tilt-upper-limit - tilt-angle)))) - - (prolog:prolog - `(and (btr:bullet-world ?w) - (rob-int:robot ?robot) - (btr:%object ?w ?robot ?robot-object) - (assert ?world - (btr:joint-state - ?robot ((,?pan-joint ,cropped-pan-angle) - (,?tilt-joint ,cropped-tilt-angle)))))) - (unless (and (< (abs (- pan-angle cropped-pan-angle)) 0.00001) - (< (abs (- tilt-angle cropped-tilt-angle)) 0.00001)) - (cpl:fail 'common-fail:ptu-goal-not-reached - :description "Look action wanted to twist the neck"))))) + (rob-int:joint-upper-limit ?robot ?tilt-joint ?tilt-upper-limit) + (rob-int:robot-neck-pan-joint-forward-facing-axis-sign ?robot + ?pan-forward-axis ?pan-forward-sign) + (rob-int:robot-neck-tilt-joint-forward-facing-axis-sign ?robot + ?tilt-forward-axis ?tilt-forward-sign)))) + + (multiple-value-bind (cropped-angles original-angles) + + (btr:calculate-pan-tilt + (btr:get-robot-object) + ?pan-link ?tilt-link + pose-stamped + ?pan-forward-axis ?pan-forward-sign + ?tilt-forward-axis ?tilt-forward-sign + ?pan-lower-limit ?pan-upper-limit + ?tilt-lower-limit ?tilt-upper-limit) + + (let ((cropped-pan-angle + (first cropped-angles)) + (cropped-tilt-angle + (second cropped-angles)) + (pan-angle + (first original-angles)) + (tilt-angle + (second original-angles))) + + (prolog:prolog + `(and (btr:bullet-world ?w) + (rob-int:robot ?robot) + (btr:%object ?w ?robot ?robot-object) + (assert ?world + (btr:joint-state + ?robot ((,?pan-joint ,cropped-pan-angle) + (,?tilt-joint ,cropped-tilt-angle)))))) + + (unless (and (< (abs (- pan-angle cropped-pan-angle)) 0.00001) + (< (abs (- tilt-angle cropped-tilt-angle)) 0.00001)) + (cpl:fail 'common-fail:ptu-goal-not-reached + :description "Look action wanted to twist the neck")))))) (defun get-neck-ik (ee-link cartesian-pose base-link joint-names) (cut:with-vars-strictly-bound (?camera-resampling-step @@ -287,7 +295,7 @@ (roslisp:msg-slot-value joint-state-msg :position)))))) (defun calculate-camera-pose-from-object-pose (neck-base-t-object) - "Takes the vector from neck-base to object, sets its Z to 0, + "Takes the vector from neck-base to object, sets its Z to 0 (in neck frame), then normalizes to get a unit vector, then multiplies with a multiplier to make it shorter (multiplier should be comparable to maximum length between neck base and camera), then pulls the vector up in Z a bit @@ -400,27 +408,25 @@ with the object, calculates similar angle around Y axis and applies the rotation (neck-base-t-camera (calculate-camera-pose-from-object-pose neck-base-t-object)) - (camera-t-neck-ee - (cl-transforms:transform-inv - (cl-transforms:pose->transform neck-ee-p-camera))) - (neck-base-t-neck-ee - (cl-transforms:transform* neck-base-t-camera camera-t-neck-ee)) - (neck-base-p-neck-ee - (cl-transforms:transform->pose neck-base-t-neck-ee)) - - (joint-state - (get-neck-ik neck-ee-frame neck-base-p-neck-ee - neck-base-frame neck-joints)) - (map-t-camera (cl-transforms:transform-pose map-t-neck-base neck-base-t-camera))) - (btr:add-vis-axis-object map-t-camera) - (if joint-state - (look-at-joint-angles joint-state) - (cpl:fail 'common-fail:ptu-goal-not-reached - :description "Look goal was not reachable")))) + (let* ((camera-t-neck-ee + (cl-transforms:transform-inv + (cl-transforms:pose->transform neck-ee-p-camera))) + (neck-base-t-neck-ee + (cl-transforms:transform* neck-base-t-camera camera-t-neck-ee)) + (neck-base-p-neck-ee + (cl-transforms:transform->pose neck-base-t-neck-ee)) + + (joint-state + (get-neck-ik neck-ee-frame neck-base-p-neck-ee + neck-base-frame neck-joints))) + (if joint-state + (look-at-joint-angles joint-state) + (cpl:fail 'common-fail:ptu-goal-not-reached + :description "Look goal was not reachable"))))) (defun look-at (pose configuration) @@ -697,6 +703,7 @@ with the given offsets (the offsets are specified in the torso frame). (make-instance 'common-fail:manipulation-goal-not-reached :description "Robot is in collision with environment."))) ((or :allow-hand + :allow-fingers :allow-arm) ;; allow hand allows collisions between the hand and anything ;; but not the rest of the robot @@ -729,7 +736,7 @@ with the given offsets (the offsets are specified in the torso frame). `(and (rob-int:robot ?robot) ,(ecase collision-mode - (:allow-hand + ((or :allow-hand :allow-fingers) '(rob-int:hand-links ?robot :left ?links)) (:allow-arm '(rob-int:arm-links ?robot :left ?links)))))))) @@ -741,7 +748,7 @@ with the given offsets (the offsets are specified in the torso frame). `(and (rob-int:robot ?robot) ,(ecase collision-mode - (:allow-hand + ((or :allow-hand :allow-fingers) '(rob-int:hand-links ?robot :right ?links)) (:allow-arm '(rob-int:arm-links ?robot :right ?links))))))))) @@ -1034,7 +1041,8 @@ collision by moving its torso and base" (:z (- torso-joint-upper-limit current-torso-angle) (- torso-joint-lower-limit current-torso-angle) - *torso-resampling-step*))))) + *torso-resampling-step* + :disable-resampling disable-base-resampling))))) (unless ik-solution-msg (cpl:fail 'common-fail:manipulation-low-level-failure :description @@ -1072,9 +1080,9 @@ collision by moving its torso and base" (cram-tf:visualize-marker (list left-tcp-pose right-tcp-pose) :r-g-b-list '(1 0 1)) (when right-tcp-pose - (btr:add-vis-axis-object right-tcp-pose)) + (btr:add-vis-axis-object right-tcp-pose :length 0.1)) (when left-tcp-pose - (btr:add-vis-axis-object left-tcp-pose)) + (btr:add-vis-axis-object left-tcp-pose :length 0.1)) (cut:with-vars-strictly-bound (?robot ?left-tool-frame ?right-tool-frame ?left-ee-frame ?right-ee-frame diff --git a/cram_3d_world/cram_urdf_projection/src/process-modules.lisp b/cram_3d_world/cram_urdf_projection/src/process-modules.lisp index 4e4b0f5e44..605c9af68e 100644 --- a/cram_3d_world/cram_urdf_projection/src/process-modules.lisp +++ b/cram_3d_world/cram_urdf_projection/src/process-modules.lisp @@ -32,8 +32,9 @@ ;;;;;;;;;;;;;;;;; NAVIGATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (cpm:def-process-module urdf-proj-navigation (motion-designator) - (destructuring-bind (command argument) + (destructuring-bind (command argument &rest args) (desig:reference motion-designator) + (declare (ignore args)) (ecase command (cram-common-designators:move-base (drive argument))))) @@ -95,6 +96,17 @@ (third arg-2) (fourth arg-2) (fifth arg-2) (sixth arg-2) (seventh arg-2)))))) +;;;;;;;;;;;;;;;;; NOOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(cpm:def-process-module urdf-proj-noop (motion-designator) + (destructuring-bind (command &rest args) + (desig:reference motion-designator) + (declare (ignore args)) + (case command + (cram-common-designators:monitor-joint-state + (loop do (cpl:sleep 1000))) + (t + nil)))) ;;;;;;;;;;;;;;;;;;;;; PREDICATES ;;;;;;;;;;;;;;;;;;;;;;;; @@ -122,4 +134,7 @@ (or (desig:desig-prop ?motion-designator (:type :moving-tcp)) (desig:desig-prop ?motion-designator (:type :moving-arm-joints)) (desig:desig-prop ?motion-designator (:type :pulling)) - (desig:desig-prop ?motion-designator (:type :pushing))))) + (desig:desig-prop ?motion-designator (:type :pushing)))) + + (<- (cpm:matching-process-module ?motion-designator urdf-proj-noop) + (desig:desig-prop ?motion-designator (:type :monitoring-joint-state)))) diff --git a/cram_3d_world/cram_urdf_projection/src/projection-environment.lisp b/cram_3d_world/cram_urdf_projection/src/projection-environment.lisp index 27c9b57982..ae6ca83be8 100644 --- a/cram_3d_world/cram_urdf_projection/src/projection-environment.lisp +++ b/cram_3d_world/cram_urdf_projection/src/projection-environment.lisp @@ -36,7 +36,9 @@ (cram-projection:define-projection-environment urdf-bullet-projection-environment :special-variable-initializers - ((cram-tf:*transformer* + ((cram-tf:*tf-default-timeout* + 0.1) ; 1/10th of a second + (cram-tf:*transformer* (make-instance 'cl-tf:transformer)) ;; TODO: use custom tf topic "tf_sim" ;; For that first change tf2_ros/TransformListener to accept custom topic names @@ -64,7 +66,9 @@ urdf-proj-perception urdf-proj-grippers urdf-proj-arms - btr-belief:world-state-detecting-pm) + urdf-proj-noop + btr-belief:world-state-detecting-pm + common-desig:wait-pm) :startup (progn (cram-bullet-reasoning-belief-state:set-tf-from-bullet) (cram-bullet-reasoning-belief-state:update-bullet-transforms) @@ -85,7 +89,7 @@ urdf-proj-perception urdf-proj-grippers urdf-proj-arms - btr-belief:world-state-detecting-pm))) + urdf-proj-noop))) (symbol-value cram-projection:*projection-environment* urdf-bullet-projection-environment)) (<- (cpm::projection-running ?pm) @@ -96,7 +100,7 @@ urdf-proj-perception urdf-proj-grippers urdf-proj-arms - btr-belief:world-state-detecting-pm))) + urdf-proj-noop))) (symbol-value cram-projection:*projection-environment* urdf-bullet-projection-environment))) diff --git a/cram_3d_world/cram_urdf_projection_reasoning/src/check-collisions.lisp b/cram_3d_world/cram_urdf_projection_reasoning/src/check-collisions.lisp index 176a11df08..b4afbf3280 100644 --- a/cram_3d_world/cram_urdf_projection_reasoning/src/check-collisions.lisp +++ b/cram_3d_world/cram_urdf_projection_reasoning/src/check-collisions.lisp @@ -32,7 +32,15 @@ (defparameter *projection-checks-enabled* t) -(defun check-navigating-collisions (navigation-location-desig &optional (samples-to-try 30)) +(defun infer-move-base (object-designator action-designator) + (not + (prolog:prolog + `(and (once (or (spec:property ,action-designator (:target ?location-desig)) + (spec:property ,object-designator (:location ?location-desig)))) + (man-int:location-always-reachable ?location-desig))))) + +(defun check-navigating-collisions (navigation-location-desig + &optional (samples-to-try 30)) (declare (type desig:location-designator navigation-location-desig)) "Store current world state and in the current world try to go to different poses that satisfy `navigation-location-desig'. @@ -46,7 +54,8 @@ Store found pose into designator or throw error if good pose not found." (cpl:with-failure-handling ((desig:designator-error (e) (roslisp:ros-warn (coll-check nav) - "Desig ~a could not be resolved: ~a~%Cannot navigate." + "Desig ~a could not be resolved: ~a~%~ + Cannot navigate." navigation-location-desig e) (cpl:fail 'common-fail:navigation-goal-in-collision :description "Designator could not be resolved"))) @@ -66,15 +75,19 @@ Store found pose into designator or throw error if good pose not found." (cpl:retry)) (progn (roslisp:ros-warn (coll-check nav) - "No other samples in designator. Propagating up.") + "No other samples in designator. ~ + Propagating up.") (cpl:fail 'common-fail:navigation-goal-in-collision - :description "No other samples in designator")))) + :description + "No other samples in designator")))) (roslisp:ros-warn (coll-check nav) - "Couldn't find a nav pose after all retries for~%~a.~%~ - Propagating up." + "Couldn't find a nav pose ~ + after all retries for~%~a.~%~ + Propagating up." navigation-location-desig) (cpl:fail 'common-fail:navigation-goal-in-collision - :description "Couldn't find a nav pose after all retries"))) + :description "Couldn't find a nav pose ~ + after all retries"))) ;; Pick one pose, store it in `pose-at-navigation-location' ;; In projected world, drive to picked pose @@ -82,11 +95,13 @@ Store found pose into designator or throw error if good pose not found." ;; driving throws a failure. ;; Otherwise, the pose was found, so return location designator, ;; which is currently referenced to the found pose. - (let ((pose-at-navigation-location (desig:reference navigation-location-desig))) + (let ((pose-at-navigation-location + (desig:reference navigation-location-desig))) (urdf-proj::drive pose-at-navigation-location) ;; (roslisp:ros-info (coll-check nav) ;; "Found non-colliding pose~%~a to satisfy~%~a." - ;; pose-at-navigation-location navigation-location-desig) + ;; pose-at-navigation-location + ;; navigation-location-desig) navigation-location-desig)))) (btr:restore-world-poses world-pose-info))))) @@ -125,7 +140,8 @@ Store found pose into designator or throw error if good pose not found." "No more pick-up samples to try.~ Object unreachable.") (cpl:fail 'common-fail:object-unreachable - :description "No more pick-up samples to try.")))) + :description + "No more pick-up samples to try.")))) (roslisp:ros-warn (coll-check pick) "No more retries left :'(") (cpl:fail 'common-fail:object-unreachable :description "No more grasp retries left."))) @@ -133,33 +149,49 @@ Store found pose into designator or throw error if good pose not found." (let* ((pick-up-action-referenced (second (desig:reference pick-up-action-desig))) (object-designator - (desig:desig-prop-value pick-up-action-referenced :object)) + (desig:current-desig + (desig:desig-prop-value pick-up-action-referenced + :object))) (arm - (desig:desig-prop-value pick-up-action-referenced :arm)) + (desig:desig-prop-value pick-up-action-referenced + :arm)) (gripper-opening - (desig:desig-prop-value pick-up-action-referenced :gripper-opening)) + (desig:desig-prop-value pick-up-action-referenced + :gripper-opening)) (grasp - (desig:desig-prop-value pick-up-action-referenced :grasp)) + (desig:desig-prop-value pick-up-action-referenced + :grasp)) (left-reach-poses - (desig:desig-prop-value pick-up-action-referenced :left-reach-poses)) + (desig:desig-prop-value pick-up-action-referenced + :left-reach-poses)) (right-reach-poses - (desig:desig-prop-value pick-up-action-referenced :right-reach-poses)) + (desig:desig-prop-value pick-up-action-referenced + :right-reach-poses)) (left-grasp-poses - (desig:desig-prop-value pick-up-action-referenced :left-grasp-poses)) + (desig:desig-prop-value pick-up-action-referenced + :left-grasp-poses)) (right-grasp-poses - (desig:desig-prop-value pick-up-action-referenced :right-grasp-poses)) + (desig:desig-prop-value pick-up-action-referenced + :right-grasp-poses)) (left-lift-poses - (desig:desig-prop-value pick-up-action-referenced :left-lift-poses)) + (desig:desig-prop-value pick-up-action-referenced + :left-lift-poses)) (right-lift-poses - (desig:desig-prop-value pick-up-action-referenced :right-lift-poses)) + (desig:desig-prop-value pick-up-action-referenced + :right-lift-poses)) (object-name - (desig:desig-prop-value object-designator :name))) + (desig:desig-prop-value object-designator + :name)) + (move-base + (infer-move-base object-designator + pick-up-action-referenced))) (urdf-proj::gripper-action gripper-opening arm) ;; Go over all the trajectory via points and check for collisions ;; with any object except the one to pick up. - ;; If collision happens, throw `manipulation-goal-in-collision' failure. + ;; If collision happens, + ;; throw `manipulation-goal-in-collision' failure. (roslisp:ros-info (coll-check pick) "Trying grasp ~a on object ~a with arm ~a~%" grasp object-name arm) @@ -170,8 +202,9 @@ Store found pose into designator or throw error if good pose not found." (cut:equalize-two-list-lengths left-poses right-poses) (dotimes (i (length left-poses)) (urdf-proj::move-tcp (nth i left-poses) (nth i right-poses) - :allow-all) - (unless (< (abs urdf-proj::*debug-short-sleep-duration*) 0.0001) + :allow-all nil nil nil move-base) + (unless (< (abs urdf-proj::*debug-short-sleep-duration*) + 0.0001) (cpl:sleep urdf-proj::*debug-short-sleep-duration*)) (when (urdf-proj::perform-collision-check collision-flag @@ -215,7 +248,7 @@ Store found pose into designator or throw error if good pose not found." (cpl:retry) (progn (roslisp:ros-warn (coll-check place) - "No more placing samples to try.~ + "No more placing samples to try. ~ Object unreachable.") (cpl:fail 'common-fail:object-unreachable :description @@ -235,25 +268,39 @@ Store found pose into designator or throw error if good pose not found." (let* ((placing-action-referenced (second (desig:reference placing-action-desig))) (object-designator - (desig:desig-prop-value placing-action-referenced :object)) + (desig:desig-prop-value placing-action-referenced + :object)) (arm - (desig:desig-prop-value placing-action-referenced :arm)) + (desig:desig-prop-value placing-action-referenced + :arm)) + (gripper-opening + (desig:desig-prop-value placing-action-referenced + :gripper-opening)) (left-reach-poses - (desig:desig-prop-value placing-action-referenced :left-reach-poses)) + (desig:desig-prop-value placing-action-referenced + :left-reach-poses)) (right-reach-poses - (desig:desig-prop-value placing-action-referenced :right-reach-poses)) - (left-put-poses - (desig:desig-prop-value placing-action-referenced :left-put-poses)) - (right-put-poses - (desig:desig-prop-value placing-action-referenced :right-put-poses)) + (desig:desig-prop-value placing-action-referenced + :right-reach-poses)) + ;; (left-put-poses + ;; (desig:desig-prop-value placing-action-referenced + ;; :left-put-poses)) + ;; (right-put-poses + ;; (desig:desig-prop-value placing-action-referenced + ;; :right-put-poses)) (left-retract-poses - (desig:desig-prop-value placing-action-referenced :left-retract-poses)) + (desig:desig-prop-value placing-action-referenced + :left-retract-poses)) (right-retract-poses - (desig:desig-prop-value placing-action-referenced :right-retract-poses)) + (desig:desig-prop-value placing-action-referenced + :right-retract-poses)) (object-name - (desig:desig-prop-value object-designator :name))) + (desig:desig-prop-value object-designator + :name)) + (move-base + (infer-move-base object-designator placing-action-desig))) - (urdf-proj::gripper-action :open arm) + (urdf-proj::gripper-action gripper-opening arm) (roslisp:ros-info (coll-check place) "Trying to place object ~a with arm ~a~%" @@ -265,8 +312,9 @@ Store found pose into designator or throw error if good pose not found." (cut:equalize-two-list-lengths left-poses right-poses) (dotimes (i (length left-poses)) (urdf-proj::move-tcp (nth i left-poses) (nth i right-poses) - :allow-all) - (unless (< (abs urdf-proj:*debug-short-sleep-duration*) 0.0001) + :allow-all nil nil nil move-base) + (unless (< (abs urdf-proj:*debug-short-sleep-duration*) + 0.0001) (cpl:sleep urdf-proj:*debug-short-sleep-duration*)) (when (or ;; either robot collied with environment @@ -287,15 +335,15 @@ Store found pose into designator or throw error if good pose not found." ;; :key #'btr:name) ) (roslisp:ros-warn (coll-check place) - "Robot is in collision with environment.") + "Robot is in collision with ~a." + (btr:robot-colliding-objects-without-attached)) (cpl:sleep urdf-proj:*debug-long-sleep-duration*) (btr:restore-world-poses world-pose-info) - ;; (cpl:fail 'common-fail:manipulation-goal-in-collision) - )))) - ;; (list left-put-poses) - ;; (list right-put-poses) - (list left-reach-poses left-put-poses left-retract-poses) - (list right-reach-poses right-put-poses right-retract-poses)))))) + (cpl:fail 'common-fail:manipulation-goal-in-collision))))) + (list left-reach-poses ;; left-put-poses + left-retract-poses) + (list right-reach-poses ;; right-put-poses + right-retract-poses)))))) (btr:restore-world-poses world-pose-info))))) @@ -374,11 +422,9 @@ Store found pose into designator or throw error if good pose not found." (right-poses-2 (desig:desig-prop-value action-referenced :right-grasp-poses)) (left-poses-3 - (or (desig:desig-prop-value action-referenced :left-open-poses) - (desig:desig-prop-value action-referenced :left-close-poses))) + (desig:desig-prop-value action-referenced :left-manipulate-poses)) (right-poses-3 - (or (desig:desig-prop-value action-referenced :right-open-poses) - (desig:desig-prop-value action-referenced :right-close-poses))) + (desig:desig-prop-value action-referenced :right-manipulate-poses)) (left-poses-4 (desig:desig-prop-value action-referenced :left-retract-poses)) (right-poses-4 @@ -403,9 +449,11 @@ Store found pose into designator or throw error if good pose not found." (when (eq (desig:desig-prop-value action-desig :type) :opening) (when (btr:robot-colliding-objects-without-attached) (roslisp:ros-warn (coll-check environment) - "Robot is in collision with environment.") + "Robot is in collision with ~a." + (btr:robot-colliding-objects-without-attached)) (cpl:sleep urdf-proj:*debug-long-sleep-duration*) (btr:restore-world-poses world-pose-info) + ;; Ignoring collisions with the environment and only reacting to IK fails. ;; (cpl:fail 'common-fail:manipulation-goal-in-collision) )))) (btr:restore-world-poses world-pose-info))))) diff --git a/cram_3rdparty/cffi/package.xml b/cram_3rdparty/cffi/package.xml index db9d932c64..e1fe9ca01c 100644 --- a/cram_3rdparty/cffi/package.xml +++ b/cram_3rdparty/cffi/package.xml @@ -15,7 +15,7 @@ https://github.com/cram2/cram_3rdparty/issues https://github.com/cram2/cram_3rdparty https://gitlab.common-lisp.net/cffi/cffi.git - + catkin diff --git a/cram_3rdparty/cffi/src/Makefile b/cram_3rdparty/cffi/src/Makefile index 125f2f3b4c..f0da0db213 100644 --- a/cram_3rdparty/cffi/src/Makefile +++ b/cram_3rdparty/cffi/src/Makefile @@ -33,6 +33,7 @@ SBCL ?= sbcl CLISP ?= clisp ALLEGRO ?= alisp SCL ?= scl +ECL ?= ecl shlibs: @$(MAKE) -wC tests shlibs @@ -63,6 +64,9 @@ test-clisp-modern: test-allegro: @-$(ALLEGRO) -L tests/run-tests.lisp -test: test-openmcl test-sbcl test-cmucl test-clisp +test-ecl: + @-$(ECL) --quiet --load tests/run-tests.lisp + +test: test-openmcl test-sbcl test-cmucl test-clisp test-ecl # vim: ft=make ts=3 noet diff --git a/cram_3rdparty/cffi/src/README.md b/cram_3rdparty/cffi/src/README.md index 91e2135ddd..c05ddf388e 100644 --- a/cram_3rdparty/cffi/src/README.md +++ b/cram_3rdparty/cffi/src/README.md @@ -1,19 +1,66 @@ [![Build Status](https://travis-ci.org/cffi/cffi.svg?branch=master)](https://travis-ci.org/cffi/cffi) -CFFI, the Common Foreign Function Interface, purports to be a portable -foreign function interface for Common Lisp. The CFFI library is -composed of a Lisp-implementation-specific backend in the CFFI-SYS -package, and a portable frontend in the CFFI package. +# What + +CFFI, the Common Foreign Function Interface, purports +to be a portable FFI for Common Lisp. It abstracts away the +differences between the API of the native FFI's of the various Common +Lisp implementations. + +# How + +The CFFI library is composed of a Lisp-implementation-specific backend +in the CFFI-SYS package, and a portable frontend in the CFFI package. The CFFI-SYS backend package defines a low-level interface to the native FFI support in the Lisp implementation. It offers operators for allocating and dereferencing foreign memory, calling foreign -functions, and loading shared libraries. The CFFI frontend provides a -declarative interface for defining foreign functions, structures, -typedefs, enumerated types, etc. It is implemented in portable ANSI CL -making use of the low-level operators exported by CFFI-SYS. +functions, and loading shared libraries. + +The CFFI frontend provides a more comfortable, declarative interface +for defining foreign functions, structures, typedefs, enumerated +types, etc. It is implemented in portable ANSI CL making use of the +low-level operators exported by CFFI-SYS. + +The CFFI-LIBFFI subsystem loads support for passing structs by +value. It requires [libffi](https://sourceware.org/libffi/) for that. + +Please consult [the +manual](http://common-lisp.net/project/cffi/manual/html_node/) for +further details, including installation instructions. + +# Where + +Please visit [Github](https://github.com/cffi/cffi/issues) for bug +reports, feature suggestions, the latest version, and to send your +contributions. CFFI also has a [mailing +list](https://mailman.common-lisp.net/listinfo/cffi-devel), and a +project page at [cffi.common-lisp.dev](https://cffi.common-lisp.dev/). + +# Notes + +### CFFI/C2FFI + +CFFI/C2FFI is an ASDF-integrated mechanism to automatically generate a +complete CFFI binding from a C header file. It requires a CLI tool +called [c2ffi](https://github.com/rpav/c2ffi), but only for the +developers of the libraries, not their users. `c2ffi` is written in +C++, and it uses LLVM/Clang as the parsing library. It generates JSON +output that can be checked in into the repositories. CFFI/C2FFI uses +these JSON files to automatically generate a CL file that contains the +CFFI definition forms. The generated bindings mirror the C namespace +into an otherwise empty CL package as closely as possible. It means +that they retain the upper/lower case of the names, and it also +includes the `#define` macros as CL constants. + +Until CFFI/C2FFI is properly documented, you may check out these +projects as examples: +[hu.dwim.bluez](https://github.com/hu-dwim/hu.dwim.bluez), +[hu.dwim.zlib](https://github.com/hu-dwim/hu.dwim.zlib), +[hu.dwim.sdl](https://github.com/hu-dwim/hu.dwim.sdl), and +[hu.dwim.mosquitto](https://github.com/attila-lendvai/hu.dwim.mosquitto). -Please consult [the manual][1] for further details, including -installation instructions. +### Related projects -[1]: http://common-lisp.net/project/cffi/manual/html_node/ +- [cl-autowrap](https://github.com/rpav/cl-autowrap) is another + project that uses `c2ffi` to generate CFFI bindings. diff --git a/cram_3rdparty/cffi/src/TODO b/cram_3rdparty/cffi/src/TODO index 912d5e243b..ff25df1db2 100644 --- a/cram_3rdparty/cffi/src/TODO +++ b/cram_3rdparty/cffi/src/TODO @@ -102,6 +102,14 @@ This is a collection of TODO items and ideas in no particular order. or an autodetection after loading everything, see https://github.com/borodust/cl-bodge/blob/0.3.0/distribution/build.lisp#L79 +### CFFI/C2FFI + +-> Generate wrappers for C inline function definitions (and maybe for some + #define's?) +-> It would be nice if c2ffi emitted its output in a stable order + for details see https://github.com/rpav/c2ffi/issues/28 +-> Handle va_list. For now it's treated as any other argument. + ### Other -> Type-checking pointer interface. diff --git a/cram_3rdparty/cffi/src/cffi-toolchain.asd b/cram_3rdparty/cffi/src/cffi-toolchain.asd index 7d9977c63f..f3864f193c 100644 --- a/cram_3rdparty/cffi/src/cffi-toolchain.asd +++ b/cram_3rdparty/cffi/src/cffi-toolchain.asd @@ -40,7 +40,7 @@ :components (;; This is a plain copy of bundle.lisp from ASDF 3.2.0 ;; in case your asdf isn't up to snuff. - (:file "bundle" :if-feature (#.(if (version< "3.2.0" (asdf-version)) :or :and))) + (:file "bundle" :if-feature (#.(if (version< "3.1.8" (asdf-version)) :or :and))) (:file "package") (:file "c-toolchain" :depends-on ("package")) (:file "static-link" :depends-on ("bundle" "c-toolchain")))))) diff --git a/cram_3rdparty/cffi/src/cffi.asd b/cram_3rdparty/cffi/src/cffi.asd index 53b46e21ce..4a142154c9 100644 --- a/cram_3rdparty/cffi/src/cffi.asd +++ b/cram_3rdparty/cffi/src/cffi.asd @@ -31,8 +31,7 @@ #-(or openmcl mcl sbcl cmucl scl clisp lispworks ecl allegro cormanlisp abcl mkcl clasp) (error "Sorry, this Lisp is not yet supported. Patches welcome!") -(defsystem :cffi - :version "0.19.0" +(defsystem "cffi" :description "The Common Foreign Function Interface" :author "James Bielman " :maintainer "Luis Oliveira " @@ -76,8 +75,8 @@ (or (null (component-version c)) (call-next-method))) -(defsystem :cffi/c2ffi - :description "CFFI definition generator from the FFI spec generated by c2ffi. This system is enough to use the ASDF machinery (as a :defsystem-depends-on)." +(defsystem "cffi/c2ffi" + :description "CFFI definition generator from the FFI spec generated by c2ffi. This system can be used through ASDF's :DEFSYSTEM-DEPENDS-ON." :author "Attila Lendvai " :depends-on (:alexandria :cffi) @@ -89,8 +88,8 @@ (:file "c2ffi" :depends-on ("package")) (:file "asdf" :depends-on ("package" "c2ffi")))))) -(defsystem :cffi/c2ffi-generator - :description "This system gets loaded lazily when the CFFI bindings need to be regenerated." +(defsystem "cffi/c2ffi-generator" + :description "This system gets loaded lazily when the CFFI bindings need to be regenerated. This only happens if the developer chose not to include the generated binding files, or the spec file generated by c2ffi has been modified." :author "Attila Lendvai " :depends-on (:cffi/c2ffi :cl-ppcre diff --git a/cram_3rdparty/cffi/src/doc/cffi-manual.texinfo b/cram_3rdparty/cffi/src/doc/cffi-manual.texinfo index f8f596d93e..b032ad7e97 100644 --- a/cram_3rdparty/cffi/src/doc/cffi-manual.texinfo +++ b/cram_3rdparty/cffi/src/doc/cffi-manual.texinfo @@ -432,10 +432,6 @@ On platforms where ECL's dynamic FFI is not supported (ie. when @code{:dffi} is not present in @code{*features*}), @code{cffi:load-foreign-library} does not work and you must use ECL's own @code{ffi:load-foreign-library} with a constant string argument. -@item -Does not support the @code{:long-long} type natively. -@item -Unicode support is not enabled by default. @end itemize @subheading Lispworks @@ -1852,13 +1848,16 @@ respectively. @ForeignType{:uint32} @ForeignType{:int64} @ForeignType{:uint64} +@ForeignType{:size} +@ForeignType{:ssize} +@ForeignType{:intptr} +@ForeignType{:uintptr} +@ForeignType{:ptrdiff} +@ForeignType{:offset} Foreign integer types of specific sizes, corresponding to the C types defined in @code{stdint.h}. -@c @ForeignType{:size} -@c @ForeignType{:ssize} -@c @ForeignType{:ptrdiff} @c @ForeignType{:time} @c Foreign integer types corresponding to the standard C types (without @@ -2530,7 +2529,7 @@ CFFI-USER> (code-char (mem-aref * :char 5)) @Macro{defbitfield name-and-options &body masks} masks ::= [docstring] @{ (symbol value) @}* @* -name-and-options ::= name | (name &optional (base-type :int)) +name-and-options ::= name | (name &optional (base-type :int)) @* @subheading Arguments and Values @@ -2582,7 +2581,7 @@ which is @code{:int} by default. ;; @lispcmt{etc@dots{}} CFFI> (foreign-bitfield-symbols 'open-flags #b1101) -@result{} (:RDONLY :WRONLY :NONBLOCK :APPEND) +@result{} (:WRONLY :NONBLOCK :APPEND) CFFI> (foreign-bitfield-value 'open-flags '(:rdwr :creat)) @result{} 514 ; #x0202 @@ -2614,8 +2613,7 @@ CFFI> (unix-open "/tmp/foo" '(:wronly :creat) #o644) @subheading Syntax @Macro{defcstruct name-and-options &body doc-and-slots @res{} name} -name-and-options ::= structure-name | (structure-name &key size) - +name-and-options ::= structure-name | (structure-name &key size) @* doc-and-slots ::= [docstring] @{ (slot-name slot-type &key count offset) @}* @subheading Arguments and Values @@ -2824,8 +2822,8 @@ you should use @ref{define-foreign-type}. @subheading Syntax @Macro{defcenum name-and-options &body enum-list} -enum-list ::= [docstring] @{ keyword | (keyword value) @}* -name-and-options ::= name | (name &optional (base-type :int)) +enum-list ::= [docstring] @{ keyword | (keyword value) @}* @* +name-and-options ::= name | (name &optional (base-type :int) &key allow-undeclared-values) @* @subheading Arguments and Values @@ -2839,6 +2837,10 @@ A documentation string, ignored. @item base-type A symbol denoting a foreign type. +@item allow-undeclared-values +Whether to pass through integer values that were not explicitly declared +in the enum when translating from foreign memory. + @item keyword A keyword symbol. @@ -2859,6 +2861,14 @@ being passed as arguments to or returned from foreign functions, respectively. The same applies to any other situations where an object of an @code{enum} type is expected. +If a value should be translated to lisp that is not declared in the +enum, an error will be signalled. You can elide this error and instead +make it pass the original enum value by specifying +@var{allow-undeclared-values}. This can be useful for very large +enumerations of which we only care about a subset of values, or for +enumerations that should allow for client or vendor extensions that we +cannot know about. + Types defined with @code{defcenum} canonicalize to @var{base-type} which is @code{:int} by default. @@ -3081,7 +3091,7 @@ list of symbols that correspond to @var{value} in @var{type}. (flag-b 2) (flag-c 4)) -CFFI> (foreign-bitfield-symbols 'boolean #b101) +CFFI> (foreign-bitfield-symbols 'flags #b101) @result{} (FLAG-A FLAG-C) @end lisp @@ -3765,8 +3775,9 @@ pointer. The return value is not used. @table @var @item vars -A list with each element a symbol, or list of length two with the -first element @code{:pointer} and the second a symbol. +A list with binding descriptors; each is either a symbol, or list with +up to 3 elements: an optional new name to bind, an optional symbol +@code{:pointer} and finally the required slot symbol. @item ptr A foreign pointer to a structure. @@ -3779,11 +3790,14 @@ A list of forms to be executed. @end table @subheading Description -The @code{with-foreign-slots} macro creates local symbol macros for each -var in @var{vars} to reference foreign slots in @var{ptr} of @var{type}. -If the var is a list starting with @code{:pointer}, it will bind the -pointer to the slot (rather than the value). It is similar to Common -Lisp's @code{with-slots} macro. +The @code{with-foreign-slots} macro establishes a lexical environment for +referring to the foreign slots of @var{type} addressed by @var{ptr}. +Like Common Lisp's @code{with-slots} macro, each var in @var{vars} may +be a symbol naming a slot, or a list @code{(name slot)} which creates a +binding to a slot with a different name. +Prefixing the slot name with @code{:pointer} creates a binding to a +foreign pointer that addresses the slot rather than its value. Both +@code{(:pointer slot)} and @code{(name :pointer slot)} are acceptable. @subheading Examples @lisp @@ -3805,9 +3819,9 @@ CFFI> (with-foreign-object (time :int) (foreign-funcall "time" :pointer (null-pointer) :int)) (foreign-funcall "gmtime" :pointer time (:pointer (:struct tm)))) @result{} # -CFFI> (with-foreign-slots ((sec min hour mday mon year) * (:struct tm)) +CFFI> (with-foreign-slots ((sec min hour (day-of-month mday) mon year) * (:struct tm)) (format nil "~A:~A:~A, ~A/~A/~A" - hour min sec (+ 1900 year) mon mday)) + hour min sec (+ 1900 year) mon day-of-month)) @result{} "7:22:47, 2005/8/2" @end lisp @@ -4653,7 +4667,7 @@ CFFI> (pointer-eq (null-pointer) (null-pointer)) @anchor{with-foreign-objects} @Macro{with-foreign-objects (bindings) &body body} -bindings ::= @{(var type &optional count)@}* +bindings ::= @{(var type &optional count)@}* @* @subheading Arguments and Values @@ -5024,7 +5038,7 @@ CFFI> (with-foreign-pointer-as-string (str 255) @anchor{with-foreign-strings} @Macro{with-foreign-strings (bindings) &body body} -var-or-vars ::= var | (var &optional octet-size-var) +var-or-vars ::= var | (var &optional octet-size-var) @* bindings ::= @{(var-or-vars string &rest args)@}* @subheading Arguments and Values @@ -5054,12 +5068,6 @@ foreign string in octets including the null terminator. CFFI> (with-foreign-string (foo "12345") (foreign-funcall "strlen" :pointer foo :int)) @result{} 5 - -CFFI> (let ((array (coerce #(84 117 114 97 110 103 97) - '(array (unsigned-byte 8))))) - (with-foreign-string (foreign-string array) - (foreign-string-to-lisp foreign-string))) -@result{} "Turanga" @end lisp @subheading See Also @@ -5133,7 +5141,7 @@ Dictionary @Macro{defcvar name-and-options type &optional documentation @res{} lisp-name} @var{name-and-options} ::= name | (name &key read-only (library :default)) @* -@var{name} ::= lisp-name [foreign-name] | foreign-name [lisp-name] +@var{name} ::= lisp-name [foreign-name] | foreign-name [lisp-name] @* @subheading Arguments and Values @@ -5257,6 +5265,8 @@ Dictionary * defcfun:: * foreign-funcall:: * foreign-funcall-pointer:: +* foreign-funcall-varargs:: +* foreign-funcall-pointer-varargs:: * translate-camelcase-name:: * translate-name-from-foreign:: * translate-name-to-foreign:: @@ -5280,9 +5290,9 @@ Dictionary @Macro{defcfun name-and-options return-type &body [docstring] arguments [&rest] @ @res{} lisp-name} -@var{name-and-options} ::= name | (name &key library convention) @* +@var{name-and-options} ::= @var{name} | (@var{name} &key @var{library} @var{convention}) @* @var{name} ::= @var{lisp-name} [@var{foreign-name}] | @var{foreign-name} [@var{lisp-name}] @* -@var{arguments} ::= @{ (arg-name arg-type) @}* @* +@var{arguments} ::= @{ (@var{arg-name} @var{arg-type}) @}* @* @subheading Arguments and Values @@ -5387,7 +5397,9 @@ CFFI> (with-foreign-pointer-as-string (s 100) @subheading See Also @seealso{foreign-funcall} @* -@seealso{foreign-funcall-pointer} +@seealso{foreign-funcall-pointer} @* +@seealso{foreign-funcall-varargs} @* +@seealso{foreign-funcall-pointer-varargs} @c =================================================================== @@ -5399,8 +5411,8 @@ CFFI> (with-foreign-pointer-as-string (s 100) @subheading Syntax @Macro{foreign-funcall name-and-options &rest arguments @res{} return-value} -arguments ::= @{ arg-type arg @}* [return-type] -name-and-options ::= name | ( name &key library convention) +@var{arguments} ::= @{ @var{arg-type} @var{arg} @}* [@var{return-type}] @* +@var{name-and-options} ::= @var{name} | (@var{name} &key @var{library} @var{convention}) @* @subheading Arguments and Values @@ -5500,13 +5512,13 @@ CFFI> (foreign-funcall "printf" :string (format nil "%s: %d.~%") @c FOREIGN-FUNCALL-POINTER @page -@node foreign-funcall-pointer, translate-camelcase-name, foreign-funcall, Functions +@node foreign-funcall-pointer, foreign-funcall-varargs, foreign-funcall, Functions @heading foreign-funcall-pointer @subheading Syntax @Macro{foreign-funcall-pointer pointer options &rest arguments @res{} return-value} -arguments ::= @{ arg-type arg @}* [return-type] -options ::= ( &key convention ) +@var{arguments} ::= @{ @var{arg-type} @var{arg} @}* [@var{return-type}] @* +@var{options} ::= (&key @var{convention}) @* @subheading Arguments and Values @@ -5560,11 +5572,120 @@ CFFI> (foreign-funcall-pointer (foreign-symbol-pointer "abs") () @seealso{foreign-funcall} +@c =================================================================== +@c FOREIGN-FUNCALL-VARARGS + +@page +@node foreign-funcall-varargs, foreign-funcall-pointer-varargs, foreign-funcall-pointer, Functions +@heading foreign-funcall-varargs +@subheading Syntax +@Macro{foreign-funcall-varargs name-and-options (fixed-arguments) &rest arguments @res{} return-value} + +@var{fixed-arguments} ::= @{ @var{arg-type} @var{arg} @}* [@var{return-type}] @* +@var{arguments} ::= @{ @var{arg-type} @var{arg} @}* [@var{return-type}] @* +@var{name-and-options} ::= @var{name} | (@var{name} &key @var{library} @var{convention}) @* + +@subheading Arguments and Values + +@table @var +@item name +A Lisp string. + +@item arg-type +A foreign type. + +@item arg +An argument of type @var{arg-type}. + +@item return-type +A foreign type, @code{:void} by default. + +@item return-value +A lisp object. + +@item library +A lisp symbol; not evaluated. + +@item convention +One of @code{:cdecl} (default) or @code{:stdcall}. +@end table + +@subheading Description +The @code{foreign-funcall-varargs} macro is the main primitive for +calling foreign variadic functions. It behaves similarily to +@code{foreign-funcall} except @code{fixed-arguments} are distinguished +from the remaining arguments. + +@subheading Examples + +@lisp +CFFI> (with-foreign-pointer-as-string (s 100) + (setf (mem-ref s :char) 0) + (foreign-funcall-varargs + "sprintf" (:pointer s :string) "%.2f") + :double (coerce pi 'double-float) :int)) +@result{} 3.14 +@end lisp + + +@c =================================================================== +@c FOREIGN-FUNCALL-POINTER-VARARGS + +@page +@node foreign-funcall-pointer-varargs, translate-camelcase-name, foreign-funcall-varargs, Functions +@heading foreign-funcall-pointer-varargs +@subheading Syntax +@Macro{foreign-funcall-pointer-varargs pointer options (fixed-arguments) &rest arguments @res{} return-value} + +@var{fixed-arguments} ::= @{ @var{arg-type} @var{arg} @}* [@var{return-type}] @* +@var{arguments} ::= @{ @var{arg-type} @var{arg} @}* [@var{return-type}] @* +@var{options} ::= (&key @var{convention}) @* + +@subheading Arguments and Values + +@table @var +@item pointer +A foreign pointer. + +@item arg-type +A foreign type. + +@item arg +An argument of type @var{arg-type}. + +@item return-type +A foreign type, @code{:void} by default. + +@item return-value +A lisp object. + +@item convention +One of @code{:cdecl} (default) or @code{:stdcall}. +@end table + +@subheading Description +The @code{foreign-funcall-pointer-varargs} macro is the main primitive +for calling foreign variadic functions. It behaves similarily to +@code{foreign-funcall-pointer} except @code{fixed-arguments} are +distinguished from the remaining arguments. + +@subheading Examples + +@lisp +CFFI> (with-foreign-pointer-as-string (s 100) + (setf (mem-ref s :char) 0) + (foreign-funcall-pointer-varargs + (foreign-symbol-pointer "sprintf") () (:pointer s :string "%.2f") + :double (coerce pi 'double-float) :int)) +@result{} 3.14 +@end lisp + + @c =================================================================== @c TRANSLATE-CAMELCASE-NAME @page -@node translate-camelcase-name, translate-name-from-foreign, foreign-funcall-pointer, Functions +@node translate-camelcase-name, translate-name-from-foreign, foreign-funcall-pointer-varargs, Functions @heading translate-camelcase-name @subheading Syntax @Function{translate-camelcase-name name &key upper-initial-p special-words @res{} return-value} @@ -5947,8 +6068,8 @@ CFFI> (let ((lib (load-foreign-library '(:framework "OpenGL")))) @Macro{define-foreign-library name-and-options @{ load-clause @}* @res{} name} -name-and-options ::= name | (name &key convention search-path) -load-clause ::= (feature library &key convention search-path) +name-and-options ::= name | (name &key canary convention search-path) @* +load-clause ::= (feature library &key convention search-path) @* @subheading Arguments and Values @@ -5962,6 +6083,16 @@ A feature expression. @item library A library designator. +@item canary +A string denoting a foreign symbol that will be searched in core +before attempting to load the library. If that symbol is found, the +library is assumed to be preloaded (either statically or dynamically +linked) and @code{load-foreign-library} only marks the library as +loaded. + +Some implementations (Clisp, ECL, SBCL) natively support static +linking, sometimes referred to as a @emph{link kit}. + @item convention One of @code{:cdecl} (default) or @code{:stdcall} @@ -6193,17 +6324,19 @@ is then searched in @code{*darwin-framework-directories*}, and loaded when found. @item :or -Each remaining list element, itself a library designator, is loaded in +Each remaining list element, itself a @dfn{library designator}, is loaded in order, until one succeeds. @item :default The name is transformed according to the platform's naming convention -to shared libraries, and the resultant string is loaded as a library -designator. For example, on @sc{unix}, the name is suffixed with +to shared libraries, and the resultant string is loaded as a @dfn{library +designator}. For example, on @sc{unix}, the name is suffixed with @file{.so}. @end table @end enumerate +If the library is already loaded it will be reloaded. + If the load fails, signal a @code{load-foreign-library-error}. @strong{Please note:} For system libraries, you should not need to @@ -6369,8 +6502,8 @@ CFFI> (callback sum) @subheading Syntax @Macro{defcallback name-and-options return-type arguments &body body @res{} name} -name-and-options ::= name | (name &key convention) -arguments ::= (@{ (arg-name arg-type) @}*) +name-and-options ::= name | (name &key convention) @* +arguments ::= (@{ (arg-name arg-type) @}*) @* @subheading Arguments and Values @@ -6519,6 +6652,7 @@ necessary calls to the C compiler and resulting file management. * Groveller Syntax:: How grovel files should look like. * Groveller ASDF Integration:: ASDF components for grovel files. * Groveller Implementation Notes:: Implementation notes. +* Wrapper for Inline/Static Functions and Macros:: Wrapper @end menu @node Groveller Syntax, Groveller ASDF Integration, The Groveller, The Groveller @@ -6573,6 +6707,13 @@ constant will be a symbol of the same name interned in the current package. @end deffn +@deffn {Grovel Form} feature lisp-feature-name c-name &key feature-list + +Adds @var{lisp-feature-name} to the list @var{feature-list} if the @var{c-name} +string is known to the C preprocessor. @var{feature-list} defaults +to @code{cl:*features*}. +@end deffn + @deffn {Grovel Form} define name &optional value Defines an additional C preprocessor symbol, which is useful for @@ -6740,7 +6881,7 @@ written by @cffi{}-Grovel; if your specification file is @cffi{} definitions needed by the rest of your project. @xref{Groveller Syntax}. -@node Groveller Implementation Notes, , Groveller ASDF Integration, The Groveller +@node Groveller Implementation Notes, Wrapper for Inline/Static Functions and Macros, Groveller ASDF Integration, The Groveller @section Implementation Notes @cffi{}-Grovel will generate many files that not only architecture-specific, @@ -6768,6 +6909,89 @@ between the implementations running on a given system.} @c TODO: document the new wrapper stuff. +@node Wrapper for Inline/Static Functions and Macros, , Groveller Implementation Notes, The Groveller +@section Wrapper for Inline/Static Functions and Macros + +In a shared library, information in static/inlined functions and +macros are already removed during the compilation. Wrapper file +enables to write an uninlined function wrapping the call to them. + +A wrapper file compilation/loading proceeds as follows: +Unlike groveller which generates C code that emits lisp files +containing cffi definitions, it generates C code, compiles it as a +shared library, loads the library, generate the cffi definitions (as +lisp code) and then loads the lisp code. + +It has asdf integration similar to groveller. + +@lisp +(defsystem "example-software" + :defsystem-depends-on ("cffi-grovel") + :depends-on ("cffi") + :serial t + :components + ((:file "package") + (:cffi-grovel-file "example-grovelling") + (:cffi-wrapper-file "example-wrappers") ;; <<--- this part + (:file "example"))) +@end lisp + +@deffn {Wrapper Form} defwrapper name-and-options return-type &rest args +@end deffn + +@example +static inline int foo(int i) @{ + return 1+i; +@}; +#define bar(i) (1+(i)) +@end example + +@lisp +(in-package :mypackage) +(defwrapper ("foo" foo) :int + (i :int)) +(defwrapper ("bar" bar) :int + (i :int)) +@end lisp + +Other forms are similar to grovel files. + +@deffn {Wrapper Form} progn &rest forms + +Processes a list of forms. Useful for conditionalizing several +forms. For example: +@end deffn + +@lisp +#+freebsd +(progn + (constant (ev-enable "EV_ENABLE")) + (constant (ev-disable "EV_DISABLE"))) +@end lisp + +@deffn {Wrapper Form} include &rest files + +Include the specified files (specified as strings) in the generated C +source code. +@end deffn + +@deffn {Wrapper Form} in-package symbol + +Set the package to be used for the final Lisp output. +@end deffn + +@deffn {Wrapper Form} flags &rest flags + +Adds @var{cc-flags} to the command line arguments used for the C compiler +invocation. +@end deffn + +@deffn {Wrapper Form} proclaim &rest proclaimations +@end deffn +@deffn {Wrapper Form} declaim &rest declaimations +@end deffn + + @c =================================================================== @c CHAPTER: Static Linking @@ -6775,13 +6999,21 @@ between the implementations running on a given system.} @node Static Linking, Limitations, The Groveller, Top @chapter Static Linking -On recent enough versions of supported implementations (currently, -GNU CLISP 2.49, CMUCL 2015-11, and SBCL 1.2.17), and with a recent -enough ASDF (3.1.2 or later), you can create a statically linked -Lisp executable image that includes all the C extensions -(wrappers and any other objects output by @code{compile-op}) -as well as your Lisp code --- or a standalone application executable. -This makes it easier to deliver your code as a single file. +On recent enough versions of supported implementations (currently, GNU +CLISP 2.49 or later, CMUCL 2015-11 or later, and SBCL 1.2.17 or later, +except SBCL 2.0.4), and with a recent enough ASDF (3.1.2 or later), +you can create a statically linked Lisp executable image (or a +standalone application executable) that includes all the C extensions +defined via @ref{The Groveller}'s @code{:cffi-wrapper-file} ASDF +components (and any other such objects output by +@code{asdf:compile-op}), as well as those defined by @code{:c-file} or +@code{:o-file} ASDF components, and your Lisp code. This makes it +easier to deliver your code as a single file. + +Note that the resulting binary will typically still depend on any +shared libraries loaded via @xref{load-foreign-library} or +@xref{use-foreign-library} as well as core libraries such as +@code{libc}. To dump a statically linked executable image, use: diff --git a/cram_3rdparty/cffi/src/doc/cffi-sys-spec.texinfo b/cram_3rdparty/cffi/src/doc/cffi-sys-spec.texinfo index 14668d84b6..e3ebf5c422 100644 --- a/cram_3rdparty/cffi/src/doc/cffi-sys-spec.texinfo +++ b/cram_3rdparty/cffi/src/doc/cffi-sys-spec.texinfo @@ -270,6 +270,26 @@ function, as returned by @code{foreign-symbol-pointer}, rather than a string @var{name}. @end defmac +@defmac %foreign-funcall-varargs name (@{fixed-type arg@}*) @{vararg-type arg@}* &optional result-type @result{} object +@defmacx %foreign-funcall-varargs-pointer ptr (@{fixed-type arg@}*) @{vararg-type arg@}* &optional result-type @result{} object +Invoke a foreign variadic function called @var{name} in the foreign +source code. + +Each @var{fixed-type} and @var{vararg-type} is a foreign type +specifier, followed by @var{arg}, Lisp data to be converted to foreign +data of type @var{arg-type}. @var{result-type} is the foreign type of +the function's return value, and is assumed to be @code{:void} if not +supplied. + +@code{%foreign-funcall-pointer-varargs} takes a pointer @var{ptr} to +the variadic function, as returned by @code{foreign-symbol-pointer}, +rather than a string @var{name}. + +Both functions have default implementation which call +@code{%foreign-funcall} and @code{%foreign-funcall-pointer} +approprietly. +@end defmac + @heading Examples @lisp diff --git a/cram_3rdparty/cffi/src/doc/gendocs.sh b/cram_3rdparty/cffi/src/doc/gendocs.sh old mode 100644 new mode 100755 diff --git a/cram_3rdparty/cffi/src/grovel/asdf.lisp b/cram_3rdparty/cffi/src/grovel/asdf.lisp index c90885a9b1..11eddc67ea 100644 --- a/cram_3rdparty/cffi/src/grovel/asdf.lisp +++ b/cram_3rdparty/cffi/src/grovel/asdf.lisp @@ -33,11 +33,6 @@ (defclass cc-flags-mixin () ((cc-flags :initform nil :accessor cc-flags-of :initarg :cc-flags))) -(defmethod perform :around ((op compile-op) (file cc-flags-mixin)) - (let ((*cc-flags* (append (ensure-list (cc-flags-of file)) - *cc-flags*))) - (call-next-method))) - (defclass process-op (downward-operation) () (:documentation "This ASDF operation performs the steps necessary @@ -57,6 +52,11 @@ COMPILE-OP and LOAD-SOURCE-OP operations to the file generated by PROCESS-OP.")) +(defmethod perform :around ((op process-op) (file cc-flags-mixin)) + (let ((*cc-flags* (append (ensure-list (cc-flags-of file)) + *cc-flags*))) + (call-next-method))) + (defmethod input-files ((op process-op) (c process-op-input)) (list (component-pathname c))) diff --git a/cram_3rdparty/cffi/src/grovel/common.h b/cram_3rdparty/cffi/src/grovel/common.h index 895059ff99..a7703e43d4 100644 --- a/cram_3rdparty/cffi/src/grovel/common.h +++ b/cram_3rdparty/cffi/src/grovel/common.h @@ -3,6 +3,7 @@ #include #include #include +#include #ifndef offsetof #define offsetof(type, slot) ((long) ((char *) &(((type *) 0)->slot))) diff --git a/cram_3rdparty/cffi/src/grovel/grovel.lisp b/cram_3rdparty/cffi/src/grovel/grovel.lisp index 32081d3c7f..cdc05cdf88 100644 --- a/cram_3rdparty/cffi/src/grovel/grovel.lisp +++ b/cram_3rdparty/cffi/src/grovel/grovel.lisp @@ -141,7 +141,9 @@ int main(int argc, char**argv) { do (c-write out subform no-package)) (c-format out ")")) ((symbolp form) - (c-print-symbol out form no-package)))) + (c-print-symbol out form no-package)) + ((numberp form) + (c-format out "~A" form)))) ;;; Always NIL for now, add {ENABLE,DISABLE}-AUTO-EXPORT grovel forms ;;; later, if necessary. @@ -202,7 +204,10 @@ int main(int argc, char**argv) { (flag (warn "Groveler clause FLAG is deprecated, use CC-FLAGS instead."))) (case (form-kind f) (in-package - (setf *package* (find-package (second f))) + (setf *package* + (or (find-package (second f)) + (error "The name ~S does not designate any package." + (second f)))) (push f forms)) (progn ;; flatten progn forms @@ -354,6 +359,16 @@ int main(int argc, char**argv) { (dotimes (i (length c-names)) (format out "~&#endif~%"))) +(define-grovel-syntax feature (lisp-feature-name c-name &key (feature-list 'cl:*features*)) + (c-section-header out "feature" lisp-feature-name) + (format out "~&#ifdef ~A~%" c-name) + (c-format out "(cl:pushnew '") + (c-print-symbol out lisp-feature-name t) + (c-format out " ") + (c-print-symbol out feature-list) + (c-format out ")~%") + (format out "~&#endif~%")) + (define-grovel-syntax cunion (union-lisp-name union-c-name &rest slots) (let ((documentation (when (stringp (car slots)) (pop slots)))) (c-section-header out "cunion" union-lisp-name) diff --git a/cram_3rdparty/cffi/src/libffi/libffi-types.lisp b/cram_3rdparty/cffi/src/libffi/libffi-types.lisp index 939a87b4f5..7fe9e0db3e 100644 --- a/cram_3rdparty/cffi/src/libffi/libffi-types.lisp +++ b/cram_3rdparty/cffi/src/libffi/libffi-types.lisp @@ -2,7 +2,7 @@ ;;; ;;; libffi-types.lisp -- CFFI-Grovel definitions for libffi ;;; -;;; Copyright (C) 2009, 2010, 2011 Liam M. Healy +;;; Copyright (C) 2009, 2010, 2011, 2017 Liam M. Healy ;;; ;;; Permission is hereby granted, free of charge, to any person ;;; obtaining a copy of this software and associated documentation @@ -38,6 +38,9 @@ #+openbsd (cc-flags "-I/usr/local/include") +#+freebsd +(cc-flags "-I/usr/local/include") + (pkg-config-cflags "libffi" :optional t) #+darwin @@ -68,7 +71,9 @@ #-(or freebsd windows) (cenum abi ((:default-abi "FFI_DEFAULT_ABI")) + #-x86-64 ((:sysv "FFI_SYSV")) + #+x86-64 ((:unix64 "FFI_UNIX64"))) (ctype ffi-abi "ffi_abi") diff --git a/cram_3rdparty/cffi/src/libffi/libffi.lisp b/cram_3rdparty/cffi/src/libffi/libffi.lisp index 0320825280..0dfcba97e6 100644 --- a/cram_3rdparty/cffi/src/libffi/libffi.lisp +++ b/cram_3rdparty/cffi/src/libffi/libffi.lisp @@ -31,8 +31,8 @@ (:darwin (:or "libffi.dylib" "libffi32.dylib" "/usr/lib/libffi.dylib")) (:solaris (:or "/usr/lib/amd64/libffi.so" "/usr/lib/libffi.so")) (:openbsd "libffi.so") - (:unix (:or "libffi.so.6" "libffi32.so.6" "libffi.so.5" "libffi32.so.5")) - (:windows (:or "libffi-6.dll" "libffi-5.dll" "libffi.dll")) + (:unix (:or "libffi.so.8" "libffi32.so.8" "libffi.so.7" "libffi32.so.7" "libffi.so.6" "libffi32.so.6" "libffi.so.5" "libffi32.so.5")) + (:windows (:or "libffi-8.dll" "libffi-7.dll" "libffi-6.dll" "libffi-5.dll" "libffi.dll")) (t (:default "libffi"))) (load-foreign-library 'libffi) diff --git a/cram_3rdparty/cffi/src/scripts/release.lisp b/cram_3rdparty/cffi/src/scripts/release.lisp old mode 100644 new mode 100755 diff --git a/cram_3rdparty/cffi/src/src/c2ffi/asdf.lisp b/cram_3rdparty/cffi/src/src/c2ffi/asdf.lisp index 03fe84b92b..7891978005 100644 --- a/cram_3rdparty/cffi/src/src/c2ffi/asdf.lisp +++ b/cram_3rdparty/cffi/src/src/c2ffi/asdf.lisp @@ -73,39 +73,51 @@ (:default-initargs :type nil) (:documentation - "The input of this ASDF component is a C header file, plus configuration for the -binding generation process. This header file will define the initial scope of -the generation process, which can further be filtered by other configuration + "The input of this ASDF component is a C header file and the configuration for +the binding generation process. This header file will define the initial scope of +the generation process, which can be further filtered by other configuration parameters. -An external program based on clang/llvm called 'c2ffi' is then invoked with -this header file to generate a json file for various platforms. The generation -of the underlying platform's json file must succeed to continue, but the -generation for the other platforms is allowed to fail -\(see ENSURE-SPEC-FILE-EXISTS). +A clang/llvm based external tool called 'c2ffi' is used to process this header +file and generate a json spec file for each supported architecture triplet. Normally +these .spec files are only (re)generated by the author of the lib and are checked into +the corresponding source repository. It needs to be done manually by invoking the +following command: -It's advisable to deliver these json files with the project, so that users -don't need to have c2ffi installed. +(cffi/c2ffi:generate-spec :your-system) -Once/if the json file is available for the underlying platform, then the json -file is used to generate a lisp file with CFFI definitions (see -PROCESS-C2FFI-SPEC-FILE). This file will then be compiled as any other lisp -file, except that it's will be stored in the fasl cache.")) +which is a shorthand for: + +(asdf:operate 'cffi/c2ffi::generate-spec-op :your-system) + +The generation of the underlying platform's json file must succeed, but the +generation for the other arch's is allowed to fail +\(see ENSURE-SPEC-FILE-IS-UP-TO-DATE for details). + +During the normal build process the json file is used as the input to generate +a lisp file containing the CFFI definitions (see PROCESS-C2FFI-SPEC-FILE). +This file will be placed next to the .spec file, and will be compiled as any +other lisp file. This process requires loading the ASDF system called +\"cffi/c2ffi-generator\" that has more dependencies than CFFI itself. If you +want to avoid those extra dependencies in your project, then you can check in +these generated lisp files into your source repository, but keep in mind that +you'll need to manually force their regeneration if CFFI/C2FFI itself gets +updated (by e.g. deleting them from the filesystem) .")) (defun input-file (operation component) (let ((files (input-files operation component))) (assert (length=n-p files 1)) (first files))) -(defclass generate-spec-op (downward-operation) - ()) +(defclass generate-spec-op (selfward-operation) + ((selfward-operation :initform 'prepare-op))) + +(defun generate-spec (system &key force) + (asdf:operate 'generate-spec-op system :force force)) (defmethod input-files ((op generate-spec-op) (c c2ffi-file)) (list (component-pathname c))) -(defmethod component-depends-on ((op generate-spec-op) (c c2ffi-file)) - `((prepare-op ,c) ,@(call-next-method))) - (defmethod output-files ((op generate-spec-op) (c c2ffi-file)) (let* ((input-file (input-file op c)) (spec-file (spec-path input-file))) @@ -114,6 +126,9 @@ file, except that it's will be stored in the fasl cache.")) ;; Tell ASDF not to apply output translation. t))) +(defmethod perform ((op generate-spec-op) (c asdf:component)) + (values)) + (defmethod perform ((op generate-spec-op) (c c2ffi-file)) (let ((input-file (input-file op c)) (*c2ffi-executable* (if (slot-boundp c 'c2ffi-executable) @@ -125,15 +140,25 @@ file, except that it's will be stored in the fasl cache.")) ;; NOTE: we don't call OUTPUT-FILE here, which may be a violation ;; of the ASDF contract, that promises that OUTPUT-FILE can be ;; customized by users. - (ensure-spec-file-exists input-file - :exclude-archs (c2ffi-file/exclude-archs c) - :sys-include-paths (c2ffi-file/sys-include-paths c)))) + (ensure-spec-file-is-up-to-date + input-file + :exclude-archs (c2ffi-file/exclude-archs c) + :sys-include-paths (c2ffi-file/sys-include-paths c)))) -(defclass generate-lisp-op (downward-operation) - ()) +(defclass generate-lisp-op (selfward-operation) + ((selfward-operation :initform '()))) ; we will specify it in our own COMPONENT-DEPENDS-ON (defmethod component-depends-on ((op generate-lisp-op) (c c2ffi-file)) - `((generate-spec-op ,c) ,@(call-next-method))) + `((load-op ,(find-system "cffi/c2ffi-generator")) + ;; Regenerating the spec file is a lot of headache, so we ignore + ;; the file modification times, and only communicate the + ;; dependency to ASDF if the spec file is missing. + ,@(let ((spec-file (input-file op c))) ; TODO is it legal to call ASDF:INPUT-FILES here? + (when (or (not (probe-file spec-file)) + (zerop (with-input-from-file (s spec-file) + (file-length s)))) + `((generate-spec-op ,c)))) + ,@(call-next-method))) (defmethod component-depends-on ((op compile-op) (c c2ffi-file)) `((generate-lisp-op ,c) ,@(call-next-method))) @@ -161,8 +186,6 @@ file, except that it's will be stored in the fasl cache.")) (generated-lisp-file (output-file op c))) (with-staging-pathname (tmp-output generated-lisp-file) (format *debug-io* "~&; CFFI/C2FFI is generating the file ~S~%" generated-lisp-file) - (unless (component-loaded-p :cffi/c2ffi-generator) - (load-system :cffi/c2ffi-generator)) (apply 'process-c2ffi-spec-file spec-file (c2ffi-file/package c) :output tmp-output diff --git a/cram_3rdparty/cffi/src/src/c2ffi/c2ffi.lisp b/cram_3rdparty/cffi/src/src/c2ffi/c2ffi.lisp index 531d11b1b4..95dd0c376f 100644 --- a/cram_3rdparty/cffi/src/src/c2ffi/c2ffi.lisp +++ b/cram_3rdparty/cffi/src/src/c2ffi/c2ffi.lisp @@ -57,7 +57,7 @@ (defun local-arch () (strcat (local-cpu) (local-vendor) (local-os) (local-environment))) -(defparameter *known-archs* +(defparameter *target-archs* '("i686-pc-linux-gnu" "x86_64-pc-linux-gnu" "i686-pc-windows-msvc" @@ -68,7 +68,7 @@ "x86_64-unknown-freebsd")) (defvar *c2ffi-executable* "c2ffi") - +(defvar *c2ffi-extra-arguments* (list)) (defvar *trace-c2ffi* nil) (defun c2ffi-executable-available? () @@ -86,11 +86,13 @@ :error-output error-output :ignore-error-status ignore-error-status)))) -(defun generate-spec-with-c2ffi (input-header-file output-spec-path +(defun generate-spec-using-c2ffi (input-header-file output-spec-path &key arch sys-include-paths ignore-error-status) "Run c2ffi on `INPUT-HEADER-FILE`, outputting to `OUTPUT-FILE` and `MACRO-OUTPUT-FILE`, optionally specifying a target triple `ARCH`." + (format *debug-io* "; cffi/c2ffi is generating ~S~%" output-spec-path) (uiop:with-temporary-file (:pathname tmp-macro-file + :type "h" :keep *trace-c2ffi*) nil ; workaround for an UIOP bug; delme eventually (attila, 2016-01-27). :close-stream @@ -105,10 +107,13 @@ ;; get hold of their value. This is a kludge and eventually we could/should ;; support generating cffi-grovel files, and in grovel mode not rely ;; on this kludge anymore. - (when (run-program* *c2ffi-executable* (list* (namestring input-header-file) - "--driver" "null" - "--macro-file" (namestring tmp-macro-file) - (append arch sys-include-paths)) + (when (run-program* *c2ffi-executable* (append + (list "--driver" "null" + "--macro-file" (namestring tmp-macro-file)) + arch + sys-include-paths + *c2ffi-extra-arguments* + (list (namestring input-header-file))) :output *standard-output* :ignore-error-status ignore-error-status) ;; Write a tmp header file that #include's the original input file and @@ -116,14 +121,18 @@ ;; final, second pass. (uiop:with-temporary-file (:stream tmp-include-file-stream :pathname tmp-include-file + :type "h" :keep *trace-c2ffi*) (format tmp-include-file-stream "#include \"~A\"~%" input-header-file) (format tmp-include-file-stream "#include \"~A\"~%" tmp-macro-file) :close-stream ;; Invoke c2ffi again to generate the final output. - (run-program* *c2ffi-executable* (list* (namestring tmp-include-file) - "--output" (namestring output-spec-path) - (append arch sys-include-paths)) + (run-program* *c2ffi-executable* (append + (list "--output" (namestring output-spec-path)) + arch + sys-include-paths + *c2ffi-extra-arguments* + (list (namestring tmp-include-file))) :output *standard-output* :ignore-error-status ignore-error-status)))))) @@ -146,32 +155,51 @@ (when errorp (error "c2ffi spec file not found for base name ~S" base-name))))) -(defun ensure-spec-file-exists (header-file-path &key exclude-archs sys-include-paths version) - (multiple-value-bind - (h-name m-name) - (find-local-spec header-file-path nil) - (if h-name - (values h-name m-name) - (let ((local-arch (local-arch))) - (unless (c2ffi-executable-available?) - (error "No spec found for ~S on arch '~A' and c2ffi not found" - header-file-path local-arch)) - (generate-spec-with-c2ffi header-file-path - (spec-path header-file-path - :arch local-arch - :version version) - :arch local-arch - :sys-include-paths sys-include-paths) - ;; also run c2ffi for other architectures, but tolerate failure - (dolist (arch *known-archs*) - (unless (or (string= local-arch arch) - (member arch exclude-archs :test #'string=)) - (unless (generate-spec-with-c2ffi header-file-path - (spec-path header-file-path - :arch arch - :version version) - :arch arch - :sys-include-paths sys-include-paths - :ignore-error-status t) - (warn "Failed to generate spec for other arch: ~S" arch)))) - (find-local-spec header-file-path))))) +(defun ensure-spec-file-is-up-to-date (header-file-path + &key exclude-archs sys-include-paths version) + (let ((spec-path (find-local-spec header-file-path nil))) + (flet ((regenerate-spec-file () + (let ((local-arch (local-arch))) + (unless (c2ffi-executable-available?) + (error "No spec found for ~S on arch '~A' and the c2ffi executable was not found" + header-file-path local-arch)) + (generate-spec-using-c2ffi header-file-path + (spec-path header-file-path + :arch local-arch + :version version) + :arch local-arch + :sys-include-paths sys-include-paths) + ;; Try to run c2ffi for other architectures, but tolerate failure + (dolist (arch *target-archs*) + (unless (or (string= local-arch arch) + (member arch exclude-archs :test #'string=)) + (unless (generate-spec-using-c2ffi header-file-path + (spec-path header-file-path + :arch arch + :version version) + :arch arch + :sys-include-paths sys-include-paths + :ignore-error-status t) + (warn "Failed to generate spec for other arch: ~S" arch)))) + (find-local-spec header-file-path)))) + (if (and spec-path + (not (zerop (with-input-from-file (s spec-path) + (file-length s)))) + (uiop:timestamp< (file-write-date header-file-path) + (file-write-date spec-path))) + spec-path ; it's up to date, just return it as is + (restart-case + (regenerate-spec-file) + (touch-old-copy () + :report (lambda (stream) + (format stream "Update the modification time of the out-of-date copy ~S" spec-path)) + ;; Make it only be visible when the spec file exists (but it's out of date) + :test (lambda (condition) + (declare (ignore condition)) + (not (null spec-path))) + ;; Update the last modification time. Yes, it's convoluted and wasteful, + ;; but I can't see any other way. + (with-staging-pathname (tmp-file spec-path) + (copy-file spec-path tmp-file)) + ;; The return value of RESTART-CASE + spec-path)))))) diff --git a/cram_3rdparty/cffi/src/src/c2ffi/generator.lisp b/cram_3rdparty/cffi/src/src/c2ffi/generator.lisp index 5fe2d6cf46..9bc1c88d4d 100644 --- a/cram_3rdparty/cffi/src/src/c2ffi/generator.lisp +++ b/cram_3rdparty/cffi/src/src/c2ffi/generator.lisp @@ -267,13 +267,14 @@ (defun find-cffi-type-or-die (type-name &optional (namespace :default)) (when (eq namespace :enum) ;; TODO FIXME this should be cleaned up in CFFI. more about namespace confusion at: - ;; https://bugs.launchpad.net/cffi/+bug/1527947 + ;; https://github.com/cffi/cffi/issues/266 (setf namespace :default)) (cffi::find-type-parser type-name namespace)) -(define-constant +name-kinds+ '(:struct :union :function :variable :type - :constant :field :argument :enum :member) - :test 'equal) +(eval-when (:compile-toplevel :load-toplevel :execute) + (define-constant +name-kinds+ '(:struct :union :function :variable :type + :constant :field :argument :enum :member) + :test 'equal)) (deftype ffi-name-kind () '#.(list* 'member +name-kinds+)) @@ -293,6 +294,9 @@ (intern name)))) (when (and (not anonymous) (boundp '*generated-names*)) + ;; TODO FIXME this function also gets called for e.g. argument types of a function. and + ;; if the function ends up *not* getting emitted, e.g. because of a missing type, then + ;; we wrongly record here the missing type in the *generated-names* registry. (setf (gethash name (cdr (assoc kind *generated-names*))) cffi-name)) cffi-name)) @@ -469,6 +473,10 @@ (t (assert (not (starts-with #\: tag))) (let ((cffi-name (json-name-to-cffi-name tag :type))) + ;; TODO FIXME json-name-to-cffi-name collects the mentioned + ;; types to later emit +TYPE-NAMES+, but if this next + ;; find-cffi-type-or-die dies then the entire function is + ;; skipped. (find-cffi-type-or-die cffi-name) cffi-name))))) (assert cffi-type () "Failed to map ~S to a cffi type" json-entry) @@ -527,9 +535,9 @@ target package." (@ include-definitions) (@ exclude-definitions)) (with-standard-io-syntax - (with-input-from-file (in c2ffi-spec-file :external-format (asdf/driver:encoding-external-format :utf-8)) + (with-input-from-file (in c2ffi-spec-file :external-format (uiop:encoding-external-format :utf-8)) (with-output-to-file (*c2ffi-output-stream* output :if-exists :supersede - :external-format (asdf/driver:encoding-external-format output-encoding)) + :external-format (uiop:encoding-external-format output-encoding)) (let* ((*package* (or (find-package package-name) (make-package package-name))) ;; Make sure we use an uninterned symbol, so that it's neutral to READTABLE-CASE. @@ -540,7 +548,9 @@ target package." ;; the previous state. This avoids redefinition warning ;; when the generated file gets compiled and loaded ;; later. - (cffi::*type-parsers* (copy-hash-table cffi::*type-parsers*)) + (cffi::*default-type-parsers* (copy-hash-table cffi::*default-type-parsers*)) + (cffi::*struct-type-parsers* (copy-hash-table cffi::*struct-type-parsers*)) + (cffi::*union-type-parsers* (copy-hash-table cffi::*union-type-parsers*)) (*anon-name-counter* 0) (*anon-entities* (make-hash-table)) (*generated-names* (mapcar (lambda (key) @@ -570,7 +580,7 @@ target package." (output/code `(cffi:define-foreign-library ,foreign-library-name ,@foreign-library-spec)) ;; TODO: Unconditionally emitting a USE-FOREIGN-LIBRARY may not be smart. - ;; For details see: https://bugs.launchpad.net/cffi/+bug/1593635 + ;; For details see: https://github.com/cffi/cffi/issues/272 (output/code `(cffi:use-foreign-library ,foreign-library-name))) (etypecase prelude (null) diff --git a/cram_3rdparty/cffi/src/src/c2ffi/package.lisp b/cram_3rdparty/cffi/src/src/c2ffi/package.lisp index e1b6de34f1..ff690b4dbf 100644 --- a/cram_3rdparty/cffi/src/src/c2ffi/package.lisp +++ b/cram_3rdparty/cffi/src/src/c2ffi/package.lisp @@ -29,9 +29,11 @@ #:common-lisp) (:import-from :asdf #:cl-source-file + #:find-system #:output-file #:output-files #:input-files + #:operation-done-p #:perform #:compile-op #:load-op @@ -39,14 +41,17 @@ #:prepare-op #:component-pathname #:component-depends-on + #:operation #:downward-operation + #:selfward-operation #:load-system #:component-loaded-p) (:export #:c2ffi-file - #:default-ffi-name-transformer - #:default-ffi-type-transformer - #:change-case-to-readtable-case #:camelcased? #:camelcase-to-dash-separated + #:change-case-to-readtable-case + #:default-ffi-name-transformer + #:default-ffi-type-transformer + #:generate-spec #:maybe-camelcase-to-dash-separated)) diff --git a/cram_3rdparty/cffi/src/src/cffi-abcl.lisp b/cram_3rdparty/cffi/src/src/cffi-abcl.lisp index b999915faa..6d9362c20b 100644 --- a/cram_3rdparty/cffi/src/src/cffi-abcl.lisp +++ b/cram_3rdparty/cffi/src/src/cffi-abcl.lisp @@ -69,8 +69,6 @@ #:native-namestring #:%mem-ref #:%mem-set - ;; #:make-shareable-byte-vector - ;; #:with-pointer-to-vector-data #:%foreign-symbol-pointer #:%defcallback #:%callback @@ -291,10 +289,55 @@ supplied, it will be bound to SIZE during BODY." (:pointer "getPointer") ((:short :unsigned-short) "getShort"))) +;;; HACK for now: keep track of all the pointers to malloc()'d memory +;;; hashed by the shareable byte vectors we allocate. +(defvar *static-vector-pointer* + (make-hash-table :weakness :value)) + +;;; available in abcl-1.7.0 +;;; presence of :nio-buffer keyword to CL:MAKE-ARRAY +#+nio +(defun make-shareable-vector (length &key (element-type '(unsigned-byte 8))) + "Use memory on the heap for storing a vector of LENGTH with ELEMENT-TYPE + +Returns the allocated vector as the first value, and the pointer to +the heap memory as the second. + +Only works for 8, 16, 32 bit bytes. +" + (let* ((type + (first element-type)) + (bits-per-byte + (second element-type)) + (bytes-per-element ;; ehh, not going to work well for element type not of size 8, 16, or 32 + (ceiling bits-per-byte 8))) + (unless (subtypep element-type + '(or (unsigned-byte 8) (unsigned-byte 16) (unsigned-byte 32))) + (signal 'type-error :datum element-type + :expected-type '(or + (unsigned-byte 8) + (unsigned-byte 16) + (unsigned-byte 32)))) + (let* ((bytes + (* length bytes-per-element)) + (heap-pointer + (jss:new "com.sun.jna.Memory" bytes)) + (bytebuffer + (#"getByteBuffer" heap-pointer 0 bytes)) + (static-vector + (make-array length :element-type element-type :nio-buffer bytebuffer))) + (setf (gethash static-vector *static-vector-pointer*) + heap-pointer) + (values + static-vector + heap-pointer)))) + (defun make-shareable-byte-vector (size) "Create a Lisp vector of SIZE bytes can passed to WITH-POINTER-TO-VECTOR-DATA." - (make-array size :element-type '(unsigned-byte 8))) + (if (find :nio *features*) + (make-shareable-vector size :element-type '(unsigned-byte 8)) ;; abcl-1.6.2-dev, upcoming abcl-1.7.0 + (make-array size :element-type '(unsigned-byte 8)))) (let ((method (jmethod "com.sun.jna.Pointer" (jna-setter :char) "long" (jna-setter-arg-type :char)))) @@ -314,13 +357,17 @@ WITH-POINTER-TO-VECTOR-DATA." (defmacro with-pointer-to-vector-data ((ptr-var vector) &body body) "Bind PTR-VAR to a foreign pointer to the data in VECTOR." - (let ((vector-sym (gensym "VECTOR"))) - `(let ((,vector-sym ,vector)) - (with-foreign-pointer (,ptr-var (length ,vector-sym)) - (copy-to-foreign-vector ,vector-sym ,ptr-var) - (unwind-protect - (progn ,@body) - (copy-from-foreign-vector ,vector-sym ,ptr-var)))))) + (let ((vector-sym (gensym "VECTOR")) + (heap-pointer (gethash vector *static-vector-pointer*))) + (if heap-pointer + `(let ((,ptr-var ,heap-pointer)) + (progn ,@body)) + `(let ((,vector-sym ,vector)) + (with-foreign-pointer (,ptr-var (length ,vector-sym)) + (copy-to-foreign-vector ,vector-sym ,ptr-var) + (unwind-protect + (progn ,@body) + (copy-from-foreign-vector ,vector-sym ,ptr-var))))))) ;;;# Dereferencing @@ -414,14 +461,18 @@ WITH-POINTER-TO-VECTOR-DATA." (jcall-raw (jmethod "com.sun.jna.NativeLibrary" "getFunction" "java.lang.String") library name)))) - (if (eq library :default) - (or (find-it - (jstatic "getProcess" "com.sun.jna.NativeLibrary")) - ;; The above should find it, but I'm not exactly sure, so - ;; let's still do it manually just in case. - (loop for lib being the hash-values of *loaded-libraries* - thereis (find-it lib))) - (find-it (gethash library *loaded-libraries*))))) + (or (if (eq library :default) + (or (find-it + (jstatic "getProcess" "com.sun.jna.NativeLibrary")) + ;; The above should find it, but I'm not exactly sure, so + ;; let's still do it manually just in case. + (loop for lib being the hash-values of *loaded-libraries* + thereis (find-it lib))) + (find-it (or (gethash library *loaded-libraries*) + (error "Foreign library ~S is not loaded" library)))) + (error "Undefined foreign function ~S~@[ in library ~S~]" + name + (if (eq library :default) nil library))))) (defun convert-calling-convention (convention) (ecase convention @@ -493,7 +544,7 @@ Used with jna-4.0.0 or later.") else do (setf return-type type) finally (return (values types fargs return-type))))) -(defmacro %foreign-funcall (name args &key library convention) +(defmacro %foreign-funcall (name args &key (library :default) convention) (declare (ignore convention)) (multiple-value-bind (types fargs rettype) (foreign-funcall-type-and-args args) diff --git a/cram_3rdparty/cffi/src/src/cffi-ecl.lisp b/cram_3rdparty/cffi/src/src/cffi-ecl.lisp index 9c007a605e..0b595efb91 100644 --- a/cram_3rdparty/cffi/src/src/cffi-ecl.lisp +++ b/cram_3rdparty/cffi/src/src/cffi-ecl.lisp @@ -48,6 +48,8 @@ #:%mem-set #:%foreign-funcall #:%foreign-funcall-pointer + #:%foreign-funcall-varargs + #:%foreign-funcall-pointer-varargs #:%foreign-type-alignment #:%foreign-type-size #:%load-foreign-library @@ -269,39 +271,34 @@ WITH-POINTER-TO-VECTOR-DATA." (defconstant +ecl-inline-codes+ "#0,#1,#2,#3,#4,#5,#6,#7,#8,#9,#a,#b,#c,#d,#e,#f,#g,#h,#i,#j,#k,#l,#m,#n,#o,#p,#q,#r,#s,#t,#u,#v,#w,#x,#y,#z") -(defun c-inline-function-pointer-call (pointer types values return-type) - (cond ((not (stringp pointer)) - `(ffi:c-inline - ,(list* pointer values) - ,(list* :pointer-void types) ,return-type - ,(with-output-to-string (s) - (let ((types (mapcar #'ecl-type->c-type types))) - ;; On AMD64, the following code only works with the extra - ;; argument ",...". If this is not present, functions - ;; like sprintf do not work - (format s "((~A (*)(~@[~{~A,~}...~]))(#0))(~A)" - (ecl-type->c-type return-type) types - (subseq +ecl-inline-codes+ 3 - (max 3 (+ 2 (* (length values) 3))))))) - :one-liner t :side-effects t)) - ((eq *cffi-ecl-method* :c/c++) - `(ffi:c-inline ,values ,types ,return-type - ,(with-output-to-string (s) - (let ((types (mapcar #'ecl-type->c-type types))) - ;; On AMD64, the following code only works with the extra - ;; argument ",...". If this is not present, functions - ;; like sprintf do not work - (format s "{ extern ~A ~A(~@[~{~A~^, ~}~]); ~A~A(~A); }" - (ecl-type->c-type return-type) pointer types - (if (eq return-type :void) "" "@(return) = ") - pointer - (subseq +ecl-inline-codes+ 0 - (max 0 (1- (* (length values) 3))))))) - :one-liner nil :side-effects t)) - (t - (c-inline-function-pointer-call - `(%foreign-symbol-pointer ,pointer nil) - types values return-type)))) +(defun c-inline-function-call (thing fixed-types types values return-type dynamic-call variadic) + (when dynamic-call + (when (stringp thing) + (setf thing `(%foreign-symbol-pointer ,thing nil))) + (push thing values) + (push :pointer-void types)) + (let* ((decl-args + (format nil "~{~A~^, ~}~A" + (mapcar #'ecl-type->c-type fixed-types) (if (null variadic) "" ", ..."))) + (call-args + (if dynamic-call + ;; #0 is already used in a cast (it is a function pointer) + (subseq +ecl-inline-codes+ 3 (max 3 (1- (* (length values) 3)))) + ;; #0 is not used, so we start from the beginning + (subseq +ecl-inline-codes+ 0 (max 0 (1- (* (length values) 3)))))) + (clines + (if dynamic-call + nil + (format nil "extern ~A ~A(~A);" + (ecl-type->c-type return-type) thing decl-args))) + (call-code + (if dynamic-call + (format nil "((~A (*)(~A))(#0))(~A)" + (ecl-type->c-type return-type) decl-args call-args) + (format nil "~A(~A)" thing call-args)))) + `(progn + (ffi:clines ,@(ensure-list clines)) + (ffi:c-inline ,values ,types ,return-type ,call-code :one-liner t :side-effects t)))) (defun dffi-function-pointer-call (pointer types values return-type) (when (stringp pointer) @@ -312,25 +309,6 @@ WITH-POINTER-TO-VECTOR-DATA." #+dffi `(si::call-cfun ,pointer ,return-type (list ,@types) (list ,@values))) -#.(cl:when (>= ext:+ecl-version-number+ 100402) - (cl:pushnew :ecl-with-backend cl:*features*) - cl:nil) - -(defun produce-function-pointer-call (pointer types values return-type) - #-ecl-with-backend - (progn - (if (eq *cffi-ecl-method* :dffi) - (dffi-function-pointer-call pointer types values return-type) - (c-inline-function-pointer-call pointer types values return-type))) - #+ecl-with-backend - `(ext:with-backend - :bytecodes - ,(dffi-function-pointer-call pointer types values return-type) - :c/c++ - (if (eq *cffi-ecl-method* :dffi) - ,(dffi-function-pointer-call pointer types values return-type) - ,(c-inline-function-pointer-call pointer types values return-type)))) - (defun foreign-funcall-parse-args (args) "Return three values, lists of arg types, values, and result type." (let ((return-type :void)) @@ -345,14 +323,60 @@ WITH-POINTER-TO-VECTOR-DATA." (declare (ignore library convention)) (multiple-value-bind (types values return-type) (foreign-funcall-parse-args args) - (produce-function-pointer-call name types values return-type))) - -(defmacro %foreign-funcall-pointer (ptr args &key convention) + `(ext:with-backend + :bytecodes + ,(dffi-function-pointer-call name types values return-type) + :c/c++ + ,(ecase *cffi-ecl-method* + (:dffi (dffi-function-pointer-call name types values return-type)) + (:dlopen (c-inline-function-call name types types values return-type t nil)) + (:c/c++ (c-inline-function-call name types types values return-type nil nil)))))) + +(defmacro %foreign-funcall-pointer (pointer args &key convention) "Funcall a pointer to a foreign function." (declare (ignore convention)) (multiple-value-bind (types values return-type) (foreign-funcall-parse-args args) - (produce-function-pointer-call ptr types values return-type))) + `(ext:with-backend + :bytecodes + ,(dffi-function-pointer-call pointer types values return-type) + :c/c++ + ,(if (eq *cffi-ecl-method* :dffi) + (dffi-function-pointer-call pointer types values return-type) + (c-inline-function-call pointer types types values return-type t nil))))) + +(defmacro %foreign-funcall-varargs (name args varargs &key library convention) + (declare (ignore library convention)) + (multiple-value-bind (fixed-types fixed-values) + (foreign-funcall-parse-args args) + (multiple-value-bind (varargs-types varargs-values return-type) + (foreign-funcall-parse-args varargs) + (let ((all-types (append fixed-types varargs-types)) + (values (append fixed-values varargs-values))) + `(ext:with-backend + :bytecodes + ,(dffi-function-pointer-call name all-types values return-type) + :c/c++ + ,(ecase *cffi-ecl-method* + (:dffi (dffi-function-pointer-call name all-types values return-type)) + (:dlopen (c-inline-function-call name fixed-types all-types values return-type t t)) + (:c/c++ (c-inline-function-call name fixed-types all-types values return-type nil t)))))))) + +(defmacro %foreign-funcall-pointer-varargs (pointer args varargs &key convention) + (declare (ignore convention)) + (multiple-value-bind (fixed-types fixed-values) + (foreign-funcall-parse-args args) + (multiple-value-bind (varargs-types varargs-values return-type) + (foreign-funcall-parse-args varargs) + (let ((all-types (append fixed-types varargs-types)) + (values (append fixed-values varargs-values))) + `(ext:with-backend + :bytecodes + ,(dffi-function-pointer-call pointer all-types values return-type) + :c/c++ + ,(if (eq *cffi-ecl-method* :dffi) + (dffi-function-pointer-call pointer all-types values return-type) + (c-inline-function-call pointer fixed-types all-types values return-type t t))))))) ;;;# Foreign Libraries diff --git a/cram_3rdparty/cffi/src/src/cffi-sbcl.lisp b/cram_3rdparty/cffi/src/src/cffi-sbcl.lisp index 63cdce54bd..ef939ad0b2 100644 --- a/cram_3rdparty/cffi/src/src/cffi-sbcl.lisp +++ b/cram_3rdparty/cffi/src/src/cffi-sbcl.lisp @@ -46,6 +46,8 @@ #:with-foreign-pointer #:%foreign-funcall #:%foreign-funcall-pointer + #:%foreign-funcall-varargs + #:%foreign-funcall-pointer-varargs #:%foreign-type-alignment #:%foreign-type-size #:%load-foreign-library @@ -167,7 +169,7 @@ SIZE-VAR is supplied, it will be bound to SIZE during BODY." (declaim (inline make-shareable-byte-vector)) (defun make-shareable-byte-vector (size) - "Create a Lisp vector of SIZE bytes can passed to + "Create a Lisp vector of SIZE bytes that can be passed to WITH-POINTER-TO-VECTOR-DATA." ; (declare (type sb-int:index size)) (make-array size :element-type '(unsigned-byte 8))) @@ -286,12 +288,21 @@ WITH-POINTER-TO-VECTOR-DATA." (defun foreign-funcall-type-and-args (args) "Return an SB-ALIEN function type for ARGS." - (let ((return-type 'void)) - (loop for (type arg) on args by #'cddr - if arg collect (convert-foreign-type type) into types - and collect arg into fargs - else do (setf return-type (convert-foreign-type type)) - finally (return (values types fargs return-type))))) + (let ((return-type 'void) + types + fargs) + (loop while args + do (let ((type (pop args))) + (cond ((eq type '&optional) + (push type types)) + ((not args) + (setf return-type (convert-foreign-type type))) + (t + (push (convert-foreign-type type) types) + (push (pop args) fargs))))) + (values (nreverse types) + (nreverse fargs) + return-type))) (defmacro %%foreign-funcall (name types fargs rettype) "Internal guts of %FOREIGN-FUNCALL." @@ -315,6 +326,30 @@ WITH-POINTER-TO-VECTOR-DATA." `(with-alien ((,function (* (function ,rettype ,@types)) ,ptr)) (alien-funcall ,function ,@fargs))))) +(defmacro %foreign-funcall-varargs (name fixed-args varargs + &rest args &key convention library) + (declare (ignore convention library)) + `(%foreign-funcall ,name ,(append fixed-args (and varargs + ;; All SBCL platforms would understand this + ;; but this is the only one where it's required. + ;; Omitting elsewhere makes it work on older + ;; versions of SBCL. + (append #+(and darwin arm64) + '(&optional) + varargs))) + ,@args)) + +(defmacro %foreign-funcall-pointer-varargs (pointer fixed-args varargs + &rest args &key convention) + (declare (ignore convention)) + `(%foreign-funcall-pointer ,pointer ,(append fixed-args + (and varargs + (append #+(and darwin arm64) + '(&optional) + varargs))) + ,@args)) + + ;;;# Callbacks ;;; The *CALLBACKS* hash table contains a direct mapping of CFFI @@ -329,10 +364,7 @@ WITH-POINTER-TO-VECTOR-DATA." `(setf (gethash ',name *callbacks*) (alien-sap (sb-alien::alien-lambda - #+alien-callback-conventions (,convention ,(convert-foreign-type rettype)) - #-alien-callback-conventions - ,(convert-foreign-type rettype) ,(mapcar (lambda (sym type) (list sym (convert-foreign-type type))) arg-names arg-types) @@ -350,8 +382,7 @@ WITH-POINTER-TO-VECTOR-DATA." error (sem (sb-thread:make-semaphore))) (sb-thread:interrupt-thread - ;; KLUDGE: find a better way to get the initial thread. - (car (last (sb-thread:list-all-threads))) + sb-thread::*initial-thread* (lambda () (multiple-value-setq (result error) (ignore-errors (apply fn args))) @@ -367,8 +398,8 @@ WITH-POINTER-TO-VECTOR-DATA." (declare (ignore name)) ;; As of MacOS X 10.6.6, loading things like CoreFoundation from a ;; thread other than the initial one results in a crash. - #+darwin (call-within-initial-thread 'load-shared-object path) - #-darwin (load-shared-object path)) + #+(and darwin sb-thread) (call-within-initial-thread 'load-shared-object path) + #-(and darwin sb-thread) (load-shared-object path)) ;;; SBCL 1.0.21.15 renamed SB-ALIEN::SHARED-OBJECT-FILE but introduced ;;; SB-ALIEN:UNLOAD-SHARED-OBJECT which we can use instead. @@ -393,7 +424,7 @@ WITH-POINTER-TO-VECTOR-DATA." (when obj (sb-alien::dlclose-or-lose obj) (removef sb-alien::*shared-objects* obj) - #+(and linkage-table (not win32)) + #-win32 (sb-alien::update-linkage-table))))) (defun native-namestring (pathname) diff --git a/cram_3rdparty/cffi/src/src/early-types.lisp b/cram_3rdparty/cffi/src/src/early-types.lisp index 992004227d..aa13c013e9 100644 --- a/cram_3rdparty/cffi/src/src/early-types.lisp +++ b/cram_3rdparty/cffi/src/src/early-types.lisp @@ -50,8 +50,12 @@ ;;; Type parsers, defined with DEFINE-PARSE-METHOD should return a ;;; subtype of the foreign-type class. -(defvar *type-parsers* (make-hash-table :test 'equal) - "Hash table of defined type parsers.") +(defvar *default-type-parsers* (make-hash-table) + "Hash table for :DEFAULT namespace") +(defvar *struct-type-parsers* (make-hash-table) + "Hash table for :STRUCT namespace") +(defvar *union-type-parsers* (make-hash-table) + "Hash table for :UNION namespace") (define-condition cffi-error (error) ()) @@ -88,10 +92,16 @@ (error 'undefined-foreign-type-error :type-name type-name :namespace namespace)) ;; TODO this is not according to the C namespace rules, -;; see bug: https://bugs.launchpad.net/cffi/+bug/1527947 +;; see bug: https://github.com/cffi/cffi/issues/266 (deftype c-namespace-name () '(member :default :struct :union)) +(defun namespace-table (namespace) + (ecase namespace + (:default *default-type-parsers*) + (:struct *struct-type-parsers*) + (:union *union-type-parsers*))) + ;; for C namespaces read: https://stackoverflow.com/questions/12579142/type-namespace-in-c ;; (section 6.2.3 Name spaces of identifiers) ;; NOTE: :struct is probably an unfortunate name for the tagged (?) namespace @@ -99,19 +109,22 @@ "Return the type parser for SYMBOL. NAMESPACE is either :DEFAULT (for variables, functions, and typedefs) or :STRUCT (for structs, unions, and enums)." (check-type symbol (and symbol (not null))) - (check-type namespace c-namespace-name) - (or (gethash (cons namespace symbol) *type-parsers*) + (or (gethash symbol (namespace-table namespace)) (undefined-foreign-type-error symbol namespace))) +(defun find-default-type-parser (symbol) + (check-type symbol (and symbol (not null))) + (or (gethash symbol *default-type-parsers*) + (undefined-foreign-type-error symbol :default))) + (defun (setf find-type-parser) (func symbol &optional (namespace :default)) "Set the type parser for SYMBOL." (check-type symbol (and symbol (not null))) - (check-type namespace c-namespace-name) ;; TODO Shall we signal a redefinition warning here? - (setf (gethash (cons namespace symbol) *type-parsers*) func)) + (setf (gethash symbol (namespace-table namespace)) func)) (defun undefine-foreign-type (symbol &optional (namespace :default)) - (remhash (cons namespace symbol) *type-parsers*) + (remhash symbol (namespace-table namespace)) (values)) ;;; Using a generic function would have been nicer but generates lots @@ -402,21 +415,20 @@ Signals an error if FOREIGN-TYPE is undefined.")) ;;; Checks NAMEs, not object identity. (defun check-for-typedef-cycles (type) - (let ((seen (make-hash-table :test 'eq))) - (labels ((%check (cur-type) - (when (typep cur-type 'foreign-typedef) - (when (gethash (name cur-type) seen) - (simple-foreign-type-error type :default - "Detected cycle in type ~S." type)) - (setf (gethash (name cur-type) seen) t) - (%check (actual-type cur-type))))) - (%check type)))) + (labels ((%check (cur-type seen) + (when (typep cur-type 'foreign-typedef) + (when (member (name cur-type) seen) + (simple-foreign-type-error type :default + "Detected cycle in type ~S." type)) + (%check (actual-type cur-type) + (cons (name cur-type) seen))))) + (%check type nil))) ;;; Only now we define PARSE-TYPE because it needs to do some extra ;;; work for ENHANCED-FOREIGN-TYPES. (defun parse-type (type) (let* ((spec (ensure-list type)) - (ptype (apply (find-type-parser (car spec)) (cdr spec)))) + (ptype (apply (find-default-type-parser (car spec)) (cdr spec)))) (when (typep ptype 'foreign-typedef) (check-for-typedef-cycles ptype)) (when (typep ptype 'enhanced-foreign-type) @@ -522,7 +534,7 @@ Signals an error if the type cannot be resolved." (defgeneric expand-into-foreign-memory (value type ptr) (:method (value type ptr) - (declare (ignore type)) + (declare (ignore type ptr)) value)) (defmethod expand-into-foreign-memory :around @@ -532,7 +544,7 @@ Signals an error if the type cannot be resolved." (call-next-method))) (defmethod expand-into-foreign-memory (value (type translatable-foreign-type) ptr) - (declare (ignore value)) + (declare (ignore value ptr)) *runtime-translator-form*) ;;; EXPAND-TO-FOREIGN-DYN diff --git a/cram_3rdparty/cffi/src/src/enum.lisp b/cram_3rdparty/cffi/src/src/enum.lisp index cdd275e146..437446d5d2 100644 --- a/cram_3rdparty/cffi/src/src/enum.lisp +++ b/cram_3rdparty/cffi/src/src/enum.lisp @@ -55,7 +55,11 @@ (value-keywords :initform (error "Must specify VALUE-KEYWORDS.") :initarg :value-keywords - :reader value-keywords)) + :reader value-keywords) + (allow-undeclared-values + :initform nil + :initarg :allow-undeclared-values + :reader allow-undeclared-values)) (:documentation "Describes a foreign enumerated type.")) (deftype enum-key () @@ -149,7 +153,7 @@ bit-index->keyword :adjustable nil :fill-pointer nil))))) -(defun make-foreign-enum (type-name base-type values) +(defun make-foreign-enum (type-name base-type values &key allow-undeclared-values) "Makes a new instance of the foreign-enum class." (multiple-value-bind (base-type keyword-values value-keywords) @@ -158,18 +162,19 @@ :name type-name :actual-type (parse-type base-type) :keyword-values keyword-values - :value-keywords value-keywords))) + :value-keywords value-keywords + :allow-undeclared-values allow-undeclared-values))) (defun %defcenum-like (name-and-options enum-list type-factory) (discard-docstring enum-list) - (destructuring-bind (name &optional base-type) + (destructuring-bind (name &optional base-type &rest args) (ensure-list name-and-options) - (let ((type (funcall type-factory name base-type enum-list))) + (let ((type (apply type-factory name base-type enum-list args))) `(eval-when (:compile-toplevel :load-toplevel :execute) (notice-foreign-type ',name ;; ,type is not enough here, someone needs to ;; define it when we're being loaded from a fasl. - (,type-factory ',name ',base-type ',enum-list)) + (,type-factory ',name ',base-type ',enum-list ,@args)) ,@(remove nil (mapcar (lambda (key) (unless (keywordp key) @@ -219,7 +224,7 @@ (%foreign-enum-keyword type-obj value :errorp errorp)))) (defmethod translate-to-foreign (value (type foreign-enum)) - (if (keywordp value) + (if (typep value 'enum-key) (%foreign-enum-value type value :errorp t) value)) @@ -229,11 +234,14 @@ (translate-to-foreign value type))) (defmethod translate-from-foreign (value (type foreign-enum)) - (%foreign-enum-keyword type value :errorp t)) + (if (allow-undeclared-values type) + (or (%foreign-enum-keyword type value :errorp nil) + value) + (%foreign-enum-keyword type value :errorp t))) (defmethod expand-to-foreign (value (type foreign-enum)) (once-only (value) - `(if (keywordp ,value) + `(if (typep ,value 'enum-key) (%foreign-enum-value ,type ,value :errorp t) ,value))) diff --git a/cram_3rdparty/cffi/src/src/functions.lisp b/cram_3rdparty/cffi/src/src/functions.lisp index 2cb33a144f..5499b68d10 100644 --- a/cram_3rdparty/cffi/src/src/functions.lisp +++ b/cram_3rdparty/cffi/src/src/functions.lisp @@ -150,6 +150,20 @@ ((:unsigned-char :unsigned-short) :unsigned-int) (t builtin-type))) +;; If cffi-sys doesn't provide a %foreign-funcall-varargs macros we +;; define one that use %foreign-funcall. +(eval-when (:compile-toplevel :load-toplevel :execute) + (unless (fboundp '%foreign-funcall-varargs) + (defmacro %foreign-funcall-varargs (name fixed-args varargs + &rest args &key convention library) + (declare (ignore convention library)) + `(%foreign-funcall ,name ,(append fixed-args varargs) ,@args))) + (unless (fboundp '%foreign-funcall-pointer-varargs) + (defmacro %foreign-funcall-pointer-varargs (pointer fixed-args varargs + &rest args &key convention) + (declare (ignore convention)) + `(%foreign-funcall-pointer ,pointer ,(append fixed-args varargs) ,@args)))) + (defun foreign-funcall-varargs-form (thing options fixed-args varargs pointerp) (multiple-value-bind (fixed-types fixed-ctypes fixed-fargs) (parse-args-and-types fixed-args) @@ -162,27 +176,20 @@ (append fixed-fargs varargs-fargs) (append fixed-types varargs-types) rettype - `(,(if pointerp '%foreign-funcall-pointer '%foreign-funcall) + `(,(if pointerp '%foreign-funcall-pointer-varargs '%foreign-funcall-varargs) ,thing + ,(mapcan #'list fixed-ctypes fixed-syms) ,(append (mapcan #'list - (nconc fixed-ctypes - (mapcar #'promote-varargs-type varargs-ctypes)) - (append fixed-syms - (loop for sym in varargs-syms - and type in varargs-ctypes - if (eq type :float) - collect `(float ,sym 1.0d0) - else collect sym))) + (mapcar #'promote-varargs-type varargs-ctypes) + (loop for sym in varargs-syms + and type in varargs-ctypes + if (eq type :float) + collect `(float ,sym 1.0d0) + else collect sym)) (list (canonicalize-foreign-type rettype))) ,@options)))))) -;;; For now, the only difference between this macro and -;;; FOREIGN-FUNCALL is that it does argument promotion for that -;;; variadic argument. This could be useful to call an hypothetical -;;; %foreign-funcall-varargs on some hypothetical lisp on an -;;; hypothetical platform that has different calling conventions for -;;; varargs functions. :-) (defmacro foreign-funcall-varargs (name-and-options fixed-args &rest varargs) "Wrapper around %FOREIGN-FUNCALL that translates its arguments diff --git a/cram_3rdparty/cffi/src/src/libraries.lisp b/cram_3rdparty/cffi/src/src/libraries.lisp index cbecd03e5a..dcbd206306 100644 --- a/cram_3rdparty/cffi/src/src/libraries.lisp +++ b/cram_3rdparty/cffi/src/src/libraries.lisp @@ -54,6 +54,8 @@ (defun darwin-fallback-library-path () (or (explode-path-environment-variable "DYLD_FALLBACK_LIBRARY_PATH") (list (merge-pathnames #p"lib/" (user-homedir-pathname)) + #+arm64 #p"/opt/homebrew/lib/" + #p"/opt/local/lib/" #p"/usr/local/lib/" #p"/usr/lib/"))) @@ -97,13 +99,13 @@ (defun find-darwin-framework (framework-name) "Searches for FRAMEWORK-NAME in *DARWIN-FRAMEWORK-DIRECTORIES*." (dolist (directory (parse-directories *darwin-framework-directories*)) - (let ((path (make-pathname - :name framework-name - :directory - (append (pathname-directory directory) - (list (format nil "~A.framework" framework-name)))))) - (when (probe-file path) - (return-from find-darwin-framework path))))) + (let ((framework-directory + (merge-pathnames (format nil "~A.framework/" framework-name) + directory))) + + (when (probe-file framework-directory) + (let ((path (merge-pathnames framework-name framework-directory))) + (return-from find-darwin-framework path)))))) ;;;# Defining Foreign Libraries ;;; @@ -134,6 +136,7 @@ (type :initform :system :initarg :type) (spec :initarg :spec) (options :initform nil :initarg :options) + (load-state :initform nil :initarg :load-state :accessor foreign-library-load-state) (handle :initform nil :initarg :handle :accessor foreign-library-handle) (pathname :initform nil))) @@ -187,7 +190,7 @@ finally (return (mapcar #'pathname search-path)))) (defun foreign-library-loaded-p (lib) - (not (null (foreign-library-handle (get-foreign-library lib))))) + (not (null (foreign-library-load-state (get-foreign-library lib))))) (defun list-foreign-libraries (&key (loaded-only t) type) "Return a list of defined foreign libraries. @@ -229,7 +232,7 @@ all libraries are returned." spec)) (defmethod initialize-instance :after - ((lib foreign-library) &key search-path + ((lib foreign-library) &key canary search-path (cconv :cdecl cconv-p) (calling-convention cconv calling-convention-p) (convention calling-convention)) @@ -249,7 +252,8 @@ all libraries are returned." (when value (setf (getf options key) value)))) (set-option :convention convention) (set-option :search-path - (mapcar #'pathname (ensure-list search-path))))))) + (mapcar #'pathname (ensure-list search-path))) + (set-option :canary canary))))) (defun register-foreign-library (name spec &rest options) (let ((old-handle @@ -317,7 +321,7 @@ ourselves." (handler-case (values (%load-foreign-library name path) (pathname path)) - (error (error) + (simple-error (error) (let ((dirs (parse-directories *foreign-library-directories*))) (if-let (file (find-file path (append search-path dirs))) (handler-case @@ -357,7 +361,7 @@ This will need to be extended as we test on more OSes." (defun load-foreign-library-helper (name thing &optional search-path) (etypecase thing ((or pathname string) - (load-foreign-library-path (filter-pathname name) thing search-path)) + (load-foreign-library-path name (filter-pathname thing) search-path)) (cons (ecase (first thing) (:framework (load-darwin-framework name (second thing))) @@ -373,11 +377,17 @@ This will need to be extended as we test on more OSes." (defun %do-load-foreign-library (library search-path) (flet ((%do-load (lib name spec) - (when (foreign-library-spec lib) - (with-slots (handle pathname) lib - (setf (values handle pathname) - (load-foreign-library-helper - name spec (foreign-library-search-path lib))))) + (let ((canary (getf (foreign-library-options lib) :canary))) + (cond + ((and canary (foreign-symbol-pointer canary)) + ;; Do nothing because the library is already loaded. + (setf (foreign-library-load-state lib) :static)) + ((foreign-library-spec lib) + (with-slots (handle pathname) lib + (setf (values handle pathname) + (load-foreign-library-helper + name spec (foreign-library-search-path lib))) + (setf (foreign-library-load-state lib) :external))))) lib)) (etypecase library (symbol @@ -409,7 +419,10 @@ This will need to be extended as we test on more OSes." "Loads a foreign LIBRARY which can be a symbol denoting a library defined through DEFINE-FOREIGN-LIBRARY; a pathname or string in which case we try to load it directly first then search for it in *FOREIGN-LIBRARY-DIRECTORIES*; -or finally list: either (:or lib1 lib2) or (:framework )." +or finally list: either (:or lib1 lib2) or (:framework ). +The option :CANARY can specify a symbol that will be searched to detect if +the library is already loaded, in which case DEFINE-FOREIGN-LIBRARY will mark +the library as loaded and return." (let ((library (filter-pathname library))) (restart-case (progn @@ -445,6 +458,8 @@ or finally list: either (:or lib1 lib2) or (:framework )." (when handle (%close-foreign-library handle) (setf (foreign-library-handle lib) nil) + ;; Reset the load state only when the library was externally loaded. + (setf (foreign-library-load-state lib) nil) t))) (defun reload-foreign-libraries (&key (test #'foreign-library-loaded-p)) diff --git a/cram_3rdparty/cffi/src/src/package.lisp b/cram_3rdparty/cffi/src/src/package.lisp index f54c7a9f0b..2d6fd24d71 100644 --- a/cram_3rdparty/cffi/src/src/package.lisp +++ b/cram_3rdparty/cffi/src/src/package.lisp @@ -103,6 +103,8 @@ #:defcfun #:foreign-funcall #:foreign-funcall-pointer + #:foreign-funcall-varargs + #:foreign-funcall-pointer-varargs #:translate-camelcase-name #:translate-name-from-foreign #:translate-name-to-foreign @@ -112,6 +114,7 @@ #:*foreign-library-directories* #:*darwin-framework-directories* #:foreign-library + #:foreign-library-load-state #:foreign-library-name #:foreign-library-pathname #:foreign-library-type diff --git a/cram_3rdparty/cffi/src/src/strings.lisp b/cram_3rdparty/cffi/src/src/strings.lisp index d56f1f9412..3d0b0bf837 100644 --- a/cram_3rdparty/cffi/src/src/strings.lisp +++ b/cram_3rdparty/cffi/src/src/strings.lisp @@ -192,7 +192,9 @@ The string must be freed with FOREIGN-STRING-FREE." 0)) (length (+ count nul-length)) (ptr (foreign-alloc :char :count length))) - (funcall (encoder mapping) string start end ptr 0) + (unwind-protect-case () + (funcall (encoder mapping) string start end ptr 0) + (:abort (foreign-free ptr))) (dotimes (i nul-length) (setf (mem-ref ptr :char (+ count i)) 0)) (values ptr length)))) diff --git a/cram_3rdparty/cffi/src/src/types.lisp b/cram_3rdparty/cffi/src/src/types.lisp index 5dc0b6d812..aa01a3ea63 100644 --- a/cram_3rdparty/cffi/src/src/types.lisp +++ b/cram_3rdparty/cffi/src/src/types.lisp @@ -123,6 +123,12 @@ ;;;# Foreign Pointers +(define-compiler-macro inc-pointer (&whole form pointer offset) + (if (and (constantp offset) + (eql 0 (eval offset))) + pointer + form)) + (define-modify-macro incf-pointer (&optional (offset 1)) inc-pointer) (defun mem-ref (ptr type &optional (offset 0)) @@ -388,7 +394,8 @@ newly allocated memory." form)) (defun lisp-array-to-foreign (array pointer array-type) - "Copy elements from a Lisp array to POINTER." + "Copy elements from a Lisp array to POINTER. ARRAY-TYPE must be a CFFI array +type." (let* ((type (ensure-parsed-base-type array-type)) (el-type (element-type type)) (dimensions (dimensions type))) @@ -400,14 +407,15 @@ newly allocated memory." (row-major-index-to-indexes i dimensions)) do (setf (mem-ref pointer el-type offset) element)))) -(defun foreign-array-to-lisp (pointer array-type) - "Copy elements from ptr into a Lisp array. If POINTER is a null -pointer, returns NIL." +(defun foreign-array-to-lisp (pointer array-type &rest make-array-args) + "Copy elements from pointer into a Lisp array. ARRAY-TYPE must be a CFFI array +type; the type of the resulting Lisp array can be defined in MAKE-ARRAY-ARGS +that are then passed to MAKE-ARRAY. If POINTER is a null pointer, returns NIL." (unless (null-pointer-p pointer) (let* ((type (ensure-parsed-base-type array-type)) (el-type (element-type type)) (dimensions (dimensions type)) - (array (make-array dimensions))) + (array (apply #'make-array dimensions make-array-args))) (loop with foreign-type-size = (array-element-size type) with size = (reduce #'* dimensions) for i from 0 below size @@ -837,22 +845,24 @@ The foreign array must be freed with foreign-array-free." (defmacro with-foreign-slots ((vars ptr type) &body body) "Create local symbol macros for each var in VARS to reference foreign slots in PTR of TYPE. Similar to WITH-SLOTS. -Each var can be of the form: slot-name - in which case slot-name will -be bound to the value of the slot or: (:pointer slot-name) - in which -case slot-name will be bound to the pointer to that slot." +Each var can be of the form: + name name bound to slot of same name + (:pointer name) name bound to pointer to slot of same name + (name slot-name) name bound to slot-name + (name :pointer slot-name) name bound to pointer to slot-name" (let ((ptr-var (gensym "PTR"))) `(let ((,ptr-var ,ptr)) (symbol-macrolet ,(loop :for var :in vars - :collect - (if (listp var) - (if (eq (first var) :pointer) - `(,(second var) (foreign-slot-pointer - ,ptr-var ',type ',(second var))) - (error - "Malformed slot specification ~a; must be:`name' or `(:pointer name)'" - var)) - `(,var (foreign-slot-value ,ptr-var ',type ',var)))) + :collect + (if (listp var) + (let ((p1 (first var)) (p2 (second var)) (p3 (third var))) + (if (eq p1 :pointer) + `(,p2 (foreign-slot-pointer ,ptr-var ',type ',p2)) + (if (eq p2 :pointer) + `(,p1 (foreign-slot-pointer ,ptr-var ',type ',p3)) + `(,p1 (foreign-slot-value ,ptr-var ',type ',p2))))) + `(,var (foreign-slot-value ,ptr-var ',type ',var)))) ,@body)))) ;;; We could add an option to define a struct instead of a class, in @@ -1026,24 +1036,36 @@ The buffer has dynamic extent and may be stack allocated." (defctype :llong :long-long) (defctype :ullong :unsigned-long-long) +(defmacro defctype-matching (name size-or-type base-types &key (match-by '=)) + (let* ((target-size (typecase size-or-type + (integer size-or-type) + (t (foreign-type-size size-or-type)))) + (matching-type (loop for type in base-types + for size = (foreign-type-size type) + when (funcall match-by target-size size) + return type))) + (if matching-type + `(defctype ,name ,matching-type) + `(warn "Found no matching type of size ~d in~% ~a" + ,target-size ',base-types)))) + ;;; We try to define the :[u]int{8,16,32,64} types by looking at ;;; the sizes of the built-in integer types and defining typedefs. -(eval-when (:compile-toplevel :load-toplevel :execute) - (macrolet - ((match-types (sized-types mtypes) - `(progn - ,@(loop for (type . size-or-type) in sized-types - for m = (car (member (if (keywordp size-or-type) - (foreign-type-size size-or-type) - size-or-type) - mtypes :key #'foreign-type-size)) - when m collect `(defctype ,type ,m))))) - ;; signed - (match-types ((:int8 . 1) (:int16 . 2) (:int32 . 4) (:int64 . 8) - (:intptr . :pointer)) - (:char :short :int :long :long-long)) - ;; unsigned - (match-types ((:uint8 . 1) (:uint16 . 2) (:uint32 . 4) (:uint64 . 8) - (:uintptr . :pointer)) - (:unsigned-char :unsigned-short :unsigned-int :unsigned-long - :unsigned-long-long)))) +(macrolet ((match-types (sized-types base-types) + `(progn ,@(loop for (name size-or-type) in sized-types + collect `(defctype-matching ,name ,size-or-type ,base-types))))) + ;; signed + (match-types ((:int8 1) (:int16 2) (:int32 4) (:int64 8) + (:intptr :pointer)) + (:char :short :int :long :long-long)) + ;; unsigned + (match-types ((:uint8 1) (:uint16 2) (:uint32 4) (:uint64 8) + (:uintptr :pointer)) + (:unsigned-char :unsigned-short :unsigned-int :unsigned-long + :unsigned-long-long))) + +;;; Pretty safe bets. +(defctype :size #+64-bit :uint64 #+32-bit :uint32) +(defctype :ssize #+64-bit :int64 #+32-bit :int32) +(defctype :ptrdiff :ssize) +(defctype :offset #+(or 64-bit bsd) :int64 #-(or 64-bit bsd) :int32) diff --git a/cram_3rdparty/cffi/src/src/utils.lisp b/cram_3rdparty/cffi/src/src/utils.lisp index 637619654e..7afaccdef2 100644 --- a/cram_3rdparty/cffi/src/src/utils.lisp +++ b/cram_3rdparty/cffi/src/src/utils.lisp @@ -27,10 +27,10 @@ (in-package #:cffi) -(defmacro discard-docstring (body-var &optional force) +(defmacro discard-docstring (body-var) "Discards the first element of the list in body-var if it's a -string and the only element (or if FORCE is T)." - `(when (and (stringp (car ,body-var)) (or ,force (cdr ,body-var))) +string." + `(when (stringp (car ,body-var)) (pop ,body-var))) (defun single-bit-p (integer) diff --git a/cram_3rdparty/cffi/src/tests/arrays.lisp b/cram_3rdparty/cffi/src/tests/arrays.lisp index f24824f5f8..1e96514da9 100644 --- a/cram_3rdparty/cffi/src/tests/arrays.lisp +++ b/cram_3rdparty/cffi/src/tests/arrays.lisp @@ -31,7 +31,41 @@ (in-package #:cffi-tests) -(deftest array.round-trip +(deftest array.foreign-to-lisp.basic (with-foreign-array (ptr #(1 2 3 4 5) '(:array :int32 5)) (foreign-array-to-lisp ptr '(:array :int32 5))) #(1 2 3 4 5)) + +(deftest array.foreign-to-lisp.adjustable + (with-foreign-array (ptr #(1 2 3 4 5) '(:array :int32 5)) + (let ((array (foreign-array-to-lisp ptr '(:array :int32 5) + :adjustable t))) + (adjustable-array-p array))) + t) + +(deftest array.foreign-to-lisp.displaced + (let ((array (make-array 10 :initial-contents '(1 2 3 4 5 6 7 8 9 0)))) + (with-foreign-array (ptr #(10 20 30 40 50) '(:array :int32 5)) + (let ((displaced (foreign-array-to-lisp ptr '(:array :int32 5) + :displaced-to array + :displaced-index-offset 5))) + array))) + #(1 2 3 4 5 10 20 30 40 50)) + +;;; Implementation detail: 15.1.2.2 of the CL standard states that the only +;;; truly portable array specializations are for bits (bit-vectors) and +;;; characters (strings). Since char-codes are implementation-dependent, it +;;; would be tricky to write a portable test for them without generating +;;; characters at runtime. So, for a truly portable test, we are only left with +;;; bits, which are luckily numeric, and equal to (UNSIGNED-BYTE 1). +;;; This is why the below test is so terribly wasteful, spending a whole byte +;;; for a single bit - CFFI has no capabilities for dealing with single bits, +;;; and this test is only meant to check correctness of the :ELEMENT-TYPE +;;; argument to MAKE-ARRAY. In actual use cases of specialized +;;; FOREIGN-ARRAY-TO-LISP, capable implementations will be able to make +;;; specialized arrays of types that are commonly optimized for and/or +;;; representable in hardware, such as (UNSIGNED-BYTE 8) on x86 architectures. +(deftest array.foreign-to-lisp.specialized + (with-foreign-array (ptr #(1 0 1 0 1 1 1 0) '(:array :int8 8)) + (foreign-array-to-lisp ptr '(:array :int8 8) :element-type 'bit)) + #*10101110) diff --git a/cram_3rdparty/cffi/src/tests/bindings.lisp b/cram_3rdparty/cffi/src/tests/bindings.lisp index b0d62d668e..f00589c3cc 100644 --- a/cram_3rdparty/cffi/src/tests/bindings.lisp +++ b/cram_3rdparty/cffi/src/tests/bindings.lisp @@ -55,11 +55,11 @@ (defmacro deftest (name &rest body) (destructuring-bind (name &key expected-to-fail) (alexandria:ensure-list name) - (let ((result `(rt:deftest ,name ,@body))) + (let ((result `(rtest:deftest ,name ,@body))) (when expected-to-fail (setf result `(progn (when ,expected-to-fail - (pushnew ',name rt::*expected-failures*)) + (pushnew ',name rtest::*expected-failures*)) ,result))) result))) @@ -140,8 +140,11 @@ regression-test::*expected-failures*))) (defun run-all-cffi-tests () - (append (run-cffi-tests :compiled nil) - (run-cffi-tests :compiled t))) + (let ((unexpected-failures + (append (run-cffi-tests :compiled nil) + (run-cffi-tests :compiled t)))) + (format t "~%~%Overall unexpected failures: ~{~% ~A~}~%" unexpected-failures) + unexpected-failures)) (defmacro expecting-error (&body body) `(handler-case (progn ,@body :no-error) diff --git a/cram_3rdparty/cffi/src/tests/callbacks.lisp b/cram_3rdparty/cffi/src/tests/callbacks.lisp index 932362b043..1d3c4595a2 100644 --- a/cram_3rdparty/cffi/src/tests/callbacks.lisp +++ b/cram_3rdparty/cffi/src/tests/callbacks.lisp @@ -228,7 +228,7 @@ (setq *int* (mem-ref a :int))) #+(and darwin cmucl) -(pushnew 'callbacks.void rt::*expected-failures*) +(pushnew 'callbacks.void rtest::*expected-failures*) (deftest callbacks.void (progn @@ -268,8 +268,8 @@ (defcfun "call_sum_127_no_ll" :long (cb :pointer)) -;;; CMUCL, ECL and CCL choke on this one. -#-(or ecl cmucl clozure +;;; CMUCL and CCL choke on this one. +#-(or cmucl clozure #.(cl:if (cl:>= cl:lambda-parameters-limit 127) '(:or) '(:and))) (defcallback sum-127-no-ll :long ((a1 :unsigned-long) (a2 :pointer) (a3 :long) (a4 :double) @@ -326,7 +326,7 @@ (format t "a~A: ~A~%" i arg)) (reduce #'+ args))) -#+(or openmcl cmucl ecl (and darwin (or allegro lispworks))) +#+(or openmcl cmucl (and darwin (or allegro lispworks))) (push 'callbacks.bff.1 regression-test::*expected-failures*) #+#.(cl:if (cl:>= cl:lambda-parameters-limit 127) '(:and) '(:or)) @@ -341,8 +341,8 @@ (progn (defcfun "call_sum_127" :long-long (cb :pointer)) - ;;; CMUCL, ECL and CCL choke on this one. - #-(or cmucl ecl clozure) + ;;; CMUCL and CCL choke on this one. + #-(or cmucl clozure) (defcallback sum-127 :long-long ((a1 :short) (a2 :char) (a3 :pointer) (a4 :float) (a5 :long) (a6 :double) (a7 :unsigned-long-long) (a8 :unsigned-short) (a9 :unsigned-char) @@ -393,8 +393,8 @@ (values (floor a108)) a109 a110 a111 a112 a113 a114 a115 a116 a117 a118 a119 a120 a121 (values (floor a122)) a123 a124 a125 a126 a127)) - #+(or openmcl cmucl ecl) - (push 'callbacks.bff.2 rt::*expected-failures*) + #+(or openmcl cmucl) + (push 'callbacks.bff.2 rtest::*expected-failures*) (deftest callbacks.bff.2 (call-sum-127 (callback sum-127)) @@ -428,14 +428,14 @@ (defcfun "call_double26" :double (f :pointer)) #+(and darwin (or allegro cmucl)) -(pushnew 'callbacks.double26 rt::*expected-failures*) +(pushnew 'callbacks.double26 rtest::*expected-failures*) (deftest callbacks.double26 (call-double26 (callback double26)) 81.64d0) #+(and darwin cmucl) -(pushnew 'callbacks.double26.funcall rt::*expected-failures*) +(pushnew 'callbacks.double26.funcall rtest::*expected-failures*) #-cffi-sys::no-foreign-funcall (deftest callbacks.double26.funcall diff --git a/cram_3rdparty/cffi/src/tests/defcfun.lisp b/cram_3rdparty/cffi/src/tests/defcfun.lisp index 83f0c514f0..123dc77cc8 100644 --- a/cram_3rdparty/cffi/src/tests/defcfun.lisp +++ b/cram_3rdparty/cffi/src/tests/defcfun.lisp @@ -175,7 +175,7 @@ (n :unsigned-long-long)) #+allegro ; lp#914500 - (pushnew 'defcfun.unsigned-long-long rt::*expected-failures*) + (pushnew 'defcfun.unsigned-long-long rtest::*expected-failures*) (deftest defcfun.unsigned-long-long (let ((ullong-max (1- (expt 2 (* 8 (foreign-type-size :unsigned-long-long)))))) @@ -256,7 +256,7 @@ (defcfun "noop" :void) -#+(or allegro openmcl ecl) (pushnew 'defcfun.noop rt::*expected-failures*) +#+(or allegro openmcl ecl) (pushnew 'defcfun.noop rtest::*expected-failures*) (deftest defcfun.noop (noop) @@ -264,6 +264,20 @@ ;;;# Calling varargs functions +(defcfun "sum_double_arbitrary" :double (n :int) &rest) + +(deftest defcfun.varargs.nostdlib + (sum-double-arbitrary + 26 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0) + 81.64d0) + (defcfun "sprintf" :int "sprintf docstring" (str (:pointer :char)) @@ -272,7 +286,7 @@ ;;; CLISP and ABCL discard macro docstrings. #+(or clisp abcl) -(pushnew 'defcfun.varargs.docstrings rt::*expected-failures*) +(pushnew 'defcfun.varargs.docstrings rtest::*expected-failures*) (deftest defcfun.varargs.docstrings (documentation 'sprintf 'function) @@ -300,20 +314,20 @@ (deftest defcfun.varargs.float (with-foreign-pointer-as-string (s 100) - (sprintf s "%.2f" :float (float pi))) - "3.14") + (sprintf s "%.0f" :float (* pi 100))) + "314") (deftest defcfun.varargs.double (with-foreign-pointer-as-string (s 100) - (sprintf s "%.2f" :double (float pi 1.0d0))) - "3.14") + (sprintf s "%.0f" :double (* pi 100d0))) + "314") #+(and scl long-float) (deftest defcfun.varargs.long-double (with-foreign-pointer-as-string (s 100) (setf (mem-ref s :char) 0) - (sprintf s "%.2Lf" :long-double pi)) - "3.14") + (sprintf s "%.0Lf" :long-double (* pi 100))) + "314") (deftest defcfun.varargs.string (with-foreign-pointer-as-string (s 100) @@ -455,8 +469,8 @@ ;;; regression test: defining an undefined foreign function should only ;;; throw some sort of warning, not signal an error. -#+(or cmucl (and sbcl (or (not linkage-table) win32))) -(pushnew 'defcfun.undefined rt::*expected-failures*) +#+(or cmucl (and sbcl win32)) +(pushnew 'defcfun.undefined rtest::*expected-failures*) (deftest defcfun.undefined (progn diff --git a/cram_3rdparty/cffi/src/tests/enum.lisp b/cram_3rdparty/cffi/src/tests/enum.lisp index 44ca176a77..660b4cb1c9 100644 --- a/cram_3rdparty/cffi/src/tests/enum.lisp +++ b/cram_3rdparty/cffi/src/tests/enum.lisp @@ -50,7 +50,7 @@ 1) (defcenum another-boolean :false :true) -(defcfun "return_enum" another-boolean (x :int)) +(defcfun "return_enum" another-boolean (x :uint)) (deftest enum.2 (and (eq :false (return-enum 0)) @@ -130,6 +130,23 @@ 3.42 4.42) +;; Test undeclared values +(defcenum (enum.undeclared :int :allow-undeclared-values T) + (:one 1) + (:two 2)) + +(deftest enum.undeclared + (with-foreign-object (enum 'enum.undeclared 3) + (setf (mem-aref enum 'enum.undeclared 0) 1) + (setf (mem-aref enum 'enum.undeclared 1) 2) + (setf (mem-aref enum 'enum.undeclared 2) 3) + (values (mem-aref enum 'enum.undeclared 0) + (mem-aref enum 'enum.undeclared 1) + (mem-aref enum 'enum.undeclared 2))) + :one + :two + 3) + ;;;# Bitfield tests ;;; Regression test: defbitfield was misbehaving when the first value diff --git a/cram_3rdparty/cffi/src/tests/foreign-globals.lisp b/cram_3rdparty/cffi/src/tests/foreign-globals.lisp index 8527cdfeef..947082025d 100644 --- a/cram_3rdparty/cffi/src/tests/foreign-globals.lisp +++ b/cram_3rdparty/cffi/src/tests/foreign-globals.lisp @@ -104,7 +104,7 @@ *var-string* "Hello, foreign world!") -#+openmcl (push 'foreign-globals.set.long-long rt::*expected-failures*) +#+openmcl (push 'foreign-globals.set.long-long rtest::*expected-failures*) (deftest foreign-globals.ref.long-long *var-long-long* diff --git a/cram_3rdparty/cffi/src/tests/fsbv.lisp b/cram_3rdparty/cffi/src/tests/fsbv.lisp index 85681fc270..70f1959843 100644 --- a/cram_3rdparty/cffi/src/tests/fsbv.lisp +++ b/cram_3rdparty/cffi/src/tests/fsbv.lisp @@ -79,8 +79,8 @@ (deftest fsbv.4 (let ((ans (doublepairdouble '(pr (a 4 b 5) dbl 2.5d0)))) (values (getf (getf ans 'pr) 'a) - (getf (getf ans 'pr) 'b) - (getf ans 'dbl))) + (getf (getf ans 'pr) 'b) + (getf ans 'dbl))) 8 10 5.0d0) diff --git a/cram_3rdparty/cffi/src/tests/funcall.lisp b/cram_3rdparty/cffi/src/tests/funcall.lisp index bdb15d36d8..e76af82f01 100644 --- a/cram_3rdparty/cffi/src/tests/funcall.lisp +++ b/cram_3rdparty/cffi/src/tests/funcall.lisp @@ -104,24 +104,41 @@ ;;;# Calling Varargs Functions +(deftest funcall.varargs.nostdlib + (foreign-funcall-varargs + "sum_double_arbitrary" (:int 26) + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 :double 3.14d0 :double 3.14d0 + :double 3.14d0 :double 3.14d0 + :double) + 81.64d0) + ;; The CHAR argument must be passed as :INT because chars are promoted ;; to ints when passed as variable arguments. (deftest funcall.varargs.char (with-foreign-pointer-as-string (s 100) (setf (mem-ref s :char) 0) - (foreign-funcall "sprintf" :pointer s :string "%c" :int 65 :int)) + (foreign-funcall-varargs + "sprintf" (:pointer s :string "%c") :int 65 :int)) "A") (deftest funcall.varargs.int (with-foreign-pointer-as-string (s 100) (setf (mem-ref s :char) 0) - (foreign-funcall "sprintf" :pointer s :string "%d" :int 1000 :int)) + (foreign-funcall-varargs + "sprintf" (:pointer s :string "%d") :int 1000 :int)) "1000") (deftest funcall.varargs.long (with-foreign-pointer-as-string (s 100) (setf (mem-ref s :char) 0) - (foreign-funcall "sprintf" :pointer s :string "%ld" :long 131072 :int)) + (foreign-funcall-varargs + "sprintf" (:pointer s :string "%ld") + :long 131072 :int)) "131072") ;;; There is no FUNCALL.VARARGS.FLOAT as floats are promoted to double @@ -130,23 +147,23 @@ (deftest funcall.varargs.double (with-foreign-pointer-as-string (s 100) (setf (mem-ref s :char) 0) - (foreign-funcall "sprintf" :pointer s :string "%.2f" - :double (coerce pi 'double-float) :int)) - "3.14") + (foreign-funcall-varargs + "sprintf" (:pointer s :string "%.0f") :double (* pi 100d0) :int)) + "314") #+(and scl long-float) (deftest funcall.varargs.long-double (with-foreign-pointer-as-string (s 100) (setf (mem-ref s :char) 0) - (foreign-funcall "sprintf" :pointer s :string "%.2Lf" - :long-double pi :int)) - "3.14") + (foreign-funcall-varargs + "sprintf" :pointer s :string "%.0Lf" :long-double (* pi 100) :int)) + "314") (deftest funcall.varargs.string (with-foreign-pointer-as-string (s 100) (setf (mem-ref s :char) 0) - (foreign-funcall "sprintf" :pointer s :string "%s, %s!" - :string "Hello" :string "world" :int)) + (foreign-funcall-varargs + "sprintf" (:pointer s :string "%s, %s!") :string "Hello" :string "world" :int)) "Hello, world!") ;;; See DEFCFUN.DOUBLE26. diff --git a/cram_3rdparty/cffi/src/tests/grovel-test.h b/cram_3rdparty/cffi/src/tests/grovel-test.h new file mode 100644 index 0000000000..e9354c6de6 --- /dev/null +++ b/cram_3rdparty/cffi/src/tests/grovel-test.h @@ -0,0 +1,15 @@ +/* + * Factitious C header file for testing CFFI-GROVELER + */ + +#ifndef _GROVEL_TEST_H +#define _GROVEL_TEST_H + +#define TAGGED_ARRAY_MAX_LENGTH 64 + +struct tagged_array { + void *arr[TAGGED_ARRAY_MAX_LENGTH]; + unsigned int len; +}; + +#endif // _GROVEL_TEST_H diff --git a/cram_3rdparty/cffi/src/tests/grovel.lisp b/cram_3rdparty/cffi/src/tests/grovel.lisp index fcaab3d130..040f345f11 100644 --- a/cram_3rdparty/cffi/src/tests/grovel.lisp +++ b/cram_3rdparty/cffi/src/tests/grovel.lisp @@ -31,25 +31,28 @@ (cffi-grovel::invoke "echo" "test") nil nil 0) +(defun grovel-forms (forms &key (quiet t)) + (uiop:with-temporary-file (:stream grovel-stream :pathname grovel-file) + (with-standard-io-syntax + (with-open-stream (*standard-output* grovel-stream) + (let ((*package* (find-package :keyword))) + (mapc #'write forms)))) + (let ((lisp-file (let ((*debug-io* (if quiet (make-broadcast-stream) *debug-io*))) + (cffi-grovel:process-grovel-file grovel-file)))) + (unwind-protect + (load lisp-file) + (uiop:delete-file-if-exists lisp-file))))) + (defun bug-1395242-helper (enum-type base-type constant-name) (check-type enum-type (member constantenum cenum)) (check-type base-type string) (check-type constant-name string) (let ((enum-name (intern (symbol-name (gensym)))) (base-type-name (intern (symbol-name (gensym))))) - (uiop:with-temporary-file (:stream grovel-stream :pathname grovel-file) - ;; Write the grovel file - (with-open-stream (*standard-output* grovel-stream) - (write `(ctype ,base-type-name ,base-type)) - (write `(,enum-type (,enum-name :base-type ,base-type-name) - ((:value ,constant-name))))) - ;; Get the value of :inaddr-broadcast - (let ((lisp-file (cffi-grovel:process-grovel-file grovel-file))) - (unwind-protect - (progn - (load lisp-file) - (cffi:foreign-enum-value enum-name :value)) - (uiop/filesystem:delete-file-if-exists lisp-file)))))) + (grovel-forms `((ctype ,base-type-name ,base-type) + (,enum-type (,enum-name :base-type ,base-type-name) + ((:value ,constant-name))))) + (cffi:foreign-enum-value enum-name :value))) (deftest bug-1395242 (labels @@ -72,3 +75,42 @@ ("uint32_t" ("UINT32_MAX" 4294967295) ("INT8_MIN" 4294967168)) ("int32_t" ("INT32_MIN" -2147483648) ("INT32_MAX" 2147483647))))) t) + +(defvar *grovelled-features*) + +(deftest grovel-feature + (let ((*grovelled-features* nil)) + (grovel-forms `((in-package :cffi-tests) + (include "limits.h") + (feature grovel-test-feature "CHAR_BIT") + (feature :char-bit "CHAR_BIT" + :feature-list *grovelled-features*) + (feature :inexistent-grovel-feature + "INEXISTENT_CFFI_GROVEL_FEATURE" + :feature-list *grovelled-features*))) + (unwind-protect + (values (and (member 'grovel-test-feature *features*) t) + (and (member :char-bit *grovelled-features*) t) + (member :inexistent-grovel-feature *grovelled-features*)) + (alexandria:removef *features* 'grovel-test-feature))) + t t nil) + +(deftest grovel-types + (let* ((this #.(or *compile-file-truename* *load-truename*)) + (include-dir (uiop:native-namestring (make-pathname :directory (pathname-directory this))))) + (grovel-forms `((in-package :cffi-tests) + (cc-flags ,(concatenate 'string "-I" include-dir)) + (include "grovel-test.h") + (constant (tagged-array-max-length "TAGGED_ARRAY_MAX_LENGTH") + :documentation "Maximum length of tagged_array.arr (should be 64)") + (cstruct tagged-array "struct tagged_array" + (tagged-array-arr "arr" :type (:array :pointer 64)) + (tagged-array-len "len" :type :unsigned-int)))) + (let ((arr-type (cffi:foreign-slot-type '(:struct tagged-array) 'tagged-array-arr)) + (len-type (cffi:foreign-slot-type '(:struct tagged-array) 'tagged-array-len))) + (values (eql tagged-array-max-length 64) + (and (eql (car arr-type) :array) + (eql (cadr arr-type) :pointer) + (eql (caddr arr-type) tagged-array-max-length)) + (and (eql len-type :unsigned-int))))) + t t t) diff --git a/cram_3rdparty/cffi/src/tests/libtest.c b/cram_3rdparty/cffi/src/tests/libtest.c index 8cbed7c44b..2aba85848a 100644 --- a/cram_3rdparty/cffi/src/tests/libtest.c +++ b/cram_3rdparty/cffi/src/tests/libtest.c @@ -31,6 +31,7 @@ #define DLLEXPORT #endif +#include #include #include #include @@ -38,11 +39,9 @@ #include #include #include - -/* MSVC doesn't have stdint.h and uses a different syntax for stdcall */ -#ifndef _MSC_VER +#include #include -#endif +#include #ifdef WIN32 #ifdef _MSC_VER @@ -840,6 +839,21 @@ double sum_double26(double a1, double a2, double a3, double a4, double a5, a26; } +/* + * DEFCFUN.VARARGS.NOSTDLIB and FUNCALL.VARARGS.NOSTDLIB + */ +DLLEXPORT +double sum_double_arbitrary(int n, ...) +{ + va_list ap; + double sum = 0; + va_start(ap, n); + for(int j=0; j + cl_png + 0.8.0 + + 3rd party library: CL-PNG + + + Harald Musum, Vebjorn Ljosa, Jeff Cunningham + + Gayane Kazhoyan + + LGPL-2.1 + + http://www.ljosa.com/~ljosa/software/cl-png + https://github.com/cram2/cram_3rdparty/issues + https://github.com/cram2/cram_3rdparty + https://github.com/sharplispers/cl-png.git + + + catkin + + cffi + + + diff --git a/cram_3rdparty/cl_png/src/.circleci/config.yml b/cram_3rdparty/cl_png/src/.circleci/config.yml new file mode 100644 index 0000000000..5de2af052f --- /dev/null +++ b/cram_3rdparty/cl_png/src/.circleci/config.yml @@ -0,0 +1,26 @@ +version: 2 +jobs: + build: + docker: + - image: debian:stable + + working_directory: /src/cl-png + + steps: + - run: apt-get update -y && apt-get install -y sbcl wget gcc libpng-dev git ssh + + - checkout + + - run: wget https://beta.quicklisp.org/quicklisp.lisp + + - run: sbcl --load quicklisp.lisp --eval "(quicklisp-quickstart:install)" --eval '(ql:quickload "cffi")' --quit + + - run: ln -s /src/cl-png /root/quicklisp/local-projects/png + + - run: sbcl --disable-debugger --load /root/quicklisp/setup.lisp --eval '(ql:quickload "png")' --eval "(asdf:oos 'asdf:load-op '#:png-test)" --eval "(lisp-unit:run-all-tests :png-test)" --quit + + - run: sbcl --disable-debugger --load /root/quicklisp/setup.lisp --eval '(ql:quickload "png")' --eval "(asdf:oos 'asdf:load-op '#:image-test)" --eval "(lisp-unit:run-all-tests :image-test)" --quit + + - run: sbcl --disable-debugger --load /root/quicklisp/setup.lisp --eval '(ql:quickload "png")' --eval "(asdf:oos 'asdf:load-op '#:bmp-test)" --eval "(lisp-unit:run-all-tests :bmp-test)" --quit + + - run: sbcl --disable-debugger --load /root/quicklisp/setup.lisp --eval '(ql:quickload "png")' --eval "(asdf:oos 'asdf:load-op '#:ops-test)" --eval "(lisp-unit:run-all-tests :ops-test)" --quit diff --git a/cram_3rdparty/cl_png/src/.gitignore b/cram_3rdparty/cl_png/src/.gitignore new file mode 100644 index 0000000000..be303db032 --- /dev/null +++ b/cram_3rdparty/cl_png/src/.gitignore @@ -0,0 +1 @@ +*.fasl diff --git a/cram_3rdparty/cl_png/src/AUTHORS b/cram_3rdparty/cl_png/src/AUTHORS new file mode 100644 index 0000000000..2ca6a73be5 --- /dev/null +++ b/cram_3rdparty/cl_png/src/AUTHORS @@ -0,0 +1,3 @@ +Harald Musum +Vebjorn Ljosa +Jeff Cunningham diff --git a/cram_3rdparty/cl_png/src/COPYING b/cram_3rdparty/cl_png/src/COPYING new file mode 100644 index 0000000000..223ede7de3 --- /dev/null +++ b/cram_3rdparty/cl_png/src/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/cram_3rdparty/cl_png/src/MANIFEST b/cram_3rdparty/cl_png/src/MANIFEST new file mode 100644 index 0000000000..967055532f --- /dev/null +++ b/cram_3rdparty/cl_png/src/MANIFEST @@ -0,0 +1,28 @@ +AUTHORS +compat.lisp +COPYING +debian/changelog +debian/compat +debian/control +debian/copyright +debian/docs +debian/postinst +debian/prerm +debian/rules +doc/index.html +grovel.lisp +image.lisp +libpng.lisp +lisp-unit.lisp +MANIFEST +NEWS +package.lisp +png.asd +png-test.asd +PngSuite/basn0g08.png +PngSuite/basn0g16.png +PngSuite/basn0g04.png +PngSuite/basn0g02.png +PngSuite/basn0g01.png +README +test.lisp \ No newline at end of file diff --git a/cram_3rdparty/cl_png/src/NEWS b/cram_3rdparty/cl_png/src/NEWS new file mode 100644 index 0000000000..28b7e0d47a --- /dev/null +++ b/cram_3rdparty/cl_png/src/NEWS @@ -0,0 +1,18 @@ +Version 0.6 (2009-02-08) + - Read and write from Lisp streams, also those without file descriptors + - Added unit tests. + - Fixed pointer size bug causing memory fault on SBCL Linux x86_64. + - Read, write, and represent 16-bit images. (Previously downscaled + to 8 bits on read.) + - Fixed reading of 1, 2, and 4-bit images on CCL DarwinPPC. +Version 0.5 (2008-12-01) + - Complete rewrite, using foreign calls to libpng. +Version 0.4 (2004-03-06) + - Fix simple bug (#4) in package definition that made CL-PNG unloadable. + - Fix simple bug (#5) that made memory allocation in UNCOMPRESS-STRING + slightly inefficient. + - Fix bug (#6) that made CL-PNG not work at all on CMUCL. +Version 0.3 (2004-03-05) + - Use compression and decompression code from libz (via UFFI) instead + of the CL implementation. + - Changes (mostly cosmetic) from Kevin Rosenberg's Debian package. diff --git a/cram_3rdparty/cl_png/src/README b/cram_3rdparty/cl_png/src/README new file mode 100644 index 0000000000..2bef0749bc --- /dev/null +++ b/cram_3rdparty/cl_png/src/README @@ -0,0 +1,9 @@ +CL-PNG is a Common Lisp package for reading and writing PNG (Portable +Network Graphics) files. The CL-PNG homepage is at +. + +Copyright (C) 2001--2009 by the authors (see the file AUTHORS). +Licensed under the GNU Lesser General Public License; see the file +COPYING for details. + +See doc/index.html for documentation. diff --git a/cram_3rdparty/cl_png/src/benchmark.c b/cram_3rdparty/cl_png/src/benchmark.c new file mode 100644 index 0000000000..9c15222475 --- /dev/null +++ b/cram_3rdparty/cl_png/src/benchmark.c @@ -0,0 +1,294 @@ +#include +#include +#include +#include +#include +#include + + +/* Error handling. */ + +const char *program_name = NULL; + +void set_program_name(const char *argv0) +{ + program_name = strrchr(argv0, '/'); + if (program_name) + program_name++; + else + program_name = argv0; +} + +static void +verror(const char *format, va_list ap) +{ + if (program_name) + fprintf(stderr, "%s: ", program_name); + vfprintf(stderr, format, ap); +} + +__attribute__((noreturn)) +void +fatal_error(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + verror(format, ap); + va_end(ap); + fprintf(stderr, "\n"); + exit(1); +} + +__attribute__((noreturn)) +void +fatal_perror(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + verror(format, ap); + va_end(ap); + fprintf(stderr, ": %s", strerror(errno)); + fprintf(stderr, "\n"); + exit(1); +} + + + +png_bytep +make_image(png_uint_32 height, png_uint_32 width, png_byte nchannels, + png_byte bit_depth) +{ + png_bytep image; + image = malloc(height * width * nchannels * bit_depth / 8); + if (!image) fatal_perror("malloc"); + return image; +} + +png_bytepp +make_row_pointers(png_bytep image, png_uint_32 height, png_uint_32 width, + png_byte nchannels) +{ + png_bytepp row_pointers; + png_uint_32 i; + row_pointers = malloc(height * sizeof(png_bytep)); + if (!row_pointers) fatal_perror("malloc"); + for (i = 0; i < height; i++) + row_pointers[i] = image + i * width * nchannels; + return row_pointers; +} + +void +decode(FILE *input, png_bytep *image, png_uint_32 *height, png_uint_32 *width, + png_byte *nchannels) +{ + png_structp png_ptr; + png_infop info_ptr, end_info; + int bit_depth, color_type; + png_bytepp row_pointers; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) fatal_error("png_create_read_struct"); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) fatal_error("png_create_info_struct"); + end_info = png_create_info_struct(png_ptr); + if (!end_info) fatal_error("png_create_info_struct"); + if (setjmp(png_jmpbuf(png_ptr))) fatal_error("png_error via setjmp"); + + png_init_io(png_ptr, input); + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, width, height, &bit_depth, &color_type, + NULL, NULL, NULL); + if (bit_depth != 8) + fatal_error("Can only handle 8-bit images."); + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + if (!(color_type & ~PNG_COLOR_MASK_ALPHA)) + png_set_expand(png_ptr); + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png_ptr); + + *nchannels = color_type & ~PNG_COLOR_MASK_ALPHA ? 3 : 1; + *image = make_image(*height, *width, *nchannels, bit_depth); + row_pointers = make_row_pointers(*image, *height, *width, *nchannels); + png_read_image(png_ptr, row_pointers); + free(row_pointers); + png_read_end(png_ptr, end_info); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); +} + +void encode(FILE *output, png_bytep image, png_uint_32 height, + png_uint_32 width, png_byte nchannels) +{ + png_structp png_ptr; + png_infop info_ptr; + int bit_depth, color_type; + png_bytepp row_pointers; + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, + NULL); + if (!png_ptr) fatal_error("png_create_write_struct"); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) fatal_error("png_create_info_struct"); + if (setjmp(png_jmpbuf(png_ptr))) fatal_error("png_error via setjmp"); + + png_init_io(png_ptr, output); + bit_depth = 8; + switch (nchannels) { + case 1: color_type = PNG_COLOR_TYPE_GRAY; break; + case 3: color_type = PNG_COLOR_TYPE_RGB; break; + default: fatal_error("Cannot write images with %d channels", nchannels); + } + png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + row_pointers = make_row_pointers(image, height, width, nchannels); + png_set_rows(png_ptr, info_ptr, row_pointers); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + free(row_pointers); + png_destroy_write_struct(&png_ptr, &info_ptr); +} + +png_bytep to_16_bit(const png_bytep image8, png_uint_32 height, + png_uint_32 width, png_byte nchannels) +{ + png_bytep image16; + png_uint_32 i; + + image16 = make_image(height, width, nchannels, 16); + for (i = 0; i < height * width * nchannels; i++) { + image16[2 * i] = image8[i]; + image16[2 * i + 1] = image8[i]; + } + return image16; +} + +png_bytep to_8_bit(const png_bytep image16, png_uint_32 height, + png_uint_32 width, png_byte nchannels) +{ + png_bytep image8; + png_uint_32 i; + + image8 = make_image(height, width, nchannels, 8); + for (i = 0; i < height * width * nchannels; i++) + image8[i] = image16[2 * i] - (image16[2 * i + 1] < image16[2 * i]); + return image8; +} + + + +double elapsed_time(struct timeval *start_time, int divisor) +{ + struct timeval end_time; + gettimeofday(&end_time, NULL); + return (end_time.tv_sec - start_time->tv_sec + + (end_time.tv_usec - start_time->tv_usec) / 1000000.0) / divisor; +} + +double time_decode(const char *filename, int n) +{ + int i; + png_bytep image; + FILE *input; + struct timeval start_time; + png_uint_32 height, width; + png_byte nchannels; + + gettimeofday(&start_time, NULL); + for (i = 0; i < n; i++) { + input = fopen(filename, "r"); + if (!input) fatal_perror("%s", filename); + decode(input, &image, &height, &width, &nchannels); + fclose(input); + free(image); + } + return elapsed_time(&start_time, n); +} + +double time_encode(const char *input_filename, const char *output_filename, + int n) +{ + int i; + png_bytep image; + FILE *input, *output; + struct timeval start_time; + png_uint_32 height, width; + png_byte nchannels; + + input = fopen(input_filename, "r"); + if (!input) fatal_perror("%s", input_filename); + decode(input, &image, &height, &width, &nchannels); + fclose(input); + + gettimeofday(&start_time, NULL); + for (i = 0; i < n; i++) { + output = fopen(output_filename, "w"); + if (!output) fatal_perror("%s", output_filename); + encode(output, image, height, width, nchannels); + fclose(output); + } + free(image); + return elapsed_time(&start_time, n); +} + +double time_to_16_bit(const char *input_filename, int n) +{ + int i; + png_bytep image8, image16; + FILE *input; + struct timeval start_time; + png_uint_32 height, width; + png_byte nchannels; + + input = fopen(input_filename, "r"); + if (!input) fatal_perror("%s", input_filename); + decode(input, &image8, &height, &width, &nchannels); + fclose(input); + + gettimeofday(&start_time, NULL); + for (i = 0; i < n; i++) { + image16 = to_16_bit(image8, height, width, nchannels); + free(image16); + } + free(image8); + return elapsed_time(&start_time, n); +} + +double time_to_8_bit(const char *input_filename, int n) +{ + int i; + png_bytep image, image8, image16; + FILE *input; + struct timeval start_time; + png_uint_32 height, width; + png_byte nchannels; + + input = fopen(input_filename, "r"); + if (!input) fatal_perror("%s", input_filename); + decode(input, &image, &height, &width, &nchannels); + fclose(input); + + image16 = to_16_bit(image, height, width, nchannels); + + gettimeofday(&start_time, NULL); + for (i = 0; i < n; i++) { + image8 = to_8_bit(image16, height, width, nchannels); + free(image8); + } + free(image16); + free(image); + return elapsed_time(&start_time, n); +} + +int main(int argc, char *argv[]) +{ + set_program_name(argv[0]); + if (argc < 3) fatal_error("Usage: %s INPUT OUTPUT", program_name); + + printf("to_16_bit: %f s\n", time_to_16_bit(argv[1], 50)); + printf("to_8_bit: %f s\n", time_to_8_bit(argv[1], 50)); + printf("decode: %f s\n", time_decode(argv[1], 10)); + printf("encode: %f s\n", time_encode(argv[1], argv[2], 1)); + return 0; +} diff --git a/cram_3rdparty/cl_png/src/benchmark.lisp b/cram_3rdparty/cl_png/src/benchmark.lisp new file mode 100644 index 0000000000..8aed2a201c --- /dev/null +++ b/cram_3rdparty/cl_png/src/benchmark.lisp @@ -0,0 +1,32 @@ + +(in-package #:png-test) + +(defparameter *fall-pathname* + #+asdf (asdf:system-relative-pathname '#:png "Fall.png")) + +(defun decode-fall () + (with-open-file (input *fall-pathname* :element-type '(unsigned-byte 8)) + (decode input))) + + +(defun time-decode (n) + (time (dotimes (i n) + (decode-fall)))) + +(defun time-encode (n) + (let ((im (decode-fall))) + (time + (dotimes (i n) + (with-open-file (output "/tmp/foo.png" :element-type '(unsigned-byte 8) + :direction :output :if-exists :supersede) + (encode im output)))))) + +(defun time-16-bit-image (n) + (let ((im (decode-fall))) + (time (dotimes (i n) + (16-bit-image im))))) + +(defun time-8-bit-image (n) + (let ((im (16-bit-image (decode-fall)))) + (time (dotimes (i n) + (8-bit-image im))))) diff --git a/cram_3rdparty/cl_png/src/bmp.lisp b/cram_3rdparty/cl_png/src/bmp.lisp new file mode 100644 index 0000000000..55db610a98 --- /dev/null +++ b/cram_3rdparty/cl_png/src/bmp.lisp @@ -0,0 +1,259 @@ +(defpackage #:bmp + (:use #:common-lisp #:image) + (:export #:decode #:encode)) + +(in-package #:bmp) + +(defun read-u2le (in) + "Reads 2 unsigned BYTES in little-endian from IN stream without +testing for end of file." + (let ((u 0)) + (setf (ldb (byte 8 0) u) (read-byte in)) + (setf (ldb (byte 8 8) u) (read-byte in)) + u)) + +(defun read-u4le (in) + "Reads 4 unsigned BYTES in little-endian from IN stream without +testing for end of file." + (let ((u 0)) + (setf (ldb (byte 8 0) u) (read-byte in)) + (setf (ldb (byte 8 8) u) (read-byte in)) + (setf (ldb (byte 8 16) u) (read-byte in)) + (setf (ldb (byte 8 24) u) (read-byte in)) + u)) + +(defun write-u2le (out u) + "Writes 2 unsigned BYTES in little-endian to OUT stream." + (write-byte (ldb (byte 8 0) u) out) + (write-byte (ldb (byte 8 8) u) out)) + +(defun write-u4le (out u) + "Writes 4 unsigned BYTES in little-endian to OUT stream." + (write-byte (ldb (byte 8 0) u) out) + (write-byte (ldb (byte 8 8) u) out) + (write-byte (ldb (byte 8 16) u) out) + (write-byte (ldb (byte 8 24) u) out)) + +(define-condition unhandled-compression () + ((mode :initarg :mode :reader unhandled-compression-mode)) + (:report (lambda (condition stream) + (format stream "Unhandled BMP bitmap compression mode ~a~%" + (unhandled-compression-mode condition))))) + +(define-condition unhandled-bitcount () + ((bitcount :initarg :bitcount :reader unhandled-bitcount-bitcount)) + (:report (lambda (condition stream) + (format stream "Unhandled BMP bitcount ~a~%" + (unhandled-bitcount-bitcount condition))))) + +(defun decode (input &key bgr flip strip-alpha) + "Reads an image in BMP format from input and returns an array of +type IMAGE. The bit depth of the returned IMAGE will be either 8 or +16. + +Setting FLIP will flip the image vertically. +Setting STRIP-ALPHA will strip an alpha channel, if present. + +Setting BGR will leave the channels ordered as read from the BMP +stream. That is, in BGR or BGRA order, rather than swapping them to +RGB or RGBA order normal to IMAGE). + +The current version will decode 24-bit RGB and 32-bit ARGB BMP +streams. Compressed formats are not currently supported and will +signal an error. + +Signals an error if reading the image fails." + ;; Check for "BM" signature at beginning + (unless (= #x4d42 (read-u2le input)) + (error "~s Not a BMP bitmap image stream" input)) + ;; Read rest of header + (let* ((file-sz (read-u4le input)) + (reserve (read-u4le input)) + (raster-data-offset (read-u4le input)) + (sz (read-u4le input)) + (cols (read-u4le input)) + (rows (read-u4le input)) + (planes (read-u2le input)) + (bitcount (read-u2le input)) + (compression (read-u4le input)) + (image-sz (read-u4le input)) + (ppm (list (read-u4le input) (read-u4le input))) + (colors (list (read-u4le input) (read-u4le input))) + (current-offset 54)) + (declare (ignorable reserve sz planes ppm colors)) + ;; Check if we can decode this stream + (unless (= compression 0) + (error 'unhandled-compression :mode compression)) + (unless (member bitcount '(8 24 32)) + (error 'unhandled-bitcount :bitcount bitcount)) + ;; Note: the image-sz is only non-zero when compression is being + ;; used. The image size should be calculated from the filesize + ;; and the raster-data-offset, both of which must be accurate. + (setf image-sz (- file-sz raster-data-offset)) + (let* ((channels (floor image-sz (* rows cols))) + (bit-depth (/ bitcount channels)) + (stripping-alpha (and strip-alpha (= channels 4))) + (chan-loop-lim (if stripping-alpha (1- channels) channels)) + (image (make-image rows cols + (if stripping-alpha 3 channels) + (if (= 16 bit-depth) 16 8))) + (npad (mod (* channels cols) 4)) + (bgridx (make-array channels))) + + ;; Set up BGR channel swap index array + (dotimes (c channels) (setf (aref bgridx c) c)) + (when (and (not bgr) (>= channels 3)) + (setf (aref bgridx 0) 2) + (setf (aref bgridx 2) 0)) + + ;; Fix npad + (when (< 0 npad) (setf npad (- 4 npad))) + + ;; Change some values to reflect stripping of alpha + (when stripping-alpha + (setf bitcount 24 + image-sz (* 24/32 image-sz)) + (setf file-sz (+ image-sz raster-data-offset))) +#| + (format t "~& dims: ~ax~a~%" rows cols) + (format t " bitcount: ~a~%" bitcount) + (format t " compression: ~a~%" compression) + (format t " file size: ~a image size:~a~%" file-sz image-sz) + (format t "raster-offset: ~x~%" raster-data-offset) + (format t " npad:~a~%" npad) + (format t " bgridx:~s~%" bgridx) +|# + ;; Read palette if there is one + (when (> raster-data-offset current-offset) + (let ((table-size (- raster-data-offset current-offset))) + ;; (format t " table-size: ~d~%" table-size) + (dotimes (r table-size) + (read-byte input)))) + + ;; Read pixel data + (dotimes (row (image-height image)) + (dotimes (col (image-width image)) + (dotimes (chan chan-loop-lim) + (setf (aref image + (if flip (- rows row 1) row) + col + (aref bgridx chan)) (read-byte input))) + (when stripping-alpha + (read-byte input))) + (dotimes (c npad) + (read-byte input))) + image))) + + +(defun decode-file (pathname &key flip bgr) + "Reads file PATHNAME, decodes as BMP file and returns IMAGE." + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (bmp:decode input :flip flip :bgr bgr))) + + +(defun encode (image output &key flip (xppi 72) (yppi 72) + xppm yppm (reserve 0) strip-alpha bgr) + "Writes IMAGE in BMP format to OUTPUT. + +Flips image vertically if FLIP set. XPPI and YPPI specify pixels per +inch Strips alpha channel if STRIP-ALPHA is set (and there is one) - in +other words, encodes ARGB as RGB. + +The current version only encodes RGB and ARGB BMP files (24 and 32 bit +pixels, respectively). Paletted versions signal an error. + +Signals an error if writing the image fails." + ;; Notes: + ;; reserve: 4-bytes that can be set by caller arbitrarily. + ;; + ;; compression: 0= BI_RGB (none: most common) + ;; 1= BI_RLE8 palettized (8-bits/pixel) + ;; 2= BI_RLE4 palettized (4-bits/pixel) + ;; 3= BI_BITFIELDS (16,32-bits/pixel bitmaps) + ;; 4= BI_JPEG (not supported) + ;; 5= BI_PNG (not supported) + ;; + ;; xppm,yppm: horizontal,vertical resolution in pixels/meter + ;; + ;; colors_used: 0 defaults to 2**n + ;; colors_important is generally ignored + ;; + (check-type image (or rgb-image grayscale-image)) + (let ((raster-data-offset (if (/= 1 (image-channels image)) 54 (+ 54 1024))) + (sz 40) + (planes 1) + (compression 0) + (imagesize 0) + (colors-used 0) + (colors-important 0) + (stripping-alpha (and strip-alpha (= 4 (image-channels image))))) + ;; Convert the resolution if necessary + (unless (numberp xppm) + (setf xppm (floor xppi 0.0254))) + (unless (numberp yppm) + (setf yppm (floor yppi 0.0254))) + ;; Rows of pixels are padded out to 4-byte boundaries, so we have + ;; to calculate the number of pad bytes + (let* ((channels (if stripping-alpha 3 (image-channels image))) + (bitcount (* channels (image-bit-depth image))) + (bytes/pixel (/ bitcount 8)) + (bytes/row (* bytes/pixel (image-width image) channels)) + (npad (mod bytes/row 4)) + (nbytes (* (image-height image) + (+ npad (* channels + (image-width image))))) + (bgridx (make-array channels)) + (filesize (+ nbytes raster-data-offset))) + ;; Set up BGR channel swap index array + (dotimes (c channels) (setf (aref bgridx c) c)) + (when (and (not bgr) (>= channels 3)) + (setf (aref bgridx 0) 2) + (setf (aref bgridx 2) 0)) + ;; Fix npad + (when (and (= channels 1) (< 0 npad)) + (setf npad (- 4 npad))) + ;; Write "BM" signature + (write-u2le output 19778) + ;; Write primary header + (write-u4le output filesize) + (write-u4le output reserve) + (write-u4le output raster-data-offset) + ;; Write DIB header + (write-u4le output sz) + (write-u4le output (image-width image)) + (write-u4le output (image-height image)) + (write-u2le output planes) + (write-u2le output bitcount) + (write-u4le output compression) + (write-u4le output imagesize) + (write-u4le output xppm) + (write-u4le output yppm) + (write-u4le output colors-used) + (write-u4le output colors-important) + ;; Write color table if required + (cond ((member bitcount '(8)) ; bogus color table for grayscale images + (dotimes (n 256) + (dotimes (c 3) + (write-byte n output)) + (write-byte 0 output))) + ((member bitcount '(24 32))) ; don't need one + (t (error 'unhandled-bitcount :bitcount bitcount))) + ;; Write raster data + (dotimes (row (image-height image)) + (dotimes (col (image-width image)) + (dotimes (chan channels) + (write-byte (aref image + (if flip (- (image-height image) row 1) row) + col + (aref bgridx chan)) + output))) + (dotimes (c npad) + (write-byte 0 output)))))) + +(defun encode-file (image pathname &key flip strip-alpha bgr) + "Encodes IMAGE as BMP and writes to PATHNAME." + (with-open-file (output pathname :element-type '(unsigned-byte 8) + :direction :output :if-exists :supersede) + (bmp:encode image output :flip flip :strip-alpha strip-alpha :bgr bgr))) + + diff --git a/cram_3rdparty/cl_png/src/compat.lisp b/cram_3rdparty/cl_png/src/compat.lisp new file mode 100644 index 0000000000..ea6d1a1214 --- /dev/null +++ b/cram_3rdparty/cl_png/src/compat.lisp @@ -0,0 +1,98 @@ +(in-package #:png) + +#+sbcl +(macrolet ((make-array-storage-vector () + (let ((%array-data-vector (or (find-symbol "%ARRAY-DATA-VECTOR" :sb-kernel) + (find-symbol "%ARRAY-DATA" :sb-kernel)))) ;; renamed in sbcl 2.1.6 + `(progn + (declaim (ftype (function (array) (values (simple-array * (*)) &optional)) array-storage-vector)) + (defun array-storage-vector (array) + "Returns the underlying storage vector of ARRAY, which must be a non-displaced array. + +In SBCL, if ARRAY is a of type \(SIMPLE-ARRAY * \(*)), it is its own storage +vector. Multidimensional arrays, arrays with fill pointers, and adjustable +arrays have an underlying storage vector with the same ARRAY-ELEMENT-TYPE as +ARRAY, which this function returns. + +Important note: the underlying vector is an implementation detail. Even though +this function exposes it, changes in the implementation may cause this +function to be removed without further warning." + (sb-ext:truly-the (simple-array * (*)) + (if (sb-kernel:array-header-p array) + (if (sb-kernel:%array-displaced-p array) + (error "~S cannot be used with displaced arrays. Use ~S instead." + 'array-storage-vector 'array-displacement) + (,%array-data-vector array)) + array))))))) + (make-array-storage-vector)) + +#+allegro +(defmacro with-pointer-to-array-data ((ptr-var array) &body body) + "Bind PTR-VAR to a foreign pointer to the data in VECTOR. Not safe +except with array allocated by MAKE-SHAREABLE-ARRAY and +possibly arrays of type simple-array (unsigned-byte 8) (*)." +;;; An array allocated in static-reclamable is a non-simple array in +;;; the normal Lisp allocation area, pointing to a simple array in the +;;; static-reclaimable allocation area. Therefore we have to get out +;;; the simple-array to find the pointer to the actual contents. + (let ((simple-arr (gensym "SIMPLE-ARR"))) + `(excl:with-underlying-simple-vector (,array ,simple-arr) + (let ((,ptr-var (ff:fslot-address-typed :unsigned-char + :lisp ,simple-arr))) + ,@body)))) + +#+clisp +(defmacro with-pointer-to-array-data ((ptr-var array) &body body) + "Bind PTR-VAR to a foreign pointer to the data in ARRAY." + (let ((array-var (gensym)) + (type (gensym)) + (nbytes (gensym)) + (bytes-per-word (gensym))) + `(let* ((,array-var ,vector) + ,type ,bytes-per-word) + (etypecase ,array-var + ((simple-array (unsigned-byte 8)) (setq ,type :unsigned-char + ,bytes-per-word 1)) + ((simple-array (unsigned-byte 16)) (setq ,type :unsigned-short + ,bytes-per-word 2))) + (with-foreign-pointer (,ptr-var (* (array-total-size ,array-var) + ,bytes-per-word) + ,nbytes) + ;; copy-in + (loop + for word from 0 + and byte below ,nbytes by ,bytes-per-word + do (cffi-sys:%mem-set (row-major-aref ,array-var word) + ,ptr-var ,type byte)) + (unwind-protect (progn ,@body) + ;; copy-out + (loop + for word from 0 + and byte below ,nbytes by ,bytes-per-word + do (setf (row-major-aref ,array-var word) + (cffi-sys:%mem-ref ,ptr-var ,type byte)))))))) + +#+lispworks +(defmacro with-pointer-to-array-data ((ptr-var array) &body body) + `(progn + (assert (system:staticp ,array) `(,array) + "Array must be allocated in the static area.") + (with-pointer-to-vector-data (,ptr-var ,array) ,@body))) + +#+sbcl +(defmacro with-pointer-to-array-data ((ptr-var array) &body body) + `(cffi:with-pointer-to-vector-data (,ptr-var (array-storage-vector ,array)) + ,@body)) + +#+ccl +(defmacro with-pointer-to-array-data ((ptr-var array) &body body) + (let ((v (gensym))) + `(let ((,v (ccl::array-data-and-offset ,array))) + (unless (typep ,v 'ccl::ivector) + (ccl::report-bad-arg ,v 'ccl::ivector)) + (ccl::without-gcing + (ccl:with-macptrs ((,ptr-var)) + (ccl::%vect-data-to-macptr ,v ,ptr-var) + ,@body))))) + + diff --git a/cram_3rdparty/cl_png/src/debian/changelog b/cram_3rdparty/cl_png/src/debian/changelog new file mode 100644 index 0000000000..866ae1e114 --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/changelog @@ -0,0 +1,27 @@ +cl-png (0.2.1-1) unstable; urgency=low + + * Patch from Milan Zamazal (closes:20600) + + -- Kevin M. Rosenberg Mon, 18 Aug 2003 01:22:23 -0600 + +cl-png (0.2-3) unstable; urgency=low + + * Remove 'load-compiled-op from .asd file + * Changes compared to upstream: + - Added .asd file for use with Common Lisp Controller + - Change package naming for compatibility with Allegro case-sensitive mode + - Change defconstants to defvars for objects that aren't EQL on reload + + -- Kevin M. Rosenberg Mon, 2 Dec 2002 11:37:39 -0700 + +cl-png (0.2-2) unstable; urgency=low + + * Fix description + + -- Kevin M. Rosenberg Tue, 5 Nov 2002 21:37:42 -0700 + +cl-png (0.2-1) unstable; urgency=low + + * Initial release (closes: 167961) + + -- Kevin M. Rosenberg Tue, 22 Oct 2002 09:57:38 -0600 diff --git a/cram_3rdparty/cl_png/src/debian/compat b/cram_3rdparty/cl_png/src/debian/compat new file mode 100644 index 0000000000..b8626c4cff --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/compat @@ -0,0 +1 @@ +4 diff --git a/cram_3rdparty/cl_png/src/debian/control b/cram_3rdparty/cl_png/src/debian/control new file mode 100644 index 0000000000..22e72709b2 --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/control @@ -0,0 +1,15 @@ +Source: cl-png +Section: devel +Priority: optional +Maintainer: Kevin M. Rosenberg +Build-Depends-Indep: debhelper (>= 4.0.0) +Standards-Version: 3.6.0 + +Package: cl-png +Architecture: all +Depends: ${shlibs:Depends}, common-lisp-controller (>= 3.47) +Description: Common Lisp package to read and write PNG image files + This package includes functions for reading and writing PNG image files as + well as functions for compressing and decompressing zipped files. + + diff --git a/cram_3rdparty/cl_png/src/debian/copyright b/cram_3rdparty/cl_png/src/debian/copyright new file mode 100644 index 0000000000..a2e7cc7d3a --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/copyright @@ -0,0 +1,15 @@ +This package was debianized by Kevin M. Rosenberg in +Nov 2002. + +It was downloaded from http://www.pvv.ntnu.no/~musum/lisp/code/ + +Upstream Author: Harald Musum + +Copyright (c) 2001 Harald Musum + +This code is free software; you can redistribute it and/or modify it +under the terms of the version 2.1 of the GNU Lesser General Public +License. + +The GNU Lessor General Public License can be found in your Debian file +system in /usr/share/common-licenses/LGPL. diff --git a/cram_3rdparty/cl_png/src/debian/docs b/cram_3rdparty/cl_png/src/debian/docs new file mode 100644 index 0000000000..e845566c06 --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/docs @@ -0,0 +1 @@ +README diff --git a/cram_3rdparty/cl_png/src/debian/postinst b/cram_3rdparty/cl_png/src/debian/postinst new file mode 100644 index 0000000000..d9d69702d4 --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/postinst @@ -0,0 +1,48 @@ +#! /bin/sh +# postinst script for cl-png +# +# see: dh_installdeb(1) + +set -e + +# package name according to lisp +LISP_PKG=png + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + /usr/sbin/register-common-lisp-source ${LISP_PKG} + ;; + abort-upgrade|abort-remove|abort-deconfigure) + ;; + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/cram_3rdparty/cl_png/src/debian/prerm b/cram_3rdparty/cl_png/src/debian/prerm new file mode 100644 index 0000000000..c73be4eb0f --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/prerm @@ -0,0 +1,42 @@ +#! /bin/sh +# prerm script for cl-png +# +# see: dh_installdeb(1) + +set -e + +# package name according to lisp +LISP_PKG=png + +# summary of how this script can be called: +# * `remove' +# * `upgrade' +# * `failed-upgrade' +# * `remove' `in-favour' +# * `deconfigure' `in-favour' +# `removing' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + remove|upgrade|deconfigure) + /usr/sbin/unregister-common-lisp-source ${LISP_PKG} + ;; + failed-upgrade) + ;; + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/cram_3rdparty/cl_png/src/debian/rules b/cram_3rdparty/cl_png/src/debian/rules new file mode 100644 index 0000000000..daff0fcba5 --- /dev/null +++ b/cram_3rdparty/cl_png/src/debian/rules @@ -0,0 +1,67 @@ +#!/usr/bin/make -f + +pkg := png +debpkg := cl-png + + +clc-source := usr/share/common-lisp/source +clc-systems := usr/share/common-lisp/systems +clc-png := $(clc-source)/$(pkg) + +doc-dir := usr/share/doc/$(debpkg) + + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + + touch configure-stamp + + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + # Add here commands to compile the package. + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + # Add here commands to clean up after the build process. + rm -f debian/cl-png.postinst.* debian/cl-png.prerm.* + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + # Add here commands to install the package into debian/png. + dh_installdirs $(clc-systems) $(clc-png) + dh_install png.asd $(shell echo *.cl) $(clc-png) + dh_link $(clc-png)/png.asd $(clc-systems)/png.asd + +# Build architecture-independent files here. +binary-indep: build install + + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs + dh_installchangelogs + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure + diff --git a/cram_3rdparty/cl_png/src/doc/index.html b/cram_3rdparty/cl_png/src/doc/index.html new file mode 100644 index 0000000000..a4100ff6b0 --- /dev/null +++ b/cram_3rdparty/cl_png/src/doc/index.html @@ -0,0 +1,597 @@ + + + + + CL-PNG + + + + +
+ +Fork me on GitHub + +

Vebjorn Ljosa » +Software » CL-PNG + +

CL-PNG

+ +

CL-PNG is a Common Lisp library for reading and writing PNG +(Portable Network Graphics) files. It is currently maintained +by Vebjorn Ljosa, +and new versions can be found at the CL-PNG +homepage, http://www.ljosa.com/~ljosa/software/cl-png/. + +

Copyright © 2001–2010 by the authors (see the file AUTHORS). Licensed under the GNU +Lesser General Public License; see the file COPYING for +details. This manual is in the public domain. + +

Table of contents: +

    +
  1. Status +
  2. Download +
  3. Installation +
  4. Example +
  5. API reference +
  6. Symbol index +
+ +

Status

+ +

CL-PNG 0.6 has been verified to work on the following platforms. +

    +
  • SBCL on Linux (x86_64), Mac OS X (i386 and x86_64), and Windows (i386) +
  • Clozure CL on Mac OS X (ppc and x86_64) +
  • CLISP on Linux (x86_64) +
  • Allegro CL on Mac OS X (i386 and ppc) +
  • LispWorks on Mac OS X (i386) +
+

Please report success/failure on other platforms. + +

Since version 0.5, CL-PNG uses a foreign function interface to call +libpng, the +official PNG reference library. As a result, it benefits from all the +effort that has been put into that library: CL-PNG is much faster than +before, and better able to handle corner cases. + +

The interface is likely to change in future versions. Please report on your + experience with the current interface. + +

The current version has the following limitation: +

    +
  • Alpha channels and metadata (such as timestamps and comments) + cannot be included when writing an image. They are silently + ignored when reading an image. +
+ +

News in version 0.6:

+
    +
  • Can now read from and write to Lisp streams, even those without + file descriptors +
  • Fixed bug causing crash on 64-bit platforms +
  • Can now read, write, and represent 16-bit images. (Previously + downscaled to 8 bits on read.) +
  • Fixed bug in reading of 1, 2, and 4-bit images on CCL DarwinPPC. +
+ +

Download

+ + + + +

Installation

+ +

CL-PNG depends on libpng (your +operating system distribution may have a separate package, called +libpng-dev or something similar, that contains the required +png.h header file) and CFFI. CFFI in turn +depends on Alexandria, Babel, and trivial-features. + +

The easiest way to download and install CL-PNG and the Lisp +libraries that it depends on is +using QuickLisp: +

+    (ql:quickload "png")
+
+ +

If you do not want to use QuickLisp, install the dependencies, then +symlink png.asd (and, if you'd like to run the unit +tests, png-test.asd) to one of the directories +in asdf:*central-registry*. +Then, evaluate (asdf:oos 'asdf:load-op '#:png) in order +to compile and load CL-PNG.

+ +

On Mac OS X 10.4, you may discover that the C compiler does not +accept the -m32 option that CFFI-Grovel +attempts to pass to it. You will need to work around this, for instance +by setting cffi-grovel::*cpu-word-size-flags* to the empty +string. + +

If you would like to run the unit tests, evaluate (asdf:oos +'asdf:load-op '#:png-test) followed by +(lisp-unit:run-all-tests #:png-test). + +

Example

+
+ +
(defun rotate (input-pathname output-pathname)
  "Read a PNG image, rotate it 90 degrees, and write it to a new file."
  (let* ((old (with-open-file (input input-pathname
                                     :element-type '(unsigned-byte 8)
)

                (png:decode input)
)
)

         (new (png:make-image (png:image-width old)
                              (png:image-height old)
                              (png:image-channels old)
                              (png:image-bit-depth old)
)
)

         (m (png:image-width old))
)

      (dotimes (i (png:image-height new))
        (dotimes (j (png:image-width new))
          (dotimes (k (png:image-channels new))
            (setf (aref new i j k) (aref old j (- m i 1) k))
)
)
)

      (with-open-file (output output-pathname :element-type '(unsigned-byte 8)
                              :direction :output :if-exists :supersede
)

        (png:encode new output)
)
)
)
+ +
+

API reference

+ +

Type IMAGE + +

Supertypes:

array, +t + +

Description:

An image is a three-dimensional array of +(unsigned-byte 8) or (unsigned-byte 16). The three +dimensions represent row, column, and channel. +In other words, (aref image i j k) is the intensity in the +k-th channel of the pixel in the i-th row and +j-th column of image.

+ + +

In the current version, an image is displaced to a one-dimensional +simple-array +with the same total number of elements, but applications should not +rely on this implementation detail, as it is likely to change in +future versions. Also, the simple-array +must be allocated in the a static area on some Lisp implementations. +For these reasons, you should use make-image to make your images rather +than call make-array +directly. + + +

Compound Type Specifier Kind: +

Specializing. + +

Compound Type Specifier Syntax: +

image [{ height + | * + } { width + | * + } { channels + | * + }] + +

Compound Type Specifier Arguments: +

height, width, channels---valid +array dimensions + +


+ +

Type 8-BIT-IMAGE + +

Supertypes:

image, array, +t + +

Description: +

An image with element type +(unsigned-byte 8).

+ +

Compound Type Specifier Kind: +

Specializing. + +

Compound Type Specifier Syntax: +

8-bit-image [{ height + | * + } { width + | * + } { channels + | * + }] + +

Compound Type Specifier Arguments: +

height, width, channels---valid +array dimensions + +


+ +

Type 16-BIT-IMAGE + +

Supertypes:

image, array, +t + +

Description: +

An image with element type +(unsigned-byte 16).

+ +

Compound Type Specifier Kind: +

Specializing. + +

Compound Type Specifier Syntax: +

8-bit-image [{ height + | * + } { width + | * + } { channels + | * + }] + +

Compound Type Specifier Arguments: +

height, width, channels---valid +array dimensions + +


+ +

Type GRAYSCALE-IMAGE + +

Supertypes:

image, array, +t + +

Description: +

An image with one channel.

+ +

Compound Type Specifier Kind: +

Specializing. + +

Compound Type Specifier Syntax: +

grayscale-image [{ height + | * + } { width + | * + }] + +

Compound Type Specifier Arguments: +

height, width---valid +array dimensions + +

Notes: +

(grayscale-image n m) == (image n m 1) + +


+ +

Type RGB-IMAGE + +

Supertypes:

image, array, +t + +

Description: +

An image with three channels.

+ +

Compound Type Specifier Kind: +

Specializing. + +

Compound Type Specifier Syntax: +

rgb-image [{ height + | * + } { width + | * + }] + +

Compound Type Specifier Arguments: +

height, width---valid +array dimensions + +

Notes: +

(rgb-image n m) == (image n m 3) + +


+ +

Function MAKE-IMAGE + +

Syntax: + +

make-image height width channels &optional bit-depth => image + +

Arguments and Values: + +

height, width, channels---valid +array dimensions + +

bit-depth---either 8, or 16, or nil + +

image---an image + +

Description:

Makes a new image with the specified height, width, and +number of channels. +The image will be an 8-bit-image if +bit-depth is 8 or nil, and a 16-bit-image if bit-depth is +16. The contents of the image are undefined. + +


+ +

Function IMAGE-HEIGHT + +

Syntax: + +

image-height image => height + +

Arguments and Values: + +

image---an image +

height---a valid +array dimension + +

Description: +

Returns the height of image, i.e., the number of rows.

+ +
+

Function IMAGE-WIDTH + +

Syntax: + +

image-width image => width + +

Arguments and Values: + +

image---an image +

width---a valid +array dimension + +

Description: +

Returns the width of image, i.e., the number of columns.

+ +
+ +

Function IMAGE-CHANNELS + +

Syntax: +

image-channels image => channels + +

Arguments and Values: +

image---an image +

channels---a valid +array dimension + +

Description: +

Returns the number +of channels +in image. Grayscale images have one channel, whereas RGB +images have three.

+ +
+ +

Function IMAGE-BIT-DEPTH + +

Syntax: +

image-bit-depth image => bit-depth + +

Arguments and Values: +

image---an image +

bit-depth---either 8 or 16 + +

Description:

Returns the bit-depth of the image, i.e., +the number of bits in the byte representing each sample. The bit +depth of an 8-bit-image is 8, and +the bit-depth of a 16-bit-image is +16.

+ +
+ +

Function COPY-IMAGE + +

Syntax: +

copy-image image => copied-image + +

Arguments and Values: +

image---an image +

copied-image---an image + +

Description:

Creates a copy of image. The +elements of the new image are the same +as the corresponding elements of image, and copied-image +has the same height, width, number of channels, and bit depth as +image.

+ +
+ +

Function 8-BIT-IMAGE + +

Syntax: +

8-bit-image image => result-image + +

Arguments and Values: +

image---an image +

result-image---an image + +

Description:

If image is an 8-bit-image, return it or a copy of it. +If image is a 16-bit-image, +return an 8-bit-image that has the +same width, height, and number of channels as image, but where +each element is the corresponding element in image divided by +257 and rounded to the nearest integer. The effect of this division +is to compress the dynamic range of the image so as to fit within the +smaller bit depth.

+ +
+ +

Function 16-BIT-IMAGE + +

Syntax: +

16-bit-image image => result-image + +

Arguments and Values: +

image---an image +

result-image---an image + +

Description:

If image is a 16-bit-image, return it or a copy of +it. If image is an 8-bit-image, return a 16-bit-image that has the same width, +height, and number of channels as image, but where each element +is the corresponding element in image multiplied by 257. The +effect of this multiplication is to stretch the dynamic range of the +image to utilize the increased bit depth.

+ +
+ +

Function DECODE + +

Syntax: +

decode input => image + +

Arguments and Values: +

input---an fd input +stream

+

image---an image + +

Description:

Reads an image in PNG format from +input and returns an array of type image. If the bit depth of the PNG file is +less than or equal to 8, an 8-bit-image will be returned; +otherwise, a 16-bit-image will be +returned. + +

Applications that would like to receive images of consistent bit +depth (rather than 8 or 16 depending on the PNG file) can apply the +function 8-bit-image or the +function 16-bit-image to the +result of decode. + +

An image with bit depths below 8 will be converted to 8 bits when +read, and an image with bit depths between 8 and 16 bits will be +converted to 16 bits. As an example, a 2-bit PNG file contains only the +pixel values 0, 1, 2, and 3. These will be converted to 0, 85, 170, +and 255, respectively, in order to fill the dynamic range of the 8-bit +image that is returned. + +

Exceptional Situations: +

Signals +an error +if reading the image fails.

+ +
+ +

Function ENCODE + +

Syntax: +

encode image output => t + +

Arguments and Values: +

image---a grayscale-image or rgb-image +

output---an fd output +stream

+ +

Description:

Writes image in PNG format to +output. The current version always writes an 8-bit PNG file if +image is an 8-bit-image and a +16-bit PNG file if image is an 16-bit-image. Future versions may +write PNG files of lower bit depths than image when the least +significant bits may be trimmed without loss of precision. + +

Exceptional Situations:

Signals an error +if writing the image fails. +

+ +
+ +

SYMBOL INDEX:

+ + + +
+ +

Last updated: 2013-07-24

+
+ + diff --git a/cram_3rdparty/cl_png/src/doc/tutorial.lisp b/cram_3rdparty/cl_png/src/doc/tutorial.lisp new file mode 100644 index 0000000000..02d99a96c8 --- /dev/null +++ b/cram_3rdparty/cl_png/src/doc/tutorial.lisp @@ -0,0 +1,73 @@ +(defpackage #:tutorial + (:use #:common-lisp #:lisp-unit #:png) + (:export #:*images-pathname*)) +(in-package #:tutorial) + +;;;# IMAGE arrays +;;; +;;; An image is a 3-dimensional array of row, column, and channel +;;; representing pixels. +;;; +;;; The BIT-DEPTH is the size of unsigned-byte used representing the +;;; array. Currently, this is restricted to 8 or 16. +;;; +;;;## Image types +;;; +;;; The following image types are defined: 8-BIT-IMAGE, 16-BIT-IMAGE, +;;; GRAY-SCALE-IMAGE, RGB-IMAGE, ARGB-IMAGE. +;;; +;;; Note that the Lisp TYPE-OF function returns the size as well as +;;; the element type for an array. This means that if you compare +;;; types you are also comparing image sizes. + +(let ((a (make-image 200 300 3 8)) + (b (make-image 200 300 3 16)) + (c (make-image 200 301 3 8)) + (d (make-image 200 300 3 8))) + (format t "~&TYPE-OF A: ~s~%" (type-of a)) + (format t " A equals B: ~a~%" (equal (type-of a) (type-of b))) + (format t " A equals C: ~a~%" (equal (type-of a) (type-of c))) + (format t " A equals D: ~a~%" (equal (type-of a) (type-of d)))) + +;; TYPE-OF A: (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (200 300 3)) +;; A equals B: NIL +;; A equals C: NIL +;; A equals D: T + +;;;# Operations on IMAGEs +;;; +;;; + + + +;;;# Encoders and Decoders +;;; +;;;## PNG +;;; +;;; TBD +;;; +;;;### Example +;;; +(defun rotate-file (input-pathname output-pathname) + "Read a PNG image, rotate it 90 degrees CCW, and write it to a new file." + (let* ((old (with-open-file (input input-pathname :element-type '(unsigned-byte 8)) + (decode input))) + (new (rotate old))) + (with-open-file (output output-pathname :element-type '(unsigned-byte 8) + :direction :output :if-exists :supersede) + (encode new output)))) + + +;;;## BMP +;;; +;;; TBD +;;; +;;;### Example +;;; +;;; TBD + +;;;## TIF, JPEG, and other formats +;;; +;;; Planned but not implemented yet. +;;; + diff --git a/cram_3rdparty/cl_png/src/example.lisp b/cram_3rdparty/cl_png/src/example.lisp new file mode 100644 index 0000000000..33e5a8a090 --- /dev/null +++ b/cram_3rdparty/cl_png/src/example.lisp @@ -0,0 +1,23 @@ +(defpackage #:png-example + (:use #:common-lisp) + (:export #:rotate)) + +(in-package #:png-example) + +(defun rotate (input-pathname output-pathname) + "Read a PNG image, rotate it 90 degrees, and write it to a new file." + (let* ((old (with-open-file (input input-pathname + :element-type '(unsigned-byte 8)) + (png:decode input))) + (new (png:make-image (png:image-width old) + (png:image-height old) + (png:image-channels old) + (png:image-bit-depth old))) + (m (png:image-width old))) + (dotimes (i (png:image-height new)) + (dotimes (j (png:image-width new)) + (dotimes (k (png:image-channels new)) + (setf (aref new i j k) (aref old j (- m i 1) k))))) + (with-open-file (output output-pathname :element-type '(unsigned-byte 8) + :direction :output :if-exists :supersede) + (png:encode new output)))) diff --git a/cram_3rdparty/cl_png/src/grovel.lisp b/cram_3rdparty/cl_png/src/grovel.lisp new file mode 100644 index 0000000000..c16352f447 --- /dev/null +++ b/cram_3rdparty/cl_png/src/grovel.lisp @@ -0,0 +1,26 @@ +(flag "-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/usr/X11/include") +(flag "-I/opt/local/include") +(include "png.h") + +(in-package #:png) + +(constant (+png-color-mask-palette+ "PNG_COLOR_MASK_PALETTE")) +(constant (+png-color-mask-color+ "PNG_COLOR_MASK_COLOR")) +(constant (+png-color-mask-alpha+ "PNG_COLOR_MASK_ALPHA")) +(constant (+png-color-type-palette+ "PNG_COLOR_TYPE_PALETTE")) +(constant (+png-color-type-rgb+ "PNG_COLOR_TYPE_RGB")) +(constant (+png-color-type-rgb-alpha+ "PNG_COLOR_TYPE_RGB_ALPHA")) +(constant (+png-color-type-gray+ "PNG_COLOR_TYPE_GRAY")) +(constant (+png-color-type-gray-alpha+ "PNG_COLOR_TYPE_GRAY_ALPHA")) +(constant (+png-transform-strip-16+ "PNG_TRANSFORM_STRIP_16")) +(constant (+png-transform-strip-alpha+ "PNG_TRANSFORM_STRIP_ALPHA")) +(constant (+png-transform-swap-endian+ "PNG_TRANSFORM_SWAP_ENDIAN")) +(constant (+png-compression-type-base+ "PNG_COMPRESSION_TYPE_BASE")) +(constant (+png-compression-type-default+ "PNG_COMPRESSION_TYPE_DEFAULT")) +(constant (+png-filter-type-base+ "PNG_FILTER_TYPE_BASE")) +(constant (+png-filter-type-default+ "PNG_FILTER_TYPE_DEFAULT")) +(constant (+png-transform-identity+ "PNG_TRANSFORM_IDENTITY")) +(constant (+png-interlace-none+ "PNG_INTERLACE_NONE")) +(ctype ssize "ssize_t") +(ctype size "size_t") +(ctype png-size "png_size_t") diff --git a/cram_3rdparty/cl_png/src/image-package.lisp b/cram_3rdparty/cl_png/src/image-package.lisp new file mode 100644 index 0000000000..e0e1baee35 --- /dev/null +++ b/cram_3rdparty/cl_png/src/image-package.lisp @@ -0,0 +1,52 @@ +(in-package #:cl-user) + +(defpackage #:image + (:documentation "Image representation and manipulation.") + (:use #:common-lisp) + (:export + ;; image.lisp + #:image + #:8-bit-image + #:16-bit-image + #:grayscale-image + #:grayscale-alpha-image + #:rgb-image + #:rgb-alpha-image + #:transparent-image + #:opaque-image + #:make-image + #:copy-image + #:image-height + #:image-width + #:image-channels + #:image-alpha + #:image-bit-depth + ;; ops.lisp + #:mismatched-image-types + #:mismatched-image-sizes + #:mismatched-image-dims + #:make-image-like + #:size + #:dims + #:fillv + #:channel-min + #:channel-max + #:intensity-max + #:norm2 + #:rotate + #:flip + #:mirror + #:add + #:add* + #:subtract + #:subtract* + #:threshold-filter + #:binary-morphological-filter + #:erosion-filter + #:dilation-filter + #:majority-filter + #:open-filter + #:close-filter + #:move-towards + #:convolve + )) diff --git a/cram_3rdparty/cl_png/src/image.lisp b/cram_3rdparty/cl_png/src/image.lisp new file mode 100644 index 0000000000..656487cfed --- /dev/null +++ b/cram_3rdparty/cl_png/src/image.lisp @@ -0,0 +1,342 @@ +;;; TODO: +;;; * The displacement messes up the type inference, so making image +;;; operations efficient is a pain. Should see if I can just pass +;;; the 3-D array to the C functions. + +(defpackage #:image + (:documentation "Image representation and manipulation.") + (:use #:common-lisp) + (:export + ;; image.lisp + #:image + #:8-bit-image + #:16-bit-image + #:grayscale-image + #:grayscale-alpha-image + #:rgb-image + #:rgb-alpha-image + #:transparent-image + #:opaque-image + #:make-image + #:copy-image + #:image-height + #:image-width + #:image-channels + #:image-alpha + #:image-bit-depth + ;; ops.lisp + #:mismatched-image-types + #:mismatched-image-sizes + #:mismatched-image-dims + #:make-image-like + #:size + #:dims + #:fillv + #:channel-min + #:channel-max + #:intensity-max + #:norm2 + #:rotate + #:flip + #:mirror + #:add + #:add* + #:subtract + #:subtract* + #:threshold-filter + #:binary-morphological-filter + #:erosion-filter + #:dilation-filter + #:majority-filter + #:open-filter + #:close-filter + #:move-towards + #:convolve)) + +(in-package #:image) + +(deftype 8-bit-image (&optional height width channels) + "An IMAGE with element type (UNSIGNED-BYTE 8)." + `(and (simple-array (unsigned-byte 8) (,height ,width ,channels)))) + +(deftype 16-bit-image (&optional height width channels) + "An IMAGE with element type (UNSIGNED-BYTE 16)." + `(and (simple-array (unsigned-byte 16) (,height ,width ,channels)))) + +(deftype image (&optional height width channels) + "A three-dimensional array of (unsigned-byte 8) or (unsigned-byte +16). In the current version, an IMAGE is displaced to a +one-dimensional SIMPLE-ARRAY with the same total number of elements, +but applications should not rely on this implementation detail, as it +is likely to change in future versions. The functions MAKE-IMAGE, +DECODE, COPY-IMAGE, 8-BIT-IMAGE, AND 16-BIT-IMAGE return IMAGEs. + +The three dimensions represent row, column, and channel. In other +words, (aref image i j k) is the intensity in the k-th channel of the +pixel in the i-th row and j-th column of image." + `(or (8-bit-image ,height ,width ,channels) + (16-bit-image ,height ,width ,channels))) + +(defun even-channels-p (image) + (evenp (array-dimension image 2))) + +(deftype transparent-image (&optional height width) + "An IMAGE with either two or four channels (i.e. has an alphs +channel)." + `(and (image ,height ,width) + (satisfies even-channels-p))) + +(deftype opaque-image (&optional height width) + "An IMAGE with either 1 or 3 channels" + `(and (image ,height ,width) + (not (satisfies even-channels-p)))) + +(defun color-channels-p (image) + (> (array-dimension image 2) 2)) + +(deftype rgb-image (&optional height width) + "An IMAGE with either three or four channels." + `(and (image ,height ,width) + (satisfies color-channels-p))) + +(defun color-and-alpha-channels-p (image) + (= (array-dimension image 2) 4)) + +(deftype rgb-alpha-image (&optional height width) + "An IMAGE with exactly four channels." + `(and (image ,height ,width) + (satisfies color-and-alpha-channels-p))) + +(defun grayscale-channels-p (image) + (<= (array-dimension image 2) 2)) + +(deftype grayscale-image (&optional height width) + "An IMAGE with either one or two channels." + `(and (image ,height ,width) + (satisfies grayscale-channels-p))) + +(defun grayscale-alpha-channels-p (image) + (= (array-dimension image 2) 2)) + +(deftype grayscale-alpha-image (&optional height width) + "An IMAGE with exactly two channels." + `(and (image ,height ,width) + (satisfies grayscale-alpha-channels-p))) + +(defun make-shareable-array (&rest args) + #+(or lispworks3 lispworks4 lispworks5.0) + (sys:in-static-area + (apply #'make-array args)) + #-(or lispworks3 lispworks4 lispworks5.0) + (apply #'make-array + #+(or lispworks allegro) :allocation + #+lispworks :static #+allegro :static-reclaimable + args)) + +(defun make-image (height width channels &optional bit-depth) + "Make a new IMAGE of the specified height, width, and number of +channels. The image will be an 8-bit-image or a 16-bit-image depending +on the value of byte-size. Makes an 8-BIT-IMAGE if BIT-DEPTH is 8 or +NIL and a 16-BIT-IMAGE if BIT-DEPTH is 16. The contents of the image +are undefined." + (make-shareable-array (list height width channels) + :element-type (ecase bit-depth + ((8 nil) '(unsigned-byte 8)) + (16 '(unsigned-byte 16))))) + +(defun image-height (image) + "The height of image, i.e., the number of rows." + (array-dimension image 0)) + +(defun image-width (image) + "The width of IMAGE, i.e., the number of columns." + (array-dimension image 1)) + +(defun image-channels (image) + "The number of channels in IMAGE. Grayscale images have one +channel, whereas RGB images have three." + (array-dimension image 2)) + +(defun image-alpha (image) + "Returns T if there is an alpha channel, NIL otherwise." + (evenp (array-dimension image 2))) + +(defun image-bit-depth (image) + "Returns the bit-depth of the image, i.e., the number of bits in the +byte representing each sample. The bit depth is 8 or 16, depending on +whether the image is an 8-bit-image or a 16-bit-image, respectively." + (etypecase image + (8-bit-image 8) + (16-bit-image 16))) + +(defun copy-image (image) + "Creates a copy of IMAGE. The elements of the new image are the same +as the corresponding elements of IMAGE, and the new image has the same +height, width, number of channels, and bit depth as IMAGE." + (let ((new (make-image (image-height image) (image-width image) + (image-channels image) (image-bit-depth image)))) + (dotimes (i (array-total-size image) new) + (setf (row-major-aref new i) (row-major-aref image i))))) + +(defun 8-bit-image (image) + "If IMAGE is an 8-BIT-IMAGE, return it or a copy of it. If IMAGE is +a 16-BIT-IMAGE, return an 8-BIT-IMAGE that has the same width, height, +and number of channels as image, but where each element is the +corresponding element in image divided by 257 and rounded to the +nearest integer. The effect of this division is to compress the +dynamic range of the image so as to fit within the smaller bit depth." + (etypecase image + (8-bit-image image) + (16-bit-image + (let ((new (make-image (image-height image) (image-width image) + (image-channels image) 8))) + (dotimes (i (array-total-size image) new) + (setf (row-major-aref new i) (round (row-major-aref image i) 257))))))) + +(defun 16-bit-image (image) + "If IMAGE is a 16-BIT-IMAGE, return it or a copy of it. If IMAGE is +an 8-BIT-IMAGE, return a 16-BIT-IMAGE that has the same width, height, +and number of channels as IMAGE, but where each element is the +corresponding element in image multiplied by 257. The effect of this +multiplication is to stretch the dynamic range of the image to utilize +the increased bit depth." + (etypecase image + (16-bit-image image) + (8-bit-image + (let ((new (make-image (image-height image) (image-width image) + (image-channels image) 16))) + (dotimes (i (array-total-size image) new) + (setf (row-major-aref new i) (* 257 (row-major-aref image i)))))))) + +(defun grayscale-image (image) + "If IMAGE is a GRAYSCALE-IMAGE, return it, otherwise return a +GRAYSCALE-IMAGE of the same width and height whose corresponding +elements are the average of the channel intensities of IMAGE. +Strip out any alpha channel present." + (flet ((convert () + (let* ((bit-depth (image-bit-depth image)) + (gray (make-image (image-height image) (image-width image) + 1 bit-depth)) + (tp `(unsigned-byte ,bit-depth))) + (dotimes (h (image-height image) gray) + (dotimes (w (image-width image)) + ;; average the RGB channel intensities + (let ((avg (+ (coerce (aref image h w 0) 'float) + (coerce (aref image h w 1) 'float) + (coerce (aref image h w 2) 'float)))) + (setf (aref gray h w 0) (coerce (floor avg 3) tp))))))) + (strip () + (let ((gray (make-image (image-height image) (image-width image) + 1 (image-bit-depth image)))) + (dotimes (h (image-height image) gray) + (dotimes (w (image-width image)) + (setf (aref gray h w 0) (aref image h w 0))))))) + (etypecase image + (grayscale-alpha-image (strip)) + (grayscale-image image) + (t (convert))))) + +(defun grayscale-alpha-image (image) + "If IMAGE is a GRAYSCALE-ALPHA-IMAGE, return it, otherwise return a +GRAYSCALE-ALPHA-IMAGE of the same width and height whose corresponding +elements are the average of the channel intensities of IMAGE. +Add an alpha channel if needed." + (flet ((convert () + (let* ((bit-depth (image-bit-depth image)) + (gray (make-image (image-height image) (image-width image) + 2 bit-depth)) + (tp `(unsigned-byte ,bit-depth)) + (use-this-alpha (cond + ((image-alpha image) nil) + ((= bit-depth 8) 255) + ((= bit-depth 16) 65535)))) + (dotimes (h (image-height image) gray) + (dotimes (w (image-width image)) + ;; average the RGB channel intensities + (let ((avg (+ (coerce (aref image h w 0) 'float) + (coerce (aref image h w 1) 'float) + (coerce (aref image h w 2) 'float)))) + (setf (aref gray h w 0) (coerce (floor avg 3) tp) + (aref gray h w 1) (or use-this-alpha + (aref image h w 3)))))))) + (add-alpha () + (let* ((bit-depth (image-bit-depth image)) + (gray (make-image (image-height image) (image-width image) + 2 bit-depth)) + (use-this-alpha (cond + ((= bit-depth 8) 255) + ((= bit-depth 16) 65535)))) + (dotimes (h (image-height image) gray) + (dotimes (w (image-width image)) + (setf (aref gray h w 0) (aref image h w 0) + (aref gray h w 1) use-this-alpha)))))) + (etypecase image + (grayscale-alpha-image image) + (grayscale-image (add-alpha)) + (t (convert))))) + +(defun rgb-image (image) + "If IMAGE is an RGB-IMAGE, return it, otherwise return an +RGB-IMAGE of the same width and height whose corresponding +elements are the grayscale value repeated as needed. Strip +out any alpha channels." + (flet ((convert () + (let ((rgb (make-image (image-height image) (image-width image) + 3 (image-bit-depth image)))) + (dotimes (h (image-height image) rgb) + (dotimes (w (image-width image)) + (setf (aref rgb h w 0) (aref image h w 0) + (aref rgb h w 1) (aref image h w 0) + (aref rgb h w 2) (aref image h w 0)))))) + (strip () + (let ((rgb (make-image (image-height image) (image-width image) + 3 (image-bit-depth image)))) + (dotimes (h (image-height image) rgb) + (dotimes (w (image-width image)) + (setf (aref rgb h w 0) (aref image h w 0) + (aref rgb h w 1) (aref image h w 1) + (aref rgb h w 2) (aref image h w 2))))))) + (etypecase image + (rgb-alpha-image (strip)) + (rgb-image image) + (t (convert))))) + +(defun rgb-alpha-image (image) + "If IMAGE is a RGB-ALPHA-IMAGE, return it, otherwise return a +RGB-ALPHA-IMAGE of the same width and height whose corresponding +elements are the rgb elements of the original if the original is +an RGB-IMAGE and the repeated grayscale values if the original is +a GRAYSCALE image. Add an alpha channel if needed." + (flet ((convert () + (let* ((bit-depth (image-bit-depth image)) + (rgba (make-image (image-height image) (image-width image) + 4 bit-depth)) + (use-this-alpha (cond + ((image-alpha image) nil) + ((= bit-depth 8) 255) + ((= bit-depth 16) 65535)))) + (dotimes (h (image-height image) rgba) + (dotimes (w (image-width image)) + ;; average the RGB channel intensities + (setf (aref rgba h w 0) (aref image h w 0) + (aref rgba h w 1) (aref image h w 0) + (aref rgba h w 2) (aref image h w 0) + (aref rgba h w 3) (or use-this-alpha + (aref image h w 1))))))) + (add-alpha () + (let* ((bit-depth (image-bit-depth image)) + (rgba (make-image (image-height image) (image-width image) + 4 bit-depth)) + (use-this-alpha (cond + ((= bit-depth 8) 255) + ((= bit-depth 16) 65535)))) + (dotimes (h (image-height image) rgba) + (dotimes (w (image-width image)) + (setf (aref rgba h w 0) (aref image h w 0) + (aref rgba h w 1) (aref image h w 1) + (aref rgba h w 2) (aref image h w 2) + (aref rgba h w 3) use-this-alpha)))))) + (etypecase image + (rgb-alpha-image image) + (rgb-image (add-alpha)) + (t (convert))))) diff --git a/cram_3rdparty/cl_png/src/libpng.lisp b/cram_3rdparty/cl_png/src/libpng.lisp new file mode 100644 index 0000000000..f4cbcc11d0 --- /dev/null +++ b/cram_3rdparty/cl_png/src/libpng.lisp @@ -0,0 +1,363 @@ +(in-package #:png) + +#+cffi-features:darwin +(push #p"/usr/X11/lib/" cffi:*foreign-library-directories*) + +#+cffi-features:darwin +(push #p"/opt/local/lib/" cffi:*foreign-library-directories*) + +(define-foreign-library libpng + (:darwin "libpng.dylib") + (t (:default "libpng"))) + +(use-foreign-library libpng) + +(defparameter +png-libpng-ver-string+ (get-png-libpng-ver-string)) + +;;; Foreign function definitions. + +(defcfun "png_access_version_number" :uint32) + +(defcfun "png_create_read_struct" :pointer + (user-png-ver :string) + (error-ptr :pointer) + (error-fn :pointer) + (warn-fn :pointer)) + +(defcfun "png_destroy_read_struct" :void + (png-ptr-ptr :pointer) + (info-ptr-ptr :pointer) + (end-info-ptr-ptr :pointer)) + +(defcfun "png_create_write_struct" :pointer + (user-png-ver :string) + (error-ptr :pointer) + (error-fn :pointer) + (warn-fn :pointer)) + +(defcfun "png_destroy_write_struct" :void + (png-ptr-ptr :pointer) + (info-ptr-ptr :pointer)) + +(defcfun "png_create_info_struct" :pointer + (png-ptr :pointer)) + +(defcfun "png_destroy_info_struct" :void + (png-ptr :pointer) + (info-ptr-ptr :pointer)) + +(defcfun "png_init_io" :void + (png-ptr :pointer) + (file :pointer)) + +(defcfun "png_set_read_fn" :void + (png-ptr :pointer) + (io-ptr :pointer) + (read-data-fn :pointer)) + +(defcfun "png_set_write_fn" :void + (png-ptr :pointer) + (io-ptr :pointer) + (write-data-fn :pointer) + (output-flush-fn :pointer)) + +(defcfun "png_get_io_ptr" :pointer + (png-ptr :pointer)) + +(defcfun "png_read_info" :void + (png-ptr :pointer) + (info-ptr :pointer)) + +(defcfun "png_read_png" :void + (png-ptr :pointer) + (info-ptr :pointer) + (png-transforms :int) + (params :pointer)) + +(defcfun "png_get_IHDR" :uint32 + (png-ptr :pointer) + (info-ptr :pointer) + (width-uint32-ptr :pointer) + (height-uint32-ptr :pointer) + (bit-depth-int-ptr :pointer) + (color-type-int-ptr :pointer) + (interlace-type-int-ptr :pointer) + (compression-type-int-ptr :pointer) + (filter-type-int-ptr :pointer)) + +(defcfun "png_set_IHDR" :void + (png-ptr :pointer) + (info-ptr :pointer) + (width :uint32) + (height :uint32) + (bit-depth :int) + (color-type :int) + (interlace-type :int) + (compression-type :int) + (filter-type :int)) + +(defcfun "png_set_bgr" :void + (png-ptr :pointer)) + +(defcfun "png_set_palette_to_rgb" :void + (png-ptr :pointer)) + +(defcfun "png_set_expand_gray_1_2_4_to_8" :void + (png-ptr :pointer)) + +(defcfun "png_set_expand" :void + (png-ptr :pointer)) + +(defcfun "png_get_valid" :uint32 + (png-ptr :pointer) + (info-ptr :pointer) + (flag :uint32)) + +(defcfun "png_set_tRNS_to_alpha" :void + (png-ptr :pointer)) + +(defcfun "png_set_strip_16" :void + (png-ptr :pointer)) + +(defcfun "png_set_strip_alpha" :void + (png-ptr :pointer)) + +(defcfun "png_set_swap" :void + (png-ptr :pointer)) + +(defcfun "png_get_rows" :pointer + (png-ptr :pointer) + (info-ptr :pointer)) + +(defcfun "png_set_rows" :void + (png-ptr :pointer) + (info-ptr :pointer) + (row-pointers :pointer)) + +(defcfun "png_read_image" :void + (png-ptr :pointer) + (row-pointers :pointer)) + +(defcfun "png_write_png" :void + (png-ptr :pointer) + (info-ptr :pointer) + (transforms :int) + (params :pointer)) + +(defcfun "memcpy" :pointer + (dest :pointer) + (source :pointer) + (n size)) + + +;;; Input/output. + +(defvar *stream*) + +(defvar *buffer*) + +(defun ensure-buffer-sufficient (needed) + (when (< (length *buffer*) needed) + (let ((new-length (length *buffer*))) + (loop while (< new-length needed) + do (setf new-length (* 2 new-length))) + (setf *buffer* (make-shareable-byte-vector new-length))))) + +(defcallback user-read-data :void ((png-ptr :pointer) (data :pointer) + (length png-size)) + (declare (ignore png-ptr)) + (ensure-buffer-sufficient length) + (let ((bytes-read (read-sequence *buffer* *stream* :start 0 :end length))) + (unless (= bytes-read length) + (error "Expected to read ~D bytes, but only read ~D." length + bytes-read))) + (with-pointer-to-vector-data (buffer-ptr *buffer*) + (memcpy data buffer-ptr length))) + +(defcallback user-write-data :void ((png-ptr :pointer) (data :pointer) + (length png-size)) + (declare (ignore png-ptr)) + (ensure-buffer-sufficient length) + (with-pointer-to-vector-data (buffer-ptr *buffer*) + (memcpy buffer-ptr data length)) + (write-sequence *buffer* *stream* :start 0 :end length)) + +(defcallback user-flush-data :void ((png-ptr :pointer)) + (declare (ignore png-ptr))) + + +;;; Error handling. + +(defcallback error-fn :void ((png-structp :pointer) (message :string)) + (declare (ignore png-structp)) + (error message)) + +(defcallback warn-fn :void ((png-structp :pointer) (message :string)) + (declare (ignore png-structp)) + (error message)) + + +;;; Encode and decode PNG files. + +(defmacro with-png-struct ((var &key (direction :input)) &body body) + (let ((pointer (gensym "POINTER"))) + `(let ((,var (,(ecase direction + (:input 'png-create-read-struct) + (:output 'png-create-write-struct)) + +png-libpng-ver-string+ (null-pointer) + (callback error-fn) (callback warn-fn))) + (*buffer* (make-shareable-byte-vector 1024))) + (when (null-pointer-p ,var) + (error "Failed to allocate PNG write struct.")) + (unwind-protect (progn ,@body) + (with-foreign-pointer (,pointer (foreign-type-size :pointer)) + (setf (mem-ref ,pointer :pointer) ,var) + ,(ecase direction + (:input `(png-destroy-read-struct ,pointer (null-pointer) + (null-pointer))) + (:output `(png-destroy-write-struct ,pointer + (null-pointer))))))))) + +(defmacro with-png-info-struct ((var png-struct initform) &body body) + (let ((pointer (gensym "POINTER"))) + `(let ((,var ,initform)) + (when (null-pointer-p ,var) + (error "Failed to allocate PNG info struct.")) + (unwind-protect (progn ,@body) + (with-foreign-pointer (,pointer (foreign-type-size :pointer)) + (setf (mem-ref ,pointer :pointer) ,var) + (png-destroy-info-struct ,png-struct ,pointer)))))) + +(defun get-ihdr (png-ptr info-ptr) + (with-foreign-pointer (width (foreign-type-size :uint32)) + (with-foreign-pointer (height (foreign-type-size :uint32)) + (with-foreign-pointer (bit-depth (foreign-type-size :int)) + (with-foreign-pointer (color-type (foreign-type-size :int)) + (png-get-ihdr png-ptr info-ptr width height bit-depth + color-type (null-pointer) (null-pointer) + (null-pointer)) + (values (mem-ref width :uint32) (mem-ref height :uint32) + (mem-ref bit-depth :int) (mem-ref color-type :int))))))) + +(defun bytes-per-pixel (image) + (ecase (image-bit-depth image) + (16 2) + (8 1))) + +(defmacro with-row-pointers ((rows-ptr image) + &body body) + (let ((row-pointers (gensym "ROW-POINTERS")) + (raw-data (gensym "RAW-DATA")) + (i (gensym "I"))) + `(let ((,row-pointers (make-shareable-byte-vector + (* (image-height ,image) + (foreign-type-size :pointer))))) + (with-pointer-to-vector-data (,rows-ptr ,row-pointers) + (with-pointer-to-array-data (,raw-data ,image) + (dotimes (,i (image-height ,image)) + (setf (mem-aref ,rows-ptr :pointer ,i) + (inc-pointer ,raw-data (* ,i (image-width ,image) + (image-channels ,image) + (bytes-per-pixel ,image))))) + ,@body))))) + +(defun grayp (color-type) + (zerop (logand color-type (lognot +png-color-mask-alpha+)))) + +(defun decode (input &key swapbgr preserve-alpha) + "Reads an image in PNG format from input and returns an array of +type IMAGE. If the bit depth of the PNG file is less than or equal to +8, an 8-BIT-IMAGE will be returned; otherwise, a 16-BIT-IMAGE will be +returned. + +Applications that would like to receive images of consistent bit +depth (rather than 8 or 16 depending on the PNG file) can apply the +function 8-BIT-IMAGE or the function 16-BIT-IMAGE to the result of +DECODE. + +Bit depths less than 8 will be converted to 8 bits when read, and bit +depths between 8 and 16 bits will be converted to 16 bits. As an +example, 2-bit PNG files contain only the pixel values 0, 1, 2, and 3. +These will be converted to 0, 85, 170, and 255, respectively, in order +to fill the dynamic range of the 8-bit image that is returned. + +Swaps blue and red if SWAPBGR set. + +Strips alpha channel unless PRESERVE-ALPHA is set. + +Signals an error if reading the image fails." + (with-png-struct (png-ptr :direction :input) + (with-png-info-struct (info-ptr png-ptr (png-create-info-struct png-ptr)) + (with-png-info-struct (end-ptr png-ptr (png-create-info-struct png-ptr)) + (let ((*stream* input)) + (png-set-read-fn png-ptr (null-pointer) (callback user-read-data)) + (png-read-info png-ptr info-ptr) + (multiple-value-bind (width height bit-depth color-type) + (get-ihdr png-ptr info-ptr) + (when (= color-type +png-color-type-palette+) + (png-set-palette-to-rgb png-ptr)) + (when (grayp color-type) + ;; png-set-expand-gray-1-2-4-to-8 did nothing on CCL + ;; DarwinPPC, but png-set-expand seems to work. + (png-set-expand png-ptr)) + #+little-endian + (when (= bit-depth 16) + (png-set-swap png-ptr)) + (unless (or preserve-alpha + (zerop (logand color-type +png-color-mask-alpha+))) + (png-set-strip-alpha png-ptr)) + (when swapBGR + (png-set-bgr png-ptr)) + (let* ((alphas (if (and preserve-alpha + (plusp (logand color-type + +png-color-mask-alpha+))) + 1 0)) + (image (make-image height width + (+ (if (grayp color-type) 1 3) alphas) + (if (= 16 bit-depth) 16 8)))) + (with-row-pointers (row-pointers image) + (png-set-rows png-ptr info-ptr row-pointers) + (png-read-image png-ptr row-pointers)) + image))))))) + +(defun decode-file (pathname &key swapbgr) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (decode input :swapbgr swapbgr))) + +(defun encode (image output &key swapbgr) + "Writes IMAGE in PNG format to OUTPUT. The current version always +writes an 8-bit PNG file if image is an 8-BIT-IMAGE and a 16-bit PNG +file if image is an 16-BIT-IMAGE. Future versions may write PNG files +of lower bit depths than IMAGE when the least significant bits may be +trimmed without loss of precision. + +Signals an error if writing the image fails." + (check-type image (or grayscale-image rgb-image)) + (with-png-struct (png-ptr :direction :output) + (with-png-info-struct (info-ptr png-ptr (png-create-info-struct png-ptr)) + (let ((*stream* output)) + (png-set-write-fn png-ptr (null-pointer) (callback user-write-data) + (callback user-flush-data)) + (png-set-ihdr png-ptr info-ptr (image-width image) (image-height image) + (image-bit-depth image) + (ecase (image-channels image) + (1 +png-color-type-gray+) + (2 +png-color-type-gray-alpha+) + (3 +png-color-type-rgb+) + (4 +png-color-type-rgb-alpha+)) + +png-interlace-none+ +png-compression-type-default+ + +png-filter-type-default+) + (when swapBGR + (png-set-bgr png-ptr)) + (with-row-pointers (row-pointers image) + (png-set-rows png-ptr info-ptr row-pointers) + (png-write-png png-ptr info-ptr + #+little-endian +png-transform-swap-endian+ + #-little-endian +png-transform-identity+ + (null-pointer)))))) + t) + +(defun encode-file (image pathname &key swapbgr) + (with-open-file (output pathname :element-type '(unsigned-byte 8) + :direction :output :if-exists :supersede) + (encode image output :swapbgr swapbgr))) diff --git a/cram_3rdparty/cl_png/src/make-dist.sh b/cram_3rdparty/cl_png/src/make-dist.sh new file mode 100755 index 0000000000..2a12ab1c1e --- /dev/null +++ b/cram_3rdparty/cl_png/src/make-dist.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -e +version="$1" +if [ -z "$version" ]; then + exec >&2 + echo Usage: `basename "$0"` VERSION + exit 64 +fi + +dir="cl-png-$version" +rm -rf "$dir" +mkdir "$dir" +tar cf - `cat MANIFEST` | tar -C "$dir" -xf - +tar cvzf "$dir.tar.gz" "$dir" +rm -rf "$dir" diff --git a/cram_3rdparty/cl_png/src/ops.lisp b/cram_3rdparty/cl_png/src/ops.lisp new file mode 100644 index 0000000000..93ef70aa41 --- /dev/null +++ b/cram_3rdparty/cl_png/src/ops.lisp @@ -0,0 +1,469 @@ +(in-package #:image) + +;;; Error handlers + +(define-condition mismatched-image-types (error) + ((types :initarg :types :reader mismatched-image-types-types)) + (:report (lambda (condition stream) + (format stream "Mismatched image types:~%~{ ~s~%~}" + (mismatched-image-types-types condition))))) + +(define-condition mismatched-image-sizes (error) + ((sizes :initarg :sizes :reader mismatched-image-sizes)) + (:report (lambda (condition stream) + (format stream "Mismatched image sizes:~%~{ ~s~%~}" + (mismatched-image-sizes condition))))) + +(define-condition mismatched-image-dims () + ((dims :initarg :dims :reader mismatched-image-dims-dims)) + (:report (lambda (condition stream) + (format stream "Mismatched image dims:~%~{ ~s~%~}" + (mismatched-image-dims-dims condition))))) + +;;; Convenience functions + +(defun make-image-like (im) + "Makes an image the same size and bit-depth as IM." + (destructuring-bind (nm tp (h w c)) (type-of im) + (declare (ignorable nm)) + (make-image h w c (second tp)))) + + +;;; Additional IMAGE accessors + +(defun size (im) + "The (height x width) of an image as an alist" + (cons (array-dimension im 0) (array-dimension im 1))) + +(defun dims (im) + "The dimensions (height x width x channels) of an image as a list" + (list (array-dimension im 0) (array-dimension im 1) (array-dimension im 2))) + + +;;; Image setting functions + +(defun fillv (im val) + "Fills entire image with constant value. Value must be a list with + the same number of elements as IM has channels. + +Returns IM. " + (unless (= (length val) (image-channels im)) + (error "Image channels doesn't match fill dimension: ~s" (length val))) + (dotimes (i (image-height im) im) + (dotimes (j (image-width im)) + (dotimes (k (image-channels im)) + (setf (aref im i j k) (nth k val)))))) + + + +;;; Scalar-valued functions of images + +(defun channel-max (im) + "Finds the max values over all the pixel channels (separately) +in the image. " + (let ((mx (make-array (image-channels im) :initial-element 0))) + (dotimes (i (image-height im) mx) + (dotimes (j (image-width im)) + (dotimes (k (image-channels im)) + (when (< (aref mx k) (aref im i j k)) + (setf (aref mx k) (aref im i j k)))))))) + +(defun channel-min (im) + "Finds the min values over all the pixel channels (separately) +in the image. " + (let ((mn (make-array (image-channels im) :initial-element 255))) + (dotimes (i (image-height im) mn) + (dotimes (j (image-width im)) + (dotimes (k (image-channels im)) + (when (> (aref mn k) (aref im i j k)) + (setf (aref mn k) (aref im i j k)))))))) + +(defun intensity-max (im) + "Finds the max intensities over all the pixels (sum of all the +channels) in the image. " + (let ((mx 0)) + (dotimes (i (image-height im) mx) + (dotimes (j (image-width im)) + (let ((acc 0)) + (dotimes (k (image-channels im)) + (incf acc (aref im i j k))) + (when (< mx acc) + (setf mx acc))))))) + + +(defun norm2 (im) + "Calculates the sum of the squared intensities of all the pixels in + the image. " + (let ((acc 0)) + (dotimes (i (image-height im) acc) + (dotimes (j (image-width im)) + (dotimes (k (image-channels im)) + (incf acc (* (aref im i j k) (aref im i j k)))))))) + + +;;; Image-valued operations on single images + +(defun rotate (old) + "Returns a new image which is rotated counter-clockwise 90-degrees +from the old image" + (let* ((new (make-image (image-width old) (image-height old) + (image-channels old) (image-bit-depth old))) + (m (image-width old))) + (dotimes (i (image-height new) new) + (dotimes (j (image-width new)) + (dotimes (k (image-channels new)) + (setf (aref new i j k) (aref old j (- m i 1) k))))))) + + +(defun flip (old) + "Returns a new image which is flipped vertically from the old image" + (let ((new (make-image-like old)) + (m (image-height old))) + (dotimes (h (image-height new) new) + (dotimes (w (image-width new)) + (dotimes (c (image-channels new)) + (setf (aref new h w c) (aref old (- m h 1) w c))))))) + + +(defun mirror (old) + "Returns a new image which is mirrored horizontally from the old +image" + (let ((new (make-image-like old)) + (m (image-width old))) + (dotimes (h (image-height new) new) + (dotimes (w (image-width new)) + (dotimes (c (image-channels new)) + (setf (aref new h w c) (aref old h (- m w 1) c))))))) + + +;;; Image-valued operations on multiple images + +(defun subtract (im1 im2) + "Subtracts image IM2 from image IM1 and returns the resulting image +difference without modifying either IM1 or IM2. Both images must be +the same type and size. + +Clips pixel intensity to 0 when necessary. " + (unless (equalp (type-of im1) (type-of im2)) + (error 'mismatched-image-types :types (list (type-of im1) (type-of im2)))) + (let ((new (make-image-like im1))) + (dotimes (i (image-height new) new) + (dotimes (j (image-width new)) + (dotimes (k (image-channels new)) + (setf (aref new i j k) + (if (> (aref im1 i j k) (aref im2 i j k)) + (- (aref im1 i j k) (aref im2 i j k)) + 0))))))) + +(defun subtract* (im1 im2) + "Destructively subtracts image IM2 from image IM1, leaving the +resulting image difference in im1. Both images must be the same type +and size. + +Clips pixel intensity to 0 when necessary. " + (unless (equalp (type-of im1) (type-of im2)) + (error 'mismatched-image-types :types (list (type-of im1) (type-of im2)))) + (dotimes (i (image-height im1) im1) + (dotimes (j (image-width im1)) + (dotimes (k (image-channels im1)) + (if (> (aref im1 i j k) (aref im2 i j k)) + (decf (aref im1 i j k) (aref im2 i j k)) + (setf (aref im1 i j k) 0)))))) + + +(defun add (im1 im2) + "Adds image IM2 from image IM1 and returns the resulting image sum +without modifying either IM1 or IM2. Both images must be the same type +and size. + +Clips to maximum intensity in each channel if exceeded. " + (unless (equalp (type-of im1) (type-of im2)) + (error 'mismatched-image-types :types (list (type-of im1) (type-of im2)))) + (let ((lim (1- (expt 2 (image-bit-depth im1)))) + (new (make-image-like im1))) + (dotimes (i (image-height new) new) + (dotimes (j (image-width new)) + (dotimes (k (image-channels new)) + (let ((sum (+ (coerce (aref im1 i j k) '(unsigned-byte 16)) + (coerce (aref im2 i j k) '(unsigned-byte 16))))) + (setf (aref new i j k) (if (> sum lim) lim sum)))))))) + + +(defun add* (im1 im2) + "Destructively adds image IM2 from image IM1, leaving the resulting +image sum in im1. Both images must be the same type and size. +Clips to maximum intensity in each channel if exceeded" + (unless (equalp (type-of im1) (type-of im2)) + (error 'mismatched-image-types :types (list (type-of im1) (type-of im2)))) + (let ((lim (1- (expt 2 (image-bit-depth im1))))) + (dotimes (i (image-height im1) im1) + (dotimes (j (image-width im1)) + (dotimes (k (image-channels im1)) + (if (< (aref im1 i j k) (- lim (aref im2 i j k))) + (incf (aref im1 i j k) (aref im2 i j k)) + (setf (aref im1 i j k) lim))))))) + + +(defun threshold-filter (image threshold) + "Returns a GRAYSCALE-IMAGE the same dimensions as IMAGE whose + corresponding elements are white if they exceed a threshold, or + black if they do not. " + (let* ((img (grayscale-image image)) + (new (image::make-image-like img)) + (maxval (if (= 8 (image-bit-depth img)) #xff #xffff))) + (dotimes (i (array-total-size img) new) + (setf (row-major-aref new i) (if (< (row-major-aref img i) threshold) + 0 maxval))))) + +(defun generate-mask (name 1side) + "Generates a binary mask matrix of '(UNSIGNED-BYTE 8) elements whose +sides are both (2*1SIDE+1) pixels. Valid mask shapes are specified by +NAME, currently :square and :cross. An invalid name will signal an +error. +" + (let* ((width (1+ (* 2 1side))) + (mask (make-array (list width width) + :element-type '(unsigned-byte 8) + :initial-element 1))) + (ecase name + (:square mask) + (:cross + (multiple-value-bind (d r) (floor width 3) + (declare (ignorable r)) + ;; Notch out the corners + (dotimes (r d mask) + (dotimes (w d) + (setf (aref mask r w) 0) + (setf (aref mask r (- width w 1)) 0) + (setf (aref mask (- width r 1) w) 0) + (setf (aref mask (- width r 1) (- width w 1)) 0)))))))) + + +(defun view-mask (mask) + "Prints MASK to *standard-output* for quick examination. " + (let ((dims (array-dimensions mask))) + (format t "~&") + (dotimes (h (first dims)) + (dotimes (w (second dims)) + (format t "~:[ ~;1~]" (> (aref mask h w) 0))) + (terpri)))) + +;; (view-mask (generate-mask :cross 3)) +;; (view-mask (apply #'generate-mask '(:cross 4))) + +(defun binary-morph-kernel (image r c mask op) + "Impliments a binary morphological filter using binary MASK centered +at R,C on IMAGE. OP works as follows: +* OP = :or (erosion) any mask pixel set results in output set, +* OP = :and (dilation), all mask pixels set results in output set, +* OP = :maj (median), majority of mask pixels set results in output set +" + (let* ((dim (array-dimension mask 0)) + (1side (floor dim 2)) + (ro (- r 1side)) + (co (- c 1side)) + (rv (if (= 8 (image-bit-depth image)) #xff #xffff))) + (cond ((eql op :or) + (dotimes (r dim 0) + (dotimes (c dim) + (when (> (aref mask r c) 0) + (when (> (aref image (+ ro r) (+ co c) 0) 0) + (return-from binary-morph-kernel rv)))))) + ((eql op :and) + (dotimes (r dim rv) + (dotimes (c dim) + (when (> (aref mask r c) 0) + (when (= (aref image (+ ro r ) (+ co c) 0) 0) + (return-from binary-morph-kernel 0)))))) + ((eql op :maj) + (let ((acc 0)) + (dotimes (r dim) + (dotimes (c dim) + (when (and (> (aref image (+ ro r ) (+ co c) 0) 0) + (> (aref mask r c) 0)) + (incf acc)))) + (if (> acc (floor (array-total-size mask) 2)) + rv + 0)))))) + +(defun binary-morphological-filter (image operation mask fill) + "Returns a binary-valued GRAYSCALE-IMAGE the same dimensions as + IMAGE whose corresponding elements have been calculated using a + binary morphological filter. The filter kernel centers a MASK on + each pixel in IMAGE and looks at all the pixels in IMAGE which line + up with those set in the MASK. OPERATION=:or sets the filtered pixel + if any of these is set; :and sets the filtered pixel only if all of + these are set; and :maj sets the filtered pixel if a majority of + them are set. A border region can't be reached by the center of the + mask while keeping the mask within IMAGE. New pixels in the border + region are filled with FILL." + (let* ((img (grayscale-image image)) + (new (image::make-image-like img)) + (1side (floor (array-dimension mask 0) 2)) + (newrows (- (image-height image) 1side 1side)) + (newcols (- (image-width image) 1side 1side))) + ;; Fill it first so the borders are taken care of + (image::fillv new fill) + (dotimes (r newrows new) + (dotimes (c newcols) + (let ((rv (binary-morph-kernel image (+ r 1side) (+ c 1side) mask operation))) + ;; (format t " returns rv=~a~%" rv) + (setf (aref new (+ r 1side) (+ c 1side) 0) rv)))))) + + +(defun erosion-filter (image &key pattern mask (fill '(0))) + "Returns a binary GRAYSCALE-IMAGE produced by a morphological filter + with an AND operation on the mask kernel. + + The mask may be either specified by PATTERN or provided by MASK, a + 2-d array of (unsigned-byte 8) values set to 0 or 1. + + The format of PATTERN is '(:square 3) '(:cross 4), where the + 2*size+1 gives the total width and height of the mask. +" + (let ((mask (if mask mask (apply #'generate-mask pattern)))) + (binary-morphological-filter image :and mask fill))) + + +(defun dilation-filter (image &key pattern mask (fill '(0))) + "Returns a binary GRAYSCALE-IMAGE produced by a morphological filter + with an OR operation on the given mask kernel. + + The mask may be either specified by PATTERN or provided by MASK, a + 2-d array of (unsigned-byte 8) values set to 0 or 1. + + The format of PATTERN is '(:square 3) '(:cross 4), where the + 2*size+1 gives the total width and height of the mask. +" + (let ((mask (if mask mask (apply #'generate-mask pattern)))) + (binary-morphological-filter image :or mask fill))) + + +(defun majority-filter (image &key pattern mask (fill '(0))) + "Returns a binary GRAYSCALE-IMAGE produced by a morphological filter + with an MAJ operation on the given mask kernel (majority). + + The mask may be either specified by PATTERN or provided by MASK, a + 2-d array of (unsigned-byte 8) values set to 0 or 1. + + The format of PATTERN is '(:square 3) '(:cross 4), where the + 2*size+1 gives the total width and height of the mask. +" + (let ((mask (if mask mask (apply #'generate-mask pattern)))) + (binary-morphological-filter image :maj mask fill))) + + +(defun open-filter (image &key pattern mask (fill '(0))) + "Returns a binary GRAYSCALE-IMAGE produced by a cascade of an +erosion filter followed by a dilation filter, both using the same +mask. See those filters for descriptions of their properties. + +The distinctive property of the cascade is size preservation of large +scale features. +" + (let* ((mask (if mask mask (apply #'generate-mask pattern)))) + (binary-morphological-filter + (binary-morphological-filter image :and mask fill) :or mask fill))) + + +(defun close-filter (image &key pattern mask (fill '(0))) + "Returns a binary GRAYSCALE-IMAGE produced by a cascade of a +dilation filter followed by an erosion filter, both using the same +mask. See those filters for descriptions of their properties. + +The distinctive property of the cascade is size preservation of large +scale features. +" + (let* ((mask (if mask mask (apply #'generate-mask pattern)))) + (binary-morphological-filter + (binary-morphological-filter image :or mask fill) :and mask fill))) + + +(defun move-towards (im1 im2 step) + "Moves the pixels values of binary GRAYSCALE-IMAGE IM1 towards IM2 + by at most STEP. IM1 is altered, IM2 is not. Step can be 0-255 for + 8-bit depths and 0-65535 for 16-bit depths. " + (dotimes (i (image-height im1) im1) + (dotimes (j (image-width im1)) + (let ((src (aref im1 i j 0)) + (dst (aref im2 i j 0))) + (setf (aref im1 i j 0) (+ src (* (min (abs (- dst src)) step) + (if (< dst src) -1 1)))))))) + + +(defun color-channels (image) + (etypecase image + (grayscale-image 1) + (rgb-image 3))) + +(defun max-color-index (image) + (ecase (image-bit-depth image) (8 255) (16 65535))) + +(defun pixel-type (image) (cadr (type-of image))) + + +(defun convolve (image kernel &key fill) + "Returns a new image of type IMAGE produced by convolving KERNEL + with IMAGE. This is not a circular convolution and no values are + computed in the border region where the kernel is not completely + contained in IMAGE. + + FILL controls the output image size: if set, it returns an image the + same size as IMAGE, if NIL, it returns an image which is shrunk to + exclude the uncomputed border region (the dimensions of KERNEL-1). + + KERNEL must be a 2-d square mask with odd dimensions (e.g. 3x3), a + simple-array of type FLOAT. IMAGE can be GRAYSCALE-IMAGE or an + RGB-IMAGE - in the latter case the channels are convolved with the + KERNEL seperately. + + If FILL is set, it must consist of a list of values of the same type + as the pixels of IMAGE. For example, an rgb-image with 8-bit pixels + might have a fill of '(#x7f #x7f #x7f), whereas a grayscale-image + would have a fill of '(#x7f). If FILL is not set the image will shrink. +" + (declare (optimize (speed 2) (compilation-speed 0) (safety 0) (debug 0))) + (declare (type (simple-array float (* *)) kernel)) + ;; (declare (type (simple-array (unsigned-byte 8) (* * *)) image)) + (let* ((dim (array-dimension kernel 0)) + (1side (floor dim 2)) + (colors (the fixnum (color-channels image))) + (maxval (the fixnum (max-color-index image))) + (width (the fixnum (image-width image))) + (height (the fixnum (image-height image))) + ;; (typ (pixel-type image)) + ) + (flet ((innerprod (ro co k) ;; (ro,co) are the corner points of the mask + (declare (type fixnum ro co k)) + (let ((accum 0.e0)) + (declare (type float accum)) + (dotimes (r dim) + (dotimes (c dim) + (incf accum (* (aref kernel r c) + (the fixnum (aref image (+ ro r) (+ co c) k)))))) + (the fixnum (max 0 (min (the fixnum (floor accum)) maxval)))))) + (let ((newrows (the fixnum (- height 1side 1side))) + (newcols (the fixnum (- width 1side 1side)))) + (if fill + ;; Convolution preserving size with fill + (let ((new (make-image-like image))) + (dotimes (r 1side) + (dotimes (c width) + (dotimes (k colors) + (setf (aref new r c k) (nth k fill) + (aref new (- height r 1) c k) (nth k fill))))) + (dotimes (c 1side) + (dotimes (r height) + (dotimes (k colors) + (setf (aref new r c k) (nth k fill) + (aref new r (- width c 1) k) (nth k fill))))) + (dotimes (r newrows new) + (dotimes (c newcols) + (dotimes (k colors) + (setf (the fixnum (aref new (+ r 1side) (+ c 1side) k)) (innerprod r c k)))))) + ;; Shrinking convolution + (let ((new (make-image newrows newcols (image-channels image) (image-bit-depth image)))) + (dotimes (r newrows new) + (dotimes (c newcols) + (dotimes (k colors) + (setf (the fixnum (aref new r c k)) (innerprod r c k))))))))))) diff --git a/cram_3rdparty/cl_png/src/png-package.lisp b/cram_3rdparty/cl_png/src/png-package.lisp new file mode 100644 index 0000000000..c1712c9588 --- /dev/null +++ b/cram_3rdparty/cl_png/src/png-package.lisp @@ -0,0 +1,26 @@ +(in-package #:cl-user) + +(defpackage #:png + (:documentation "Read and write PNG (Portable Network Graphics) files.") + (:use #:common-lisp #:cffi #:image) + (:export + #:image + #:8-bit-image + #:16-bit-image + #:grayscale-image + #:grayscale-alpha-image + #:rgb-image + #:rgb-alpha-image + #:make-image + #:copy-image + #:image-height + #:image-width + #:image-channels + #:image-bit-depth + #:decode + #:decode-file + #:encode + #:encode-file + #:decode-bmp + #:decode-bmp-file + )) diff --git a/cram_3rdparty/cl_png/src/png.asd b/cram_3rdparty/cl_png/src/png.asd new file mode 100644 index 0000000000..c4d2e7db75 --- /dev/null +++ b/cram_3rdparty/cl_png/src/png.asd @@ -0,0 +1,19 @@ +;;;; -*- Mode: Lisp; -*- + +(in-package #:cl-user) + +(asdf:defsystem #:png + :description "Read and write PNG (Portable Network Graphics) files." + :perform (asdf:load-op :after (op png) + (pushnew :png *features*)) + :components ((:file "png-package" :depends-on ("image")) + (:file "compat" :depends-on ("png-package")) + (:file "libpng" :depends-on ("grovel" "compat" "png-package" "wrappers")) + (:cffi-grovel-file "grovel") + (:cffi-wrapper-file "wrappers") + (:file "image") + (:file "bmp" :depends-on ("image")) + (:file "pnm" :depends-on ("image")) + (:file "ops" :depends-on ("image"))) + :depends-on (#:cffi) + :defsystem-depends-on ("cffi-grovel")) diff --git a/cram_3rdparty/cl_png/src/pnm.lisp b/cram_3rdparty/cl_png/src/pnm.lisp new file mode 100644 index 0000000000..824a6b7d83 --- /dev/null +++ b/cram_3rdparty/cl_png/src/pnm.lisp @@ -0,0 +1,215 @@ +(defpackage #:pnm + (:use #:common-lisp #:image) + (:export #:decode #:encode)) + +(in-package #:pnm) + +(defun whitespace-char-p (char) + (and (member char '(#\Space #\Newline #\Return #\Tab)) + t)) + +(defun read-magic-number (input) + (with-output-to-string (output) + (loop + for char = (read-char input) + do (cond + ((whitespace-char-p char) (loop-finish)) + ((char-equal #\# char) (read-line input nil nil)) + (t (write-char char output))) + finally (unread-char char input)))) + +(defun read-whitespace (input &key (at-least 1)) + (loop + for char = (read-char input nil nil) + and count from 0 + do (cond + ((char-equal #\# char) (read-line input nil nil)) + ((not (whitespace-char-p char)) (loop-finish))) + finally + (when char + (unread-char char input)) + (when (< count at-least) + (error "Read only ~D whitespace characters; ~D required." + count at-least)))) + +(defun read-whitespace-character (input) + (let ((char (read-char input))) + (unless (whitespace-char-p char) + (error "Expected whitespace character, found ~S." char)))) + +(defun read-positive-integer (input) + (parse-integer + (with-output-to-string (output) + (loop + for char = (read-char input nil nil) + do (cond + ((null char) (loop-finish)) + ((digit-char-p char) (write-char char output)) + ((char-equal #\# char) (read-line input nil nil)) + (t (loop-finish))) + finally (when char + (unread-char char input)))))) + +(defun read-pnm-header (input) + "Read the header if it hasn't been read already, then return it." + (let* ((magic-number (read-magic-number input)) + (type (cond ((equal magic-number "P4") 'pbm) + ((equal magic-number "P5") 'pgm) + ((equal magic-number "P6") 'ppm) + (t (error "Unknown magic number: ~S" + magic-number)))) + (width (progn + (read-whitespace input) + (read-positive-integer input))) + (height (progn + (read-whitespace input) + (read-positive-integer input))) + (max-value (if (eq type 'pbm) + 1 + (progn + (read-whitespace input) + (read-positive-integer input))))) + (values magic-number width height max-value))) + +(defun decode (input) + (multiple-value-bind (magic-number width height max-value) + (read-pnm-header input) + (funcall + (cond ((equal magic-number "P4") 'read-pbm) + ((equal magic-number "P5") + (cond ((<= max-value 255) 'read-pgm-8) + ((<= max-value 65535) 'read-pgm-16) + (t (error "Invalid max-value for PGM: ~D" + max-value)))) + ((equal magic-number "P6") + (cond ((<= max-value 255) 'read-ppm-8) + ((<= max-value 65535) 'read-ppm-16) + (t (error "Invalid max-value for PPM: ~D" max-value)))) + (t (error "Invalid magic number for PNM: ~S" magic-number))) + input width height))) + +(defun read-pbm (input width height) + (let ((row (make-array (ceiling width 8) + :element-type '(unsigned-byte 8))) + (raw-data (make-array (* width height) + :element-type 'bit))) + (dotimes (y height) + (unless (= (read-sequence row input) + (length row)) + (error "Failed to read ~D bytes of raw image data." (length row))) + (dotimes (x width) + (setf (aref raw-data (+ (* y width) x)) + (ldb (byte 1 (- 7 (mod x 8))) + (aref row (floor x 8)))))) + (make-instance 'image :raw-data raw-data + :height height :width width :bits 1 :channels 1))) + +(defun read-pgm-8 (input width height) + (let ((raw-data (make-array (* width height) + :element-type '(unsigned-byte 8)))) + (unless (= (read-sequence raw-data input) + (length raw-data)) + (error "Failed to read ~D bytes of raw image data." (length raw-data))) + (make-instance 'image :raw-data raw-data :height height :width width + :bits 8 :channels 1))) + +(defun read-pgm-16 (input width height) + (let ((raw-data (make-array (* width height) + :element-type '(unsigned-byte 16))) + (row (make-array (* width 2) :element-type '(unsigned-byte 8)))) + (dotimes (y height) + (unless (= (read-sequence row input) + (length row)) + (error "Failed to read ~D bytes of raw image data." (length row))) + (dotimes (x width) + (setf (aref raw-data (+ (* y width) x)) + (+ (* 256 (aref row (* x 2))) + (aref row (1+ (* x 2))))))) + (make-instance 'image :raw-data raw-data :height height :width width + :bits 16 :channels 1))) + +(defun read-ppm-8 (input width height) + (let ((raw-data (make-array (* width height 3) + :element-type '(unsigned-byte 8))) + (row (make-array (* width 3) + :element-type '(unsigned-byte 8)))) + (dotimes (y height) + (unless (= (read-sequence row input) (length row)) + (error "Failed to read ~D bytes of raw image data." (length row))) + (dotimes (x width) + (dotimes (c 3) + (setf (aref raw-data (+ (* (+ (* y width) x) 3) c)) + (aref row (+ (* x 3) c)))))) + (make-instance 'image :raw-data raw-data :height height :width width + :bits 8 :channels 3))) + +(defun read-ppm-16 (input width height) + (let ((raw-data #1=(make-array (* width height 3) + :element-type '(unsigned-byte 16))) + (row (make-array (* width 3 2) + :element-type '(unsigned-byte 8)))) + (flet ((row-ref (x c) + (let ((i (+ (* x 3) c))) + (+ (* 256 (aref row (* i 2))) + (aref row (1+ (* i 2))))))) + (dotimes (y height) + (unless (= (read-sequence row input) (length row)) + (error "Failed to read ~D bytes of raw image data." (length row))) + (dotimes (x width) + (dotimes (c 3) + (setf (aref raw-data (+ (* (+ (* y width) x) 3) c)) + (row-ref x c)))))) + (make-instance 'image :raw-data raw-data :height height :width width + :bits 16 :channels 3))) + +(defun write-pnm-header (image stream type) + (write-sequence (map 'vector #'char-code + (format nil "~A~%~D ~D~%~D~%" type (image-width image) + (image-height image) + (1- (expt 2 (image-bit-depth image))))) + stream)) + +(defun write-pnm-data-1 (image stream) + (dotimes (y (image-height image)) + (loop + with value = 0 + for x below (image-width image) + do (let ((b (mod x 8))) + (when (zerop b) + (unless (= x 0) + (write-byte value stream) + (setf value 0))) + (setf value (dpb (aref image y x) + (byte 1 (- 7 b)) + value))) + finally (write-byte value stream)))) + +(defun write-pnm-data-8 (image stream) + (write-sequence (array-displacement image) stream)) + +(defun write-pnm-data-16 (image stream) + (dotimes (i (array-total-size image)) + (multiple-value-bind (msb lsb) (floor (row-major-aref image i) 256) + (write-byte msb stream) + (write-byte lsb stream)))) + +(defun write-pnm-data (image stream) + (let ((bits (image-bit-depth image))) + (cond ((= bits 1) (write-pnm-data-1 image stream)) + ((<= bits 8) (write-pnm-data-8 image stream)) + ((<= bits 16) (write-pnm-data-16 image stream)) + (t (error "Cannot write ~D-bit image as PNM." bits)))) + t) + +(defun encode (image stream) + (cond ((= (image-bit-depth image) 1) + (write-pnm-header image stream "P4") + (write-pnm-data image stream)) + ((= (image-channels image) 1) + (write-pnm-header image stream "P5") + (write-pnm-data image stream)) + ((= (image-channels image) 3) + (write-pnm-header image stream "P6") + (write-pnm-data image stream)) + (t (error "Cannot write image with ~D bits and ~D channels as PNM." + (image-bit-depth image) (image-channels image))))) diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi0g01.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g01.png new file mode 100644 index 0000000000..556fa72704 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi0g02.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g02.png new file mode 100644 index 0000000000..ce09821ef1 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g04.png new file mode 100644 index 0000000000..3853273f93 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g08.png new file mode 100644 index 0000000000..faed8bec44 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g16.png new file mode 100644 index 0000000000..a9f28165ef Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi2c08.png new file mode 100644 index 0000000000..2aab44d42b Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi2c16.png new file mode 100644 index 0000000000..cd7e50f914 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p01.png new file mode 100644 index 0000000000..00a7cea6c2 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p02.png new file mode 100644 index 0000000000..bb16b44b30 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p04.png new file mode 100644 index 0000000000..b4e888e247 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p08.png new file mode 100644 index 0000000000..50a6d1cac7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi4a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi4a08.png new file mode 100644 index 0000000000..398132be5f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi4a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi4a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi4a16.png new file mode 100644 index 0000000000..51192e7311 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi4a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi6a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi6a08.png new file mode 100644 index 0000000000..aecb32e0d9 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi6a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basi6a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basi6a16.png new file mode 100644 index 0000000000..4181533ad8 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basi6a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn0g01.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g01.png new file mode 100644 index 0000000000..1d722423aa Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn0g02.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g02.png new file mode 100644 index 0000000000..508332418f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g04.png new file mode 100644 index 0000000000..0bf3687863 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g08.png new file mode 100644 index 0000000000..23c82379a2 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g16.png new file mode 100644 index 0000000000..e7c82f78eb Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn2c08.png new file mode 100644 index 0000000000..db5ad15865 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn2c16.png new file mode 100644 index 0000000000..50c1cb91a0 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p01.png new file mode 100644 index 0000000000..b145c2b8ef Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p02.png new file mode 100644 index 0000000000..8985b3d818 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p04.png new file mode 100644 index 0000000000..0fbf9e827b Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p08.png new file mode 100644 index 0000000000..0ddad07e5f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn4a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn4a08.png new file mode 100644 index 0000000000..3e13052201 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn4a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn4a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn4a16.png new file mode 100644 index 0000000000..8243644d07 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn4a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn6a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn6a08.png new file mode 100644 index 0000000000..e608738763 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn6a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/basn6a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/basn6a16.png new file mode 100644 index 0000000000..984a99525f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/basn6a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bgai4a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/bgai4a08.png new file mode 100644 index 0000000000..398132be5f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bgai4a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bgai4a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/bgai4a16.png new file mode 100644 index 0000000000..51192e7311 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bgai4a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bgan6a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/bgan6a08.png new file mode 100644 index 0000000000..e608738763 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bgan6a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bgan6a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/bgan6a16.png new file mode 100644 index 0000000000..984a99525f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bgan6a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bgbn4a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/bgbn4a08.png new file mode 100644 index 0000000000..7cbefc3bff Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bgbn4a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bggn4a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/bggn4a16.png new file mode 100644 index 0000000000..13fd85ba19 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bggn4a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bgwn6a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/bgwn6a08.png new file mode 100644 index 0000000000..a67ff205bb Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bgwn6a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/bgyn6a16.png b/cram_3rdparty/cl_png/src/test/PngSuite/bgyn6a16.png new file mode 100644 index 0000000000..ae3e9be58a Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/bgyn6a16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ccwn2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/ccwn2c08.png new file mode 100644 index 0000000000..47c24817b7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ccwn2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ccwn3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/ccwn3p08.png new file mode 100644 index 0000000000..8bb2c10981 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ccwn3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cdfn2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cdfn2c08.png new file mode 100644 index 0000000000..559e5261e7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cdfn2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cdhn2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cdhn2c08.png new file mode 100644 index 0000000000..3e07e8ecbd Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cdhn2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cdsn2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cdsn2c08.png new file mode 100644 index 0000000000..076c32cc08 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cdsn2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cdun2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cdun2c08.png new file mode 100644 index 0000000000..846033be6b Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cdun2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ch1n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/ch1n3p04.png new file mode 100644 index 0000000000..17cd12dfc9 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ch1n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ch2n3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/ch2n3p08.png new file mode 100644 index 0000000000..25c17987a7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ch2n3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cm0n0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/cm0n0g04.png new file mode 100644 index 0000000000..9fba5db3b8 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cm0n0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cm7n0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/cm7n0g04.png new file mode 100644 index 0000000000..f7dc46e685 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cm7n0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cm9n0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/cm9n0g04.png new file mode 100644 index 0000000000..dd70911adc Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cm9n0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cs3n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/cs3n2c16.png new file mode 100644 index 0000000000..bf5fd20a20 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cs3n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cs3n3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cs3n3p08.png new file mode 100644 index 0000000000..f4a66237bf Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cs3n3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cs5n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cs5n2c08.png new file mode 100644 index 0000000000..40f947c33e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cs5n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cs5n3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cs5n3p08.png new file mode 100644 index 0000000000..dfd6e6e6ec Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cs5n3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cs8n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cs8n2c08.png new file mode 100644 index 0000000000..8e01d3294f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cs8n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/cs8n3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/cs8n3p08.png new file mode 100644 index 0000000000..a44066eb6e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/cs8n3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ct0n0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/ct0n0g04.png new file mode 100644 index 0000000000..40d1e062f8 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ct0n0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ct1n0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/ct1n0g04.png new file mode 100644 index 0000000000..3ba110aa76 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ct1n0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ctzn0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/ctzn0g04.png new file mode 100644 index 0000000000..b4401c9cfc Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ctzn0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f00n0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f00n0g08.png new file mode 100644 index 0000000000..45a0075967 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f00n0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f00n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f00n2c08.png new file mode 100644 index 0000000000..d6a1ffff62 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f00n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f01n0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f01n0g08.png new file mode 100644 index 0000000000..4a1107b463 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f01n0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f01n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f01n2c08.png new file mode 100644 index 0000000000..26fee958ce Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f01n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f02n0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f02n0g08.png new file mode 100644 index 0000000000..bfe410c5e7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f02n0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f02n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f02n2c08.png new file mode 100644 index 0000000000..e590f12348 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f02n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f03n0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f03n0g08.png new file mode 100644 index 0000000000..ed01e2923c Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f03n0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f03n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f03n2c08.png new file mode 100644 index 0000000000..758115059d Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f03n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f04n0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f04n0g08.png new file mode 100644 index 0000000000..663fdae3e7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f04n0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/f04n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/f04n2c08.png new file mode 100644 index 0000000000..3c8b5116e7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/f04n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g03n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/g03n0g16.png new file mode 100644 index 0000000000..41083ca80f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g03n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g03n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/g03n2c08.png new file mode 100644 index 0000000000..a9354dbee6 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g03n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g03n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/g03n3p04.png new file mode 100644 index 0000000000..60396c95af Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g03n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g04n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/g04n0g16.png new file mode 100644 index 0000000000..32395b76c9 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g04n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g04n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/g04n2c08.png new file mode 100644 index 0000000000..a652b0ce87 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g04n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g04n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/g04n3p04.png new file mode 100644 index 0000000000..5661cc3131 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g04n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g05n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/g05n0g16.png new file mode 100644 index 0000000000..70b37f01e2 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g05n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g05n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/g05n2c08.png new file mode 100644 index 0000000000..932c136536 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g05n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g05n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/g05n3p04.png new file mode 100644 index 0000000000..9619930585 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g05n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g07n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/g07n0g16.png new file mode 100644 index 0000000000..d6a47c2d57 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g07n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g07n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/g07n2c08.png new file mode 100644 index 0000000000..597346460f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g07n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g07n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/g07n3p04.png new file mode 100644 index 0000000000..c73fb61365 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g07n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g10n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/g10n0g16.png new file mode 100644 index 0000000000..85f2c958e9 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g10n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g10n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/g10n2c08.png new file mode 100644 index 0000000000..b3039970c1 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g10n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g10n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/g10n3p04.png new file mode 100644 index 0000000000..1b6a6be2ca Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g10n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g25n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/g25n0g16.png new file mode 100644 index 0000000000..a9f6787c7a Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g25n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g25n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/g25n2c08.png new file mode 100644 index 0000000000..03f505a64b Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g25n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/g25n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/g25n3p04.png new file mode 100644 index 0000000000..4f943c6175 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/g25n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi1n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi1n0g16.png new file mode 100644 index 0000000000..e7c82f78eb Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi1n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi1n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi1n2c16.png new file mode 100644 index 0000000000..50c1cb91a0 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi1n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi2n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi2n0g16.png new file mode 100644 index 0000000000..14d64c583d Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi2n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi2n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi2n2c16.png new file mode 100644 index 0000000000..4c2e3e3352 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi2n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi4n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi4n0g16.png new file mode 100644 index 0000000000..69e73ede31 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi4n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi4n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi4n2c16.png new file mode 100644 index 0000000000..93691e373a Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi4n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi9n0g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi9n0g16.png new file mode 100644 index 0000000000..9248413576 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi9n0g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/oi9n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/oi9n2c16.png new file mode 100644 index 0000000000..f0512e49f2 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/oi9n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/pngsuite.doc b/cram_3rdparty/cl_png/src/test/PngSuite/pngsuite.doc new file mode 100644 index 0000000000..7da918b4e9 --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/PngSuite/pngsuite.doc @@ -0,0 +1,520 @@ + PNGSUITE +---------------- + + testset for PNG-(de)coders + created by Willem van Schaik +------------------------------------ + +This is a collection of graphics images created to test the png applications +like viewers, converters and editors. All (as far as that is possible) +formats supported by the PNG standard are represented. + + +1. INTRODUCTION +-------------------- + +1.1 PNG capabilities +------------------------ + +Supported color-types are: + + - grayscale + - grayscale + alpha-channel + - color palettes + - rgb + - rgb + alpha-channel + +Allowed bitdepths are depending on the color-type, but are in the range +of 1-bit (grayscale, which is b&w) upto 16-bits. + +Special features are: + + - interlacing (Adam-7) + - gamma-support + - transparency (a poor-man's alpha solution) + + +1.2 File naming +------------------- + +Where possible, the testfiles are 32x32 bits icons. This results in a still +reasonable size of the suite even with a large number of tests. The name +of each test-file reflects thetype in the following way: + + g04i2c08.png + || |||+---- bit-depth + || ||+----- color-type (descriptive) + || |+------ color-type (numerical) + || +------- interlaced or non-interlaced + |+--------- parameter of test (in this case gamma-value) + +---------- test feature (in this case gamma) + + +1.3 PNG formats +------------------- + +color-type: + 0g - grayscale + 2c - rgb color + 3p - paletted + 4a - grayscale + alpha channel + 6a - rgb color + alpha channel + +bit-depth: + 01 - with color-type 0, 3 + 02 - with color-type 0, 3 + 04 - with color-type 0, 3 + 08 - with color-type 0, 2, 3, 4, 6 + 16 - with color-type 0, 2, 4, 6 + +interlacing: + n - non-interlaced + i - interlaced + + +2. THE TESTS +----------------- + +2.1 Sizes +------------- + +These tests are there to check if your software handles pictures well, with +picture sizes that are not a multiple of 8. This is particularly important +with Adam-7 type interlacing. In the same way these tests check if pictures +size 1x1 and similar are ok. + + s01 - 1x1 pixel picture + s02 - 2x2 pixel picture + s03 - 3x3 pixel picture + s04 - 4x4 pixel picture + s05 - 5x5 pixel picture + s06 - 6x6 pixel picture + s07 - 7x7 pixel picture + s08 - 8x8 pixel picture + s09 - 9x9 pixel picture + s32 - 32x32 pixel picture + s33 - 33x33 pixel picture + s34 - 34x34 pixel picture + s35 - 35x35 pixel picture + s36 - 36x36 pixel picture + s37 - 37x37 pixel picture + s38 - 38x38 pixel picture + s39 - 39x39 pixel picture + s40 - 40x40 pixel picture + + +2.2 Background +------------------ + +When the PNG file contains a background chunck, this should be used for +pictures with alpha-channel or pictures with a transparency chunck. For +pictures without this background-chunk, but with alpha, this testset +assumes a black background. + +For the images in this test, the left-side should be 100% the background +color, where moving to the right the color should gradually become the +image pattern. + + bga - alpha + no background + bgw - alpha + white background + bgg - alpha + gray background + bgb - alpha + black background + bgy - alpha + yellow background + + +2.3 Transparency +-------------------- + +Transparency should be used together with a background chunk. To test the +combination of the two the latter 4 tests are there. How to handle pictures +with transparancy, but without a background, opinions can differ. Here we +use black, but especially in the case of paletted images, the normal color +would maybe even be better. + + tp0 - not transparent for reference + tp1 - transparent, but no background chunk + tbw - transparent + white background + tbg - transparent + gray background + tbb - transparent + black background + tby - transparent + yellow background + + +2.4 Gamma +------------- + +To test if your viewer handles gamma-correction, 6 testfiles are available. +They contain corrected color-ramps and a corresponding gamma-chunk with the +file-gamma value. These are created in such a way that when the viewer does +the gamma correction right, all 6 should be displayed identical. + +If they are different, probably the gamma correction is omitted. In that +case, have a look at the two right coloumns in the 6 pictures. The image +where those two look the same (when looked from far) reflects the gamma of +your system. However, because of the limited size of the image, you should +do more elaborate tests to determine your display gamma. + + g03 - file-gamma = 0.35, for display with gamma = 2.8 + g04 - file-gamma = 0.45, for display with gamma = 2.2 (PC) + g05 - file-gamma = 0.55, for display with gamma = 1.8 (Mac) + g07 - file-gamma = 0.70, for display with gamma = 1.4 + g10 - file-gamma = 1.00, for display with gamma = 1.0 (NeXT) + g25 - file-gamma = 2.50, for display with gamma = 0.4 + + +2.5 Filtering +----------------- + +PNG uses file-filtering, for optimal compression. Normally the type is of +filtering is adjusted to the contents of the picture, but here each file +has the same picture, with a different filtering. + + f0 - no filtering + f1 - sub filtering + f2 - up filtering + f3 - average filtering + f4 - paeth filtering + + +2.6 Additional palettes +--------------------------- + +Besides the normal use of paletted images, palette chunks can in combination +with true-color (and other) images also be used to select color lookup-tables +when the video system is of limited capabilities. The suggested palette chunk +is specially created for this purpose. + + pp - normal palette chunk + ps - suggested palette chunk + + +2.7 Ancillary chunks (under construction) +------------------------ + +To test the correct decoding of ancillary chunks, these test-files contain +one or more examples of these chunkcs. Depending on the type of chunk, a +number of typical values are selected to test. Unluckily, the testset can +not contain all combinations, because that would be an endless set. + +The significant bits are used in files with the next higher bit-depth. They +indicate howmany bits are valid. + + cs3 - 3 significant bits + cs5 - 5 significant bits + cs8 - 8 significant bits (reference) + cs3 - 13 significant bits + +For the physical pixel dimensions, the result of each decoding should be +a sqare picture. The first (cdf) image is an example of flat (horizontal) +pixels, where the pHYS chunk (x is 1 per unit, y = 4 per unit) must take +care of the correction. The second is just the other way round. The last +example uses the unit specifier, for 1000 pixels per meter. This should +result in a picture of 3.2 cm square. + + cdf - physical pixel dimensions, 8x32 flat pixels + cdh - physical pixel dimensions, 32x8 high pixels + cds - physical pixel dimensions, 8x8 square pixels + cdu - physical pixel dimensions, with unit-specifier + + ccw - primary chromaticities and white point + + ch1 - histogram 15 colors + ch2 - histogram 256 colors + + cm7 - modification time, 01-jan-1970 + cm9 - modification time, 31-dec-1999 + cm0 - modification time, 01-jan-2000 + +In the textual chunk, a number of the standard, and some non-standard +text items are included. + + ct0 - no textual data + ct1 - with textual data + ctz - with compressed textual data + + +2.8 Chunk ordering (still under construction) +---------------------- + +These testfiles will test the obligatory ordering relations between various +chunk types (not yet) as well as the number of data chunks used for the image. + + oi1 - mother image with 1 idat-chunk + oi2 - image with 2 idat-chunks + oi4 - image with 4 unequal sized idat-chunks + oi9 - all idat-chunks of length one + + +2.9 Compression level +------------------------- + +Here you will find a set of images compressed by zlib, ranging from level 0 +for no compression at maximum speed upto level 9 for maximum compression. + + z00 - zlib compression level 0 - none + z03 - zlib compression level 3 + z06 - zlib compression level 6 - default + z09 - zlib compression level 9 - maximum + + +2.10 Corrupted files (under construction) +----------------------- + +All these files are illegal. When decoding they should generate appropriate +error-messages. + + x00 - empty IDAT chunk + xcr - added cr bytes + xlf - added lf bytes + xc0 - color type 0 + xc9 - color type 9 + xd0 - bit-depth 0 + xd3 - bit-depth 3 + xd9 - bit-depth 99 + xcs - incorrect IDAT checksum + + +3. TEST FILES +------------------ + +For each of the tests listed above, one or more test-files are created. A +selection is made (for each test) for the color-type and bitdepth to be used +for the tests. Further for a number of tests, both a non-interlaced as well +as an interlaced version is available. + + +3.1 Basic format test files (non-interlaced) +------------------------------------------------ + + basn0g01 - black & white + basn0g02 - 2 bit (4 level) grayscale + basn0g04 - 4 bit (16 level) grayscale + basn0g08 - 8 bit (256 level) grayscale + basn0g16 - 16 bit (64k level) grayscale + basn2c08 - 3x8 bits rgb color + basn2c16 - 3x16 bits rgb color + basn3p01 - 1 bit (2 color) paletted + basn3p02 - 2 bit (4 color) paletted + basn3p04 - 4 bit (16 color) paletted + basn3p08 - 8 bit (256 color) paletted + basn4a08 - 8 bit grayscale + 8 bit alpha-channel + basn4a16 - 16 bit grayscale + 16 bit alpha-channel + basn6a08 - 3x8 bits rgb color + 8 bit alpha-channel + basn6a16 - 3x16 bits rgb color + 16 bit alpha-channel + + +3.2 Basic format test files (Adam-7 interlaced) +--------------------------------------------------- + + basi0g01 - black & white + basi0g02 - 2 bit (4 level) grayscale + basi0g04 - 4 bit (16 level) grayscale + basi0g08 - 8 bit (256 level) grayscale + basi0g16 - 16 bit (64k level) grayscale + basi2c08 - 3x8 bits rgb color + basi2c16 - 3x16 bits rgb color + basi3p01 - 1 bit (2 color) paletted + basi3p02 - 2 bit (4 color) paletted + basi3p04 - 4 bit (16 color) paletted + basi3p08 - 8 bit (256 color) paletted + basi4a08 - 8 bit grayscale + 8 bit alpha-channel + basi4a16 - 16 bit grayscale + 16 bit alpha-channel + basi6a08 - 3x8 bits rgb color + 8 bit alpha-channel + basi6a16 - 3x16 bits rgb color + 16 bit alpha-channel + + +3.3 Sizes test files +----------------------- + + s01n3p01 - 1x1 paletted file, no interlacing + s02n3p01 - 2x2 paletted file, no interlacing + s03n3p01 - 3x3 paletted file, no interlacing + s04n3p01 - 4x4 paletted file, no interlacing + s05n3p02 - 5x5 paletted file, no interlacing + s06n3p02 - 6x6 paletted file, no interlacing + s07n3p02 - 7x7 paletted file, no interlacing + s08n3p02 - 8x8 paletted file, no interlacing + s09n3p02 - 9x9 paletted file, no interlacing + s32n3p04 - 32x32 paletted file, no interlacing + s33n3p04 - 33x33 paletted file, no interlacing + s34n3p04 - 34x34 paletted file, no interlacing + s35n3p04 - 35x35 paletted file, no interlacing + s36n3p04 - 36x36 paletted file, no interlacing + s37n3p04 - 37x37 paletted file, no interlacing + s38n3p04 - 38x38 paletted file, no interlacing + s39n3p04 - 39x39 paletted file, no interlacing + s40n3p04 - 40x40 paletted file, no interlacing + + s01i3p01 - 1x1 paletted file, interlaced + s02i3p01 - 2x2 paletted file, interlaced + s03i3p01 - 3x3 paletted file, interlaced + s04i3p01 - 4x4 paletted file, interlaced + s05i3p02 - 5x5 paletted file, interlaced + s06i3p02 - 6x6 paletted file, interlaced + s07i3p02 - 7x7 paletted file, interlaced + s08i3p02 - 8x8 paletted file, interlaced + s09i3p02 - 9x9 paletted file, interlaced + s32i3p04 - 32x32 paletted file, interlaced + s33i3p04 - 33x33 paletted file, interlaced + s34i3p04 - 34x34 paletted file, interlaced + s35i3p04 - 35x35 paletted file, interlaced + s36i3p04 - 36x36 paletted file, interlaced + s37i3p04 - 37x37 paletted file, interlaced + s38i3p04 - 38x38 paletted file, interlaced + s39i3p04 - 39x39 paletted file, interlaced + s40i3p04 - 40x40 paletted file, interlaced + + +3.4 Background test files (with alpha) +------------------------------------------ + + bgai4a08 - 8 bit grayscale, alpha, no background chunk, interlaced + bgai4a16 - 16 bit grayscale, alpha, no background chunk, interlaced + bgan6a08 - 3x8 bits rgb color, alpha, no background chunk + bgan6a16 - 3x16 bits rgb color, alpha, no background chunk + + bgbn4a08 - 8 bit grayscale, alpha, black background chunk + bggn4a16 - 16 bit grayscale, alpha, gray background chunk + bgwn6a08 - 3x8 bits rgb color, alpha, white background chunk + bgyn6a16 - 3x16 bits rgb color, alpha, yellow background chunk + + +3.5 Transparency (and background) test files +------------------------------------------------ + + tp0n1g08 - not transparent for reference (logo on gray) + tbbn1g04 - transparent, black background chunk + tbwn1g16 - transparent, white background chunk + tp0n2c08 - not transparent for reference (logo on gray) + tbrn2c08 - transparent, red background chunk + tbgn2c16 - transparent, green background chunk + tbbn2c16 - transparent, blue background chunk + tp0n3p08 - not transparent for reference (logo on gray) + tp1n3p08 - transparent, but no background chunk + tbbn3p08 - transparent, black background chunk + tbgn3p08 - transparent, light-gray background chunk + tbwn3p08 - transparent, white background chunk + tbyn3p08 - transparent, yellow background chunk + + +3.6 Gamma test files +------------------------ + + g03n0g16 - grayscale, file-gamma = 0.35 + g04n0g16 - grayscale, file-gamma = 0.45 + g05n0g16 - grayscale, file-gamma = 0.55 + g07n0g16 - grayscale, file-gamma = 0.70 + g10n0g16 - grayscale, file-gamma = 1.00 + g25n0g16 - grayscale, file-gamma = 2.50 + g03n2c08 - color, file-gamma = 0.35 + g04n2c08 - color, file-gamma = 0.45 + g05n2c08 - color, file-gamma = 0.55 + g07n2c08 - color, file-gamma = 0.70 + g10n2c08 - color, file-gamma = 1.00 + g25n2c08 - color, file-gamma = 2.50 + g03n3p04 - paletted, file-gamma = 0.35 + g04n3p04 - paletted, file-gamma = 0.45 + g05n3p04 - paletted, file-gamma = 0.55 + g07n3p04 - paletted, file-gamma = 0.70 + g10n3p04 - paletted, file-gamma = 1.00 + g25n3p04 - paletted, file-gamma = 2.50 + + +3.7 Filtering test files +---------------------------- + + f00n0g08 - grayscale, no interlacing, filter-type 0 + f01n0g08 - grayscale, no interlacing, filter-type 1 + f02n0g08 - grayscale, no interlacing, filter-type 2 + f03n0g08 - grayscale, no interlacing, filter-type 3 + f04n0g08 - grayscale, no interlacing, filter-type 4 + f00n2c08 - color, no interlacing, filter-type 0 + f01n2c08 - color, no interlacing, filter-type 1 + f02n2c08 - color, no interlacing, filter-type 2 + f03n2c08 - color, no interlacing, filter-type 3 + f04n2c08 - color, no interlacing, filter-type 4 + + +3.8 Additional palette chunk test files +------------------------------------------- + + pp0n2c16 - six-cube palette-chunk in true-color image + pp0n6a08 - six-cube palette-chunk in true-color+alpha image + ps1n0g08 - six-cube suggested palette (1 byte) in grayscale image + ps1n2c16 - six-cube suggested palette (1 byte) in true-color image + ps2n0g08 - six-cube suggested palette (2 bytes) in grayscale image + ps2n2c16 - six-cube suggested palette (2 bytes) in true-color image + + +3.9 Ancillary chunks test files +----------------------------------- + + cs5n2c08 - color, 5 significant bits + cs8n2c08 - color, 8 significant bits (reference) + cs3n2c16 - color, 13 significant bits + cs3n3p08 - paletted, 3 significant bits + cs5n3p08 - paletted, 5 significant bits + cs8n3p08 - paletted, 8 significant bits (reference) + + cdfn2c08 - physical pixel dimensions, 8x32 flat pixels + cdhn2c08 - physical pixel dimensions, 32x8 high pixels + cdsn2c08 - physical pixel dimensions, 8x8 square pixels + cdun2c08 - physical pixel dimensions, 1000 pixels per 1 meter + + ccwn2c08 - chroma chunk w:0.3127,0.3290 r:0.64,0.33 g:0.30,0.60 b:0.15,0.06 + ccwn3p08 - chroma chunk w:0.3127,0.3290 r:0.64,0.33 g:0.30,0.60 b:0.15,0.06 + + ch1n3p04 - histogram 15 colors + ch2n3p08 - histogram 256 colors + + cm7n0g04 - modification time, 01-jan-1970 00:00:00 + cm9n0g04 - modification time, 31-dec-1999 23:59:59 + cm0n0g04 - modification time, 01-jan-2000 12:34:56 + + ct0n0g04 - no textual data + ct1n0g04 - with textual data + ctzn0g04 - with compressed textual data + + + +3.10 Chunk ordering +---------------------- + + oi1n0g16 - grayscale mother image with 1 idat-chunk + oi2n0g16 - grayscale image with 2 idat-chunks + oi4n0g16 - grayscale image with 4 unequal sized idat-chunks + oi9n0g16 - grayscale image with all idat-chunks length one + oi1n2c16 - color mother image with 1 idat-chunk + oi2n2c16 - color image with 2 idat-chunks + oi4n2c16 - color image with 4 unequal sized idat-chunks + oi9n2c16 - color image with all idat-chunks length one + + + +3.11 Compression level +------------------------- + + z00n2c08 - color, no interlacing, compression level 0 (none) + z03n2c08 - color, no interlacing, compression level 3 + z06n2c08 - color, no interlacing, compression level 6 (default) + z09n2c08 - color, no interlacing, compression level 9 (maximum) + + + +3.12 Currupted files +----------------------- + + x00n0g01 - empty 0x0 grayscale file + xcrn0g04 - added cr bytes + xlfn0g04 - added lf bytes + xc0n0c08 - color type 0 + xc9n0c08 - color type 9 + xd0n2c00 - bit-depth 0 + xd3n2c03 - bit-depth 3 + xd9n2c99 - bit-depth 99 + xcsn2c08 - incorrect IDAT checksum + + +-------- + (c) Willem van Schaik + willem@schaik.com + Singapore, October 1996 diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/pngsuite_logo.png b/cram_3rdparty/cl_png/src/test/PngSuite/pngsuite_logo.png new file mode 100644 index 0000000000..205460d828 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/pngsuite_logo.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/pp0n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/pp0n2c16.png new file mode 100644 index 0000000000..8f2aad7335 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/pp0n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/pp0n6a08.png b/cram_3rdparty/cl_png/src/test/PngSuite/pp0n6a08.png new file mode 100644 index 0000000000..4ed7a30e4d Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/pp0n6a08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ps1n0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/ps1n0g08.png new file mode 100644 index 0000000000..2053df2ba3 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ps1n0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ps1n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/ps1n2c16.png new file mode 100644 index 0000000000..b03ecfc669 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ps1n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ps2n0g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/ps2n0g08.png new file mode 100644 index 0000000000..beeab8ff3d Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ps2n0g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/ps2n2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/ps2n2c16.png new file mode 100644 index 0000000000..c256f9091b Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/ps2n2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s01i3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s01i3p01.png new file mode 100644 index 0000000000..6c0fad1fc9 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s01i3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s01n3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s01n3p01.png new file mode 100644 index 0000000000..cb2c8c7826 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s01n3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s02i3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s02i3p01.png new file mode 100644 index 0000000000..2defaed911 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s02i3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s02n3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s02n3p01.png new file mode 100644 index 0000000000..2b1b669643 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s02n3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s03i3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s03i3p01.png new file mode 100644 index 0000000000..c23fdc4631 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s03i3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s03n3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s03n3p01.png new file mode 100644 index 0000000000..6d96ee4f87 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s03n3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s04i3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s04i3p01.png new file mode 100644 index 0000000000..0e710c2c39 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s04i3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s04n3p01.png b/cram_3rdparty/cl_png/src/test/PngSuite/s04n3p01.png new file mode 100644 index 0000000000..956396c45b Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s04n3p01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s05i3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s05i3p02.png new file mode 100644 index 0000000000..d14cbd351a Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s05i3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s05n3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s05n3p02.png new file mode 100644 index 0000000000..bf940f0576 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s05n3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s06i3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s06i3p02.png new file mode 100644 index 0000000000..456ada3200 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s06i3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s06n3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s06n3p02.png new file mode 100644 index 0000000000..501064dc25 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s06n3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s07i3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s07i3p02.png new file mode 100644 index 0000000000..44b66bab9e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s07i3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s07n3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s07n3p02.png new file mode 100644 index 0000000000..6a582593d6 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s07n3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s08i3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s08i3p02.png new file mode 100644 index 0000000000..acf74f3fc4 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s08i3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s08n3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s08n3p02.png new file mode 100644 index 0000000000..b7094e1b4f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s08n3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s09i3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s09i3p02.png new file mode 100644 index 0000000000..0bfae8e456 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s09i3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s09n3p02.png b/cram_3rdparty/cl_png/src/test/PngSuite/s09n3p02.png new file mode 100644 index 0000000000..711ab82451 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s09n3p02.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s32i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s32i3p04.png new file mode 100644 index 0000000000..0841910b72 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s32i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s32n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s32n3p04.png new file mode 100644 index 0000000000..fa58e3e3f6 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s32n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s33i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s33i3p04.png new file mode 100644 index 0000000000..ab0dc14aba Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s33i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s33n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s33n3p04.png new file mode 100644 index 0000000000..764f1a3dc7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s33n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s34i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s34i3p04.png new file mode 100644 index 0000000000..bd99039be4 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s34i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s34n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s34n3p04.png new file mode 100644 index 0000000000..9cbc68b3b9 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s34n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s35i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s35i3p04.png new file mode 100644 index 0000000000..e2a5e0a659 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s35i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s35n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s35n3p04.png new file mode 100644 index 0000000000..90b892ebaf Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s35n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s36i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s36i3p04.png new file mode 100644 index 0000000000..eb61b6f9a3 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s36i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s36n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s36n3p04.png new file mode 100644 index 0000000000..b38d179774 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s36n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s37i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s37i3p04.png new file mode 100644 index 0000000000..6e2b1e9b79 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s37i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s37n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s37n3p04.png new file mode 100644 index 0000000000..4d3054da51 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s37n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s38i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s38i3p04.png new file mode 100644 index 0000000000..a0a8a140ad Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s38i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s38n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s38n3p04.png new file mode 100644 index 0000000000..1233ed048e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s38n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s39i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s39i3p04.png new file mode 100644 index 0000000000..04fee93eae Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s39i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s39n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s39n3p04.png new file mode 100644 index 0000000000..c750100d55 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s39n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s40i3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s40i3p04.png new file mode 100644 index 0000000000..68f358b822 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s40i3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/s40n3p04.png b/cram_3rdparty/cl_png/src/test/PngSuite/s40n3p04.png new file mode 100644 index 0000000000..864b6b9673 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/s40n3p04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbbn1g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbbn1g04.png new file mode 100644 index 0000000000..fc8002053a Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbbn1g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbbn2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbbn2c16.png new file mode 100644 index 0000000000..5abfbbb3a2 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbbn2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbbn3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbbn3p08.png new file mode 100644 index 0000000000..4210d16832 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbbn3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbgn2c16.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbgn2c16.png new file mode 100644 index 0000000000..236c81dcf3 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbgn2c16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbgn3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbgn3p08.png new file mode 100644 index 0000000000..42db2325b1 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbgn3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbrn2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbrn2c08.png new file mode 100644 index 0000000000..8c214746d5 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbrn2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbwn1g16.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbwn1g16.png new file mode 100644 index 0000000000..dba2cbb6c3 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbwn1g16.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbwn3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbwn3p08.png new file mode 100644 index 0000000000..7922135aa7 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbwn3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tbyn3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tbyn3p08.png new file mode 100644 index 0000000000..5b2c6cbbaa Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tbyn3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tp0n1g08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tp0n1g08.png new file mode 100644 index 0000000000..caad31deae Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tp0n1g08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tp0n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tp0n2c08.png new file mode 100644 index 0000000000..f26be44679 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tp0n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tp0n3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tp0n3p08.png new file mode 100644 index 0000000000..4d6cf9e44c Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tp0n3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/tp1n3p08.png b/cram_3rdparty/cl_png/src/test/PngSuite/tp1n3p08.png new file mode 100644 index 0000000000..6c5fd6ec32 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/tp1n3p08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/x00n0g01.png b/cram_3rdparty/cl_png/src/test/PngSuite/x00n0g01.png new file mode 100644 index 0000000000..db3a5fda7e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/x00n0g01.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/xcrn0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/xcrn0g04.png new file mode 100644 index 0000000000..5bce9f3ada Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/xcrn0g04.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/xlfn0g04.png b/cram_3rdparty/cl_png/src/test/PngSuite/xlfn0g04.png new file mode 100644 index 0000000000..1fd104ba61 --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/PngSuite/xlfn0g04.png @@ -0,0 +1,13 @@ +‰PNG + + + + + +IHDR “áÈ)ÈIDATxœ]ÑÁ +Â0 P*@ð¡#° + +#TâÈ10lPF`Ø F=•ŸÄIQâ*çÅuí”`%qk +Hžñšˆ©ñ´€m÷Íüµàߟ Ñ=,¸fìOK + +ç ÐtŽÀ(Èïä’צíF ;èPº€¯¾{xpç]9‡/p*$(ì*éyìÕƒ ×þÚéçè@÷C¼  cÔqž‹NÛU#„)11·.räðfä0°ägh(¥týÙÂEøÿ‰kIEND®B`‚ \ No newline at end of file diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/z00n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/z00n2c08.png new file mode 100644 index 0000000000..7669eb8385 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/z00n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/z03n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/z03n2c08.png new file mode 100644 index 0000000000..bfb10de8de Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/z03n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/z06n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/z06n2c08.png new file mode 100644 index 0000000000..b90ebc10f5 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/z06n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/PngSuite/z09n2c08.png b/cram_3rdparty/cl_png/src/test/PngSuite/z09n2c08.png new file mode 100644 index 0000000000..5f191a78ee Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/PngSuite/z09n2c08.png differ diff --git a/cram_3rdparty/cl_png/src/test/bmp-test.asd b/cram_3rdparty/cl_png/src/test/bmp-test.asd new file mode 100644 index 0000000000..66256e538e --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/bmp-test.asd @@ -0,0 +1,7 @@ +;;;; -*- Mode: Lisp; -*- + +(asdf:defsystem :bmp-test + :components ((:file "bmp-test" :depends-on ("lisp-unit")) + (:file "lisp-unit") + ) + :depends-on (#:png)) diff --git a/cram_3rdparty/cl_png/src/test/bmp-test.lisp b/cram_3rdparty/cl_png/src/test/bmp-test.lisp new file mode 100644 index 0000000000..c31f6fbdd1 --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/bmp-test.lisp @@ -0,0 +1,128 @@ +;;;# Unit Tests for BMP file interface +;;; +;;; RUN-TESTS to run tests, either individually, multiply, or all at +;;; once: +;;; +;; (run-tests test1) ; runs one test +;; (run-tests test1 test2) ; runs two tests +;; (run-tests) ; runs all defined tests +;;; +;;;## Requirements +;;; +;;; Depends on the lisp-unit, obtained from +;;; http://www.cliki.net/lisp-unit. The package defined in +;;; bmp-test.asd will load and run them. +;;; +;;; Test images are provided which must located as defined in +;;; *BMPIMAGES-PATHNAME* below. +;;; +(defpackage #:bmp-test + (:use #:common-lisp #:lisp-unit #:image) + (:export #:*images-pathname*)) + +(in-package #:bmp-test) + +(defparameter *images-pathname* + #+asdf (merge-pathnames "images/" + (truename (asdf:system-definition-pathname + '#:bmp-test)))) +(run-tests ) +;;;## Utility functions +;;; +(defun make-name (bn tp) + (merge-pathnames (make-pathname :name bn :type tp) *images-pathname*)) + +(defun decode-pngimage (basename) + (let ((pathname (make-name basename "png"))) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (png:decode input)))) + +(defun decode-bmpimage (basename &key strip-alpha) + (let ((pathname (make-name basename "bmp"))) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (bmp:decode input :strip-alpha strip-alpha)))) + +(defun encode-decode (im &key strip-alpha keep-tmp) + (let ((pathname (make-name "tmp" "bmp"))) + (ignore-errors (delete-file pathname)) + (bmp::encode-file im pathname :strip-alpha strip-alpha) + (prog1 + (bmp::decode-file pathname) + (unless keep-tmp + (delete-file pathname))))) + +(defun max-diff (im1 im2) + (image:intensity-max (image:subtract im1 im2))) + + +;;;# Basic Tests +;;; +;;; Tests that decode function produces correct type of image and +;;; fails on those whose modes aren't supported. +(define-test image-type-test + (let ((rgb (decode-bmpimage "tagged-RGB")) + (argb (decode-bmpimage "tagged-ARGB")) + (gray (decode-bmpimage "tagged-gray"))) + (assert-true (typep rgb 'rgb-image)) + (assert-true (typep gray 'grayscale-image)) + (assert-error 'bmp::unhandled-compression (decode-bmpimage "intrepid-xrgb")) + (assert-error 'bmp::unhandled-compression (decode-bmpimage "intrepid-r5b6g5")) + (assert-error 'bmp::unhandled-compression (decode-bmpimage "intrepid-a1r5b5g5")) + (assert-error 'bmp::unhandled-bitcount (decode-bmpimage "intrepid-x1r5b5g5")))) + +;;(run-tests '(image-type-test)) + +;;; Test that the row padding is being handled properly. There are +;;; four cases: images whose widths modulo 4 result in 0,1,2,3. +;;; +;;; The methodology is to decode a file into an image, re-encode the +;;; image back to a file, then decode it again and compare the two +;;; decoded images. + +(define-test encode-modulo-0 + (let ((a (decode-bmpimage "scene"))) + (assert-equal 0 (max-diff a (encode-decode a))))) + +(define-test encode-modulo-1 + (let ((a (decode-bmpimage "scene-w765")) + (b (decode-bmpimage "scene-bw765"))) + (assert-true (typep a 'rgb-image)) + (assert-equal 0 (max-diff a (encode-decode a :keep-tmp t))) + (assert-true (typep b 'grayscale-image)) + (assert-equal 0 (max-diff b (encode-decode b))))) + +(define-test encode-modulo-2 + (let ((a (decode-bmpimage "scene-w766"))) + (assert-equal 0 (image:intensity-max (image:subtract a (encode-decode a)))))) + +(define-test encode-modulo-3 + (let ((a (decode-bmpimage "scene-w767")) + (b (decode-bmpimage "scene-bw767"))) + (assert-true (typep a 'rgb-image)) + (assert-equal 0 (max-diff a (encode-decode a))) + (assert-true (typep b 'grayscale-image)) + (assert-equal 0 (max-diff b (encode-decode b))))) + +;;(run-tests '(encode-modulo-0 encode-modulo-2)) +;;(run-tests '(encode-modulo-1 encode-modulo-3)) +;; (run-tests) + + +(define-test decode-strip-alpha + (let* ((a (decode-bmpimage "intrepid-rgb")) + (b (decode-bmpimage "intrepid-argb")) + (c (decode-bmpimage "intrepid-argb" :strip-alpha T))) + (assert-true (typep a 'rgb-image)) + (assert-true (typep c 'rgb-image)) + (assert-equal 0 (max-diff a c)))) + +(define-test encode-strip-alpha + (let* ((a (decode-bmpimage "intrepid-argb")) + (b (encode-decode a :strip-alpha T :keep-tmp T)) + (c (decode-bmpimage "tmp"))) + (assert-true (typep b 'rgb-image)) + (assert-true (typep c 'rgb-image)) + (assert-equal 0 (max-diff b c)))) + +;;(run-tests '(decode-strip-alpha)) +;;(run-tests '(encode-strip-alpha)) diff --git a/cram_3rdparty/cl_png/src/test/image-test.asd b/cram_3rdparty/cl_png/src/test/image-test.asd new file mode 100644 index 0000000000..62c9fd775b --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/image-test.asd @@ -0,0 +1,7 @@ +;;;; -*- Mode: Lisp; -*- + +(asdf:defsystem #:image-test + :components ((:file "image-test" :depends-on ("lisp-unit")) + (:file "lisp-unit") + ) + :depends-on (#:png)) diff --git a/cram_3rdparty/cl_png/src/test/image-test.lisp b/cram_3rdparty/cl_png/src/test/image-test.lisp new file mode 100644 index 0000000000..221333f829 --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/image-test.lisp @@ -0,0 +1,147 @@ +;;;# Unit Tests for Image Operations +;;; +;;; RUN-TESTS to run tests, either individually, multiply, or all at +;;; once: +;;; +;; (run-tests test1) ; runs one test +;; (run-tests test1 test2) ; runs two tests +;; (run-tests) ; runs all defined tests +;;; +;;;## Requirements +;;; +;;; These unit tests depend on the lisp-unit library, obtained from +;;; http://www.cliki.net/lisp-unit. The package defined in +;;; bmp-test.asd will load them. +;;; +;;; Test images are provided which must located relative to this file +;;; location as defined in *BMPIMAGES-PATHNAME* below +;;; +(defpackage #:image-test + (:use #:common-lisp #:lisp-unit #:image) + (:export #:*images-pathname*)) + +(in-package #:image-test) + +(defparameter *images-pathname* + #+asdf (merge-pathnames "images/" + (truename (asdf:system-definition-pathname + '#:image-test)))) + +;;;## Utility functions +;;; +(defun make-name (bn tp) + (merge-pathnames (make-pathname :name bn :type tp) *images-pathname*)) + +(defun decode-pngimage (basename) + (let ((pathname (make-name basename "png"))) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (png:decode input)))) + +(defun decode-bmpimage (basename &key strip-alpha) + (let ((pathname (make-name basename "bmp"))) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (bmp:decode input :strip-alpha strip-alpha)))) + +(defun max-diff (im1 im2) + (image:intensity-max (image:subtract im1 im2))) + + +;;;# Basic Tests +;;; + + +(in-package #:image-test) + +(define-test channel-order + (let ((rgb (decode-bmpimage "tagged-RGB")) + (argb (decode-bmpimage "tagged-ARGB"))) + (assert-true (typep rgb 'rgb-image)) + (assert-true (typep rgb 'opaque-image)) + (assert-true (typep argb 'rgb-image)) + (assert-false (typep argb 'opaque-image)) + (assert-true (typep argb 'transparent-image)))) + +(define-test fill-tests + (let ((a (make-image 10 10 3))) + (assert-error 'error (image:fillv a '(99 99))) + (assert-error 'error (image:fillv a '(1 1 2 2 2))) + (image:fillv a '(99 88 77)) + (assert-equalp #(99 88 77) (image:channel-max a)))) + +(run-tests channel-order) +(run-tests fill-tests) + + +;;; Scalar-Valued Functions of One Image +;;; +;;;## IMAGE-NORM2 +;;; +(define-test image-norm2 + (let ((a (make-image 10 10 3)) + (b (make-image 10 10 3))) + (image:fillv a '(1 1 1)) + (image:fillv b '(2 2 2)) + (assert-equal 300 (image:norm2 a)) + (assert-equal 1200 (image:norm2 b)))) + +(run-tests image-norm2) + + +;;;# Functions of One Image +;;; +;;;## IMAGE-SCALE + +;;;# Functions of Two Images +;;; + +;;;## IMAGE-SUB +;;; +(define-test image-sub-test + (let ((a (decode-bmpimage "intrepid-rgb")) + (b (decode-bmpimage "scene")) + (c (decode-bmpimage "intrepid-argb")) + (d (decode-bmpimage "intrepid-argb" :strip-alpha T)) + (err)) + (setf err (image:norm2 (image:subtract a d))) + (assert-error 'error (image:subtract a b)) + (assert-error 'error (image:subtract a c)) + (assert-equal 0 err) + (let* ((f (image:subtract a a)) + (g (make-image-like c)) + (h (make-image-like c))) + (assert-equal 0 (image:norm2 f)) + (image:subtract* a d) + (assert-equal 0 (image:norm2 a)) + (image:fillv g '(40 40 40 40)) + (setf h (image:subtract c g)) + (image:subtract* c g) + (assert-equalp c h)))) + +(run-tests image-sub-test) + + +;;; ## IMAGE-ADD +(define-test image-add-test + (let* ((a (decode-bmpimage "butterfly1")) + ;; (a-maxch (image-channel-max a)) + (a-maxin (image:intensity-max a)) + (b (make-image-like a)) + (val '(40 30 20)) + (submax #(215 225 235)) + (c) + (d)) + (image:fillv b val) + (setf c (image:subtract a b)) + (assert-equal (- a-maxin (apply #'+ val)) (image:intensity-max c)) + (assert-equalp submax (image:channel-max c)) + (setf d (image:add c b)) + (image:subtract* d a) ; contains bottom end clipping residue + ;; (format t "maxchans d = ~a~%" (image-channel-max d)) + )) +;; (still working on this one) + +(run-tests image-add-test) + + +;;;# Statistical Functions +;;; \ No newline at end of file diff --git a/cram_3rdparty/cl_png/src/test/images/butterfly1-argb.bmp b/cram_3rdparty/cl_png/src/test/images/butterfly1-argb.bmp new file mode 100644 index 0000000000..d49a07dfbb Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/butterfly1-argb.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/butterfly1-argb.png b/cram_3rdparty/cl_png/src/test/images/butterfly1-argb.png new file mode 100644 index 0000000000..126dc9128e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/butterfly1-argb.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/butterfly1.bmp b/cram_3rdparty/cl_png/src/test/images/butterfly1.bmp new file mode 100644 index 0000000000..0fc2d0ad01 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/butterfly1.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/butterfly1.jpg b/cram_3rdparty/cl_png/src/test/images/butterfly1.jpg new file mode 100644 index 0000000000..c545d9b718 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/butterfly1.jpg differ diff --git a/cram_3rdparty/cl_png/src/test/images/butterfly1.png b/cram_3rdparty/cl_png/src/test/images/butterfly1.png new file mode 100644 index 0000000000..005bccb842 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/butterfly1.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/butterfly8.jpg b/cram_3rdparty/cl_png/src/test/images/butterfly8.jpg new file mode 100644 index 0000000000..f50ec246bc Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/butterfly8.jpg differ diff --git a/cram_3rdparty/cl_png/src/test/images/butterfly8.png b/cram_3rdparty/cl_png/src/test/images/butterfly8.png new file mode 100644 index 0000000000..dd6a05f2e5 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/butterfly8.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-24.png b/cram_3rdparty/cl_png/src/test/images/intrepid-24.png new file mode 100644 index 0000000000..2692ea814c Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-24.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-32.png b/cram_3rdparty/cl_png/src/test/images/intrepid-32.png new file mode 100644 index 0000000000..f850ed0e69 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-32.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-32b.png b/cram_3rdparty/cl_png/src/test/images/intrepid-32b.png new file mode 100644 index 0000000000..71c26ed088 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-32b.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-a1r5b5g5.bmp b/cram_3rdparty/cl_png/src/test/images/intrepid-a1r5b5g5.bmp new file mode 100644 index 0000000000..03645897af Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-a1r5b5g5.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-argb.bmp b/cram_3rdparty/cl_png/src/test/images/intrepid-argb.bmp new file mode 100644 index 0000000000..2ee5eb80ef Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-argb.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-r5b6g5.bmp b/cram_3rdparty/cl_png/src/test/images/intrepid-r5b6g5.bmp new file mode 100644 index 0000000000..6fd8739db3 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-r5b6g5.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-rgb.bmp b/cram_3rdparty/cl_png/src/test/images/intrepid-rgb.bmp new file mode 100644 index 0000000000..2e12ca9550 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-rgb.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-x1r5b5g5.bmp b/cram_3rdparty/cl_png/src/test/images/intrepid-x1r5b5g5.bmp new file mode 100644 index 0000000000..b59769a630 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-x1r5b5g5.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid-xrgb.bmp b/cram_3rdparty/cl_png/src/test/images/intrepid-xrgb.bmp new file mode 100644 index 0000000000..bbe969f63e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid-xrgb.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/intrepid.jpg b/cram_3rdparty/cl_png/src/test/images/intrepid.jpg new file mode 100644 index 0000000000..871990356e Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/intrepid.jpg differ diff --git a/cram_3rdparty/cl_png/src/test/images/scene-bw765.bmp b/cram_3rdparty/cl_png/src/test/images/scene-bw765.bmp new file mode 100644 index 0000000000..1eabff9a30 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/scene-bw765.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/scene-bw765rl.bmp b/cram_3rdparty/cl_png/src/test/images/scene-bw765rl.bmp new file mode 100644 index 0000000000..87b3376010 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/scene-bw765rl.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/scene-bw767.bmp b/cram_3rdparty/cl_png/src/test/images/scene-bw767.bmp new file mode 100644 index 0000000000..9e8c8a0a86 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/scene-bw767.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/scene-w765.bmp b/cram_3rdparty/cl_png/src/test/images/scene-w765.bmp new file mode 100644 index 0000000000..a69f2a139f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/scene-w765.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/scene-w766.bmp b/cram_3rdparty/cl_png/src/test/images/scene-w766.bmp new file mode 100644 index 0000000000..5fa3fc3192 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/scene-w766.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/scene-w767.bmp b/cram_3rdparty/cl_png/src/test/images/scene-w767.bmp new file mode 100644 index 0000000000..20c890a957 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/scene-w767.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/scene.bmp b/cram_3rdparty/cl_png/src/test/images/scene.bmp new file mode 100644 index 0000000000..2c848c0144 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/scene.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/tagged-ARGB.bmp b/cram_3rdparty/cl_png/src/test/images/tagged-ARGB.bmp new file mode 100644 index 0000000000..614cf7bc81 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/tagged-ARGB.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/tagged-RGB.bmp b/cram_3rdparty/cl_png/src/test/images/tagged-RGB.bmp new file mode 100644 index 0000000000..26bddef8fa Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/tagged-RGB.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/tagged-RGB.png b/cram_3rdparty/cl_png/src/test/images/tagged-RGB.png new file mode 100644 index 0000000000..c08b480eea Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/tagged-RGB.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/tagged-gray.bmp b/cram_3rdparty/cl_png/src/test/images/tagged-gray.bmp new file mode 100644 index 0000000000..77be6376c0 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/tagged-gray.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/images/tagged-gray.png b/cram_3rdparty/cl_png/src/test/images/tagged-gray.png new file mode 100644 index 0000000000..58ee3836d4 Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/tagged-gray.png differ diff --git a/cram_3rdparty/cl_png/src/test/images/tmp.bmp b/cram_3rdparty/cl_png/src/test/images/tmp.bmp new file mode 100644 index 0000000000..caf6338e1f Binary files /dev/null and b/cram_3rdparty/cl_png/src/test/images/tmp.bmp differ diff --git a/cram_3rdparty/cl_png/src/test/lisp-unit.lisp b/cram_3rdparty/cl_png/src/test/lisp-unit.lisp new file mode 100644 index 0000000000..bf5aebfb5b --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/lisp-unit.lisp @@ -0,0 +1,429 @@ +;;;-*- Mode: Lisp; Package: LISP-UNIT -*- + +#| +Copyright (c) 2004-2005 Christopher K. Riesbeck + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +|# + + +;;; A test suite package, modelled after JUnit. +;;; Author: Chris Riesbeck +;;; +;;; Update history: +;;; +;;; 04/07/06 added ~<...~> to remaining error output forms [CKR] +;;; 04/06/06 added ~<...~> to compact error output better [CKR] +;;; 04/06/06 fixed RUN-TESTS to get tests dynamically (bug reported +;;; by Daniel Edward Burke) [CKR] +;;; 02/08/06 added newlines to error output [CKR] +;;; 12/30/05 renamed ASSERT-PREDICATE to ASSERT-EQUALITY [CKR] +;;; 12/29/05 added ASSERT-EQ, ASSERT-EQL, ASSERT-EQUALP [CKR] +;;; 12/22/05 recoded use-debugger to use handler-bind, added option to prompt for debugger, +;;; 11/07/05 added *use-debugger* and assert-predicate [DFB] +;;; 09/18/05 replaced Academic Free License with MIT Licence [CKR] +;;; 08/30/05 added license notice [CKR] +;;; 06/28/05 changed RUN-TESTS to compile code at run time, not expand time [CKR] +;;; 02/21/05 removed length check from SET-EQUAL [CKR] +;;; 02/17/05 added RUN-ALL-TESTS [CKR] +;;; 01/18/05 added ASSERT-EQUAL back in [CKR] +;;; 01/17/05 much clean up, added WITH-TEST-LISTENER [CKR] +;;; 01/15/05 replaced ASSERT-EQUAL etc. with ASSERT-TRUE and ASSERT-FALSE [CKR] +;;; 01/04/05 changed COLLECT-RESULTS to echo output on *STANDARD-OUTPuT* [CKR] +;;; 01/04/05 added optional package argument to REMOVE-ALL-TESTS [CKR] +;;; 01/04/05 changed OUTPUT-OK-P to trim spaces and returns [CKR] +;;; 01/04/05 changed OUTPUT-OK-P to not check output except when asked to [CKR] +;;; 12/03/04 merged REMOVE-TEST into REMOVE-TESTS [CKR] +;;; 12/03/04 removed ability to pass forms to RUN-TESTS [CKR] +;;; 12/03/04 refactored RUN-TESTS expansion into RUN-TEST-THUNKS [CKR] +;;; 12/02/04 changed to group tests under packages [CKR] +;;; 11/30/04 changed assertions to put expected value first, like JUnit [CKR] +;;; 11/30/04 improved error handling and summarization [CKR] +;;; 11/30/04 generalized RUN-TESTS, removed RUN-TEST [CKR] +;;; 02/27/04 fixed ASSERT-PRINTS not ignoring value [CKR] +;;; 02/07/04 fixed ASSERT-EXPANDS failure message [CKR] +;;; 02/07/04 added ASSERT-NULL, ASSERT-NOT-NULL [CKR] +;;; 01/31/04 added error handling and totalling to RUN-TESTS [CKR] +;;; 01/31/04 made RUN-TEST/RUN-TESTS macros [CKR] +;;; 01/29/04 fixed ASSERT-EXPANDS quote bug [CKR] +;;; 01/28/04 major changes from BUG-FINDER to be more like JUnit [CKR] + + +#| +How to use +---------- + +1. Read the documentation in lisp-unit.html. + +2. Make a file of DEFINE-TEST's. See exercise-tests.lisp for many +examples. If you want, start your test file with (REMOVE-TESTS) to +clear any previously defined tests. + +2. Load this file. + +2. (use-package :lisp-unit) + +3. Load your code file and your file of tests. + +4. Test your code with (RUN-TESTS test-name1 test-name2 ...) -- no quotes! -- +or simply (RUN-TESTS) to run all defined tests. + +A summary of how many tests passed and failed will be printed, +with details on the failures. + +Note: Nothing is compiled until RUN-TESTS is expanded. Redefining +functions or even macros does not require reloading any tests. + +For more information, see lisp-unit.html. + +|# + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Packages +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(cl:defpackage #:lisp-unit + (:use #:common-lisp) + (:export #:define-test #:run-all-tests #:run-tests + #:assert-eq #:assert-eql #:assert-equal #:assert-equalp + #:assert-error #:assert-expands #:assert-false + #:assert-equality #:assert-prints #:assert-true + #:get-test-code #:get-tests + #:remove-all-tests #:remove-tests + #:logically-equal #:set-equal + #:use-debugger + #:with-test-listener) + ) + +(in-package #:lisp-unit) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Globals +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *test-listener* nil) + +(defparameter *tests* (make-hash-table)) + +;;; Used by RUN-TESTS to collect summary statistics +(defvar *test-count* 0) +(defvar *pass-count* 0) + +;;; Set by RUN-TESTS for use by SHOW-FAILURE +(defvar *test-name* nil) + +;;; If nil, errors in tests are caught and counted. +;;; If :ask, user is given option of entering debugger or not. +;;; If true and not :ask, debugger is entered. +(defparameter *use-debugger* nil) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Macros +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; DEFINE-TEST + +(defmacro define-test (name &body body) + `(progn + (store-test-code ',name ',body) + ',name)) + +;;; ASSERT macros + +(defmacro assert-eq (expected form &rest extras) + (expand-assert :equal form form expected extras :test #'eq)) + +(defmacro assert-eql (expected form &rest extras) + (expand-assert :equal form form expected extras :test #'eql)) + +(defmacro assert-equal (expected form &rest extras) + (expand-assert :equal form form expected extras :test #'equal)) + +(defmacro assert-equalp (expected form &rest extras) + (expand-assert :equal form form expected extras :test #'equalp)) + +(defmacro assert-error (condition form &rest extras) + (expand-assert :error form (expand-error-form form) + condition extras)) + +(defmacro assert-expands (&environment env expansion form &rest extras) + (expand-assert :macro form + (expand-macro-form form #+lispworks nil #-lispworks env) + expansion extras)) + +(defmacro assert-false (form &rest extras) + (expand-assert :result form form nil extras)) + +(defmacro assert-equality (test expected form &rest extras) + (expand-assert :equal form form expected extras :test test)) + +(defmacro assert-prints (output form &rest extras) + (expand-assert :output form (expand-output-form form) + output extras)) + +(defmacro assert-true (form &rest extras) + (expand-assert :result form form t extras)) + + +(defun expand-assert (type form body expected extras &key (test #'eql)) + `(internal-assert + ,type ',form #'(lambda () ,body) #'(lambda () ,expected) ,(expand-extras extras), test)) + +(defun expand-error-form (form) + `(handler-case ,form + (condition (error) error))) + +(defun expand-output-form (form) + (let ((out (gensym))) + `(let* ((,out (make-string-output-stream)) + (*standard-output* (make-broadcast-stream *standard-output* ,out))) + ,form + (get-output-stream-string ,out)))) + +(defun expand-macro-form (form env) + `(macroexpand-1 ',form ,env)) + +(defun expand-extras (extras) + `#'(lambda () + (list ,@(mapcan #'(lambda (form) (list `',form form)) extras)))) + + +;;; RUN-TESTS + +(defmacro run-all-tests (package &rest tests) + `(let ((*package* (find-package ',package))) + (run-tests + ,@(mapcar #'(lambda (test) (find-symbol (symbol-name test) package)) + tests)))) + +(defmacro run-tests (&rest names) + `(run-test-thunks (get-test-thunks ,(if (null names) '(get-tests *package*) `',names)))) + +(defun get-test-thunks (names &optional (package *package*)) + (mapcar #'(lambda (name) (get-test-thunk name package)) + names)) + +(defun get-test-thunk (name package) + (assert (get-test-code name package) (name package) + "No test defined for ~S in package ~S" name package) + (list name (coerce `(lambda () ,@(get-test-code name)) 'function))) + +(defun use-debugger (&optional (flag t)) + (setq *use-debugger* flag)) + +;;; WITH-TEST-LISTENER +(defmacro with-test-listener (listener &body body) + `(let ((*test-listener* #',listener)) ,@body)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Public functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun get-test-code (name &optional (package *package*)) + (let ((table (get-package-table package))) + (unless (null table) + (gethash name table)))) + +(defun get-tests (&optional (package *package*)) + (let ((l nil) + (table (get-package-table package))) + (cond ((null table) nil) + (t + (maphash #'(lambda (key val) + (declare (ignore val)) + (push key l)) + table) + (sort l #'string< :key #'string))))) + + +(defun remove-tests (names &optional (package *package*)) + (let ((table (get-package-table package))) + (unless (null table) + (if (null names) + (clrhash table) + (dolist (name names) + (remhash name table)))))) + +(defun remove-all-tests (&optional (package *package*)) + (if (null package) + (clrhash *tests*) + (remhash (find-package package) *tests*))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Private functions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;; DEFINE-TEST support + +(defun get-package-table (package &key create) + (let ((table (gethash (find-package package) *tests*))) + (or table + (and create + (setf (gethash package *tests*) + (make-hash-table)))))) + +(defun get-test-name (form) + (if (atom form) form (cadr form))) + +(defun store-test-code (name code &optional (package *package*)) + (setf (gethash name + (get-package-table package :create t)) + code)) + + +;;; ASSERTION support + +(defun internal-assert (type form code-thunk expected-thunk extras test) + (let* ((expected (multiple-value-list (funcall expected-thunk))) + (actual (multiple-value-list (funcall code-thunk))) + (passed (test-passed-p type expected actual test))) + + (incf *test-count*) + (when passed + (incf *pass-count*)) + + (record-result passed type form expected actual extras) + + passed)) + +(defun record-result (passed type form expected actual extras) + (funcall (or *test-listener* 'default-listener) + passed type *test-name* form expected actual + (and extras (funcall extras)) + *test-count* *pass-count*)) + +(defun default-listener + (passed type name form expected actual extras test-count pass-count) + (declare (ignore test-count pass-count)) + (unless passed + (show-failure type (get-failure-message type) + name form expected actual extras))) + +(defun test-passed-p (type expected actual test) + (ecase type + (:error + (or (eql (car actual) (car expected)) + (typep (car actual) (car expected)))) + (:equal + (and (<= (length expected) (length actual)) + (every test expected actual))) + (:macro + (equal (car actual) (car expected))) + (:output + (string= (string-trim '(#\newline #\return #\space) + (car actual)) + (car expected))) + (:result + (logically-equal (car actual) (car expected))) + )) + + +;;; RUN-TESTS support + +(defun run-test-thunks (test-thunks) + (unless (null test-thunks) + (let ((total-test-count 0) + (total-pass-count 0) + (total-error-count 0)) + (dolist (test-thunk test-thunks) + (multiple-value-bind (test-count pass-count error-count) + (run-test-thunk (car test-thunk) (cadr test-thunk)) + (incf total-test-count test-count) + (incf total-pass-count pass-count) + (incf total-error-count error-count))) + (unless (null (cdr test-thunks)) + (show-summary 'total total-test-count total-pass-count total-error-count)) + (values)))) + +(defun run-test-thunk (*test-name* thunk) + (if (null thunk) + (format t "~& Test ~S not found" *test-name*) + (prog ((*test-count* 0) + (*pass-count* 0) + (error-count 0)) + (handler-bind + ((error #'(lambda (e) + (let ((*print-escape* nil)) + (setq error-count 1) + (format t "~& ~S: ~W" *test-name* e)) + (if (use-debugger-p e) e (go exit))))) + (funcall thunk) + (show-summary *test-name* *test-count* *pass-count*)) + exit + (return (values *test-count* *pass-count* error-count))))) + +(defun use-debugger-p (e) + (and *use-debugger* + (or (not (eql *use-debugger* :ask)) + (y-or-n-p "~A -- debug?" e)))) + +;;; OUTPUT support + +(defun get-failure-message (type) + (case type + (:error "~&~@[Should have signalled ~{~S~^; ~} but saw~] ~{~S~^; ~}") + (:macro "~&Should have expanded to ~{~S~^; ~} ~<~%~:;but saw ~{~S~^; ~}~>") + (:output "~&Should have printed ~{~S~^; ~} ~<~%~:;but saw ~{~S~^; ~}~>") + (t "~&Expected ~{~S~^; ~} ~<~%~:;but saw ~{~S~^; ~}~>") + )) + +(defun show-failure (type msg name form expected actual extras) + (format t "~&~@[~S: ~]~S failed: " name form) + (format t msg expected actual) + (format t "~{~& ~S => ~S~}~%" extras) + type) + +(defun show-summary (name test-count pass-count &optional error-count) + (format t "~&~A: ~S assertions passed, ~S failed~@[, ~S execution errors~]." + name pass-count (- test-count pass-count) error-count)) + +(defun collect-form-values (form values) + (mapcan #'(lambda (form-arg value) + (if (constantp form-arg) + nil + (list form-arg value))) + (cdr form) + values)) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Useful equality predicates for tests +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; (LOGICALLY-EQUAL x y) => true or false +;;; Return true if x and y both false or both true + +(defun logically-equal (x y) + (eql (not x) (not y))) + +;;; (SET-EQUAL l1 l2 :test) => true or false +;;; Return true if every element of l1 is an element of l2 +;;; and vice versa. + +(defun set-equal (l1 l2 &key (test #'equal)) + (and (listp l1) + (listp l2) + (subsetp l1 l2 :test test) + (subsetp l2 l1 :test test))) + + +(provide "lisp-unit") diff --git a/cram_3rdparty/cl_png/src/test/ops-test.asd b/cram_3rdparty/cl_png/src/test/ops-test.asd new file mode 100644 index 0000000000..3647ead09e --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/ops-test.asd @@ -0,0 +1,8 @@ +;;;; -*- Mode: Lisp; -*- + +(asdf:defsystem :ops-test + :components ((:file "ops-test" :depends-on ("lisp-unit")) + (:file "lisp-unit") + ) + :depends-on (#:png)) + diff --git a/cram_3rdparty/cl_png/src/test/ops-test.lisp b/cram_3rdparty/cl_png/src/test/ops-test.lisp new file mode 100644 index 0000000000..5c39c36c15 --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/ops-test.lisp @@ -0,0 +1,242 @@ +;;;# Unit Tests for Image Operations +;;; +;;;## Requirements +;;; +;;; This test suite depends on lisp-unit.lisp, obtained from +;;; http://www.cliki.net/lisp-unit, but also included herein. +;;; +;;; Everything should be loaded correctly by loading ops-test with +;;; asdf, provided the asd links have been established: + +;; (asdf:oos 'asdf:load-op :ops-test) + +;;; Some of the tests refer to provided images which must be located +;;; as defined in *BMPIMAGES-PATHNAME* as set below. +;;; +(defpackage #:ops-test + (:use #:common-lisp #:lisp-unit #:image #:png) + (:export #:*images-pathname*)) +(in-package #:ops-test) + +(defparameter *images-pathname* + #+asdf (merge-pathnames "images/" + (truename (asdf:system-definition-pathname + '#:ops-test)))) +;;;## Convenience functions +(defun make-name (bn tp) + (merge-pathnames (make-pathname :name bn :type tp) *images-pathname*)) + +(defun decode-pngimage (basename) + (let ((pathname (make-name basename "png"))) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (png:decode input)))) + +(defun decode-bmpimage (basename &key strip-alpha) + (let ((pathname (make-name basename "bmp"))) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (bmp:decode input :strip-alpha strip-alpha)))) + +(defun max-diff (im1 im2) + (image:intensity-max (image:subtract im1 im2))) + +(defun list2array (lst) + (make-array (length lst) :initial-contents lst)) + +(defun fill-graded (a) + (dotimes (h (image-height a) a) + (dotimes (w (image-width a)) + (dotimes (c (image-channels a)) + (let ((val (+ (* (image-width a) h) w c))) + (setf (aref a h w c) val)))))) + +;;;# Basic Tests +;;; +;;; Basic tests are those which will subsequently be used to help +;;; verify other functions. +;;; +;;;## Accessor Tests +(define-test accessor-test + (let ((a (make-image 111 222 3))) + (assert-equal '(111 . 222) (image:size a)) + (assert-equal '(111 222 3) (image:dims a)))) + +(run-tests accessor-test) + +(defparameter *simple-set* '(((10 11 1 8) grayscale-image (99)) + ((12 13 1 16) grayscale-image (88)) + ((14 15 3 8) rgb-image (99 88 77)) + ((16 17 3 16) rgb-image (66 55 44)) + ((18 19 4 8) rgb-image (111 122 133 144)) + ((20 21 4 16) rgb-image (122 133 144 155)))) + +;;;## Test FILLV +;;; +;;; Creates an image of each type, fills it with an arbitrary pixel +;;; value, then checks to see that all are set correctly. Also checks +;;; the check function by changing one pixel. +(define-test fillv-test + (flet ((check-for-diff (im val) + (block found-diff + (dotimes (r (image-height im) NIL) + (dotimes (c (image-width im)) + (dotimes (ch (image-channels im)) + (unless (= (aref im r c ch) (nth ch val)) + (return-from found-diff T)))))))) + (dolist (tst *simple-set*) + (let ((img (apply #'make-image (car tst))) + (typ (cadr tst)) + (val (caddr tst))) + (assert-true (typep img typ)) + (image:fillv img val) + (assert-false (check-for-diff img val)) + (decf (aref img 2 3 0)) + (assert-true (check-for-diff img val)))))) + +(run-tests fillv-test) + +;;;## Test INTENSITY-MAX and CHANNEL-MAX +;;; +;;; +(define-test max-test + (labels ((intensity (pix &optional (sum 0)) + (if (null pix) + sum + (intensity (cdr pix) (+ sum (car pix)))))) + (dolist (tst *simple-set*) + (let ((img (apply #'make-image (car tst))) + (val (caddr tst))) + (image:fillv img val) + (assert-equalp (list2array val) (channel-max img)) + (assert-equal (intensity val) (intensity-max img)) + )))) + +(run-tests max-test) + +;;;# Functions that Modify a Single Image +;;; + +;;;## SCALE +;;; +;;; TBD + +;;;# Functions that Combine Images +;;; +;;;## ADD, ADD* +;;; +;;; Depends on FLIP, MIRROR, CHANNEL-MIN, CHANNEL-MAX + +(defparameter *add-set* '(((5 6 1 8) grayscale-image) + ((5 6 1 16) grayscale-image) + ((5 6 3 8) rgb-image) + ((5 6 3 16) rgb-image) + ((5 6 4 8) rgba-image) + ((5 6 4 16) rgba-image))) + +(define-test image-add-test + (dolist (tst *add-set*) + (let* ((a (fill-graded (apply #'make-image (car tst)))) + (b (flip a)) + (c (add a b)) + (d (image::mirror c)) + (e (add c d))) + ;; test non-destructive version + (assert-equalp (image::channel-min e) (channel-max e)) + ;; test destructive version + (add* a b) + (setf c (image::mirror a)) + (add* a c) + (assert-equalp (image::channel-min a) (channel-max a))))) + +(run-tests image-add-test) + +(define-test image-sub-test + (dolist (tst *add-set*) + (let* ((a (fill-graded (apply #'make-image (car tst)))) + (b (flip a)) + (c (add a b)) + (d (subtract c b))) + (assert-equalp a d) + ;; test destructive version + (subtract* c b) + (assert-equalp a c)))) + +(run-tests image-sub-test) + + +;;;## MOVE-TO +;;; +(define-test image-move-to-test + (let* ((a (image:fillv (make-image 4 4 1) '(100))) + (b (image:fillv (make-image 4 4 1) '(10))) + (c (image:fillv (make-image 4 4 1) '(80))) + (d (image:fillv (make-image 4 4 1) '(30)))) + (assert-equalp c (image::move-towards a b 20)) + (assert-equalp d (image::move-towards b a 20)))) + +(run-tests image-move-to-test) + + + + +;;;# Other Scalar Valued Functions +;;; +;;;## IMAGE-NORM2 +;;; +(define-test image-norm2 + (let ((a (make-image 10 10 3)) + (b (make-image 10 10 3))) + (image:fillv a '(1 1 1)) + (image:fillv b '(2 2 2)) + (assert-equal 300 (image:norm2 a)) + (assert-equal 1200 (image:norm2 b)))) + +(run-tests image-norm2) + + + +;;;# Edge Detector +;;; +;;; We will use a convolutional filter with this kernel: +;;; +;;; 0 -1 0 +;;; -1 4 -1 +;;; 0 -1 0 +;;; + +(defparameter *edge-kernel* + (let ((mask (make-array (list 3 3) + :element-type 'float :initial-element 0.e0))) + (setf (aref mask 0 1) -1.e0 + (aref mask 1 0) -1.e0 + (aref mask 1 2) -1.e0 + (aref mask 2 1) -1.e0 + (aref mask 1 1) 4.e0) + mask)) +(print *edge-kernel*) + +;; Disabled because the input file butterfly8-gray.png is missing. +#+ignore +(define-test convolve-edge + (let* ((a (png:decode-file (merge-pathnames "butterfly8-gray.png" *images-pathname*))) + (c (png:decode-file (merge-pathnames "butterfly8.png" *images-pathname*))) + (ea) + (ec)) + (time + (setf ea (image::convolve a *edge-kernel* :fill '(#x7f)))) + (png:encode-file ea "test-ea.png") + + (time + (setf ec (image::convolve c *edge-kernel*))) + (format t "ec size:~s~%" (size ec)) + (png:encode-file ec "test-ec.png") + + (time + (setf ec (image::convolve c *edge-kernel* :fill '(#x7f #x7f #x7f)))) + (format t "ec size:~s~%" (size ec)) + (png:encode-file ec "test-ecb.png") + + (assert-true (typep ec 'rgb-image)))) + +;;(run-tests convolve-edge) + +;; (run-tests) diff --git a/cram_3rdparty/cl_png/src/test/png-test.asd b/cram_3rdparty/cl_png/src/test/png-test.asd new file mode 100644 index 0000000000..729ccf48f9 --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/png-test.asd @@ -0,0 +1,7 @@ +;;;; -*- Mode: Lisp; -*- + +(asdf:defsystem :png-test + :components ((:file "png-test" :depends-on ("lisp-unit")) + (:file "lisp-unit") + ) + :depends-on (#:png)) \ No newline at end of file diff --git a/cram_3rdparty/cl_png/src/test/png-test.lisp b/cram_3rdparty/cl_png/src/test/png-test.lisp new file mode 100644 index 0000000000..f5a0af35ca --- /dev/null +++ b/cram_3rdparty/cl_png/src/test/png-test.lisp @@ -0,0 +1,128 @@ +(defpackage #:png-test + (:use #:common-lisp #:lisp-unit #:png) + (:export #:*pngsuite-pathname*)) + +(in-package #:png-test) + +;; ASDF:SYSTEM-RELATIVE-PATHNAME only exists in very recent versions +;; of ASDF, so we'll do it this way. +(defparameter *pngsuite-pathname* + #+asdf (merge-pathnames "PngSuite/" + (truename (asdf:system-definition-pathname + '#:png-test)))) + +(defun decode-pngsuite (basename) + (let ((pathname (merge-pathnames (make-pathname :name basename :type "png") + *pngsuite-pathname*))) + (with-open-file (input pathname :element-type '(unsigned-byte 8)) + (decode input)))) + +(defun encode-decode (im) + (ignore-errors (delete-file "tmp.png")) + (png::encode-file im "tmp.png") + (prog1 + (png::decode-file "tmp.png") + (delete-file "tmp.png"))) + +(defun unused-bits (im) + "The number of least significant bits that are always zero." + (let ((x (reduce #'logior (array-displacement im)))) + (loop + for bits from 0 + until (or (= bits (etypecase im + (8-bit-image 8) + (16-bit-image 16))) + (not (zerop (ldb (byte 1 bits) x)))) + finally (return bits)))) + +(define-test make-image + (let ((i8 (make-image 2 4 3)) + (i16 (make-image 2 4 3 16))) + (assert-true (typep i8 '8-bit-image)) + (assert-false (typep i8 '16-bit-image)) + (assert-true (typep i16 '16-bit-image)) + (assert-false (typep i16 '8-bit-image)) + (assert-true (typep i8 'image)) + (assert-true (typep i8 'rgb-image)) + (assert-true (typep i16 'image)) + (assert-true (typep i16 'rgb-image)) + (assert-equal '(2 4 3) (array-dimensions i8)))) + +(define-test decode-8-bit + (let ((im (decode-pngsuite "basn0g08"))) + (assert-true (typep im '8-bit-image)) + (assert-equal 0 (aref im 0 0 0)) + (assert-equal 255 (aref im 7 31 0)) + (assert-equal #x1f (aref im 0 31 0)) + (assert-equal #x1c (aref im 31 0 0)))) + +(define-test decode-16-bit + (let ((im (decode-pngsuite "basn0g16"))) + (assert-true (typep im '16-bit-image)) + (assert-equal 0 (aref im 0 0 0)) + (assert-equal 65535 (aref im 2 28 0)) + (assert-equal #xf700 (aref im 2 27 0)) + (assert-equal #x3e00 (aref im 31 0 0)))) + +(defun print-image (image) + (let ((f (etypecase image + (8-bit-image "~2x ") + (16-bit-image "~4x ")))) + (dotimes (i (image-height image)) + (dotimes (j (image-width image)) + (format t f (aref image i j 0))) + (terpri)))) + +(defun values-used (image) + (let ((values (make-array (typecase image + (8-bit-image 256) + (16-bit-image 65536)) + :element-type 'bit + :initial-element 0))) + (dotimes (i (array-total-size image)) + (setf (aref values (row-major-aref image i)) 1)) + (loop for i from 0 and b across values + when (= b 1) + collect i))) + +(define-test decode-4-bit + (let ((im (decode-pngsuite "basn0g04"))) + (assert-true (typep im '8-bit-image)) + (assert-equal #xEE (aref im 31 31 0)) + (assert-equal #x77 (aref im 31 0 0)) + (assert-equal #x00 (aref im 0 0 0)))) + +(define-test decode-2-bit + (let ((im (decode-pngsuite "basn0g02"))) + (assert-true (typep im '8-bit-image)) + (assert-equal #xAA (aref im 31 31 0)) + (assert-equal #xFF (aref im 31 0 0)) + (assert-equal #x00 (aref im 0 0 0)))) + +(define-test decode-1-bit + (let ((im (decode-pngsuite "basn0g01"))) + (assert-true (typep im '8-bit-image)) + (assert-equal #xFF (aref im 0 0 0)) + (assert-equal #x00 (aref im 31 31 0)))) + +(define-test encode-8-bit + (let* ((a (decode-pngsuite "basn0g08")) + (b (encode-decode a))) + (assert-equalp a b))) + +(define-test encode-16-bit + (let* ((a (decode-pngsuite "basn0g16")) + (b (encode-decode a))) + (assert-equalp a b))) + +(define-test copy-image + (let* ((a (decode-pngsuite "basn0g08")) + (b (copy-image a))) + (assert-equalp a b))) + +(define-test 16-bit-image + (let* ((a (decode-pngsuite "basn0g08")) + (b (16-bit-image a)) + (c (8-bit-image b))) + (assert-equalp a c))) + diff --git a/cram_3rdparty/cl_png/src/wrappers.lisp b/cram_3rdparty/cl_png/src/wrappers.lisp new file mode 100644 index 0000000000..4778ac2fb8 --- /dev/null +++ b/cram_3rdparty/cl_png/src/wrappers.lisp @@ -0,0 +1,7 @@ +(in-package #:png) + +(flag "-I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk/usr/X11/include") +(flag "-I/opt/local/include") +(include "png.h") + +(defwrapper* "get_png_libpng_ver_string" :string () "return PNG_LIBPNG_VER_STRING;") diff --git a/cram_3rdparty/cl_store/package.xml b/cram_3rdparty/cl_store/package.xml index 830c8a0ec7..a02eb82dd5 100644 --- a/cram_3rdparty/cl_store/package.xml +++ b/cram_3rdparty/cl_store/package.xml @@ -15,7 +15,7 @@ https://github.com/cram2/cram_3rdparty/issues https://github.com/cram2/cram_3rdparty https://github.com/skypher/cl-store.git - + catkin diff --git a/cram_3rdparty/cl_store/src/backends.lisp b/cram_3rdparty/cl_store/src/backends.lisp index 5aa102ed73..156de1530e 100644 --- a/cram_3rdparty/cl_store/src/backends.lisp +++ b/cram_3rdparty/cl_store/src/backends.lisp @@ -12,7 +12,7 @@ (error "~S is a required argument" name)) (defclass backend () - ((name :accessor name :initform "Unknown" :initarg :name :type symbol) + ((name :accessor name :initform :|Unknown| :initarg :name :type symbol) (magic-number :accessor magic-number :initarg :magic-number :type integer) (compatible-magic-numbers :accessor compatible-magic-numbers :initarg :compatible-magic-numbers :type list) diff --git a/cram_3rdparty/cl_store/src/circularities.lisp b/cram_3rdparty/cl_store/src/circularities.lisp index bad6385008..0daeb1124c 100644 --- a/cram_3rdparty/cl_store/src/circularities.lisp +++ b/cram_3rdparty/cl_store/src/circularities.lisp @@ -98,6 +98,7 @@ (defvar *stored-values*) (defvar *store-hash-size* 50) +(defvar *restore-hash-size* 50) (defvar *grouped-store-hash*) (defvar *grouped-restore-hash*) @@ -111,21 +112,23 @@ structures to be reused. The keys store-hash and restore-hash are expected to be either nil or hash-tables as produced by the function create-serialize-hash." - `(let ((*grouped-store-hash* (or ,store-hash (create-serialize-hash))) - (*grouped-restore-hash* (or ,restore-hash (create-serialize-hash)))) + `(let ((*grouped-store-hash* (or ,store-hash + (create-serialize-hash :size *store-hash-size*))) + (*grouped-restore-hash* (or ,restore-hash + (create-serialize-hash :size *restore-hash-size*)))) ,@body)) (defun get-store-hash () (when *check-for-circs* (if (boundp '*grouped-store-hash*) (clrhash *grouped-store-hash*) - (create-serialize-hash)))) + (create-serialize-hash :size *store-hash-size*)))) (defun get-restore-hash () (when *check-for-circs* (if (boundp '*grouped-restore-hash*) (clrhash *grouped-restore-hash*) - (create-serialize-hash)))) + (create-serialize-hash :size *restore-hash-size*)))) (defmethod backend-store :around ((backend resolving-backend) (place t) (obj t)) (call-next-method)) @@ -188,7 +191,6 @@ hash-tables as produced by the function create-serialize-hash." (defvar *restore-counter*) (defvar *need-to-fix*) (defvar *restored-values*) -(defvar *restore-hash-size* 50) (defmethod backend-restore ((backend resolving-backend) (place stream)) "Restore an object from PLACE using BACKEND. Does the setup for diff --git a/cram_3rdparty/cl_store/src/doc/cl-store.texi b/cram_3rdparty/cl_store/src/doc/cl-store.texi index fb4988e4fa..5e17be72fd 100644 --- a/cram_3rdparty/cl_store/src/doc/cl-store.texi +++ b/cram_3rdparty/cl_store/src/doc/cl-store.texi @@ -439,7 +439,7 @@ created you can do this. @lisp (defmethod serializable-slots-using-class ((object t) (class clsql-sys::standard-db-class)) - (delete 'clsql-sys::view-database (call-next-method) + (remove 'clsql-sys::view-database (call-next-method) :key 'slot-definition-name)) @end lisp @end deffn diff --git a/cram_3rdparty/cl_store/src/package.lisp b/cram_3rdparty/cl_store/src/package.lisp index be024c8f1e..7ab95cd9e5 100644 --- a/cram_3rdparty/cl_store/src/package.lisp +++ b/cram_3rdparty/cl_store/src/package.lisp @@ -53,6 +53,14 @@ #+ecl (:import-from #:clos #:generic-function-name #:compute-slots + #:slot-definition + #:slot-definition-name + #:slot-definition-allocation + #:slot-definition-initform + #:slot-definition-initargs + #:slot-definition-writers + #:slot-definition-readers + #:slot-definition-type #:class-direct-default-initargs #:class-direct-slots #:class-direct-superclasses diff --git a/cram_3rdparty/cl_store/src/sbcl/custom-xml.lisp b/cram_3rdparty/cl_store/src/sbcl/custom-xml.lisp index cec9537991..939f9cf999 100644 --- a/cram_3rdparty/cl_store/src/sbcl/custom-xml.lisp +++ b/cram_3rdparty/cl_store/src/sbcl/custom-xml.lisp @@ -16,23 +16,23 @@ (defstore-xml (obj single-float stream) (with-tag ("SINGLE-FLOAT" stream) - (princ-and-store "BITS" (sb-kernel::single-float-bits obj) + (princ-and-store "BITS" (sb-kernel:single-float-bits obj) stream))) (defrestore-xml (single-float stream) - (sb-kernel::make-single-float - (restore-first (get-child "BITS" stream)))) + (sb-kernel:make-single-float + (restore-first (get-child "BITS" stream)))) (defstore-xml (obj double-float stream) (with-tag ("DOUBLE-FLOAT" stream) - (princ-and-store "HIGH-BITS" (sb-kernel::double-float-high-bits obj) + (princ-and-store "HIGH-BITS" (sb-kernel:double-float-high-bits obj) stream) - (princ-and-store "LOW-BITS" (sb-kernel::double-float-low-bits obj) + (princ-and-store "LOW-BITS" (sb-kernel:double-float-low-bits obj) stream))) (defrestore-xml (double-float stream) - (sb-kernel::make-double-float (restore-first (get-child "HIGH-BITS" stream)) - (restore-first (get-child "LOW-BITS" stream)))) + (sb-kernel:make-double-float (restore-first (get-child "HIGH-BITS" stream)) + (restore-first (get-child "LOW-BITS" stream)))) -;; EOF \ No newline at end of file +;; EOF diff --git a/cram_boxy/cram_boxy_process_modules/cram-boxy-process-modules.asd b/cram_boxy/cram_boxy_process_modules/cram-boxy-process-modules.asd index 8a8c37a546..4b0b7f8350 100644 --- a/cram_boxy/cram_boxy_process_modules/cram-boxy-process-modules.asd +++ b/cram_boxy/cram_boxy_process_modules/cram-boxy-process-modules.asd @@ -41,6 +41,8 @@ cram-tf cram-robosherlock ; for WITH-REAL-ROBOT + cram-giskard + cram-joint-states cram-nav-pcontroller) :components ((:module "src" diff --git a/cram_boxy/cram_boxy_process_modules/package.xml b/cram_boxy/cram_boxy_process_modules/package.xml index d52a23093b..8e9720fce4 100644 --- a/cram_boxy/cram_boxy_process_modules/package.xml +++ b/cram_boxy/cram_boxy_process_modules/package.xml @@ -18,5 +18,7 @@ cram_boxy_low_level cram_tf cram_robosherlock + cram_giskard + cram_joint_states cram_nav_pcontroller diff --git a/cram_boxy/cram_boxy_process_modules/src/definitions.lisp b/cram_boxy/cram_boxy_process_modules/src/definitions.lisp index 8ae9cd78b3..03a5148013 100644 --- a/cram_boxy/cram_boxy_process_modules/src/definitions.lisp +++ b/cram_boxy/cram_boxy_process_modules/src/definitions.lisp @@ -40,61 +40,3 @@ :action-type-or-position action-type-or-position :left-or-right which-gripper :effort effort))))) - -;;;;;;;;;;;;;;;;;;;; GISKARD ;;;;;;;;;;;;;;;;;;;;;;;; - -(cpm:def-process-module giskard-pm (motion-designator) - (destructuring-bind (command argument-1 &rest rest-args) - (desig:reference motion-designator) - (ecase command - (cram-common-designators:move-tcp - (giskard:call-arm-cartesian-action - :goal-pose-left argument-1 - :goal-pose-right (first rest-args) - :collision-mode (second rest-args) - :collision-object-b (third rest-args) - :collision-object-b-link (fourth rest-args) - :collision-object-a (fifth rest-args) - :move-base (sixth rest-args) - :prefer-base (seventh rest-args) - :align-planes-left (eighth rest-args) - :align-planes-right (ninth rest-args))) - (cram-common-designators:move-joints - (giskard:call-arm-joint-action - :goal-configuration-left argument-1 - :goal-configuration-right (first rest-args) - :align-planes-left (second rest-args) - :align-planes-right (third rest-args))) - (cram-common-designators:move-arm-pull - (giskard:call-environment-manipulation-action - :open-or-close :open - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-arm-push - (giskard:call-environment-manipulation-action - :open-or-close :close - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-head - (when argument-1 - (giskard:call-neck-action - :goal-pose argument-1)) - (when (car rest-args) - (giskard:call-neck-joint-action - :goal-configuration (car rest-args)))) - (cram-common-designators:move-base - (giskard:call-base-action - :goal-pose argument-1)) - (cram-common-designators:move-torso - (giskard:call-torso-action - :goal-joint-state argument-1)) - ;; (cram-common-designators:move-gripper-joint - ;; (giskard:call-gripper-action - ;; :action-type-or-position argument-1 - ;; :arm (first rest-args) - ;; :effort (second rest-args))) - ))) diff --git a/cram_boxy/cram_boxy_process_modules/src/interface.lisp b/cram_boxy/cram_boxy_process_modules/src/interface.lisp index b4f12b6cff..9572d1d5aa 100644 --- a/cram_boxy/cram_boxy_process_modules/src/interface.lisp +++ b/cram_boxy/cram_boxy_process_modules/src/interface.lisp @@ -37,7 +37,7 @@ (desig:desig-prop ?motion-designator (:type :closing-gripper)) (desig:desig-prop ?motion-designator (:type :moving-gripper-joint)))) - (<- (cpm:matching-process-module ?motion-designator giskard-pm) + (<- (cpm:matching-process-module ?motion-designator giskard:giskard-pm) (or (desig:desig-prop ?motion-designator (:type :moving-tcp)) (desig:desig-prop ?motion-designator (:type :moving-arm-joints)) (desig:desig-prop ?motion-designator (:type :pulling)) @@ -48,12 +48,16 @@ (desig:desig-prop ?motion-designator (:type :looking)))) (<- (cpm:available-process-module ?pm) - (member ?pm (grippers-pm giskard-pm)) + (member ?pm (grippers-pm giskard:giskard-pm)) (not (cpm:projection-running ?_)))) (defmacro with-real-robot (&body body) `(cram-process-modules:with-process-modules-running - (rs:robosherlock-perception-pm grippers-pm giskard-pm) + (rs:robosherlock-perception-pm + giskard:giskard-pm + joints:joint-state-pm + grippers-pm + common-desig:wait-pm) (cpl-impl::named-top-level (:name :top-level) ,@body))) diff --git a/cram_common/cram_common_designators/cram-common-designators.asd b/cram_common/cram_common_designators/cram-common-designators.asd index d502881228..b07b7b9a29 100644 --- a/cram_common/cram_common_designators/cram-common-designators.asd +++ b/cram_common/cram_common_designators/cram-common-designators.asd @@ -1,19 +1,19 @@ ;;; Copyright (c) 2012, Lorenz Moesenlechner ;;; All rights reserved. -;;; +;;; ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions are met: -;;; +;;; ;;; * Redistributions of source code must retain the above copyright ;;; notice, this list of conditions and the following disclaimer. ;;; * Redistributions in binary form must reproduce the above copyright ;;; notice, this list of conditions and the following disclaimer in the ;;; documentation and/or other materials provided with the distribution. ;;; * Neither the name of the Intelligent Autonomous Systems Group/ -;;; Technische Universitaet Muenchen nor the names of its contributors -;;; may be used to endorse or promote products derived from this software +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software ;;; without specific prior written permission. -;;; +;;; ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -33,9 +33,13 @@ :depends-on (cram-prolog cram-designators cram-designator-specification + cram-process-modules ; for the WAITING process module cram-tf) :components ((:module "src" :components ((:file "package") - (:file "motions" :depends-on ("package")))))) + (:file "motions" :depends-on ("package")) + ;; wait-pm.lisp defines the process module for waiting, + ;; depends on motions.lisp because of the WAIT command + (:file "wait-pm" :depends-on ("motions")))))) diff --git a/cram_common/cram_common_designators/src/motions.lisp b/cram_common/cram_common_designators/src/motions.lisp index 4af4f28144..3e3035ed60 100644 --- a/cram_common/cram_common_designators/src/motions.lisp +++ b/cram_common/cram_common_designators/src/motions.lisp @@ -31,9 +31,11 @@ (def-fact-group navigation-motions (motion-grounding) - (<- (motion-grounding ?designator (move-base ?pose-stamped)) + (<- (motion-grounding ?designator (move-base ?pose-stamped ?speed)) (property ?designator (:type :going)) - (property ?designator (:pose ?pose-stamped)))) + (property ?designator (:pose ?pose-stamped)) + (once (or (property ?designator (:speed ?speed)) + (equal ?speed nil))))) (def-fact-group torso-motions (motion-grounding) @@ -161,7 +163,8 @@ (<- (motion-grounding ?designator (move-joints ?left-config ?right-config ?collision-mode ?align-planes-left - ?align-planes-right)) + ?align-planes-right + ?collisions)) (property ?designator (:type :moving-arm-joints)) (once (or (property ?designator (:left-joint-states ?left-config)) (equal ?left-config nil))) @@ -172,7 +175,9 @@ (once (or (property ?designator (:align-planes-left ?align-planes-left)) (equal ?align-planes-left nil))) (once (or (property ?designator (:align-planes-right ?align-planes-right)) - (equal ?align-planes-right nil))))) + (equal ?align-planes-right nil))) + (once (or (property ?designator (:avoid-collisions-not-much ?collisions)) + (equal ?collisions nil))))) (def-fact-group world-state-detecting (motion-grounding) @@ -185,6 +190,23 @@ (property ?object-designator (:name ?_))) (property ?object-designator (:name ?_))))) +(def-fact-group sensor-monitoring (motion-grounding) + + (<- (motion-grounding ?designator (monitor-joint-state ?joint-name + ?joint-angle-threshold + ?comparison-function)) + (property ?designator (:type :monitoring-joint-state)) + (property ?designator (:joint-name ?joint-name)) + (property ?designator (:joint-angle-threshold ?joint-angle-threshold)) + (once (or (property ?designator (:function ?comparison-function)) + (equal ?comparison-function nil))))) + + +(def-fact-group waiting-motion (motion-grounding) + + (<- (motion-grounding ?designator (wait ?duration)) + (property ?designator (:type :waiting)) + (property ?designator (:duration ?duration)))) #+wiggling-stuff diff --git a/cram_common/cram_common_designators/src/package.lisp b/cram_common/cram_common_designators/src/package.lisp index 931ba3ebb8..477e90ce5d 100644 --- a/cram_common/cram_common_designators/src/package.lisp +++ b/cram_common/cram_common_designators/src/package.lisp @@ -30,9 +30,12 @@ (in-package :cl-user) (defpackage cram-common-designators + (:nicknames :common-desig) (:use #:common-lisp #:prolog #:desig #:spec) (:export ;; motions #:move-base #:move-torso #:move-head #:detect #:inspect #:move-gripper-joint - #:move-tcp #:move-arm-push #:move-arm-pull #:move-joints #:move-with-constraints - #:world-state-detect)) + #:move-tcp #:move-arm-push #:move-arm-pull #:move-joints + #:world-state-detect #:monitor-joint-state #:wait + ;; wait-pm + #:wait-pm)) diff --git a/cram_common/cram_common_designators/src/wait-pm.lisp b/cram_common/cram_common_designators/src/wait-pm.lisp new file mode 100644 index 0000000000..33c85830f7 --- /dev/null +++ b/cram_common/cram_common_designators/src/wait-pm.lisp @@ -0,0 +1,53 @@ +;;; +;;; Copyright (c) 2022, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :cram-common-designators) + +(cpm:def-process-module wait-pm (motion-designator) + (destructuring-bind (command duration) + (desig:reference motion-designator) + (ecase command + (common-desig:wait + (sleep duration))))) + +;;; Example: +;; (cram-process-modules:with-process-modules-running +;; (common-desig:wait-pm) +;; (cpl:top-level +;; (cpm:pm-execute-matching +;; (desig:a motion (type waiting) (duration 5))))) + + +(def-fact-group wait-matching-pms (cpm:matching-process-module + cpm:available-process-module) + + (<- (cpm:matching-process-module ?motion-designator wait-pm) + (desig:desig-prop ?motion-designator (:type :waiting))) + + (<- (cpm:available-process-module wait-pm))) diff --git a/cram_common/cram_common_failures/src/failure-handling-strategies.lisp b/cram_common/cram_common_failures/src/failure-handling-strategies.lisp index ba8b3ba860..123f775c8e 100644 --- a/cram_common/cram_common_failures/src/failure-handling-strategies.lisp +++ b/cram_common/cram_common_failures/src/failure-handling-strategies.lisp @@ -55,7 +55,7 @@ using the `rethrow-failure' key." (roslisp:ros-warn ,warning-namespace "Retrying.~%") (setf ,iterator-desig next-solution-element) (loop for designator in ,reset-designators - do (desig:reset designator)) + do (setf designator (desig:reset designator))) ,@body (cpl:retry)) (roslisp:ros-warn ,warning-namespace "No samples left.~%")))) @@ -136,7 +136,7 @@ the previous solution (the default is 0.05m)." (roslisp:ros-warn ,warning-namespace "Retrying.~%") (setf ,location-desig next-solution-element) (loop for designator in ,reset-designators - do (desig:reset designator)) + do (setf designator (desig:reset designator))) ,@body (cpl:retry)) (roslisp:ros-warn ,warning-namespace "No samples left.~%")))) diff --git a/cram_common/cram_common_failures/src/manipulation.lisp b/cram_common/cram_common_failures/src/manipulation.lisp index 5f4bcfc3e5..b3b4203299 100644 --- a/cram_common/cram_common_failures/src/manipulation.lisp +++ b/cram_common/cram_common_failures/src/manipulation.lisp @@ -37,6 +37,9 @@ (define-condition manipulation-pose-unreachable (manipulation-low-level-failure) () (:documentation "Thrown when no IK solution can be found.")) +(define-condition environment-manipulation-goal-not-reached (manipulation-low-level-failure) () + (:documentation "Thrown when door / drawer opening / closing goal is not reached.")) + (define-condition gripper-low-level-failure (low-level-failure) ((action :initarg :object :initform nil :reader gripper-failure-action))) diff --git a/cram_common/cram_common_failures/src/package.lisp b/cram_common/cram_common_failures/src/package.lisp index 97384bd223..cc59809dd8 100644 --- a/cram_common/cram_common_failures/src/package.lisp +++ b/cram_common/cram_common_failures/src/package.lisp @@ -67,6 +67,7 @@ #:gripper-goal-not-reached #:manipulation-goal-not-reached #:manipulation-pose-unreachable + #:environment-manipulation-goal-not-reached ;; navigation #:navigation-low-level-failure #:navigation-failure-location diff --git a/cram_common/cram_designator_specification/src/specs.lisp b/cram_common/cram_designator_specification/src/specs.lisp index b5719a2fd9..3b073a1594 100644 --- a/cram_common/cram_designator_specification/src/specs.lisp +++ b/cram_common/cram_designator_specification/src/specs.lisp @@ -77,21 +77,43 @@ (<- (%property ?designator (?number-key ?value)) (lisp-pred typep ?designator desig:motion-designator) - (member ?number-key (:effort :joint-angle)) + (member ?number-key (:effort + :joint-angle :joint-angle-threshold :speed + :duration)) (property-member (?number-key ?value) ?designator) (assert-type ?value (or keyword number) "MOTION SPEC:PROPERTY")) + (<- (%property ?designator (?key ?value)) + (lisp-pred typep ?designator desig:motion-designator) + (member ?key (:function)) + (property-member (?key ?value) ?designator) + (assert-type ?value function "MOTION SPEC:PROPERTY")) + (<- (%property ?designator (?keyword-key ?value)) (lisp-pred typep ?designator desig:motion-designator) (member ?keyword-key (:gripper :direction :arm)) (property-member (?keyword-key ?value) ?designator) (assert-type ?value (or keyword list) "MOTION SPEC:PROPERTY")) + (<- (%property ?designator (?string-key ?value)) + (lisp-pred typep ?designator desig:motion-designator) + (member ?string-key (:joint-name)) + (property-member (?string-key ?value) ?designator) + (assert-type ?value string "MOTION SPEC:PROPERTY")) + (<- (%property ?designator (?list-key ?value)) (lisp-pred typep ?designator desig:motion-designator) (member ?list-key (:poses :joint-states :left-joint-states :right-joint-states)) (property-member (?list-key ?value) ?designator) - (assert-type ?value list "MOTION SPEC:PROPERTY"))) + (assert-type ?value list "MOTION SPEC:PROPERTY")) + + (<- (%property ?designator (?key ?value)) + (lisp-pred typep ?designator desig:motion-designator) + (member ?key (:avoid-collisions-not-much + :align-planes-left + :align-planes-right)) + (property-member (?key ?value) ?designator) + (assert-type ?value boolean "MOTION SPEC:PROPERTY"))) (def-fact-group action-designator-specs (%property) @@ -110,9 +132,11 @@ (<- (%property ?designator (?keyword-or-list-key ?value)) (lisp-pred typep ?designator desig:action-designator) - (member ?keyword-or-list-key (:gripper :arm :direction :grasp :camera :type + (member ?keyword-or-list-key (:gripper + :arm :direction :grasp :camera :type :context :link :configuration - :left-configuration :right-configuration)) + :left-configuration :right-configuration + :collision-mode)) (property-member (?keyword-or-list-key ?value) ?designator) (assert-type ?value (or keyword list) "ACTION SPEC:PROPERTY")) @@ -125,25 +149,38 @@ (<- (%property ?designator (?number-key ?value)) (lisp-pred typep ?designator desig:action-designator) - (member ?number-key (:position :effort :distance)) + (member ?number-key (:position :effort :distance :duration)) (property-member (?number-key ?value) ?designator) (assert-type ?value number "ACTION SPEC:PROPERTY")) + (<- (%property ?designator (?key ?value)) + (lisp-pred typep ?designator desig:action-designator) + (member ?key (:joint-angle-threshold)) + (property-member (?key ?value) ?designator) + (assert-type ?value (or number null) "ACTION SPEC:PROPERTY")) + (<- (%property ?designator (?string-key ?value)) (lisp-pred typep ?designator desig:action-designator) - (member ?string-key (:frame)) + (member ?string-key (:frame :joint-name)) (property-member (?string-key ?value) ?designator) (assert-type ?value string "ACTION SPEC:PROPERTY")) - (<- (%property ?designator (:joint-angle ?value)) + (<- (%property ?designator (?key ?value)) (lisp-pred typep ?designator desig:action-designator) - (property-member (:joint-angle ?value) ?designator) + (member ?key (:joint-angle :speed)) + (property-member (?key ?value) ?designator) (assert-type ?value (or keyword number) "ACTION SPEC:PROPERTY")) (<- (%property ?designator (:for ?for-value)) (lisp-pred typep ?designator desig:action-designator) (property-member (:for ?for-value) ?designator) - (assert-type ?for-value (or keyword desig:object-designator) "ACTION SPEC:PROPERTY"))) + (assert-type ?for-value (or keyword desig:object-designator) "ACTION SPEC:PROPERTY")) + + (<- (%property ?designator (?key ?value)) + (lisp-pred typep ?designator desig:action-designator) + (member ?key (:function)) + (property-member (?key ?value) ?designator) + (assert-type ?value (or function null) "ACTION SPEC:PROPERTY"))) (def-fact-group location-designator-specs (%property) @@ -164,10 +201,17 @@ (member ?object-desig-key (:object :in :on :above :left-of :right-of :in-front-of :behind - :far-from :near)) + :far-from :near + :of)) (property-member (?object-desig-key ?value) ?designator) (assert-type ?value desig:object-designator "LOCATION SPEC:PROPERTY")) + (<- (%property ?designator (?location-desig-key ?value)) + (lisp-pred typep ?designator desig:location-designator) + (member ?location-desig-key (:location)) + (property-member (?location-desig-key ?value) ?designator) + (assert-type ?value desig:location-designator "LOCATION SPEC:PROPERTY")) + (<- (%property ?designator (?keyword-key ?value)) (lisp-pred typep ?designator desig:location-designator) (member ?keyword-key (:arm :attachment)) @@ -190,10 +234,16 @@ (<- (%property ?designator (?keyword-key ?name)) (lisp-pred typep ?designator desig:object-designator) - (member ?keyword-key (:name :urdf-name)) + (member ?keyword-key (:name)) (property-member (?keyword-key ?name) ?designator) (assert-type ?name symbol "OBJECT SPEC:PROPERTY")) + (<- (%property ?designator (?keyword-key ?name)) + (lisp-pred typep ?designator desig:object-designator) + (member ?keyword-key (:urdf-name)) + (property-member (?keyword-key ?name) ?designator) + (assert-type ?name (or symbol string) "OBJECT SPEC:PROPERTY")) + (<- (%property ?designator (:part-of ?environment-or-robot)) (lisp-pred typep ?designator desig:object-designator) (property-member (:part-of ?environment-or-robot) ?designator) diff --git a/cram_common/cram_location_costmap/src/designator-integration.lisp b/cram_common/cram_location_costmap/src/designator-integration.lisp index 28b9d6e6bc..8a436fa809 100644 --- a/cram_common/cram_location_costmap/src/designator-integration.lisp +++ b/cram_common/cram_location_costmap/src/designator-integration.lisp @@ -38,6 +38,9 @@ (defun reset-costmap-cache () (setf *costmap-cache* (tg:make-weak-hash-table :test 'eq :weakness :key))) +(defmethod reset :after ((desig location-designator)) + (remhash (first-desig desig) *costmap-cache*)) + (defun get-cached-costmap (desig) (let ((first-designator (first-desig desig))) (or (gethash first-designator *costmap-cache*) diff --git a/cram_common/cram_location_costmap/src/facts.lisp b/cram_common/cram_location_costmap/src/facts.lisp index c2656506c3..40be5b524a 100644 --- a/cram_common/cram_location_costmap/src/facts.lisp +++ b/cram_common/cram_location_costmap/src/facts.lisp @@ -180,6 +180,7 @@ The order is random, so the main direction is NOT prioritized." orientation-samples orientation-sample-step reachability-orientation-offset + visibility-orientation-offset costmap-padding costmap-manipulation-padding costmap-in-reach-distance @@ -211,11 +212,16 @@ The order is random, so the main direction is NOT prioritized." (<- (orientation-sample-step ?robot-name ?step-in-radian) (fail)) - ;; when generating ORIENTATION-SAMPLES number of samples, + ;; when generating ORIENTATION-SAMPLES number of samples in reaching, ;; what should be the angle offset from looking directly at target (<- (reachability-orientation-offset ?robot-name ?offset-in-radian) (fail)) + ;; when generating ORIENTATION-SAMPLES number of samples in looking, + ;; what should be the angle offset from looking directly at target + (<- (visibility-orientation-offset ?robot-name ?offset-in-radian) + (fail)) + ;; padding offset from obstacles, depends on the robot base dimension ;; mostly used for visibility (<- (costmap-padding ?robot-name ?padding-in-meters) diff --git a/cram_common/cram_location_costmap/src/location-costmap.lisp b/cram_common/cram_location_costmap/src/location-costmap.lisp index ea706f471a..b2fefed6c2 100644 --- a/cram_common/cram_location_costmap/src/location-costmap.lisp +++ b/cram_common/cram_location_costmap/src/location-costmap.lisp @@ -1,19 +1,19 @@ ;;; Copyright (c) 2010, Lorenz Moesenlechner ;;; All rights reserved. -;;; +;;; ;;; Redistribution and use in source and binary forms, with or without ;;; modification, are permitted provided that the following conditions are met: -;;; +;;; ;;; * Redistributions of source code must retain the above copyright ;;; notice, this list of conditions and the following disclaimer. ;;; * Redistributions in binary form must reproduce the above copyright ;;; notice, this list of conditions and the following disclaimer in the ;;; documentation and/or other materials provided with the distribution. ;;; * Neither the name of the Intelligent Autonomous Systems Group/ -;;; Technische Universitaet Muenchen nor the names of its contributors -;;; may be used to endorse or promote products derived from this software +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software ;;; without specific prior written permission. -;;; +;;; ;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -219,8 +219,8 @@ calls the generator functions and runs normalization." (destructuring-bind (column row) (funcall sampling-function cost-map) (with-slots (origin-x origin-y resolution) map - (let* ((x (+ (* column resolution) origin-x)) - (y (+ (* row resolution) origin-y)) + (let* ((x (+ (* column resolution) origin-x (/ resolution 2.0))) + (y (+ (* row resolution) origin-y (/ resolution 2.0))) (z (generate-height map x y)) (point (cl-transforms:make-3d-vector x y z))) (on-visualize-costmap-sample point) diff --git a/cram_common/cram_location_costmap/src/package.lisp b/cram_common/cram_location_costmap/src/package.lisp index 374e4d187b..8770825199 100644 --- a/cram_common/cram_location_costmap/src/package.lisp +++ b/cram_common/cram_location_costmap/src/package.lisp @@ -77,6 +77,7 @@ #:on-visualize-costmap #:on-visualize-costmap-sample #:get-map-value + #:generate-height #:no-cost-functions-registered #:register-cost-function #:register-height-generator @@ -109,9 +110,10 @@ #:costmap-in-reach-distance #:costmap-reach-minimal-distance #:visibility-costmap-size #:orientation-samples #:orientation-sample-step - #:reachability-orientation-offset + #:reachability-orientation-offset #:visibility-orientation-offset ;; facts #:make-angle-to-point-generator #:make-orientation-generator + #:angle-to-point-direction #:2d-pose-covariance ;; designator-integration #:reset-costmap-cache diff --git a/cram_common/cram_location_costmap/src/visualization.lisp b/cram_common/cram_location_costmap/src/visualization.lisp index 0eaf4ae84c..86ca97c41c 100644 --- a/cram_common/cram_location_costmap/src/visualization.lisp +++ b/cram_common/cram_location_costmap/src/visualization.lisp @@ -33,7 +33,7 @@ (defvar *marker-publisher* nil) (defvar *occupancy-grid-publisher* nil) -(defparameter *z-padding* 1.0) +(defparameter *z-padding* 0.0) (defparameter *last-published-marker-index* nil) (defun location-costmap-vis-init () @@ -87,11 +87,25 @@ respectively." (vector h s v))) (t (vector 0 0 c-max))))) +(defun value->rgb (val) + (let ((segment (* val 4))) + (cond ((< segment 1.0) + (vector 0.0 (* val 4) 1.0)) + ((< segment 2.0) + (vector 0.0 1.0 (- 1.0 (* (- val 0.25) 4)))) + ((< segment 3.0) + (vector (* (- val 0.5) 4) 1.0 0.0)) + ((< segment 4.0) + (vector 1.0 (- 1.0 (* (- val 0.75) 4)) 0.0)) + (t (vector 1.0 0.0 0.0))))) + (defun location-costmap->marker-array (map &key (frame-id *fixed-frame*) - (threshold 0.0005) (z *z-padding*) - hsv-colormap + (threshold 0.0005) + (z *z-padding*) + (hsv-colormap nil) (intensity-colormap nil) + (rgb-colormap t) (base-color (vector 0 0 1)) (elevate-costmap nil)) (with-slots (origin-x origin-y resolution) map @@ -131,6 +145,8 @@ respectively." (elt mod-hsv 0) (elt mod-hsv 1) (elt mod-hsv 2)))) + (rgb-colormap + (value->rgb curr-val)) (t base-color)))) (push (make-message "visualization_msgs/Marker" (frame_id header) frame-id @@ -190,7 +206,7 @@ respectively." 'visualization_msgs-msg:marker :delete))))) (when removers - (publish *location-costmap-publisher* + (publish *location-costmap-publisher* (make-message "visualization_msgs/MarkerArray" (markers) (map 'vector #'identity removers)))))) @@ -203,7 +219,10 @@ respectively." map :frame-id frame-id :threshold threshold :z z - :hsv-colormap t) + :rgb-colormap t + ;; :hsv-colormap nil + ;; :intensity-colormap nil + ) (when *last-published-marker-index* (remove-markers-up-to-index *last-published-marker-index*)) (setf *last-published-marker-index* last-index) @@ -217,7 +236,7 @@ respectively." (make-message "visualization_msgs/Marker" (stamp header) (ros-time) (frame_id header) *fixed-frame* - ns "kipla_locations" + ns "cram_location_costmap" id (or id (incf current-index)) type (symbol-code 'visualization_msgs-msg: :sphere) @@ -227,13 +246,13 @@ respectively." (y position pose) (cl-transforms:y point) (z position pose) (cl-transforms:z point) (w orientation pose) 1.0 - (x scale) 0.15 - (y scale) 0.15 - (z scale) 0.15 - (r color) 1.0 ; (random 1.0) - (g color) 0.0 ; (random 1.0) - (b color) 0.0 ; (random 1.0) - (a color) 0.9))))) + (x scale) 0.05 + (y scale) 0.05 + (z scale) 0.05 + (r color) 1.0 + (g color) 0.0 + (b color) 0.0 + (a color) 0.7))))) (defun publish-pose (pose &key id) (let ((point (cl-transforms:origin pose)) @@ -247,7 +266,7 @@ respectively." (typecase pose (pose-stamped (frame-id pose)) (t *fixed-frame*)) - ns "kipla_locations" + ns "cram_location_costmap" id (or id (incf current-index)) type (symbol-code 'visualization_msgs-msg: :arrow) diff --git a/cram_common/cram_manipulation_interfaces/cram-manipulation-interfaces.asd b/cram_common/cram_manipulation_interfaces/cram-manipulation-interfaces.asd index 823192a675..e4e4e4540c 100644 --- a/cram_common/cram_manipulation_interfaces/cram-manipulation-interfaces.asd +++ b/cram_common/cram_manipulation_interfaces/cram-manipulation-interfaces.asd @@ -66,7 +66,9 @@ (:file "trajectories" :depends-on ("package" "prolog" "manipulation-interfaces" - "object-hierarchy")) + "object-hierarchy" + ;; for get-object-transform + "object-designator-interfaces")) (:file "standard-grasps" :depends-on ("package")) (:file "standard-rotations" :depends-on ("package")) diff --git a/cram_common/cram_manipulation_interfaces/src/package.lisp b/cram_common/cram_manipulation_interfaces/src/package.lisp index 7df64a39d5..f54d6b19c5 100644 --- a/cram_common/cram_manipulation_interfaces/src/package.lisp +++ b/cram_common/cram_manipulation_interfaces/src/package.lisp @@ -42,10 +42,11 @@ #:get-object-old-pose ;; prolog #:object-type-subtype #:object-type-direct-subtype - #:robot-free-hand #:joint-state-for-arm-config + #:robot-free-hand #:robot-arm-is-also-a-neck #:joint-state-for-arm-config #:object-rotationally-symmetric #:orientation-matters #:unidirectional-attachment + #:object-tf-prefix #:location-always-reachable #:object-is-a-robot #:object-is-a-container @@ -93,13 +94,20 @@ #:get-object-placement-transform #:def-object-type-in-other-object-transform #:get-object-look-from-pose + ;; + #:get-source-object-in-target-object-transform + #:get-tilt-angle-for-pouring + #:get-wait-duration-for-pouring ;; standard-grasps #:*x-across-z-grasp-rotation* #:*x-across-z-grasp-rotation-2* #:*-x-across-z-grasp-rotation* #:*-x-across-z-grasp-rotation-2* #:*x-across-y-grasp-rotation* + #:*x-across-y-30-deg-grasp-rotation* + #:*x-across-y-24-deg-grasp-rotation* #:*-x-across-y-grasp-rotation* + #:*-x-across-y-flipped-grasp-rotation* #:*y-across-z-grasp-rotation* #:*-y-across-z-grasp-rotation* #:*y-across-z-flipped-grasp-rotation* @@ -113,12 +121,16 @@ ;; standard-rotations #:*rotation-around-z-90-matrix* #:*rotation-around-z+90-matrix* + #:*rotation-around-z+180-matrix* #:*rotation-around-x+90-matrix* - #:*rotation-around-z-180-and-x+90-matrix* + #:*rotation-around-z-90-then-x+90-matrix* #:*identity-matrix* + #:*rotation-around-x-180-matrix* + #:*rotation-around-y-180-matrix* #:*rotation-around-x+90-list* #:*rotation-around-x-90-list* #:*rotation-around-y+90-list* #:*rotation-around-y-90-list* #:*rotation-around-z+90-list* - #:*rotation-around-z-90-list*)) + #:*rotation-around-z-90-list* + #:*rotation-around-z+180-list*)) diff --git a/cram_common/cram_manipulation_interfaces/src/prolog.lisp b/cram_common/cram_manipulation_interfaces/src/prolog.lisp index 172a22985f..a6b0edbf50 100644 --- a/cram_common/cram_manipulation_interfaces/src/prolog.lisp +++ b/cram_common/cram_manipulation_interfaces/src/prolog.lisp @@ -74,6 +74,14 @@ (fail))) +(def-fact-group environment-knowledge (object-tf-prefix) + + ;; If the object is a URDF and has a TF prefix, its link poses will + ;; need to have the prefix added to do a TF lookup + (<- (object-tf-prefix ?object-name ?prefix) + (fail))) + + (def-fact-group manipulation-knowledge () ;; most symbolic locations have a reference object ;; this predicate finds the reference object of the given location desig @@ -98,6 +106,11 @@ (rob-int:arm ?robot ?arm) (not (cpoe:object-in-hand ?_ ?arm))) + ;; says if the robot's given arm is also the robot's neck + (<- (robot-arm-is-also-a-neck ?robot ?arm) + (rob-int:arm ?robot ?arm) + (rob-int:neck ?robot ?arm)) + ;; says if the object or an object to which this object is attached, are in hand (<- (object-or-its-reference-in-hand ?some-object-designator ?object-hand) (desig:current-designator ?some-object-designator ?object-designator) @@ -169,8 +182,9 @@ (desig:current-designator ?location-designator ?current-location-designator) (spec:property ?current-location-designator (:of ?object-designator)) (desig:current-designator ?object-designator ?current-object-designator) - (spec:property ?current-object-designator (:location ?object-location)) - (man-int:location-always-reachable ?object-location)) + (once (or (and (spec:property ?current-object-designator (:location ?object-location)) + (man-int:location-always-reachable ?object-location)) + (object-is-a-robot ?current-object-designator)))) (<- (location-certain ?some-location-designator) (desig:loc-desig? ?some-location-designator) @@ -227,7 +241,8 @@ ;; (attachment object-to-other-object)) (<- (desig:location-grounding ?location-designator ?pose-stamped) (desig:current-designator ?location-designator ?current-loc-desig) - (desig:desig-prop ?current-loc-desig (:for ?object-designator)) + (desig:desig-prop ?current-loc-desig (:for ?some-object-designator)) + (desig:current-designator ?some-object-designator ?object-designator) (once (or (desig:desig-prop ?current-loc-desig (:on ?other-object-designator)) (desig:desig-prop ?current-loc-desig (:in ?other-object-designator)) @@ -242,20 +257,38 @@ (spec:property ?current-other-obj-desig (:type ?other-object-type)) ;; (-> (spec:property ?current-other-obj-desig (:urdf-name ?other-object-name)) - (and (lisp-fun roslisp-utilities:rosify-underscores-lisp-name + (and (spec:property ?current-other-obj-desig (:part-of ?part-of-name)) + (once (or (object-tf-prefix ?part-of-name ?tf-prefix) + (equal ?tf-prefix ""))) + (lisp-fun roslisp-utilities:rosify-underscores-lisp-name ?other-object-name ?link-name) + (string-concat ?tf-prefix ?link-name ?prefixed-link-name) (symbol-value cram-tf:*fixed-frame* ?parent-frame) - (lisp-fun cram-tf:frame-to-transform-in-fixed-frame - ?link-name ?parent-frame - ?other-object-transform)) + (once (or (and (lisp-fun cram-tf:frame-to-transform-in-frame + ?prefixed-link-name ?parent-frame + :no-error T + ?other-object-transform) + (lisp-pred identity ?other-object-transform)) + (and (lisp-fun cram-tf:frame-to-transform-in-frame + ?link-name ?parent-frame + :no-error T + ?other-object-transform) + (lisp-pred identity ?other-object-transform))))) (and (spec:property ?current-other-obj-desig (:name ?other-object-name)) (-> (cpoe:object-in-hand ?current-other-obj-desig ?hand ?grasp ?link) (and (rob-int:robot ?robot) (-> (rob-int:end-effector-link ?robot ?arm ?link) (and (rob-int:robot-tool-frame ?robot ?arm ?tool-frame) (symbol-value cram-tf:*fixed-frame* ?parent-frame) - (lisp-fun cram-tf:frame-to-transform-in-fixed-frame - ?tool-frame ?parent-frame + (lisp-fun cram-tf:frame-to-transform-in-frame + ?link ?parent-frame + ?map-t-ee) + (rob-int:tcp-in-ee-pose ?robot ?ee-p-tcp-not-stamped) + (lisp-fun cram-tf:pose->transform-stamped + ?link ?tool-frame 0.0 ?ee-p-tcp-not-stamped + ?ee-t-tcp) + (lisp-fun cram-tf:apply-transform + ?map-t-ee ?ee-t-tcp ?map-t-gripper) (lisp-fun get-object-type-to-gripper-transform ?other-object-type ?other-object-name diff --git a/cram_common/cram_manipulation_interfaces/src/standard-grasps.lisp b/cram_common/cram_manipulation_interfaces/src/standard-grasps.lisp index 12064df871..4a94456b71 100644 --- a/cram_common/cram_manipulation_interfaces/src/standard-grasps.lisp +++ b/cram_common/cram_manipulation_interfaces/src/standard-grasps.lisp @@ -30,7 +30,11 @@ (in-package :cram-manipulation-interfaces) (defparameter *sin-pi/4* (sin (/ pi 4))) -(defparameter *-sin-pi/4* (- (sin (/ pi 4)))) +(defparameter *-sin-pi/4* (- *sin-pi/4*)) +(defparameter *sin-pi/6* 0.5) +(defparameter *-sin-pi/6* -0.5) +(defparameter *sin-pi/3* (sin (/ pi 3))) +(defparameter *-sin-pi/3* (- *sin-pi/3*)) ;; back / front (defparameter *x-across-z-grasp-rotation* @@ -53,14 +57,22 @@ '(( 0 0 -1) ( 0 -1 0) (-1 0 0))) +(defparameter *x-across-y-30-deg-grasp-rotation* + `((,*sin-pi/6* 0 ,*-sin-pi/3*) + (0 -1 0) + (,*-sin-pi/3* 0 ,*-sin-pi/6*))) +(defparameter *x-across-y-24-deg-grasp-rotation* + `((,(sin (/ pi 7.5)) 0 ,(- (sin (/ pi 2.73)))) + (0 -1 0) + (,(- (sin (/ pi 2.73))) 0 ,(- (sin (/ pi 7.5)))))) (defparameter *-x-across-y-grasp-rotation* '(( 0 0 1) ( 0 1 0) (-1 0 0))) -(defparameter *-x-across-y-grasp-rotation* - '(( 0 0 1) - ( 0 1 0) - (-1 0 0))) +(defparameter *-x-across-y-flipped-grasp-rotation* + '((0 0 1) + (0 -1 0) + (1 0 0))) ;; side (defparameter *y-across-z-grasp-rotation* diff --git a/cram_common/cram_manipulation_interfaces/src/standard-rotations.lisp b/cram_common/cram_manipulation_interfaces/src/standard-rotations.lisp index 2017581a68..4dde49ef96 100644 --- a/cram_common/cram_manipulation_interfaces/src/standard-rotations.lisp +++ b/cram_common/cram_manipulation_interfaces/src/standard-rotations.lisp @@ -39,10 +39,15 @@ (1 0 0) (0 0 1))) -(defparameter *rotation-around-z-180-and-x+90-matrix* - '((0 0 1) - (1 0 0) - (0 1 0))) +(defparameter *rotation-around-z+180-matrix* + '((-1 0 0) + ( 0 -1 0) + ( 0 0 1))) + +(defparameter *rotation-around-z-90-then-x+90-matrix* + '(( 0 0 -1) + (-1 0 0) + ( 0 1 0))) (defparameter *rotation-around-x+90-matrix* '((1 0 0) @@ -54,6 +59,16 @@ (0 1 0) (0 0 1))) +(defparameter *rotation-around-x-180-matrix* + '((1 0 0) + (0 -1 0) + (0 0 -1))) + +(defparameter *rotation-around-y-180-matrix* + '((-1 0 0) + ( 0 1 0) + ( 0 0 -1))) + (defparameter *rotation-around-x+90-list* '(0.7071067811865475d0 0.0d0 0.0d0 0.7071067811865476d0)) @@ -67,3 +82,5 @@ '(0.0d0 0.0d0 0.7071067811865475d0 0.7071067811865476d0)) (defparameter *rotation-around-z-90-list* '(0.0d0 0.0d0 -0.7071067811865475d0 0.7071067811865476d0)) +(defparameter *rotation-around-z+180-list* + '(0.0d0 0.0d0 1.0d0 0.0d0)) diff --git a/cram_common/cram_manipulation_interfaces/src/trajectories.lisp b/cram_common/cram_manipulation_interfaces/src/trajectories.lisp index 8f8e5eac84..e8e4fd245f 100644 --- a/cram_common/cram_manipulation_interfaces/src/trajectories.lisp +++ b/cram_common/cram_manipulation_interfaces/src/trajectories.lisp @@ -534,3 +534,121 @@ correct parent frame: ~a and ~a" (cl-transforms-stamped:copy-pose-stamped gripper-initial-pose :origin (cl-transforms:make-3d-vector offset-object-x object-y-in-base offset-object-z)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;; POUR ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defgeneric get-source-object-in-target-object-transform (source-object-type + source-object-name + target-object-type + target-object-name + side grasp) + (:documentation "Returns to-T-so for pouring from given `source-object-type' +into `target-object-type', where the source object is still upright.") + (:method (source-object-type source-object-name + target-object-type target-object-name + side grasp) + "Per default we return identity, which makes no sense but gives a hint." + (cl-transforms-stamped:make-transform-stamped + (roslisp-utilities:rosify-underscores-lisp-name target-object-name) + (roslisp-utilities:rosify-underscores-lisp-name source-object-name) + 0.0 + (cl-transforms:make-identity-vector) + (cl-transforms:make-identity-rotation)) + #+for-overloaded-methods-use-translate-pose-and-rotate-pose + (translate-pose grasp-pose + :x-offset (case grasp + (:front (- *pour-xy-offset*)) + (:side 0.0) + (error "can only pour from :side or :front")) + :y-offset (case grasp + (:front 0.0) + (:side (case arm + (:left *pour-xy-offset*) + (:right (- *pour-xy-offset*)) + (t (error "arm can only be :left or :right")))) + (error "can only pour from :side or :front")) + :z-offset (+ *bottle-grasp-z-offset* + *pour-z-offset*)))) + +(defgeneric get-tilt-angle-for-pouring (source-object-type target-object-type) + (:documentation "Returns a vertical tilting angle in radians +for pouring from given `source-object-type' into `target-object-type'.") + (:method (source-object-type target-object-type) + "Per default, the robot completely flips the source-object around when tilting, +such that a 180 degree tilting angle is used per default." + pi)) + +(defgeneric get-wait-duration-for-pouring (source-object-type + target-object-type + tilt-angle) + (:documentation "Returns a wait duration in seconds +for pouring from given `source-object-type' into `target-object-type' +with the given `tilt-angle'.") + (:method (source-object-type target-object-type tilt-angle) + "Per default, the robot completely flips the source-object around when tilting, +so we assume that all the source contents drops into the target right away." + 0)) + +(defmethod get-action-trajectory :heuristics 20 ((action-type (eql :pouring)) + arm + grasp + location + objects-acted-on + &key tilt-angle side) + (let* ((source-object + (first objects-acted-on)) + (source-object-name + (desig:desig-prop-value source-object :name)) + (source-object-type + (desig:desig-prop-value source-object :type)) + (target-object + (second objects-acted-on)) + (target-object-name + (desig:desig-prop-value target-object :name)) + (target-object-type + (desig:desig-prop-value target-object :type)) + (b-T-to + (get-object-transform target-object)) + (to-T-so + (get-source-object-in-target-object-transform + source-object-type source-object-name + target-object-type target-object-name + side grasp)) + (so-T-stdg + (get-object-type-to-gripper-transform + source-object-type source-object-name arm grasp)) + (to-T-stdg + (reduce #'cram-tf:apply-transform + `(,to-T-so ,so-T-stdg) + :from-end T)) + (to-T-so-tilts + (case grasp + (:front (cram-tf:rotate-pose-in-own-frame + to-T-so :y tilt-angle)) + (:side (case arm + (:left (cram-tf:rotate-pose-in-own-frame + to-T-so :x tilt-angle)) + (:right (cram-tf:rotate-pose-in-own-frame + to-T-so :x (- tilt-angle))) + (t (error "arm can only be :left or :right")))) + (t (error "can only pour from :side or :front")))) + (to-T-stdg-tilts + (reduce #'cram-tf:apply-transform + `(,to-T-so-tilts ,so-T-stdg) + :from-end T))) + + (mapcar (lambda (label transforms) + (make-traj-segment + :label label + :poses (mapcar (alexandria:curry #'calculate-gripper-pose-in-map + b-T-to arm) + transforms))) + '(:reaching + :tilting-down + :tilting-up + :retracting) + `(,to-T-stdg + ,to-T-stdg-tilts + ,to-T-stdg + ,to-T-stdg)))) diff --git a/cram_common/cram_mobile_pick_place_plans/cram-mobile-pick-place-plans.asd b/cram_common/cram_mobile_pick_place_plans/cram-mobile-pick-place-plans.asd index cddc0a39e7..558576b98e 100644 --- a/cram_common/cram_mobile_pick_place_plans/cram-mobile-pick-place-plans.asd +++ b/cram_common/cram_mobile_pick_place_plans/cram-mobile-pick-place-plans.asd @@ -43,7 +43,7 @@ cram-designators cram-occasions-events cram-executive - cram-utilities ; for cut:var-value of prolog stuff and equalize-lists + cram-utilities ; for cut:var-value, cut:force-ll, equalize-lists cram-tf cram-plan-occasions-events @@ -58,14 +58,24 @@ ;; actions such as REACHING, LIFTING, GRASPING, GRIPPING, LOOKING-AT, etc. (:file "atomic-action-plans" :depends-on ("package")) - (:file "atomic-action-designators" :depends-on ("package" "atomic-action-plans")) + (:file "atomic-action-designators" :depends-on ("package" + "atomic-action-plans")) ;; PICKING-UP and PLACING actions - (:file "pick-place-plans" :depends-on ("package" "atomic-action-designators")) + (:file "pick-place-plans" :depends-on ("package" + "atomic-action-designators")) (:file "pick-place-designators" :depends-on ("package" "pick-place-plans")) ;; high-level plans such as DRIVE-AND-PICK-UP, PERCEIVE, etc. (:file "high-level-plans" :depends-on ("package" "atomic-action-designators" - "pick-place-designators")))))) + "pick-place-designators")) + + ;; pouring plans + (:file "pour-plans" :depends-on ("package" + "atomic-action-designators" + ;; for parking-arms + "pick-place-designators")) + (:file "pour-designators" :depends-on ("package" + "pour-plans")))))) diff --git a/cram_common/cram_mobile_pick_place_plans/src/atomic-action-designators.lisp b/cram_common/cram_mobile_pick_place_plans/src/atomic-action-designators.lisp index 6261b7570e..dce1698988 100644 --- a/cram_common/cram_mobile_pick_place_plans/src/atomic-action-designators.lisp +++ b/cram_common/cram_mobile_pick_place_plans/src/atomic-action-designators.lisp @@ -34,11 +34,15 @@ (<- (desig:action-grounding ?action-designator (go-to-target ?resolved-action-designator)) (spec:property ?action-designator (:type :going)) (spec:property ?action-designator (:target ?some-location-designator)) + (once (or (spec:property ?action-designator (:speed ?speed)) + (equal ?speed nil))) (desig:current-designator ?some-location-designator ?location-designator) (desig:designator-groundings ?location-designator ?poses) (member ?pose-stamped ?poses) (desig:designator :action ((:type :going) - (:pose ?pose-stamped)) + (:pose ?pose-stamped) + (:speed ?speed) + (:slow-speed :slow)) ?resolved-action-designator)) @@ -62,20 +66,18 @@ (<- (infer-move-base ?action-designator ?move-base) ;; infer if we should move the base at all or not ;; we shouldn't move the base if we're getting something of our own back + ;; or if we're putting something on our own back (-> (and (or (spec:property ?action-designator (:type :reaching)) - (spec:property ?action-designator (:type :grasping))) - (or (and (spec:property ?action-designator + (spec:property ?action-designator (:type :grasping)) + (spec:property ?action-designator (:type :putting))) + (or (spec:property ?action-designator (:location ?location-designator)) + (and (spec:property ?action-designator (:object ?some-object-designator)) (desig:current-designator ?some-object-designator ?object-designator) (spec:property ?object-designator - (:location ?some-location-designator))) - (spec:property ?action-designator - (:location ?some-location-designator))) - (desig:current-designator ?some-location-designator ?location-designator) - (spec:property ?location-designator (:on ?on-object-designator)) - (spec:property ?on-object-designator (:name ?robot-name)) - (rob-int:robot ?robot-name)) + (:location ?location-designator)))) + (man-int:location-always-reachable ?location-designator)) (equal ?move-base nil) (equal ?move-base t))) @@ -99,19 +101,41 @@ (<- (desig:action-grounding ?action-designator (move-arms-in-sequence ?resolved-action-designator)) (or (spec:property ?action-designator (:type :reaching)) - (spec:property ?action-designator (:type :retracting)) (spec:property ?action-designator (:type :lifting))) (spec:property ?action-designator (:type ?action-type)) (once (or (spec:property ?action-designator (:left-poses ?left-poses)) (equal ?left-poses nil))) (once (or (spec:property ?action-designator (:right-poses ?right-poses)) (equal ?right-poses nil))) + (once (or (spec:property ?action-designator (:collision-mode ?collision)) + (equal ?collision :avoid-all))) + (infer-motion-flags ?action-designator + ?_ ?move-base ?align-planes-left ?align-planes-right) + (desig:designator :action ((:type ?action-type) + (:left-poses ?left-poses) + (:right-poses ?right-poses) + (:collision-mode ?collision) + (:move-base ?move-base) + (:align-planes-left ?align-planes-left) + (:align-planes-right ?align-planes-right)) + ?resolved-action-designator)) + + (<- (desig:action-grounding ?action-designator (move-arms-in-sequence + ?resolved-action-designator)) + (or (spec:property ?action-designator (:type :retracting))) + (spec:property ?action-designator (:type ?action-type)) + (once (or (spec:property ?action-designator (:left-poses ?left-poses)) + (equal ?left-poses nil))) + (once (or (spec:property ?action-designator (:right-poses ?right-poses)) + (equal ?right-poses nil))) + (once (or (spec:property ?action-designator (:collision-mode ?collision)) + (equal ?collision :allow-hand))) (infer-motion-flags ?action-designator ?_ ?move-base ?align-planes-left ?align-planes-right) (desig:designator :action ((:type ?action-type) (:left-poses ?left-poses) (:right-poses ?right-poses) - (:collision-mode :avoid-all) + (:collision-mode ?collision) (:move-base ?move-base) (:align-planes-left ?align-planes-left) (:align-planes-right ?align-planes-right)) @@ -136,7 +160,8 @@ (equal ?collision-object-b ?robot) (equal ?object-link ?object-name)) (and (equal ?collision-object-b ?object-name) - (equal ?object-link nil))) + (once (or (spec:property ?action-designator (:link ?object-link)) + (equal ?object-link nil))))) (desig:designator :action ((:type ?action-type) (:left-poses ?left-poses) (:right-poses ?right-poses) @@ -235,36 +260,17 @@ (:align-planes-right ?align-planes-right)) ?resolved-action-designator)) - (<- (desig:action-grounding ?action-designator (park-arms ?resolved-action-desig)) - (spec:property ?action-designator (:type :parking-arms)) - ;; get the arms list from the designator or infer it - (once (or (spec:property ?action-designator (:arms ?arms-list)) - (-> (spec:property ?action-designator (:not-neck T)) - (and (rob-int:robot ?robot-name) - (rob-int:arms-that-are-not-neck ?robot-name ?arms-list)) - (and (rob-int:robot ?robot-name) - (rob-int:arms ?robot-name ?arms-list))))) - ;; see if left arm and right arm are present - ;; this is super non-general but has to be like this - ;; because positioning-arm is so non-general - (-> (member :left ?arms-list) - (equal ?left-arm-p T) - (equal ?left-arm-p NIL)) - (-> (member :right ?arms-list) - (equal ?right-arm-p T) - (equal ?right-arm-p NIL)) - (desig:designator :action ((:type :parking-arms) - (:left-arm ?left-arm-p) - (:right-arm ?right-arm-p)) - ?resolved-action-desig)) - - - - (<- (desig:action-grounding ?action-designator (release ?action-designator)) + + (<- (desig:action-grounding ?action-designator (release ?resolved-action-designator)) (spec:property ?action-designator (:type :releasing)) - (spec:property ?action-designator (:gripper ?_)) - (once (or (spec:property ?action-designator (:object ?_)) - (true)))) + (once (or (spec:property ?action-designator (:gripper ?gripper)) + (setof ?arm (rob-int:arm ?robot ?arm) ?gripper))) + (once (or (spec:property ?action-designator (:object ?object)) + (equal ?object NIL))) + (desig:designator :action ((:type :releasing) + (:gripper ?gripper) + (:object ?object)) + ?resolved-action-designator)) (<- (desig:action-grounding ?action-designator (grip ?action-designator)) (spec:property ?action-designator (:type :gripping)) @@ -364,4 +370,28 @@ (<- (desig:action-grounding ?action-designator (detect ?action-designator)) (spec:property ?action-designator (:type :detecting)) - (spec:property ?action-designator (:object ?_)))) + (spec:property ?action-designator (:object ?_))) + + + + (<- (desig:action-grounding ?action-designator (monitor-joint-state + ?resolved-action-designator)) + (spec:property ?action-designator (:type :monitoring-joint-state)) + (spec:property ?action-designator (:gripper ?left-or-right)) + (rob-int:robot ?robot) + (rob-int:gripper-joint ?robot ?left-or-right ?joint-name) + (rob-int:gripper-minimal-position ?robot ?left-or-right ?minimum) + (rob-int:gripper-convergence-delta ?robot ?left-or-right ?delta) + (lisp-fun + ?minimum ?delta ?joint-angle-threshold) + (lisp-fun symbol-function < ?function) + (desig:designator :action ((:type :monitoring-joint-state) + (:joint-name ?joint-name) + (:joint-angle-threshold ?joint-angle-threshold) + (:function ?function)) + ?resolved-action-designator)) + + + + (<- (desig:action-grounding ?action-designator (wait ?action-designator)) + (spec:property ?action-designator (:type :waiting)) + (spec:property ?action-designator (:duration ?_)))) diff --git a/cram_common/cram_mobile_pick_place_plans/src/atomic-action-plans.lisp b/cram_common/cram_mobile_pick_place_plans/src/atomic-action-plans.lisp index 18db943daf..d228b4efd4 100644 --- a/cram_common/cram_mobile_pick_place_plans/src/atomic-action-plans.lisp +++ b/cram_common/cram_mobile_pick_place_plans/src/atomic-action-plans.lisp @@ -31,12 +31,15 @@ (defun go-to-target (&key ((:pose ?pose-stamped)) + ((:speed ?speed)) + ((:slow-speed ?slow-speed)) &allow-other-keys) - (declare (type cl-transforms-stamped:pose-stamped ?pose-stamped)) - "Go to `?pose-stamped', if a failure happens propagate it up, robot-state-changed event." + (declare (type cl-transforms-stamped:pose-stamped ?pose-stamped) + (type (or keyword number null) ?speed ?slow-speed)) + "Go to `?pose-stamped', if a failure happens retry, with a slower speed." (unwind-protect - (cpl:with-retry-counters ((nav-retries 0)) + (cpl:with-retry-counters ((nav-retries 1)) (cpl:with-failure-handling ((common-fail:navigation-low-level-failure (e) (roslisp:ros-warn (pick-and-place go) @@ -44,9 +47,14 @@ e) (cpl:do-retry nav-retries (roslisp:ros-warn (pick-and-place go) "Retrying...") + (setf ?speed ?slow-speed) (cpl:retry)))) (exe:perform - (desig:a motion (type going) (pose ?pose-stamped))))) + (desig:a motion + (type going) + (pose ?pose-stamped) + (desig:when ?speed + (speed ?speed)))))) (cram-occasions-events:on-event (make-instance 'cram-plan-occasions-events:robot-state-changed)))) @@ -65,7 +73,8 @@ e) (cpl:do-retry torso-retries (roslisp:ros-warn (pick-and-place move-torso) "Retrying...") - (cpl:retry)))) + (cpl:retry)) + (return))) (exe:perform (desig:a motion (type moving-torso) (joint-angle ?joint-angle))))) (cram-occasions-events:on-event @@ -234,38 +243,48 @@ With a continuous motion planner one could have fluent arch trajectories etc. ((:right-joint-states ?right-joint-states)) ((:align-planes-left ?align-planes-left)) ((:align-planes-right ?align-planes-right)) + ((:avoid-collisions-not-much ?collisions)) &allow-other-keys) - (declare (type list ?left-joint-states ?right-joint-states)) + (declare (type list ?left-joint-states ?right-joint-states) + (type boolean ?collisions)) "Calls moving-arm-joints motion, while ignoring failures, and robot-state-changed event." (unwind-protect - (cpl:with-failure-handling - ((common-fail:manipulation-low-level-failure (e) - (roslisp:ros-warn (mobile-pp-plans move-arms-into-configuration) - "A low-level manipulation failure happened: ~a~%Ignoring." e) - (return))) + (cpl:with-retry-counters ((retries 1)) + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (mobile-pp-plans move-arms-into-configuration) + "Manipulation failure happened: ~a." + e) + (cpl:do-retry retries + (roslisp:ros-warn (pick-and-place arms-config) "Retrying...") + (setf ?collisions t) + (cpl:retry)) + (return))) - (exe:perform - (desig:a motion - (type moving-arm-joints) - (desig:when ?left-joint-states - (left-joint-states ?left-joint-states)) - (desig:when ?right-joint-states - (right-joint-states ?right-joint-states)) - (desig:when ?align-planes-left - (align-planes-left ?align-planes-left)) - (desig:when ?align-planes-right - (align-planes-right ?align-planes-right)))) - ;; (cpl:seq - ;; (exe:perform - ;; (desig:a motion - ;; (type moving-arm-joints) - ;; (right-joint-states ?right-configuration))) - ;; (exe:perform - ;; (desig:a motion - ;; (type moving-arm-joints) - ;; (left-joint-states ?left-configuration)))) - ) + (exe:perform + (desig:a motion + (type moving-arm-joints) + (desig:when ?left-joint-states + (left-joint-states ?left-joint-states)) + (desig:when ?right-joint-states + (right-joint-states ?right-joint-states)) + (desig:when ?align-planes-left + (align-planes-left ?align-planes-left)) + (desig:when ?align-planes-right + (align-planes-right ?align-planes-right)) + (desig:when ?collisions + (avoid-collisions-not-much ?collisions)))) + ;; (cpl:seq + ;; (exe:perform + ;; (desig:a motion + ;; (type moving-arm-joints) + ;; (right-joint-states ?right-configuration))) + ;; (exe:perform + ;; (desig:a motion + ;; (type moving-arm-joints) + ;; (left-joint-states ?left-configuration)))) + )) (cram-occasions-events:on-event (make-instance 'cram-plan-occasions-events:robot-state-changed)))) @@ -290,11 +309,19 @@ With a continuous motion planner one could have fluent arch trajectories etc. (make-instance 'cram-plan-occasions-events:robot-state-changed)) (roslisp:ros-info (pick-place release) "Retract grasp in knowledge base") (cram-occasions-events:on-event - (make-instance 'cpoe:object-detached-robot - :arm ?left-or-right - :object-name (if ?object-designator - (desig:desig-prop-value ?object-designator :name) - NIL))))) + (if (listp ?left-or-right) + (mapc (lambda (gripper) + (make-instance 'cpoe:object-detached-robot + :arm gripper + :object-name (if ?object-designator + (desig:desig-prop-value ?object-designator :name) + NIL))) + ?left-or-right) + (make-instance 'cpoe:object-detached-robot + :arm ?left-or-right + :object-name (if ?object-designator + (desig:desig-prop-value ?object-designator :name) + NIL)))))) (defun grip (&key ((:gripper ?left-or-right)) @@ -413,9 +440,11 @@ In any case, issue ROBOT-STATE-CHANGED event." (declare (type desig:object-designator ?object-designator)) "Call detecting motion on `?object-designator', retry on failure, issue perceived event, equate resulting designator to the original one." - (let ((retries (if (find :cad-model (desig:properties ?object-designator) :key #'car) - 1 - 4))) + (let ((retries 1 + ;; (if (find :cad-model (desig:properties ?object-designator) :key #'car) + ;; 1 + ;; 4) + )) (cpl:with-retry-counters ((perceive-retries retries)) (cpl:with-failure-handling ((common-fail:perception-low-level-failure (e) @@ -449,20 +478,24 @@ equate resulting designator to the original one." (desig:current-desig resulting-designator)))))) -(defun park-arms (&key - ((:left-arm ?left-arm-p)) - ((:right-arm ?right-arm-p)) - &allow-other-keys) - (declare (type boolean ?left-arm-p ?right-arm-p)) - "Puts the arms into a parking configuration" - (let* ((left-config (when ?left-arm-p :park)) - (right-config (when ?right-arm-p :park)) - (?goal `(cpoe:arms-positioned-at ,left-config ,right-config))) - (exe:perform - (desig:an action - (type positioning-arm) - (desig:when ?left-arm-p - (left-configuration park)) - (desig:when ?right-arm-p - (right-configuration park)) - (goal ?goal))))) +(defun monitor-joint-state (&key + ((:joint-name ?joint-name)) + ((:joint-angle-threshold ?joint-angle-threshold)) + ((:function ?function)) + &allow-other-keys) + (exe:perform + (desig:a motion + (type monitoring-joint-state) + (joint-name ?joint-name) + (joint-angle-threshold ?joint-angle-threshold) + (desig:when ?function + (function ?function))))) + + +(defun wait (&key + ((:duration ?duration)) + &allow-other-keys) + (exe:perform + (desig:a motion + (type waiting) + (duration ?duration)))) diff --git a/cram_common/cram_mobile_pick_place_plans/src/pick-place-designators.lisp b/cram_common/cram_mobile_pick_place_plans/src/pick-place-designators.lisp index 5844b4a3ca..e297a7e86b 100644 --- a/cram_common/cram_mobile_pick_place_plans/src/pick-place-designators.lisp +++ b/cram_common/cram_mobile_pick_place_plans/src/pick-place-designators.lisp @@ -53,6 +53,30 @@ (def-fact-group pick-and-place-plans (desig:action-grounding) + (<- (desig:action-grounding ?action-designator (park-arms ?resolved-action-desig)) + (spec:property ?action-designator (:type :parking-arms)) + ;; get the arms list from the designator or infer it + (once (or (spec:property ?action-designator (:arms ?arms-list)) + (-> (spec:property ?action-designator (:not-neck T)) + (and (rob-int:robot ?robot-name) + (rob-int:arms-that-are-not-neck ?robot-name ?arms-list)) + (and (rob-int:robot ?robot-name) + (rob-int:arms ?robot-name ?arms-list))))) + ;; see if left arm and right arm are present + ;; this is super non-general but has to be like this + ;; because positioning-arm is so non-general + (-> (member :left ?arms-list) + (equal ?left-arm-p T) + (equal ?left-arm-p NIL)) + (-> (member :right ?arms-list) + (equal ?right-arm-p T) + (equal ?right-arm-p NIL)) + (desig:designator :action ((:type :parking-arms) + (:left-arm ?left-arm-p) + (:right-arm ?right-arm-p)) + ?resolved-action-desig)) + + (<- (desig:action-grounding ?action-designator (perceive ?resolved-action-desig)) (spec:property ?action-designator (:type :perceiving)) (spec:property ?action-designator (:object ?object-designator)) @@ -73,9 +97,10 @@ (desig:current-designator ?object-designator ?current-object-desig) (spec:property ?current-object-desig (:type ?object-type)) (spec:property ?current-object-desig (:name ?object-name)) + (rob-int:robot ?robot) (-> (spec:property ?action-designator (:arm ?arm)) (true) - (man-int:robot-free-hand ?_ ?arm)) + (man-int:robot-free-hand ?robot ?arm)) (lisp-fun man-int:get-object-transform ?current-object-desig ?object-transform) ;; infer missing information like ?grasp type, gripping ?maximum-effort, manipulation poses @@ -129,6 +154,14 @@ (once (or (lisp-pred identity ?left-trajectory) (lisp-pred identity ?right-trajectory))) + (-> (lisp-pred identity ?left-grasp-poses) + (equal ?left-grasp-poses (?look-pose . ?_)) + (equal ?right-grasp-poses (?look-pose . ?_))) + + (-> (man-int:robot-arm-is-also-a-neck ?robot ?arm) + (equal ?robot-arm-is-also-a-neck T) + (equal ?robot-arm-is-also-a-neck NIL)) + ;; put together resulting action designator (desig:designator :action ((:type :picking-up) (:object ?current-object-desig) @@ -137,6 +170,8 @@ (:effort ?effort) (:grasp ?grasp) (:location-type ?location-type) + (:look-pose ?look-pose) + (:robot-arm-is-also-a-neck ?robot-arm-is-also-a-neck) (:left-reach-poses ?left-reach-poses) (:right-reach-poses ?right-reach-poses) (:left-grasp-poses ?left-grasp-poses) @@ -173,8 +208,11 @@ ;; take object-pose from action-designator :target otherwise from object-designator pose (-> (spec:property ?action-designator (:target ?location-designator)) (and (desig:current-designator ?location-designator ?current-loc-desig) - ;; if the location designator has ATTACHMENTS property, - ;; split it into a list of locations with ATTACHMENT property + ;; If the location designator has ATTACHMENTS property, + ;; split it into a list of locations with ATTACHMENT property. + ;; Although a location with attachments can be resolved, + ;; we need to know exactly which attachment we're using + ;; to build the correct trajectory. (-> (desig:desig-prop ?current-loc-desig (:attachments ?_)) (and (lisp-fun split-attachments-desig ?current-loc-desig ?list-of-current-loc-desig-split) @@ -249,10 +287,20 @@ (once (or (lisp-pred identity ?left-trajectory) (lisp-pred identity ?right-trajectory))) + (-> (lisp-pred identity ?left-put-poses) + (equal ?left-put-poses (?look-pose . ?_)) + (equal ?right-put-poses (?look-pose . ?_))) + + (rob-int:robot ?robot) + (-> (man-int:robot-arm-is-also-a-neck ?robot ?arm) + (equal ?robot-arm-is-also-a-neck T) + (equal ?robot-arm-is-also-a-neck NIL)) + ;; put together resulting designator (desig:designator :action ((:type :placing) (:object ?current-object-designator) (:target ?current-location-designator) + (:target-object-transform ?target-object-transform) (:other-object ?other-object-designator) (:other-object-is-a-robot ?other-object-is-a-robot) (:arm ?arm) @@ -260,6 +308,8 @@ (:location-type ?location-type) (:gripper-opening ?gripper-opening) (:attachment-type ?placement-location-name) + (:look-pose ?look-pose) + (:robot-arm-is-also-a-neck ?robot-arm-is-also-a-neck) (:left-reach-poses ?left-reach-poses) (:right-reach-poses ?right-reach-poses) (:left-put-poses ?left-put-poses) diff --git a/cram_common/cram_mobile_pick_place_plans/src/pick-place-plans.lisp b/cram_common/cram_mobile_pick_place_plans/src/pick-place-plans.lisp index 96de549169..8c4df98269 100644 --- a/cram_common/cram_mobile_pick_place_plans/src/pick-place-plans.lisp +++ b/cram_common/cram_mobile_pick_place_plans/src/pick-place-plans.lisp @@ -45,6 +45,8 @@ ((:effort ?grip-effort)) ((:grasp ?grasp)) location-type + ((:look-pose ?look-pose)) + robot-arm-is-also-a-neck ((:left-reach-poses ?left-reach-poses)) ((:right-reach-poses ?right-reach-poses)) ((:left-grasp-poses ?left-grasp-poses)) @@ -65,8 +67,21 @@ (cram-tf:visualize-marker (man-int:get-object-pose ?object-designator) :r-g-b-list '(1 1 0) :id 300) + (unless robot-arm-is-also-a-neck + (roslisp:ros-info (pick-place pick-up) "Looking") + (cpl:with-failure-handling + ((common-fail:ptu-low-level-failure (e) + (roslisp:ros-warn (pp-plans pick-up) + "Looking-at had a problem: ~a~%Ignoring." + e) + (return))) + (exe:perform + (desig:an action + (type looking) + (target (desig:a location + (pose ?look-pose))))))) (cpl:par - (roslisp:ros-info (pick-place pick-up) "Opening gripper") + (roslisp:ros-info (pick-place pick-up) "Opening gripper and reaching") (let ((?goal `(cpoe:gripper-joint-at ,?arm ,?gripper-opening))) (exe:perform (desig:an action @@ -74,14 +89,12 @@ (gripper ?arm) (position ?gripper-opening) (goal ?goal)))) - (roslisp:ros-info (pick-place pick-up) "Reaching") (cpl:with-failure-handling ((common-fail:manipulation-low-level-failure (e) (roslisp:ros-warn (pp-plans pick-up) "Manipulation messed up: ~a~%Ignoring." e) - ;; (return) - )) + (return))) (let ((?goal `(cpoe:tool-frames-at ,?left-reach-poses ,?right-reach-poses))) (exe:perform (desig:an action @@ -96,8 +109,7 @@ (roslisp:ros-warn (pp-plans pick-up) "Manipulation messed up: ~a~%Ignoring." e) - (return) - )) + (return))) (let ((?goal `(cpoe:tool-frames-at ,?left-grasp-poses ,?right-grasp-poses))) (exe:perform (desig:an action @@ -117,19 +129,27 @@ (grasp ?grasp) (goal ?goal)))) (roslisp:ros-info (pick-place pick-up) "Lifting") - (cpl:with-failure-handling - ((common-fail:manipulation-low-level-failure (e) - (roslisp:ros-warn (pp-plans pick-up) - "Manipulation messed up: ~a~%Ignoring." - e) - (return))) - (let ((?goal `(cpoe:tool-frames-at ,?left-lift-poses ,?right-lift-poses))) + (cpl:pursue + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (pp-plans pick-up) + "Manipulation messed up: ~a~%Ignoring." + e) + (return))) + (let ((?goal `(cpoe:tool-frames-at ,?left-lift-poses ,?right-lift-poses))) + (exe:perform + (desig:an action + (type lifting) + (left-poses ?left-lift-poses) + (right-poses ?right-lift-poses) + (goal ?goal))))) + (cpl:seq (exe:perform (desig:an action - (type lifting) - (left-poses ?left-lift-poses) - (right-poses ?right-lift-poses) - (goal ?goal))))) + (type monitoring-joint-state) + (gripper ?arm))) + (cpl:fail 'common-fail:gripper-closed-completely + :description "Object slipped"))) (roslisp:ros-info (pick-place place) "Parking") (exe:perform (desig:an action @@ -151,6 +171,8 @@ location-type ((:gripper-opening ?gripper-opening)) ((:attachment-type ?placing-location-name)) + ((:look-pose ?look-pose)) + robot-arm-is-also-a-neck ((:left-reach-poses ?left-reach-poses)) ((:right-reach-poses ?right-reach-poses)) ((:left-put-poses ?left-put-poses)) @@ -170,6 +192,19 @@ (ignore grasp location-type)) "Reach, put, assert assemblage if given, open gripper, retract grasp event, retract arm." + (unless robot-arm-is-also-a-neck + (roslisp:ros-info (pick-place place) "Looking") + (cpl:with-failure-handling + ((common-fail:ptu-low-level-failure (e) + (roslisp:ros-warn (pp-plans place) + "Looking-at had a problem: ~a~%Ignoring." + e) + (return))) + (exe:perform + (desig:an action + (type looking) + (target (desig:a location + (pose ?look-pose))))))) (roslisp:ros-info (pick-place place) "Reaching") (cpl:with-failure-handling ((common-fail:manipulation-low-level-failure (e) @@ -192,7 +227,8 @@ (roslisp:ros-warn (pp-plans pick-up) "Manipulation messed up: ~a~%Ignoring." e) - (return))) + ;; (return) + )) (let ((?goal `(cpoe:tool-frames-at ,?left-put-poses ,?right-put-poses))) (exe:perform (desig:an action @@ -258,6 +294,25 @@ (arms (?arm))))) +(defun park-arms (&key + ((:left-arm ?left-arm-p)) + ((:right-arm ?right-arm-p)) + &allow-other-keys) + (declare (type boolean ?left-arm-p ?right-arm-p)) + "Puts the arms into a parking configuration" + (let* ((left-config (when ?left-arm-p :park)) + (right-config (when ?right-arm-p :park)) + (?goal `(cpoe:arms-positioned-at ,left-config ,right-config))) + (exe:perform + (desig:an action + (type positioning-arm) + (desig:when ?left-arm-p + (left-configuration park)) + (desig:when ?right-arm-p + (right-configuration park)) + (goal ?goal))))) + + (defun perceive (&key ((:object ?object-designator)) park-arms diff --git a/cram_common/cram_mobile_pick_place_plans/src/pour-designators.lisp b/cram_common/cram_mobile_pick_place_plans/src/pour-designators.lisp new file mode 100644 index 0000000000..5b822be250 --- /dev/null +++ b/cram_common/cram_mobile_pick_place_plans/src/pour-designators.lisp @@ -0,0 +1,171 @@ +;;; +;;; Copyright (c) 2016, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :pp-plans) + +(def-fact-group pouring-designator (desig:action-grounding) + + (<- (desig:action-grounding ?action-designator (pour ?resolved-designator)) + (spec:property ?action-designator (:type :pouring)) + (spec:property ?action-designator (:target-object ?_)) + (once (or (spec:property ?action-designator (:arm ?_)) + (spec:property ?action-designator (:source-object ?_)))) + (once (or (spec:property ?action-designator (:wait-duration ?_)) + (true))) + (-> (spec:property ?action-designator (:sides ?sides)) + (eqaul ?resolved-designator ?action-designator) + (and (desig:desig-description ?action-designator ?description) + (append ?description ((:sides (:left-side :right-side :front :back))) + ?new-description) + (desig:designator :action ?new-description ?resolved-designator)))) + + + + (<- (desig:action-grounding ?action-designator (pour-without-retries + ?resolved-action-designator)) + (spec:property ?action-designator (:type :pouring-without-retries)) + (spec:property ?action-designator (:side ?side)) + ;; source + (-> (spec:property ?action-designator (:arm ?arm)) + (-> (spec:property ?action-designator (:source-object + ?source-designator)) + (once (or (cpoe:object-in-hand ?source-designator ?arm ?grasp) + (format "WARNING: Wanted to pour from object ~a ~ + with arm ~a, but it's not in the arm.~%" + ?source-designator ?arm))) + (cpoe:object-in-hand ?source-designator ?arm ?grasp)) + (-> (spec:property ?action-designator (:source-object + ?source-designator)) + (once (or (cpoe:object-in-hand ?source-designator ?arm ?grasp) + (format "WARNING: Wanted to pour from object ~a ~ + but it's not in any of the hands.~%" + ?source-designator))) + (cpoe:object-in-hand ?source-designator ?arm ?grasp))) + (desig:current-designator ?source-designator ?current-source-designator) + ;; destination / target + (spec:property ?action-designator (:target-object ?target-designator)) + (desig:current-designator ?target-designator ?current-target-designator) + ;; angle + (-> (spec:property ?action-designator (:tilt-angle ?tilt-angle)) + (true) + (lisp-fun man-int:get-tilt-angle-for-pouring ?source-type ?target-type + ?tilt-angle)) + ;; cartesian pouring trajectory + (equal ?objects-acted-on (?current-source-designator + ?current-target-designator)) + (-> (equal ?arm :left) + (and (lisp-fun man-int:get-action-trajectory :pouring + ?arm ?grasp nil ?objects-acted-on + :tilt-angle ?tilt-angle :side ?side + ?left-trajectory) + (lisp-fun man-int:get-traj-poses-by-label ?left-trajectory :reaching + ?left-reach-poses) + (lisp-fun man-int:get-traj-poses-by-label ?left-trajectory :tilting-down + ?left-tilt-down-poses) + (lisp-fun man-int:get-traj-poses-by-label ?left-trajectory :tilting-up + ?left-tilt-up-poses) + (lisp-fun man-int:get-traj-poses-by-label ?left-trajectory :retracting + ?left-retract-poses)) + (and (equal ?left-reach-poses NIL) + (equal ?left-tilt-down-poses NIL) + (equal ?left-tilt-up-poses NIL) + (equal ?left-retract-poses NIL))) + (-> (equal ?arm :right) + (and (lisp-fun man-int:get-action-trajectory :pouring + ?arm ?grasp nil ?objects-acted-on + :tilt-angle ?tilt-angle :side ?side + ?right-trajectory) + (lisp-fun man-int:get-traj-poses-by-label ?right-trajectory :reaching + ?right-reach-poses) + (lisp-fun man-int:get-traj-poses-by-label ?right-trajectory :tilting-down + ?right-tilt-down-poses) + (lisp-fun man-int:get-traj-poses-by-label ?right-trajectory :tilting-up + ?right-tilt-up-poses) + (lisp-fun man-int:get-traj-poses-by-label ?right-trajectory :retracting + ?right-retract-poses)) + (and (equal ?right-reach-poses NIL) + (equal ?right-tilt-down-poses NIL) + (equal ?right-tilt-up-poses NIL) + (equal ?right-retract-poses NIL))) + (once (or (lisp-pred identity ?left-trajectory) + (lisp-pred identity ?right-trajectory))) + ;; wait duration + (-> (spec:property ?action-designator (:wait-duration ?wait-duration)) + (true) + (lisp-fun man-int:get-wait-duration-for-pouring + ?source-type ?target-type ?tilt-angle + ?wait-duration)) + ;; look pose + (-> (lisp-pred identity ?left-grasp-poses) + (equal ?left-tilt-down-poses (?look-pose . ?_)) + (equal ?right-tilt-down-poses (?look-pose . ?_))) + ;; should look or not? + (rob-int:robot ?robot) + (-> (man-int:robot-arm-is-also-a-neck ?robot ?arm) + (equal ?robot-arm-is-also-a-neck T) + (equal ?robot-arm-is-also-a-neck NIL)) + ;; put together resulting designator + (desig:designator :action ((:type :pouring) + (:source-object ?current-source-designator) + (:arm ?arm) + (:side ?side) + (:grasp ?grasp) + (:target-object ?current-target-designator) + ;; (:other-object-is-a-robot ?other-object-is-a-robot) + (:look-pose ?look-pose) + (:robot-arm-is-also-a-neck ?robot-arm-is-also-a-neck) + (:wait-duration ?wait-duration) + (:left-reach-poses ?left-reach-poses) + (:right-reach-poses ?right-reach-poses) + (:left-tilt-down-poses ?left-tilt-down-poses) + (:right-tilt-down-poses ?right-tilt-down-poses) + (:left-tilt-up-poses ?left-tilt-up-poses) + (:right-tilt-up-poses ?right-tilt-up-poses) + (:left-retract-poses ?left-retract-poses) + (:right-retract-poses ?right-retract-poses)) + ?resolved-action-designator)) + + + (<- (action-grounding ?action-designator (move-arms-in-sequence + ?resolved-action-designator)) + (spec:property ?action-designator (:type :tilting)) + (once (or (spec:property ?action-designator (:left-poses ?left-poses)) + (equal ?left-poses nil))) + (once (or (spec:property ?action-designator (:right-poses ?right-poses)) + (equal ?right-poses nil))) + (once (or (spec:property ?action-designator (:collision-mode ?collision)) + (equal ?collision :avoid-all))) + (desig:designator :action ((:type ?action-type) + (:left-poses ?left-poses) + (:right-poses ?right-poses) + (:collision-mode ?collision) + (:move-base nil) + (:align-planes-left nil) + (:align-planes-right nil)) + ?resolved-action-designator))) diff --git a/cram_common/cram_mobile_pick_place_plans/src/pour-plans.lisp b/cram_common/cram_mobile_pick_place_plans/src/pour-plans.lisp new file mode 100644 index 0000000000..60a9f29f3f --- /dev/null +++ b/cram_common/cram_mobile_pick_place_plans/src/pour-plans.lisp @@ -0,0 +1,206 @@ +;;; +;;; Copyright (c) 2016, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :pp-plans) + +;; (an action +;; (type pouring) +;; (target-object (an object)) +;; (side front) +;; (source-object (an object)) +;; (arm right) +;; (tilt-angle ?pi/2) +;; (vertical-offset 0.02) +;; (wait-duration 5)) + +(defun pour-without-retries (&key + ((:arm ?arm)) + side + grasp + ((:left-reach-poses ?left-reach-poses)) + ((:right-reach-poses ?right-reach-poses)) + ((:left-tilt-down-poses ?left-tilt-down-poses)) + ((:right-tilt-down-poses ?right-tilt-down-poses)) + ((:left-tilt-up-poses ?left-tilt-up-poses)) + ((:right-tilt-up-poses ?right-tilt-up-poses)) + ((:left-retract-poses ?left-retract-poses)) + ((:right-retract-poses ?right-retract-poses)) + ((:target-object ?target-object)) + source-object + ((:wait-duration ?wait-duration)) + ((:look-location ?look-location)) + robot-arm-is-also-a-neck + &allow-other-keys) + (declare (type (or null list) + ?left-reach-poses ?right-reach-poses + ?left-tilt-down-poses ?right-tilt-down-poses + ?left-tilt-up-poses ?right-tilt-up-poses + ?left-retract-poses ?right-retract-poses) + (type desig:object-designator ?target-object source-object) + (type desig:location-designator ?look-location) + (type keyword ?arm side grasp) + (type number ?wait-duration) + (ignore side grasp source-object)) + (roslisp:ros-info (pick-place pour) "Reaching") + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (pp-plans pour) + "Manipulation messed up: ~a~%Failing." + e))) + (cpl:par + (unless robot-arm-is-also-a-neck + (let ( ;; (?goal `(cpoe:looking-at ,?look-location)) + ) + (exe:perform (desig:an action + (type turning-towards) + (target ?look-location) + ;; (goal ?goal) + )))) + (let ((?goal `(cpoe:tool-frames-at ,?left-reach-poses ,?right-reach-poses))) + (exe:perform + (desig:an action + (type reaching) + (object ?target-object) + (left-poses ?left-reach-poses) + (right-poses ?right-reach-poses) + (goal ?goal)))))) + (roslisp:ros-info (pick-place pour) "Tilting down") + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (pp-plans pour) + "Manipulation messed up: ~a~%Failing." + e))) + (let ((?goal `(cpoe:tool-frames-at ,?left-tilt-down-poses + ,?right-tilt-down-poses))) + (exe:perform + (desig:an action + (type tilting) + (left-poses ?left-tilt-down-poses) + (right-poses ?right-tilt-down-poses) + (goal ?goal))))) + (roslisp:ros-info (pick-place pour) "Waiting") + (exe:perform + (desig:an action + (type waiting) + (duration ?wait-duration))) + (roslisp:ros-info (pick-place pour) "Tilting up") + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (pp-plans pour) + "Manipulation messed up: ~a~%Failing." + e))) + (let ((?goal `(cpoe:tool-frames-at ,?left-tilt-up-poses + ,?right-tilt-up-poses))) + (exe:perform + (desig:an action + (type tilting) + (left-poses ?left-tilt-up-poses) + (right-poses ?right-tilt-up-poses) + (goal ?goal))))) + (roslisp:ros-info (pick-place pour) "Retracting") + (cpl:with-failure-handling + ((common-fail:manipulation-low-level-failure (e) + (roslisp:ros-warn (pp-plans pour) + "Manipulation messed up: ~a~%Ignoring." + e) + (return))) + (let ((?goal `(cpoe:tool-frames-at ,?left-retract-poses + ,?right-retract-poses))) + (exe:perform + (desig:an action + (type retracting) + (left-poses ?left-retract-poses) + (right-poses ?right-retract-poses) + (goal ?goal))))) + (roslisp:ros-info (pick-place pour) "Parking") + (exe:perform + (desig:an action + (type parking-arms) + (arms (?arm))))) + + +(defun pour (&key + ((:arm ?arm)) + sides + ((:source-object ?source-object)) + ((:target-object ?target-object)) + ((:wait-duration ?wait-duration)) + &allow-other-keys) + (declare (type desig:object-designator ?source-object ?target-object) + (type keyword ?arm) + (type number ?wait-duration) + (type list sides)) + + (let ((?side (cut:lazy-car sides))) + ;; if pouring fails, try to pour from another side + (cpl:with-retry-counters ((side-retries 3)) + (cpl:with-failure-handling + (((or common-fail:manipulation-low-level-failure + common-fail:object-unreachable + desig:designator-error) (e) + (common-fail:retry-with-list-solutions + sides + side-retries + (:error-object-or-string + (format NIL "Pouring failed: ~a.~%Next" e) + :warning-namespace (mpp-plans pour)) + (setf ?side (cut:lazy-car sides))))) + + (exe:perform + (desig:an action + (type pouring-without-retries) + (side ?side) + (target-object ?target-object) + (desig:when ?arm + (arm ?arm)) + (desig:when ?source-object + (source-object ?source-object)) + (desig:when ?wait-duration + (wait-duration ?wait-duration)))))))) + + + +(defun add (?source-object ?target-object) + (exe:perform + (desig:an action + (type searching) + (object ?source-object))) + (exe:perform + (desig:an action + (type fetching) + (object ?source-object))) + (exe:perform + (desig:an action + (type searching) + (object ?target-object))) + (exe:perform + (desig:an action + (type pouring) + (source-object ?source-object) + (target-object ?target-object)))) diff --git a/cram_common/cram_plan_occasions_events/src/occasion-declarations.lisp b/cram_common/cram_plan_occasions_events/src/occasion-declarations.lisp index 55a9b33d13..09d4c419b7 100644 --- a/cram_common/cram_plan_occasions_events/src/occasion-declarations.lisp +++ b/cram_common/cram_plan_occasions_events/src/occasion-declarations.lisp @@ -30,7 +30,7 @@ (in-package :cram-plan-occasions-events) (def-fact-group occasions (object-in-hand - object-at-location robot-at-location + object-at-location object-placed robot-at-location torso-at gripper-joint-at gripper-opened gripper-closed arms-positioned-at tool-frames-at looking-at @@ -48,6 +48,8 @@ (<- (object-at-location ?object-designator ?location-designator) (fail)) + (<- (object-placed ?object-designator ?location-designator) + (fail)) (<- (robot-at-location ?location-designator) (fail)) diff --git a/cram_common/cram_plan_occasions_events/src/package.lisp b/cram_common/cram_plan_occasions_events/src/package.lisp index 0a5b097e22..08a74c5073 100644 --- a/cram_common/cram_plan_occasions_events/src/package.lisp +++ b/cram_common/cram_plan_occasions_events/src/package.lisp @@ -63,7 +63,7 @@ ;; occasion-declarations ;; Symbols used in plans and thus the execution trace. #:object-in-hand - #:object-at-location #:robot-at-location + #:object-at-location #:object-placed #:robot-at-location #:torso-at #:gripper-joint-at #:gripper-opened #:gripper-closed #:arms-positioned-at #:tool-frames-at diff --git a/cram_common/cram_robot_interfaces/src/arms.lisp b/cram_common/cram_robot_interfaces/src/arms.lisp index 086b120c2f..60a131be27 100644 --- a/cram_common/cram_robot_interfaces/src/arms.lisp +++ b/cram_common/cram_robot_interfaces/src/arms.lisp @@ -36,6 +36,7 @@ hand-links hand-link hand-finger-link gripper-joint end-effector-link robot-tool-frame gripper-meter-to-joint-multiplier + gripper-minimal-position gripper-convergence-delta standard<-particular-gripper-transform tcp-in-ee-pose) @@ -84,6 +85,15 @@ (<- (gripper-meter-to-joint-multiplier ?robot ?multiplier) (fail)) + ;; Sometimes the gripper joint doesn't converge all the way to 0.0 + ;; but rather some other small value such as 0.0015 + (<- (gripper-minimal-position ?robot ?arm ?position) + (fail)) + + ;; The delta at which to say that the gripper converged to the min position + (<- (gripper-convergence-delta ?robot ?arm ?delta) + (fail)) + ;; Standard gripper has the Z pointing towards the object ;; and X is aligned with the hand opening. ;; If the particular robot's gripper is different, diff --git a/cram_common/cram_robot_interfaces/src/neck.lisp b/cram_common/cram_robot_interfaces/src/neck.lisp index ac9f8a1785..c3ad8cd5cf 100644 --- a/cram_common/cram_robot_interfaces/src/neck.lisp +++ b/cram_common/cram_robot_interfaces/src/neck.lisp @@ -31,7 +31,10 @@ (def-fact-group neck (camera-frame camera-minimal-height camera-maximal-height camera-horizontal-angle camera-vertical-angle - neck robot-neck-links robot-neck-joints robot-neck-base-link + neck robot-neck-links robot-neck-joints + robot-neck-pan-joint-forward-facing-axis-sign + robot-neck-tilt-joint-forward-facing-axis-sign + robot-neck-base-link camera-in-neck-ee-pose neck-camera-z-offset neck-camera-pose-unit-vector-multiplier @@ -72,6 +75,16 @@ (<- (robot-neck-joints ?robot ?pan-joint ?tilt-joint) (fail)) + ;; For necks with 2 joints + (<- (robot-neck-pan-joint-forward-facing-axis-sign ?robot + ?axis-function + ?sign) + (fail)) + (<- (robot-neck-tilt-joint-forward-facing-axis-sign ?robot + ?axis-function + ?sign) + (fail)) + ;; For necks with more than 2 joints (<- (robot-neck-links ?robot . ?neck-links) (fail)) diff --git a/cram_common/cram_robot_interfaces/src/package.lisp b/cram_common/cram_robot_interfaces/src/package.lisp index dd67fd962b..1508aaa45b 100644 --- a/cram_common/cram_robot_interfaces/src/package.lisp +++ b/cram_common/cram_robot_interfaces/src/package.lisp @@ -35,7 +35,8 @@ ;; robot #:*robot-description-parameter* #:*robot-urdf* #:set-robot-name #:get-robot-name - #:robot #:robot-base-frame #:robot-odom-frame #:robot-torso-link-joint + #:robot #:robot-odom-frame #:robot-base-frame #:robot-base-link + #:robot-torso-link-joint #:robot-joint-states #:robot-pose #:arms #:arms-that-are-not-neck @@ -45,6 +46,7 @@ #:hand-links #:hand-link #:hand-finger-link #:gripper-joint #:end-effector-link #:robot-tool-frame #:gripper-meter-to-joint-multiplier + #:gripper-minimal-position #:gripper-convergence-delta #:standard<-particular-gripper-transform #:tcp-in-ee-pose ;; designator utils @@ -55,7 +57,10 @@ ;; neck #:camera-frame #:camera-minimal-height #:camera-maximal-height #:camera-horizontal-angle #:camera-vertical-angle - #:neck #:robot-neck-links #:robot-neck-joints #:robot-neck-base-link + #:neck #:robot-neck-links #:robot-neck-joints + #:robot-neck-pan-joint-forward-facing-axis-sign + #:robot-neck-tilt-joint-forward-facing-axis-sign + #:robot-neck-base-link #:camera-in-neck-ee-pose #:neck-camera-z-offset #:neck-camera-pose-unit-vector-multiplier #:neck-camera-resampling-step diff --git a/cram_common/cram_robot_interfaces/src/robot.lisp b/cram_common/cram_robot_interfaces/src/robot.lisp index 8b8057f9b6..c3d6f6ca7e 100644 --- a/cram_common/cram_robot_interfaces/src/robot.lisp +++ b/cram_common/cram_robot_interfaces/src/robot.lisp @@ -47,7 +47,7 @@ so the robot whose brain this is.") ROS parameter server?"))) (def-fact-group robot (robot - robot-base-frame robot-odom-frame + robot-odom-frame robot-base-frame robot-base-link robot-torso-link-joint robot-joint-states robot-pose) (<- (robot ?robot-name) @@ -57,10 +57,14 @@ so the robot whose brain this is.") Have you initialized it from a URDF on the ~ ROS parameter server?")))) + (<- (robot-odom-frame ?robot-name ?odom-frame) + (fail)) + (<- (robot-base-frame ?robot-name ?base-frame) (fail)) - (<- (robot-odom-frame ?robot-name ?odom-frame) + ;; robot-base-frame can be a virtual link, this one should be a physical link + (<- (robot-base-link ?robot-name ?base-link) (fail)) (<- (robot-torso-link-joint ?robot-name ?torso-link ?torso-joint) diff --git a/cram_common/cram_robot_pose_gaussian_costmap/src/current-pose-generator-and-pose-validator.lisp b/cram_common/cram_robot_pose_gaussian_costmap/src/current-pose-generator-and-pose-validator.lisp index 2ffd45f3c6..79184cb721 100644 --- a/cram_common/cram_robot_pose_gaussian_costmap/src/current-pose-generator-and-pose-validator.lisp +++ b/cram_common/cram_robot_pose_gaussian_costmap/src/current-pose-generator-and-pose-validator.lisp @@ -108,7 +108,8 @@ (costmap:costmap-in-reach-distance ?robot-name ?max-distance) (costmap:orientation-samples ?robot-name ?orientation-samples) (costmap:orientation-sample-step ?robot-name ?orientation-sample-step) - (costmap:reachability-orientation-offset ?robot-name ?orientation-offset)))) + (once (or (costmap:reachability-orientation-offset ?robot-name ?orientation-offset) + (equal ?orientation-offset 0.0)))))) (if (or (cut:is-var ?to-reach-pose) (cut:is-var ?min-distance) (cut:is-var ?max-distance)) @@ -136,8 +137,10 @@ (generated-angle (calculate-z-angle pose))) (if (and (< dist ?max-distance) (> dist ?min-distance) - (<= (abs (- (abs (- perfect-angle generated-angle)) - (cl-transforms:normalize-angle ?orientation-offset))) + (<= (abs (- (cl-transforms:normalize-angle + (- generated-angle perfect-angle)) + (cl-transforms:normalize-angle + ?orientation-offset))) allowed-range)) :accept :reject)))) @@ -152,7 +155,8 @@ (if (cram-robot-interfaces:visibility-designator-p designator) (cut:with-vars-bound (?to-see-pose ?max-distance - ?orientation-samples ?orientation-sample-step) + ?orientation-samples ?orientation-sample-step + ?orientation-offset) (cut:lazy-car (prolog:prolog `(and (once @@ -173,7 +177,10 @@ (costmap:visibility-costmap-size ?robot-name ?max-distance) (costmap:orientation-samples ?robot-name ?orientation-samples) (costmap:orientation-sample-step ?robot-name - ?orientation-sample-step)))) + ?orientation-sample-step) + (once (or (costmap:visibility-orientation-offset + ?robot-name ?orientation-offset) + (equal ?orientation-offset 0.0)))))) (if (or (cut:is-var ?to-see-pose) (cut:is-var ?max-distance)) :unknown (let (;; DIST ist the distance from the suggested robot pose to to-see-pose @@ -198,7 +205,11 @@ ;; GENERATED-ANGLE is the suggested robot base pose angle around Z (generated-angle (calculate-z-angle pose))) (if (and (< dist ?max-distance) - (<= (abs (- perfect-angle generated-angle)) allowed-range)) + (<= (abs (- (cl-transforms:normalize-angle + (- generated-angle perfect-angle)) + (cl-transforms:normalize-angle + ?orientation-offset))) + allowed-range)) :accept :reject)))) :unknown)) diff --git a/cram_common/cram_robot_pose_gaussian_costmap/src/prolog.lisp b/cram_common/cram_robot_pose_gaussian_costmap/src/prolog.lisp index fe9c9e8cde..6a1d4bbc49 100644 --- a/cram_common/cram_robot_pose_gaussian_costmap/src/prolog.lisp +++ b/cram_common/cram_robot_pose_gaussian_costmap/src/prolog.lisp @@ -80,9 +80,11 @@ ?cm) (costmap:orientation-samples ?robot-name ?samples) (costmap:orientation-sample-step ?robot-name ?sample-step) + (once (or (costmap:visibility-orientation-offset ?robot-name ?offset) + (equal ?offset 0.0))) (costmap:costmap-add-orientation-generator (costmap:make-angle-to-point-generator - ?mean :samples ?samples :sample-step ?sample-step) + ?mean :samples ?samples :sample-step ?sample-step :sample-offset ?offset) ?cm) (costmap:costmap-add-height-generator (costmap:make-constant-height-function 0.0) @@ -145,6 +147,10 @@ (<- (costmap:desig-costmap ?desig ?cm) (costmap:costmap ?cm) (desig-prop ?desig (:reachable-from ?from-what)) + (not (or (desig-prop ?desig (:pose ?_)) + (desig-prop ?desig (:poses ?_)) + (desig-prop ?desig (:attachments ?_)) + (desig-prop ?desig (:attachment ?_)))) (or (and (lisp-type ?from-what symbol) ;; (cram-robot-interfaces:robot ?from-what) (lisp-fun cram-tf:robot-current-pose ?pose)) @@ -157,7 +163,10 @@ reachable-from-space (costmap:make-range-cost-function ?point ?distance) ?cm) - (costmap:costmap-add-function - reachable-from-weighted - (costmap:make-location-cost-function ?pose ?distance) - ?cm))) + ;; Locations closer to the robot are not necessarily better + ;; than the further ones, so commenting this out. + ;; (costmap:costmap-add-function + ;; reachable-from-weighted + ;; (costmap:make-location-cost-function ?pose ?distance) + ;; ?cm) + )) diff --git a/cram_common/cram_tf/src/package.lisp b/cram_common/cram_tf/src/package.lisp index 60f4d72551..b7e3747f87 100644 --- a/cram_common/cram_tf/src/package.lisp +++ b/cram_common/cram_tf/src/package.lisp @@ -42,7 +42,7 @@ #:start-publishing-transforms #:stop-publishing-transforms ;; utilities #:poses-equal-p - #:frame-to-pose-in-fixed-frame #:frame-to-transform-in-fixed-frame + #:frame-to-pose-in-fixed-frame #:frame-to-transform-in-frame #:3d-vector->list #:list->3d-vector #:pose->flat-list #:pose->flat-list-w-first #:pose->list diff --git a/cram_common/cram_tf/src/utilities.lisp b/cram_common/cram_tf/src/utilities.lisp index 40e4b8e8ac..cbfb0d8c58 100644 --- a/cram_common/cram_tf/src/utilities.lisp +++ b/cram_common/cram_tf/src/utilities.lisp @@ -48,13 +48,18 @@ (make-identity-rotation)) :target-frame (or parent-frame *fixed-frame*)))) -(defun frame-to-transform-in-fixed-frame (frame-name &optional parent-frame) +(defun frame-to-transform-in-frame (frame-name parent-frame &key no-error) (when *transformer* - (cl-transforms-stamped:lookup-transform - *transformer* - parent-frame frame-name - :timeout *tf-default-timeout* - :time 0.0))) + (handler-case + (cl-transforms-stamped:lookup-transform + *transformer* + parent-frame frame-name + :timeout *tf-default-timeout* + :time 0.0) + (cl-transforms-stamped:transform-stamped-error (e) + (if no-error + nil + (error e)))))) (defun 3d-vector->list (3d-vector) (let ((x (cl-transforms:x 3d-vector)) @@ -279,15 +284,17 @@ (defun multiply-transform-stampeds (x-frame z-frame x-y-transform y-z-transform - &key (result-as-pose-or-transform :transform)) + &key result-as-pose-or-transform) (declare (type cl-transforms-stamped:transform-stamped x-y-transform y-z-transform) - (type keyword result-as-pose-or-transform) + (type (or keyword null) result-as-pose-or-transform) (type string x-frame z-frame)) "Returns a pose stamped representing xTz -- transfrom from x-frame to z-frame. Take xTy, ensure it's from x-frame. Multiply from the right with the yTz transform -- xTy * yTz == xTz." + (unless result-as-pose-or-transform + (setf result-as-pose-or-transform :transform)) (when (string-not-equal (cl-transforms-stamped:frame-id x-y-transform) x-frame) @@ -371,12 +378,14 @@ Multiply from the right with the yTz transform -- xTy * yTz == xTz." (cl-transforms-stamped:stamp pose-stamped) (cl-transforms-stamped:origin pose-stamped))) -(defun apply-transform (left-hand-side-transform right-hand-side-transform) +(defun apply-transform (left-hand-side-transform right-hand-side-transform + &key result-as-pose-or-transform) (cram-tf:multiply-transform-stampeds (cl-transforms-stamped:frame-id left-hand-side-transform) (cl-transforms-stamped:child-frame-id right-hand-side-transform) left-hand-side-transform - right-hand-side-transform)) + right-hand-side-transform + :result-as-pose-or-transform result-as-pose-or-transform)) (defun values-converged (values goal-values deltas) @@ -408,12 +417,15 @@ Multiply from the right with the yTz transform -- xTy * yTz == xTz." goal-frame :use-zero-time t)) (goal-dist (max (abs (cl-transforms:x (cl-transforms:origin pose-in-frame))) - (abs (cl-transforms:y (cl-transforms:origin pose-in-frame))))) + (abs (cl-transforms:y (cl-transforms:origin pose-in-frame))) + (abs (cl-transforms:z (cl-transforms:origin pose-in-frame))))) (goal-angle (cl-transforms:normalize-angle (cl-transforms:get-yaw (cl-transforms:orientation pose-in-frame))))) - (and (<= goal-dist delta-xy) - (<= (abs goal-angle) delta-theta)))) + (values (and (<= goal-dist delta-xy) + (<= (abs goal-angle) delta-theta)) + goal-dist + goal-angle))) (defun pose-stampeds-converged (pose other-pose delta-position delta-rotation) (declare (type (or null cl-transforms-stamped:pose-stamped) pose other-pose)) diff --git a/cram_common/cram_tf/src/visualization.lisp b/cram_common/cram_tf/src/visualization.lisp index ce14517fcf..e6932524eb 100644 --- a/cram_common/cram_tf/src/visualization.lisp +++ b/cram_common/cram_tf/src/visualization.lisp @@ -29,8 +29,22 @@ (in-package :cram-tf) +(defvar *marker-publisher* nil) + +(defun init-marker-publisher () + (setf *marker-publisher* + (roslisp:advertise "visualization_marker" + "visualization_msgs/Marker"))) + +(defun destroy-marker-publisher () + (setf *marker-publisher* nil)) + +(roslisp-utilities:register-ros-init-function init-marker-publisher) +(roslisp-utilities:register-ros-cleanup-function destroy-marker-publisher) + (defun visualize-marker (pose/s &key - (topic "visualization_marker") + ;; (topic "visualization_marker") + (namespace "cram_goal_locations") (r-g-b-list '(1 0 0)) (scale-list '(0.1 0.06 0.02)) (marker-type :arrow) @@ -38,7 +52,7 @@ (in-frame cram-tf:*fixed-frame*) mesh-path) (declare (type (or cl-transforms:pose cl-transforms-stamped:pose-stamped list) pose/s) - (type string topic) + ;; (type string topic) (type (or string null) in-frame) (type number id) (type keyword marker-type)) @@ -47,7 +61,7 @@ (let ((point (cl-transforms:origin pose)) (rot (cl-transforms:orientation pose))) (roslisp:publish - (roslisp:advertise topic "visualization_msgs/Marker") + *marker-publisher* (roslisp:make-message "visualization_msgs/Marker" (std_msgs-msg:stamp header) (roslisp:ros-time) (std_msgs-msg:frame_id header) @@ -55,7 +69,7 @@ (cl-transforms-stamped:pose-stamped (cl-transforms-stamped:frame-id pose)) (t (or in-frame cram-tf:*fixed-frame*))) - ns "cram_goal_locations" + ns namespace id id type (roslisp:symbol-code 'visualization_msgs-msg: @@ -76,6 +90,7 @@ (g color) (second r-g-b-list) (b color) (third r-g-b-list) (a color) 0.7 + :frame_locked t :mesh_resource (or mesh-path "")))) ;; (roslisp:ros-warn (ll visualize-marker) "asked to visualize a null pose") ))) diff --git a/cram_core/cram_designators/src/cram-designators/designator-protocol.lisp b/cram_core/cram_designators/src/cram-designators/designator-protocol.lisp index 80784ef1a4..c19610e7d3 100644 --- a/cram_core/cram_designators/src/cram-designators/designator-protocol.lisp +++ b/cram_core/cram_designators/src/cram-designators/designator-protocol.lisp @@ -126,15 +126,16 @@ (:method ((solution-1 array) (solution-2 array)) (equalp solution-1 solution-2))) -(defun reset (desig) - "Resets the designator by deleting all associated solutions. -Used for recalculating a designator when its dependent designator got updated. -The actual implementation creates a copy of the designator, such that only -the description is preserved. The returned designator is equated to the input one, -in case one would want to get back to the old one through the equated designator chain." - (let ((desig-copy (copy-designator desig))) - (equate desig desig-copy) - (setf desig desig-copy))) +(defgeneric reset (desig) + (:documentation "Resets the designator by deleting all associated solutions. + Used for recalculating a designator when its dependent designator got updated. + The actual implementation creates a copy of the designator, such that only + the description is preserved. The returned designator is equated to the input one, + in case one would want to get back to the old one through the equated designator chain.") + (:method (desig) + (let ((desig-copy (copy-designator desig))) + (equate desig desig-copy) + (setf desig desig-copy)))) (defvar *designator-pprint-description* t "If set to T, DESIGNATOR objects will be pretty printed with their description.") diff --git a/cram_core/cram_math/src/functions.lisp b/cram_core/cram_math/src/functions.lisp index 0aff9541be..09e4a5e795 100644 --- a/cram_core/cram_math/src/functions.lisp +++ b/cram_core/cram_math/src/functions.lisp @@ -38,3 +38,7 @@ (double-matrix-product cov-inv x-mean cov-x-prod) e-factor-mat) 0 0))))))) + +(defun average (min max) + (+ min (/ (- max min) 2))) + diff --git a/cram_core/cram_math/src/package.lisp b/cram_core/cram_math/src/package.lisp index aeee5d5875..8796765138 100644 --- a/cram_core/cram_math/src/package.lisp +++ b/cram_core/cram_math/src/package.lisp @@ -45,6 +45,6 @@ #:map-double-matrix-into #:double-matrix-transpose #:double-matrix-product #:m.+ #:m.- #:m.* #:m./ #:m+ #:m- #:m* #:m/ ;; functions - #:determinant #:gauss + #:determinant #:gauss #:average ;; geometry #:2d-point #:polygon #:point-in-polygon #:degrees->radians #:radians->degrees)) diff --git a/cram_core/cram_utilities/src/package.lisp b/cram_core/cram_utilities/src/package.lisp index a1fa081292..438ba39d3e 100644 --- a/cram_core/cram_utilities/src/package.lisp +++ b/cram_core/cram_utilities/src/package.lisp @@ -161,7 +161,7 @@ #:make-synchronized-hash-table #:with-hash-table-locked ;; utils - #:minimum #:maximum #:compare + #:minimum #:maximum #:random-with-minimum #:compare #:execute-string #:replace-all ;; semaphores, reexported from sb-thread ,@+semaphore-symbols+ diff --git a/cram_core/cram_utilities/src/utils.lisp b/cram_core/cram_utilities/src/utils.lisp index 61df5c0136..85ec64fe80 100644 --- a/cram_core/cram_utilities/src/utils.lisp +++ b/cram_core/cram_utilities/src/utils.lisp @@ -106,6 +106,9 @@ (defun maximum (seq &key (test #'>) (key #'identity)) (extremum seq test :key key)) +(defun random-with-minimum (value offset) + (+ (random (- value offset)) offset)) + (defun style-warn (datum &rest arguments) (apply #'sb-int:style-warn datum arguments)) diff --git a/cram_demos/cram_boxy_assembly_demo/launch/sandbox.launch b/cram_demos/cram_boxy_assembly_demo/launch/sandbox.launch index fbc63ce7b7..4b82bc3237 100644 --- a/cram_demos/cram_boxy_assembly_demo/launch/sandbox.launch +++ b/cram_demos/cram_boxy_assembly_demo/launch/sandbox.launch @@ -4,7 +4,7 @@ + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> diff --git a/cram_demos/cram_boxy_assembly_demo/src/projection-demo.lisp b/cram_demos/cram_boxy_assembly_demo/src/projection-demo.lisp index d0711ccdf8..d89fd00720 100644 --- a/cram_demos/cram_boxy_assembly_demo/src/projection-demo.lisp +++ b/cram_demos/cram_boxy_assembly_demo/src/projection-demo.lisp @@ -195,6 +195,7 @@ spawning-data))) (btr:attach-object 'motor-grill 'underbody) + (btr:attach-object 'holder-top-wing 'top-wing :loose T) objects)) @@ -386,7 +387,7 @@ (base-right-side-left-hand-pose `((,base-x 0.7 0) (0 0 0 1))) (base-very-right-side-left-hand-pose - `((,(- base-x 0.2) 0.65 0) (0 0 0 1)))) + `((,(- base-x 0.18) 0.65 0) (0 0 0 1)))) (urdf-proj:with-projected-robot ;; 1 @@ -436,7 +437,7 @@ :window-thread) ;; 10 - (go-connect :top-wing base-somewhat-left-side-left-hand-pose + (go-connect :top-wing base-left-side-left-hand-pose :holder-plane-vertical base-left-side-left-hand-pose ;; or `((,(- *base-x* 0.00) 1.45 0) (0 0 0 1)) :vertical-attachment) diff --git a/cram_demos/cram_donbot_retail_demo/launch/sandbox.launch b/cram_demos/cram_donbot_retail_demo/launch/sandbox.launch index 4e2689c506..487080711c 100644 --- a/cram_demos/cram_donbot_retail_demo/launch/sandbox.launch +++ b/cram_demos/cram_donbot_retail_demo/launch/sandbox.launch @@ -5,14 +5,14 @@ + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> + command="$(find xacro)/xacro '$(find iai_refills_lab)/urdf/dm_room.urdf.xacro'"/> diff --git a/cram_demos/cram_hsrb_pick_demo/launch/sandbox.launch b/cram_demos/cram_hsrb_pick_demo/launch/sandbox.launch index 423d166fea..72c61ca1e3 100644 --- a/cram_demos/cram_hsrb_pick_demo/launch/sandbox.launch +++ b/cram_demos/cram_hsrb_pick_demo/launch/sandbox.launch @@ -8,7 +8,7 @@ + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> @@ -30,7 +30,7 @@ diff --git a/cram_demos/cram_integration_tests/launch/pr2.launch b/cram_demos/cram_integration_tests/launch/pr2.launch index e6bf6e5a39..5e1b7f44cb 100644 --- a/cram_demos/cram_integration_tests/launch/pr2.launch +++ b/cram_demos/cram_integration_tests/launch/pr2.launch @@ -7,9 +7,9 @@ - + + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> @@ -39,7 +39,7 @@ diff --git a/cram_demos/cram_object_knowledge/src/assembly.lisp b/cram_demos/cram_object_knowledge/src/assembly.lisp index 61d71c0f4c..ddb4554df9 100644 --- a/cram_demos/cram_object_knowledge/src/assembly.lisp +++ b/cram_demos/cram_object_knowledge/src/assembly.lisp @@ -49,7 +49,6 @@ (<- (man-int:object-type-direct-subtype :assembly-item :nut))) (def-fact-group attachmend-knowledge (man-int:unidirectional-attachment) - (<- (man-int:unidirectional-attachment ?attachment-type) (member ?attachment-type (:horizontal-attachment :vertical-attachment)))) @@ -65,10 +64,13 @@ (defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :bolt))) 0.02) (defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :window))) - 0.02) + 0.017) (defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :underbody))) + 0.08) +(defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :top-wing))) 0.05) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmethod man-int:get-object-type-carry-config :heuristics 20 @@ -91,8 +93,8 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;; BOTTOM-WING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defparameter *bottom-wing-grasp-x-offset* 0.07) -(defparameter *bottom-wing-grasp-y-offset* 0.01) -(defparameter *bottom-wing-grasp-z-offset* 0.02) +(defparameter *bottom-wing-grasp-y-offset* 0.0) +(defparameter *bottom-wing-grasp-z-offset* 0.005) ;; SIDE grasp ;; (man-int:def-object-type-to-gripper-transforms :bottom-wing :left :right-side @@ -118,8 +120,8 @@ ;; BACK grasp (man-int:def-object-type-to-gripper-transforms :bottom-wing '(:left :right) :back :grasp-translation `(,(- *bottom-wing-grasp-x-offset*) - 0.0 - ,*bottom-wing-grasp-z-offset*) + ,*bottom-wing-grasp-y-offset* + ,(- *bottom-wing-grasp-z-offset*)) :grasp-rot-matrix man-int:*-x-across-y-grasp-rotation* :pregrasp-offsets `(,(- *default-z-offset*) 0.0 ,*default-z-offset*) :2nd-pregrasp-offsets `(,(- *default-z-offset*) 0.0 0.0) @@ -128,12 +130,13 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;; UNDERBODY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defparameter *underbody-grasp-y-offset* 0.03) -(defparameter *underbody-grasp-z-offset* 0.0) +(defparameter *underbody-grasp-x-offset* 0.02) +(defparameter *underbody-grasp-y-offset* 0.0) +(defparameter *underbody-grasp-z-offset* 0.005) ;; TOP grasp (man-int:def-object-type-to-gripper-transforms :underbody :left :top - :grasp-translation `(0.0 ,*underbody-grasp-y-offset* ,*underbody-grasp-z-offset*) + :grasp-translation `(,*underbody-grasp-x-offset* ,*underbody-grasp-y-offset* ,*underbody-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets *default-lift-offsets* :2nd-pregrasp-offsets *default-lift-offsets* @@ -141,7 +144,7 @@ :2nd-lift-translation *default-lift-offsets*) (man-int:def-object-type-to-gripper-transforms :underbody :right :top - :grasp-translation `(0.0 ,(- *underbody-grasp-y-offset*) ,*underbody-grasp-z-offset*) + :grasp-translation `(,*underbody-grasp-x-offset* ,(- *underbody-grasp-y-offset*) ,*underbody-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets *default-lift-offsets* :2nd-pregrasp-offsets *default-lift-offsets* @@ -150,12 +153,12 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;; UPPER-BODY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defparameter *upper-body-grasp-x-offset* 0.09) -(defparameter *upper-body-grasp-z-offset* 0.0) +(defparameter *upper-body-grasp-x-offset* -0.09) +(defparameter *upper-body-grasp-z-offset* 0.02) ;; TOP grasp (man-int:def-object-type-to-gripper-transforms :upper-body '(:left :right) :top - :grasp-translation `(,(- *upper-body-grasp-x-offset*) 0.0 ,*upper-body-grasp-z-offset*) + :grasp-translation `(,*upper-body-grasp-x-offset* 0.0 ,*upper-body-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets *default-lift-offsets* :2nd-pregrasp-offsets *default-lift-offsets* @@ -166,7 +169,7 @@ (defparameter *top-wing-grasp-x-offset* 0.08) (defparameter *top-wing-grasp-y-offset* 0.01) -(defparameter *top-wing-grasp-z-offset* 0.03) +(defparameter *top-wing-grasp-z-offset* 0.008) ;; BACK grasp (man-int:def-object-type-to-gripper-transforms :top-wing '(:left :right) :back @@ -174,27 +177,27 @@ 0.0 ,*top-wing-grasp-z-offset*) :grasp-rot-matrix man-int:*-x-across-y-grasp-rotation* - :pregrasp-offsets `(,(- *default-z-offset*) 0.0 ,*default-z-offset*) - :2nd-pregrasp-offsets `(,(- *default-z-offset*) 0.0 0.0) + :pregrasp-offsets `(,(- *default-z-offset*) 0.0 ,*default-small-z-offset*) + :2nd-pregrasp-offsets `(,(- *default-small-z-offset*) 0.0 0.0) :lift-translation *default-lift-offsets* :2nd-lift-translation *default-lift-offsets*) ;; SIDE grasp (for picking it up with the whole airplane later) -(man-int:def-object-type-to-gripper-transforms :top-wing :left :right-side - :grasp-translation `(,(- *top-wing-grasp-x-offset*) - ,(- *top-wing-grasp-y-offset*) - ,*top-wing-grasp-z-offset*) - :grasp-rot-matrix man-int:*-y-across-x-grasp-rotation* - :pregrasp-offsets `(0 ,(- *default-z-offset*) ,*default-z-offset*) - :2nd-pregrasp-offsets `(0 ,(- *default-z-offset*) 0.0) - :lift-translation *default-lift-offsets* - :2nd-lift-translation *default-lift-offsets*) +;; (man-int:def-object-type-to-gripper-transforms :top-wing :left :right-side +;; :grasp-translation `(,(- *top-wing-grasp-x-offset*) +;; ,(- *top-wing-grasp-y-offset*) +;; ,*top-wing-grasp-z-offset*) +;; :grasp-rot-matrix man-int:*-y-across-x-grasp-rotation* +;; :pregrasp-offsets `(0 ,(- *default-z-offset*) ,*default-z-offset*) +;; :2nd-pregrasp-offsets `(0 ,(- *default-z-offset*) 0.0) +;; :lift-translation *default-lift-offsets* +;; :2nd-lift-translation *default-lift-offsets*) ;;;;;;;;;;;;;;;;;;;;;;;;;;;; WINDOW ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defparameter *window-grasp-x-offset* 0.017) -(defparameter *window-grasp-y-offset* 0.005) +(defparameter *window-grasp-x-offset* 0.019) +(defparameter *window-grasp-y-offset* 0.008) (defparameter *window-grasp-z-offset* 0.015) ;; TOP grasp @@ -227,51 +230,68 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;; PROPELLER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defparameter *propeller-grasp-x-offset* 0.013) +(defparameter *propeller-grasp-x-offset* -0.03) (defparameter *propeller-grasp-y-offset* 0.0) -(defparameter *propeller-grasp-z-offset* 0.003) +(defparameter *propeller-grasp-z-offset* 0.01) ;; TOP grasp (man-int:def-object-type-to-gripper-transforms :propeller '(:left :right) :top :grasp-translation `(,*propeller-grasp-x-offset* ,*propeller-grasp-y-offset* - ,(- *propeller-grasp-z-offset*)) - :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* - :pregrasp-offsets *default-lift-offsets* - :2nd-pregrasp-offsets *default-lift-offsets* - :lift-translation *default-lift-offsets* - :2nd-lift-translation *default-lift-offsets*) + ,*propeller-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets '(0 0 0.02) + :2nd-pregrasp-offsets '(0 0 0.02) + :lift-translation '(0 0 0.02) + :2nd-lift-translation '(0 0 0.02)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;; BOLT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defparameter *bolt-lift-z-offset* 0.02) + ;; TOP grasp (man-int:def-object-type-to-gripper-transforms :bolt '(:left :right) :top - :grasp-translation `(0.0 0.0 0.003) + :grasp-translation `(0.0 0.0 0.023) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets *default-lift-offsets* :2nd-pregrasp-offsets *default-lift-offsets* :lift-translation *default-lift-offsets* :2nd-lift-translation *default-lift-offsets*) +;; TOP grasp for placing on propeller is shorter because propeller is very high +(man-int:def-object-type-to-gripper-transforms :bolt '(:left :right) :top + :location-type :propeller + :grasp-translation `(0.0 0.0 0.023) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*bolt-lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*bolt-lift-z-offset*) + :lift-translation `(0.0 0.0 ,*bolt-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*bolt-lift-z-offset*)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (man-int:def-object-type-in-other-object-transform :chassis :holder-plane-horizontal :horizontal-attachment - :attachment-translation `(0.084 0.0 0.022) + :attachment-translation `(0.084 0.0 0.024) :attachment-rot-matrix man-int:*rotation-around-z-90-matrix*) +(defmethod man-int:get-z-offset-for-placing-with-dropping ((object (eql :chassis)) + (other-object (eql :holder-plane-horizontal)) + (attachment (eql :horizontal-attachment))) + 0.02) + (man-int:def-object-type-in-other-object-transform :bottom-wing :chassis :wing-attachment - :attachment-translation `(0.0 -0.02 0.0) + :attachment-translation `(0.0 -0.025 0.005) :attachment-rot-matrix man-int:*identity-matrix*) (defmethod man-int:get-z-offset-for-placing-with-dropping ((object (eql :bottom-wing)) (other-object (eql :chassis)) (attachment (eql :wing-attachment))) - 0.04) + 0.025) (man-int:def-object-type-in-other-object-transform :underbody :bottom-wing :body-attachment - :attachment-translation `(0.0 -0.025 0.02) + :attachment-translation `(0.0 -0.025 0.015) :attachment-rot-matrix man-int:*rotation-around-z+90-matrix*) (man-int:def-object-type-in-other-object-transform :upper-body :underbody :body-on-body @@ -280,7 +300,7 @@ (man-int:def-object-type-in-other-object-transform :propeller :motor-grill :propeller-attachment :attachment-translation `(0.0 0.0 0.002) - :attachment-rot-matrix man-int:*identity-matrix*) + :attachment-rot-matrix man-int:*rotation-around-z+180-matrix*) (man-int:def-object-type-in-other-object-transform :front-wheel :chassis :left-wheel-attachment :attachment-translation `(-0.0 -0.15 0.00) @@ -291,15 +311,20 @@ :attachment-rot-matrix man-int:*rotation-around-x+90-matrix*) (man-int:def-object-type-in-other-object-transform :top-wing :holder-plane-vertical :vertical-attachment - :attachment-translation `(0.025 0 0.183) - :attachment-rot-matrix man-int:*rotation-around-z-180-and-x+90-matrix*) + :attachment-translation `(-0.035 0 0.16) + :attachment-rot-matrix man-int:*rotation-around-z-90-then-x+90-matrix*) + +(defmethod man-int:get-z-offset-for-placing-with-dropping ((object (eql :bolt)) other-object attachment) + 0.02) (man-int:def-object-type-in-other-object-transform :bolt :upper-body :rear-thread :attachment-translation `(-0.0525 0.0 -0.025) :attachment-rot-matrix man-int:*identity-matrix*) -(defmethod man-int:get-z-offset-for-placing-with-dropping ((object (eql :bolt)) other-object attachment) - 0.015) +(defmethod man-int:get-z-offset-for-placing-with-dropping ((object (eql :top-wing)) + (other-object (eql :upper-body)) + (attachment (eql :wing-attachment))) + 0.005) (man-int:def-object-type-in-other-object-transform :top-wing :upper-body :wing-attachment :attachment-translation `(0.05 0.0 0.0025) @@ -317,11 +342,16 @@ :attachment-translation `(0.0 -0.0525 0.0075) :attachment-rot-matrix man-int:*rotation-around-z+90-matrix*) +(defmethod man-int:get-z-offset-for-placing-with-dropping ((object (eql :window)) + (other-object (eql :top-wing)) + (attachment (eql :window-attachment))) + 0.005) + (man-int:def-object-type-in-other-object-transform :bolt :window :window-thread :attachment-translation `(-0.0125 0.0 -0.02) :attachment-rot-matrix man-int:*identity-matrix*) (man-int:def-object-type-in-other-object-transform :bolt :propeller :propeller-thread - :attachment-translation `(0.0 0.0 -0.02) + :attachment-translation `(0.0 0.0 -0.005) :attachment-rot-matrix man-int:*identity-matrix*) diff --git a/cram_demos/cram_object_knowledge/src/environment.lisp b/cram_demos/cram_object_knowledge/src/environment.lisp index a77938c57d..7dc8e5a351 100644 --- a/cram_demos/cram_object_knowledge/src/environment.lisp +++ b/cram_demos/cram_object_knowledge/src/environment.lisp @@ -29,26 +29,25 @@ (in-package :objects) -(def-fact-group costmap-metadata (costmap:costmap-size - costmap:costmap-origin - costmap:costmap-resolution) +(def-fact-group environment-knowledge (costmap:costmap-size + costmap:costmap-origin + costmap:costmap-resolution + man-int:object-tf-prefix) (<- (costmap:costmap-size :iai-kitchen 12 12)) (<- (costmap:costmap-origin :iai-kitchen -6 -6)) - (<- (costmap:costmap-resolution :iai-kitchen 0.04))) - -(def-fact-group retail-small-environment-metadata (costmap:costmap-size - costmap:costmap-origin - costmap:costmap-resolution) - (<- (costmap:costmap-size :dm-shelves 10 10)) - (<- (costmap:costmap-origin :dm-shelves -5 -5)) - (<- (costmap:costmap-resolution :dm-shelves 0.04))) - -(def-fact-group retail-environment-metadata (costmap:costmap-size - costmap:costmap-origin - costmap:costmap-resolution) - (<- (costmap:costmap-size :dm-room 10 10)) - (<- (costmap:costmap-origin :dm-room -5 -5)) - (<- (costmap:costmap-resolution :dm-room 0.04))) + (<- (costmap:costmap-resolution :iai-kitchen 0.04)) + + (<- (is-dm-room-urdf-name ?name) + (member ?name (:dm-shelves :dm-room :store :storage))) + (<- (costmap:costmap-size ?name 10 10) + (is-dm-room-urdf-name ?name)) + (<- (costmap:costmap-origin ?name -5 -5) + (is-dm-room-urdf-name ?name)) + (<- (costmap:costmap-resolution ?name 0.04) + (is-dm-room-urdf-name ?name)) + + (<- (man-int:object-tf-prefix :iai-kitchen "iai_kitchen/"))) + (def-fact-group environment-object-type-hierarchy (man-int:object-type-direct-subtype) (<- (man-int:object-type-direct-subtype :container :container-prismatic)) @@ -87,8 +86,9 @@ (defmethod man-int:get-container-opening-distance :heuristics 20 ((container-name (eql :sink-area-dish-washer-main))) - ;; 0.78d0 ; 45 deg - 0.95d0) ; 54 deg + 0.9d0 ; 45 deg + ;; 0.95d0 ; 54 deg + ) ;; (defmethod man-int:get-container-opening-distance :heuristics 20 ;; ((container-name (eql :iai-fridge-main))) diff --git a/cram_demos/cram_object_knowledge/src/household.lisp b/cram_demos/cram_object_knowledge/src/household.lisp index fc11da62b5..dff3960ebd 100644 --- a/cram_demos/cram_object_knowledge/src/household.lisp +++ b/cram_demos/cram_object_knowledge/src/household.lisp @@ -35,20 +35,35 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def-fact-group household-object-type-hierarchy (man-int:object-type-direct-subtype) - (<- (man-int:object-type-direct-subtype :household-item :cutlery)) - (<- (man-int:object-type-direct-subtype :household-item :plate)) - (<- (man-int:object-type-direct-subtype :household-item :tray)) - (<- (man-int:object-type-direct-subtype :household-item :bottle)) - (<- (man-int:object-type-direct-subtype :household-item :cup)) - (<- (man-int:object-type-direct-subtype :household-item :milk)) - (<- (man-int:object-type-direct-subtype :household-item :cereal)) - (<- (man-int:object-type-direct-subtype :household-item :bowl)) + (<- (man-int:object-type-direct-subtype :household-item :kitchen-item)) + (<- (man-int:object-type-direct-subtype :household-item :clothing-item)) + + (<- (man-int:object-type-direct-subtype :kitchen-item :cutlery)) + (<- (man-int:object-type-direct-subtype :kitchen-item :plate)) + (<- (man-int:object-type-direct-subtype :kitchen-item :tray)) + (<- (man-int:object-type-direct-subtype :kitchen-item :bottle)) + (<- (man-int:object-type-direct-subtype :kitchen-item :cup)) + (<- (man-int:object-type-direct-subtype :kitchen-item :milk)) + (<- (man-int:object-type-direct-subtype :kitchen-item :cereal)) + (<- (man-int:object-type-direct-subtype :kitchen-item :bowl)) + + (<- (man-int:object-type-direct-subtype :kitchen-item :pot)) + (<- (man-int:object-type-direct-subtype :kitchen-item :spatula)) (<- (man-int:object-type-direct-subtype :cutlery :knife)) (<- (man-int:object-type-direct-subtype :cutlery :fork)) (<- (man-int:object-type-direct-subtype :cutlery :spoon)) - (<- (man-int:object-type-direct-subtype :cereal :breakfast-cereal))) + (<- (man-int:object-type-direct-subtype :plate :ikea-small-plate)) + (<- (man-int:object-type-direct-subtype :plate :ikea-big-plate)) + + (<- (man-int:object-type-direct-subtype :bowl :bowl-round)) + + (<- (man-int:object-type-direct-subtype :cereal :breakfast-cereal)) + + (<- (man-int:object-type-direct-subtype :cup :mug)) + + (<- (man-int:object-type-direct-subtype :clothing-item :shoe))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -60,7 +75,7 @@ 20) (defmethod man-int:get-action-gripping-effort :heuristics 20 ((object-type (eql :cereal))) - 30) + 45) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -69,10 +84,16 @@ 0.10) (defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :cutlery))) - 0.04) + 0.05) (defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :plate))) 0.02) +(defmethod man-int:get-action-gripper-opening :heuristics 20 + ((object-type (eql :ikea-small-plate))) + 0.03) +(defmethod man-int:get-action-gripper-opening :heuristics 20 + ((object-type (eql :ikea-big-plate))) + 0.03) (defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :tray))) 0.02) @@ -94,6 +115,9 @@ (defmethod man-int:get-object-type-carry-config :heuristics 20 ((object-type (eql :basket)) (grasp (eql :top))) :carry-top-basket) +(defmethod man-int:get-object-type-carry-config :heuristics 20 + ((object-type (eql :tray)) grasp) + :carry-tray) (defmethod man-int:get-object-type-carry-config :heuristics 20 ((object-type (eql :plate)) grasp) :carry-side-gripper-vertical) @@ -115,17 +139,28 @@ (defparameter *cutlery-grasp-z-offset* -0.015 ;; 0.015 "in meters") ; because TCP is not at the edge (defparameter *cutlery-pregrasp-z-offset* 0.20 "in meters") +(defparameter *cutlery-shelf-pregrasp-z-offset* 0.07 "in meters") (defparameter *cutlery-pregrasp-xy-offset* 0.10 "in meters") ;; TOP grasp -(man-int:def-object-type-to-gripper-transforms '(:cutlery :fork :knife :spoon) - '(:left :right) :top +(man-int:def-object-type-to-gripper-transforms + '(:cutlery :fork :knife :spoon) '(:left :right) :top :grasp-translation `(0.0 0.0 ,*cutlery-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets `(0.0 0.0 ,*cutlery-pregrasp-z-offset*) :2nd-pregrasp-offsets `(0.0 0.0 ,*cutlery-pregrasp-z-offset*) :lift-translation `(0.0 0.0 ,*cutlery-pregrasp-z-offset*) :2nd-lift-translation `(0.0 0.0 ,*cutlery-pregrasp-z-offset*)) +;; TOP grasp shelf +(man-int:def-object-type-to-gripper-transforms + '(:cutlery :fork :knife :spoon) '(:left :right) :top + :location-type :shelf + :grasp-translation `(0.0 0.0 ,*cutlery-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*) + :lift-translation `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*)) ;; BOTTOM grasp ;; Bottom grasp is commented out because the robot grasps the spoon through the @@ -139,6 +174,28 @@ ;; :lift-translation `(0.0 0.0 ,*cutlery-pregrasp-z-offset*) ;; :2nd-lift-translation `(0.0 0.0 ,*cutlery-pregrasp-z-offset*)) +;;;;;;;;;;;;;;;;;;;;;;;;;;;; SPATULA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *spatula-grasp-z-offset* 0.0 "in meters") ; because TCP is not at the edge + +;; TOP grasp +(man-int:def-object-type-to-gripper-transforms :spatula '(:left :right) :top + :grasp-translation `(0.0 0.0 ,*spatula-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*cutlery-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*cutlery-pregrasp-z-offset*) + :lift-translation `(0.0 0.0 ,*cutlery-pregrasp-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*cutlery-pregrasp-z-offset*)) +;; TOP grasp shelf +(man-int:def-object-type-to-gripper-transforms :spatula '(:left :right) :top + :location-type :shelf + :grasp-translation `(0.0 0.0 ,*spatula-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*) + :lift-translation `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*cutlery-shelf-pregrasp-z-offset*)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PLATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defparameter *plate-diameter* 0.26 "in meters") @@ -160,18 +217,163 @@ :lift-translation *lift-offset* :2nd-lift-translation *lift-offset*) -(man-int:def-object-type-to-gripper-transforms :plate :right :right-side +(man-int:def-object-type-to-gripper-transforms '(:plate :tray) :right :right-side :grasp-translation `(0.0 ,(- *plate-grasp-y-offset*) ,*plate-grasp-z-offset*) :grasp-rot-matrix - `((0 -1 0) - (,(- (sin *plate-grasp-roll-offset*)) 0 ,(cos *plate-grasp-roll-offset*)) - (,(- (cos *plate-grasp-roll-offset*)) 0 ,(- (sin *plate-grasp-roll-offset*)))) + `((0 -1 0) + (,(- (sin *plate-grasp-roll-offset*)) 0 ,(cos *plate-grasp-roll-offset*)) + (,(- (cos *plate-grasp-roll-offset*)) 0 ,(- (sin *plate-grasp-roll-offset*)))) :pregrasp-offsets `(0.0 ,(- *plate-pregrasp-y-offset*) ,*lift-z-offset*) :2nd-pregrasp-offsets `(0.0 ,(- *plate-pregrasp-y-offset*) ,*plate-2nd-pregrasp-z-offset*) :lift-translation *lift-offset* :2nd-lift-translation *lift-offset*) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IKEA-SMALL-PLATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *ikea-small-plate-diameter* 0.2 "in meters") +(defparameter *ikea-small-plate-edge* 0.04 "in meters") +(defparameter *ikea-small-plate-grasp-xy-offset* + (- (/ *ikea-small-plate-diameter* 2) 0.02) "in meters") +(defparameter *ikea-small-plate-grasp-z-offset* 0.0 "in meters") +(defparameter *ikea-small-plate-pregrasp-xy-offset* 0.15 "in meters") +(defparameter *ikea-small-plate-pregrasp-z-offset* + (* (tan (/ pi 6)) + (+ *ikea-small-plate-pregrasp-xy-offset* *ikea-small-plate-edge*)) + "in meters") +(defparameter *ikea-small-plate-2nd-pregrasp-xy-offset* 0.05 "in meters") +(defparameter *ikea-small-plate-2nd-pregrasp-z-offset* + (* (tan (/ pi 6)) + (+ *ikea-small-plate-2nd-pregrasp-xy-offset* *ikea-small-plate-edge*)) + "in meters") +(defparameter *ikea-small-plate-z-offsets* '(0 0 0.10) "in meters") +(defparameter *ikea-small-plate-2nd-z-offsets* '(0 0 0.20) "in meters") + +(man-int:def-object-type-to-gripper-transforms :ikea-small-plate '(:left :right) :left-side + :grasp-translation `(0.0 ,*ikea-small-plate-grasp-xy-offset* ,*ikea-small-plate-grasp-z-offset*) + :grasp-rot-matrix man-int:*y-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 ,*ikea-small-plate-pregrasp-xy-offset* 0.0) + :2nd-pregrasp-offsets `(0.0 ,*ikea-small-plate-2nd-pregrasp-xy-offset* 0.0) + :lift-translation *ikea-small-plate-z-offsets* + :2nd-lift-translation *ikea-small-plate-2nd-z-offsets*) + +(man-int:def-object-type-to-gripper-transforms :ikea-small-plate '(:left :right) :right-side + :grasp-translation `(0.0 ,(- *ikea-small-plate-grasp-xy-offset*) ,*ikea-small-plate-grasp-z-offset*) + :grasp-rot-matrix man-int:*-y-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 ,(- *ikea-small-plate-pregrasp-xy-offset*) 0.0) + :2nd-pregrasp-offsets `(0.0 ,(- *ikea-small-plate-2nd-pregrasp-xy-offset*) 0.0) + :lift-translation *ikea-small-plate-z-offsets* + :2nd-lift-translation *ikea-small-plate-2nd-z-offsets*) + +(man-int:def-object-type-to-gripper-transforms :ikea-small-plate '(:left :right) :front + :grasp-translation `(,*ikea-small-plate-grasp-xy-offset* 0.0 ,*ikea-small-plate-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-y-30-deg-grasp-rotation* + :pregrasp-offsets `(,*ikea-small-plate-pregrasp-xy-offset* + 0.0 + ,*ikea-small-plate-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(,*ikea-small-plate-2nd-pregrasp-xy-offset* + 0.0 + ,*ikea-small-plate-2nd-pregrasp-z-offset*) + :lift-translation *ikea-small-plate-z-offsets* + :2nd-lift-translation *ikea-small-plate-2nd-z-offsets*) + +(man-int:def-object-type-to-gripper-transforms :ikea-small-plate '(:left :right) :back + :grasp-translation `(,(- *ikea-small-plate-grasp-xy-offset*) 0.0 ,*ikea-small-plate-grasp-z-offset*) + :grasp-rot-matrix man-int:*-x-across-y-grasp-rotation* + :pregrasp-offsets `(,(- *ikea-small-plate-pregrasp-xy-offset*) 0.0 0.0) + :2nd-pregrasp-offsets `(,(- *ikea-small-plate-2nd-pregrasp-xy-offset*) 0.0 0.0) + :lift-translation *ikea-small-plate-z-offsets* + :2nd-lift-translation *ikea-small-plate-2nd-z-offsets*) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IKEA-BIG-PLATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *ikea-big-plate-diameter* 0.263 "in meters") +(defparameter *ikea-big-plate-edge* 0.05 "in meters") +(defparameter *ikea-big-plate-grasp-xy-offset* + (- (/ *ikea-big-plate-diameter* 2) 0.02) "in meters") +(defparameter *ikea-big-plate-grasp-z-offset* 0.0 "in meters") +(defparameter *ikea-big-plate-pregrasp-xy-offset* 0.15 "in meters") +(defparameter *ikea-big-plate-pregrasp-z-offset* + (* (tan (/ pi 7.5)) + (+ *ikea-big-plate-pregrasp-xy-offset* *ikea-big-plate-edge*)) + "in meters") +(defparameter *ikea-big-plate-2nd-pregrasp-xy-offset* 0.05 "in meters") +(defparameter *ikea-big-plate-2nd-pregrasp-z-offset* + (* (/ 2 5) + (+ *ikea-big-plate-2nd-pregrasp-xy-offset* *ikea-big-plate-edge*)) + "in meters") +(defparameter *ikea-big-plate-z-offsets* '(0 0 0.10) "in meters") +(defparameter *ikea-big-plate-2nd-z-offsets* '(0 0 0.20) "in meters") + +(man-int:def-object-type-to-gripper-transforms :ikea-big-plate '(:left :right) :front + :grasp-translation `(,*ikea-big-plate-grasp-xy-offset* + 0.0 + ,*ikea-big-plate-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-y-24-deg-grasp-rotation* + :pregrasp-offsets `(,*ikea-big-plate-pregrasp-xy-offset* + 0.0 + ,*ikea-big-plate-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(,*ikea-big-plate-2nd-pregrasp-xy-offset* + 0.0 + ,*ikea-big-plate-2nd-pregrasp-z-offset*) + :lift-translation *ikea-big-plate-z-offsets* + :2nd-lift-translation *ikea-big-plate-2nd-z-offsets*) + +(man-int:def-object-type-to-gripper-transforms :ikea-big-plate '(:left :right) :left-side + :grasp-translation `(0.0 + ,*ikea-big-plate-grasp-xy-offset* + ,*ikea-big-plate-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-y-24-deg-grasp-rotation* + :pregrasp-offsets `(0.0 + ,*ikea-big-plate-pregrasp-xy-offset* + ,*ikea-big-plate-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(0.0 + ,*ikea-big-plate-2nd-pregrasp-xy-offset* + ,*ikea-big-plate-pregrasp-z-offset*) + :lift-translation *ikea-big-plate-z-offsets* + :2nd-lift-translation *ikea-big-plate-2nd-z-offsets*) + +(man-int:def-object-type-to-gripper-transforms :ikea-big-plate '(:left :right) :right-side + :grasp-translation `(0.0 + ,(- *ikea-big-plate-grasp-xy-offset*) + ,*ikea-big-plate-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-y-24-deg-grasp-rotation* + :pregrasp-offsets `(0.0 + ,(- *ikea-big-plate-pregrasp-xy-offset*) + ,*ikea-big-plate-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(0.0 + ,(- *ikea-big-plate-2nd-pregrasp-xy-offset*) + ,*ikea-big-plate-2nd-pregrasp-z-offset*) + :lift-translation *ikea-big-plate-z-offsets* + :2nd-lift-translation *ikea-big-plate-2nd-z-offsets*) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; POT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *pot-grasp-x-offset* 0.14 "in meters") +(defparameter *pot-grasp-z-offset* 0.05 "in meters") + +;; SIDE grasp +(man-int:def-object-type-to-gripper-transforms :pot '(:left :right) :left-side + :grasp-translation `(,*pot-grasp-x-offset* 0.0 ,*pot-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-y-grasp-rotation* + :pregrasp-offsets `(,*plate-pregrasp-y-offset* 0.0 ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 ,*plate-pregrasp-y-offset* 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :pot '(:left :right) :right-side + :grasp-translation `(,(- *pot-grasp-x-offset*) 0.0 ,*pot-grasp-z-offset*) + :grasp-rot-matrix man-int:*-x-across-y-flipped-grasp-rotation* + :pregrasp-offsets `(,(- *plate-pregrasp-y-offset*) 0.0 ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 ,(- *plate-pregrasp-y-offset*) 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bottle ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defparameter *bottle-pregrasp-xy-offset* 0.15 "in meters") @@ -217,10 +419,13 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cup ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defparameter *cup-pregrasp-xy-offset* 0.15 "in meters") +;; (defparameter *cup-eco-orange-grasp-xy-offset* 0.02 "in meters") (defparameter *cup-grasp-xy-offset* 0.02 "in meters") +;; (defparameter *cup-eco-orange-grasp-z-offset* 0.01 "in meters") (defparameter *cup-grasp-z-offset* 0.01 "in meters") -(defparameter *cup-top-grasp-x-offset* 0.03 "in meters") -(defparameter *cup-top-grasp-z-offset* 0.02 "in meters") +(defparameter *cup-top-grasp-x-offset* 0.05 "in meters") +;; (defparameter *cup-eco-orange-top-grasp-z-offset* 0.02 "in meters") +(defparameter *cup-top-grasp-z-offset* 0.04 "in meters") ;; TOP grasp (man-int:def-object-type-to-gripper-transforms :cup '(:left :right) :top @@ -231,6 +436,23 @@ :lift-translation *lift-offset* :2nd-lift-translation *lift-offset*) +(man-int:def-object-type-to-gripper-transforms :cup '(:left :right) :top2 + :grasp-translation `(0.0d0 ,(- *cup-top-grasp-x-offset*) ,*cup-top-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; BOTTOM grasp +(man-int:def-object-type-to-gripper-transforms :cup '(:left :right) :bottom + :grasp-translation `(0.0d0 0.0d0 ,(- *cup-grasp-z-offset*)) + :grasp-rot-matrix man-int:*-z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,(- *lift-z-offset*)) + :2nd-pregrasp-offsets `(0.0 0 ,(- *lift-z-offset*)) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + ;; SIDE grasp (man-int:def-object-type-to-gripper-transforms :cup '(:left :right) :left-side :grasp-translation `(0.0d0 ,(- *cup-grasp-xy-offset*) ,*cup-grasp-z-offset*) @@ -251,7 +473,7 @@ ;; BACK grasp (man-int:def-object-type-to-gripper-transforms :cup '(:left :right) :back :grasp-translation `(,*cup-grasp-xy-offset* 0.0d0 ,*cup-grasp-z-offset*) - :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation* + :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation-2* :pregrasp-offsets `(,(- *cup-pregrasp-xy-offset*) 0.0 ,*lift-z-offset*) :2nd-pregrasp-offsets `(,(- *cup-pregrasp-xy-offset*) 0.0 0.0) :lift-translation *lift-offset* @@ -267,57 +489,200 @@ :2nd-lift-translation *lift-offset*) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mug ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *mug-back-grasp-x-offset* 0.04 "in meters") +(defparameter *mug-side-grasp-x-offset* 0.02 "in meters") +(defparameter *mug-top-grasp-y-offset* 0.045 "in meters") + +;; FRONT grasp +(man-int:def-object-type-to-gripper-transforms :mug '(:left :right) :front + :grasp-translation `(,(- *cup-grasp-xy-offset*) 0.0d0 ,*cup-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-z-grasp-rotation-2* + :pregrasp-offsets `(,*cup-pregrasp-xy-offset* 0.0 ,*lift-z-offset*) + :2nd-pregrasp-offsets `(,*cup-pregrasp-xy-offset* 0.0 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; BACK grasp -- handle +(man-int:def-object-type-to-gripper-transforms :mug '(:left :right) :back + :grasp-translation `(,(- *mug-back-grasp-x-offset*) 0.0d0 ,*cup-grasp-z-offset*) + :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation-2* + :pregrasp-offsets `(,(- *cup-pregrasp-xy-offset*) 0.0 ,*lift-z-offset*) + :2nd-pregrasp-offsets `(,(- *cup-pregrasp-xy-offset*) 0.0 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; SIDE grasp +(man-int:def-object-type-to-gripper-transforms :mug '(:left :right) :left-side + :grasp-translation `(,*mug-side-grasp-x-offset* ,(- *cup-grasp-xy-offset*) 0.0) + :grasp-rot-matrix man-int:*y-across-z-flipped-grasp-rotation* + :pregrasp-offsets `(0.0 ,*cup-pregrasp-xy-offset* ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 ,*cup-pregrasp-xy-offset* 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :mug '(:left :right) :right-side + :grasp-translation `(,*mug-side-grasp-x-offset* ,*cup-grasp-xy-offset* 0.0) + :grasp-rot-matrix man-int:*-y-across-z-flipped-grasp-rotation* + :pregrasp-offsets `(0.0 ,(- *cup-pregrasp-xy-offset*) ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 ,(- *cup-pregrasp-xy-offset*) 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; TOP grasp +(man-int:def-object-type-to-gripper-transforms :mug '(:left :right) :top + :grasp-translation `(,*mug-side-grasp-x-offset* ,(- *mug-top-grasp-y-offset*) 0.0) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :mug '(:left :right) :top2 + :grasp-translation `(,*mug-side-grasp-x-offset* ,*mug-top-grasp-y-offset* 0.0) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; BOTTOM grasp +(man-int:def-object-type-to-gripper-transforms :mug '(:left :right) :bottom + :grasp-translation `(,*mug-side-grasp-x-offset* 0.0d0 0.0) + :grasp-rot-matrix man-int:*-z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,(- *lift-z-offset*)) + :2nd-pregrasp-offsets `(0.0 0 ,(- *lift-z-offset*)) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; shoe ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *shoe-top-grasp-x-offset* 0.1 "in meters") +(defparameter *shoe-top2-grasp-x-offset* 0.05 "in meters") +(defparameter *shoe-front-grasp-x-offset* 0.07 "in meters") +(defparameter *shoe-back-grasp-x-offset* 0.03 "in meters") +(defparameter *shoe-side-grasp-z-offset* 0.03 "in meters") + +;; TOP grasp +(man-int:def-object-type-to-gripper-transforms :shoe '(:left :right) :top + :grasp-translation `(,(- *shoe-top-grasp-x-offset*) 0.0d0 ,*cup-top-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :shoe '(:left :right) :top2 + :grasp-translation `(,(- *shoe-top2-grasp-x-offset*) + ,(- *cup-top-grasp-x-offset*) + ,*cup-top-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; SIDE grasp +(man-int:def-object-type-to-gripper-transforms :shoe '(:left :right) :left-side + :grasp-translation `(,(- *shoe-top2-grasp-x-offset*) + ,(- *cup-grasp-xy-offset*) + ,*shoe-side-grasp-z-offset*) + :grasp-rot-matrix man-int:*y-across-z-grasp-rotation* + :pregrasp-offsets `(0.0 ,*cup-pregrasp-xy-offset* ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 ,*cup-pregrasp-xy-offset* 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :shoe '(:left :right) :right-side + :grasp-translation `(,(- *shoe-top2-grasp-x-offset*) + ,*cup-grasp-xy-offset* + ,*shoe-side-grasp-z-offset*) + :grasp-rot-matrix man-int:*-y-across-z-grasp-rotation* + :pregrasp-offsets `(0.0 ,(- *cup-pregrasp-xy-offset*) ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 ,(- *cup-pregrasp-xy-offset*) 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; BACK grasp +(man-int:def-object-type-to-gripper-transforms :shoe '(:left :right) :back + :grasp-translation `(,(- *shoe-back-grasp-x-offset*) 0.0d0 ,*shoe-side-grasp-z-offset*) + :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation* + :pregrasp-offsets `(,(- *cup-pregrasp-xy-offset*) 0.0 ,*lift-z-offset*) + :2nd-pregrasp-offsets `(,(- *cup-pregrasp-xy-offset*) 0.0 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; FRONT grasp +(man-int:def-object-type-to-gripper-transforms :shoe '(:left :right) :front + :grasp-translation `(,(- *shoe-front-grasp-x-offset*) 0.0d0 ,*shoe-side-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-z-grasp-rotation* + :pregrasp-offsets `(,*cup-pregrasp-xy-offset* 0.0 ,*lift-z-offset*) + :2nd-pregrasp-offsets `(,*cup-pregrasp-xy-offset* 0.0 0.0) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + + + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; milk ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defparameter *milk-grasp-xy-offset* 0.01 "in meters") -(defparameter *milk-grasp-z-offset* 0.04 "in meters") +(defparameter *milk-grasp-z-offset* 0.03 "in meters") (defparameter *milk-pregrasp-xy-offset* 0.15 "in meters") -(defparameter *milk-lift-z-offset* 0.05 "in meters") +(defparameter *milk-lift-z-offset* 0.15 "in meters") ;; BACK grasp (man-int:def-object-type-to-gripper-transforms :milk '(:left :right) :back :grasp-translation `(,*milk-grasp-xy-offset* 0.0d0 ,*milk-grasp-z-offset*) :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation* - :pregrasp-offsets `(,(- *milk-pregrasp-xy-offset*) 0.0 ,*lift-z-offset*) + :pregrasp-offsets `(,(- *milk-pregrasp-xy-offset*) 0.0 ,*milk-lift-z-offset*) :2nd-pregrasp-offsets `(,(- *milk-pregrasp-xy-offset*) 0.0 0.0) - :lift-translation *lift-offset* - :2nd-lift-translation *lift-offset*) + :lift-translation `(0.0 0.0 ,*milk-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*milk-lift-z-offset*)) ;; FRONT grasp (man-int:def-object-type-to-gripper-transforms :milk '(:left :right) :front :grasp-translation `(,(- *milk-grasp-xy-offset*) 0.0d0 ,*milk-grasp-z-offset*) :grasp-rot-matrix man-int:*x-across-z-grasp-rotation* - :pregrasp-offsets `(,*milk-pregrasp-xy-offset* 0.0 ,*lift-z-offset*) + :pregrasp-offsets `(,*milk-pregrasp-xy-offset* 0.0 ,*milk-lift-z-offset*) :2nd-pregrasp-offsets `(,*milk-pregrasp-xy-offset* 0.0 0.0) - :lift-translation *lift-offset* - :2nd-lift-translation *lift-offset*) + :lift-translation `(0.0 0.0 ,*milk-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*milk-lift-z-offset*)) ;; SIDE grasp (man-int:def-object-type-to-gripper-transforms :milk '(:left :right) :left-side :grasp-translation `(0.0d0 ,(- *milk-grasp-xy-offset*) ,*milk-grasp-z-offset*) :grasp-rot-matrix man-int:*y-across-z-grasp-rotation* - :pregrasp-offsets `(0.0 ,*milk-pregrasp-xy-offset* ,*lift-z-offset*) + :pregrasp-offsets `(0.0 ,*milk-pregrasp-xy-offset* ,*milk-lift-z-offset*) :2nd-pregrasp-offsets `(0.0 ,*milk-pregrasp-xy-offset* 0.0) - :lift-translation *lift-offset* - :2nd-lift-translation *lift-offset*) + :lift-translation `(0.0 0.0 ,*milk-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*milk-lift-z-offset*)) (man-int:def-object-type-to-gripper-transforms :milk '(:left :right) :right-side :grasp-translation `(0.0d0 ,*milk-grasp-xy-offset* ,*milk-grasp-z-offset*) :grasp-rot-matrix man-int:*-y-across-z-grasp-rotation* - :pregrasp-offsets `(0.0 ,(- *milk-pregrasp-xy-offset*) ,*lift-z-offset*) + :pregrasp-offsets `(0.0 ,(- *milk-pregrasp-xy-offset*) ,*milk-lift-z-offset*) :2nd-pregrasp-offsets `(0.0 ,(- *milk-pregrasp-xy-offset*) 0.0) - :lift-translation *lift-offset* - :2nd-lift-translation *lift-offset*) + :lift-translation `(0.0 0.0 ,*milk-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*milk-lift-z-offset*)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cereal ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defparameter *cereal-grasp-z-offset* 0.04 "in meters") -(defparameter *cereal-grasp-xy-offset* 0.03 "in meters") +(defparameter *cereal-grasp-side-z-offset* 0.0 "in meters") +(defparameter *cereal-grasp-xy-offset* 0.015 "in meters") (defparameter *cereal-pregrasp-z-offset* 0.05 "in meters") (defparameter *cereal-pregrasp-xy-offset* 0.15 "in meters") (defparameter *cereal-postgrasp-xy-offset* 0.40 "in meters") (defparameter *cereal-lift-z-offset* 0.1 "in meters") -(defparameter *cereal-small-lift-z-offset* 0.05 "in meters") +(defparameter *cereal-small-lift-z-offset* 0.06 "in meters") ;; TOP grasp (man-int:def-object-type-to-gripper-transforms @@ -332,18 +697,28 @@ ;; FRONT grasp table (man-int:def-object-type-to-gripper-transforms '(:cereal :breakfast-cereal) '(:left :right) :front - :grasp-translation `(,*cereal-grasp-xy-offset* 0.0d0 ,*cereal-grasp-z-offset*) + :grasp-translation `(,*cereal-grasp-xy-offset* 0.0d0 ,*cereal-grasp-side-z-offset*) :grasp-rot-matrix man-int:*x-across-z-grasp-rotation* :pregrasp-offsets `(,*cereal-pregrasp-xy-offset* 0.0 ,*cereal-pregrasp-z-offset*) :2nd-pregrasp-offsets `(,*cereal-pregrasp-xy-offset* 0.0 0.0) :lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*) :2nd-lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*)) +;; FRONT grasp table flipped because Donbot has an eye on his hand +(man-int:def-object-type-to-gripper-transforms + '(:cereal :breakfast-cereal) '(:left :right) :front-flipped + :grasp-translation `(,*cereal-grasp-xy-offset* 0.0d0 ,*cereal-grasp-side-z-offset*) + :grasp-rot-matrix man-int:*x-across-z-grasp-rotation-2* + :pregrasp-offsets `(,*cereal-pregrasp-xy-offset* 0.0 ,*cereal-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(,*cereal-pregrasp-xy-offset* 0.0 0.0) + :lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*)) + ;; FRONT grasp shelf (man-int:def-object-type-to-gripper-transforms '(:cereal :breakfast-cereal) '(:left :right) :front :location-type :shelf - :grasp-translation `(,*cereal-grasp-xy-offset* 0.0d0 ,*cereal-grasp-z-offset*) + :grasp-translation `(,*cereal-grasp-xy-offset* 0.0d0 ,*cereal-grasp-side-z-offset*) :grasp-rot-matrix man-int:*x-across-z-grasp-rotation* :pregrasp-offsets `(,*cereal-pregrasp-xy-offset* 0.0 ,*cereal-pregrasp-z-offset*) :2nd-pregrasp-offsets `(,*cereal-pregrasp-xy-offset* 0.0 0.0) @@ -353,18 +728,28 @@ ;; BACK grasp table (man-int:def-object-type-to-gripper-transforms '(:cereal :breakfast-cereal) '(:left :right) :back - :grasp-translation `(,(- *cereal-grasp-xy-offset*) 0.0d0 ,*cereal-grasp-z-offset*) + :grasp-translation `(,(- *cereal-grasp-xy-offset*) 0.0d0 ,*cereal-grasp-side-z-offset*) :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation* :pregrasp-offsets `(,(- *cereal-pregrasp-xy-offset*) 0.0 ,*cereal-pregrasp-z-offset*) :2nd-pregrasp-offsets `(,(- *cereal-pregrasp-xy-offset*) 0.0 0.0) :lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*) :2nd-lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*)) +;; BACK grasp table flipped because Donbot has an eye on his hand +(man-int:def-object-type-to-gripper-transforms + '(:cereal :breakfast-cereal) '(:left :right) :back-flipped + :grasp-translation `(,(- *cereal-grasp-xy-offset*) 0.0d0 ,*cereal-grasp-side-z-offset*) + :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation-2* + :pregrasp-offsets `(,(- *cereal-pregrasp-xy-offset*) 0.0 ,*cereal-pregrasp-z-offset*) + :2nd-pregrasp-offsets `(,(- *cereal-pregrasp-xy-offset*) 0.0 0.0) + :lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*cereal-lift-z-offset*)) + ;; BACK grasp shelf (man-int:def-object-type-to-gripper-transforms '(:cereal :breakfast-cereal) '(:left :right) :back :location-type :shelf - :grasp-translation `(,(- *cereal-grasp-xy-offset*) 0.0d0 ,*cereal-grasp-z-offset*) + :grasp-translation `(,(- *cereal-grasp-xy-offset*) 0.0d0 ,*cereal-grasp-side-z-offset*) :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation* :pregrasp-offsets `(,(- *cereal-pregrasp-xy-offset*) 0.0 ,*cereal-pregrasp-z-offset*) :2nd-pregrasp-offsets `(,(- *cereal-pregrasp-xy-offset*) 0.0 0.0) @@ -374,12 +759,70 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bowl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defparameter *bowl-grasp-x-offset* 0.07 "in meters") -(defparameter *bowl-grasp-z-offset* 0.0 "in meters") +;; (defparameter *edeka-red-bowl-grasp-x-offset* 0.07 "in meters") +(defparameter *bowl-grasp-x-offset* 0.08 "in meters") +(defparameter *bowl-tilted-pregrasp-x-offset* 0.08 "in meters") +;; (defparameter *edeka-red-bowl-grasp-z-offset* 0.0 "in meters") +(defparameter *bowl-grasp-z-offset* 0.02 "in meters") +(defparameter *bowl-tilted-grasp-z-offset* 0.04 "in meters") (defparameter *bowl-pregrasp-z-offset* 0.20 "in meters") ;; TOP grasp (man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top + :grasp-translation `(,(- *bowl-grasp-x-offset*) 0.0d0 ,*bowl-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-front + :grasp-translation `(,*bowl-grasp-x-offset* 0.0d0 ,*bowl-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-left + :grasp-translation `(0.0d0 ,*bowl-grasp-x-offset* ,*bowl-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) +(man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-left-tilted + :grasp-translation `(0.0d0 ,*bowl-grasp-x-offset* ,*bowl-tilted-grasp-z-offset*) + :grasp-rot-matrix + `((0 1 0) + (,(sin *plate-grasp-roll-offset*) 0 ,(- (cos *plate-grasp-roll-offset*))) + (,(- (cos *plate-grasp-roll-offset*)) 0 ,(- (sin *plate-grasp-roll-offset*)))) + :pregrasp-offsets `(0.0d0 ,*bowl-tilted-pregrasp-x-offset* ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0d0 ,*bowl-tilted-pregrasp-x-offset* ,*lift-z-offset*) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +(man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-right + :grasp-translation `(0.0d0 ,(- *bowl-grasp-x-offset*) ,*bowl-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets *lift-offset* + :2nd-pregrasp-offsets *lift-offset* + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) +(man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-right-tilted + :grasp-translation `(0.0d0 ,(- *bowl-grasp-x-offset*) ,*bowl-tilted-grasp-z-offset*) + :grasp-rot-matrix + `((0 -1 0) + (,(- (sin *plate-grasp-roll-offset*)) 0 ,(cos *plate-grasp-roll-offset*)) + (,(- (cos *plate-grasp-roll-offset*)) 0 ,(- (sin *plate-grasp-roll-offset*)))) + :pregrasp-offsets `(0.0d0 ,(- *bowl-tilted-pregrasp-x-offset*) ,*lift-z-offset*) + :2nd-pregrasp-offsets `(0.0d0 ,(- *bowl-tilted-pregrasp-x-offset*) ,*lift-z-offset*) + :lift-translation *lift-offset* + :2nd-lift-translation *lift-offset*) + +;; TOP grasp drawer +(man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top + :location-type :drawer :grasp-translation `(,(- *bowl-grasp-x-offset*) 0.0d0 ,*bowl-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* :pregrasp-offsets `(0.0 0.0 ,*bowl-pregrasp-z-offset*) @@ -387,6 +830,7 @@ :lift-translation `(0.0 0.0 ,*bowl-pregrasp-z-offset*) :2nd-lift-translation `(0.0 0.0 ,*bowl-pregrasp-z-offset*)) (man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-front + :location-type :drawer :grasp-translation `(,*bowl-grasp-x-offset* 0.0d0 ,*bowl-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* :pregrasp-offsets `(0.0 0.0 ,*bowl-pregrasp-z-offset*) @@ -394,6 +838,7 @@ :lift-translation `(0.0 0.0 ,*bowl-pregrasp-z-offset*) :2nd-lift-translation `(0.0 0.0 ,*bowl-pregrasp-z-offset*)) (man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-left + :location-type :drawer :grasp-translation `(0.0d0 ,*bowl-grasp-x-offset* ,*bowl-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets `(0.0 0.0 ,*bowl-pregrasp-z-offset*) @@ -401,6 +846,7 @@ :lift-translation `(0.0 0.0 ,*bowl-pregrasp-z-offset*) :2nd-lift-translation `(0.0 0.0 ,*bowl-pregrasp-z-offset*)) (man-int:def-object-type-to-gripper-transforms :bowl '(:left :right) :top-right + :location-type :drawer :grasp-translation `(0.0d0 ,(- *bowl-grasp-x-offset*) ,*bowl-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets `(0.0 0.0 ,*bowl-pregrasp-z-offset*) @@ -410,6 +856,47 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; bowl-round ;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *bowl-round-grasp-x-offset* 0.065 "in meters") +(defparameter *bowl-round-grasp-z-offset* 0.02 "in meters") +(defparameter *bowl-round-lift-z-offset* 0.04 "in meters") + +;; TOP grasp +(man-int:def-object-type-to-gripper-transforms :bowl-round '(:left :right) :top + :grasp-translation `(,(- *bowl-round-grasp-x-offset*) 0.0d0 ,*bowl-round-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*)) + +(man-int:def-object-type-to-gripper-transforms :bowl-round '(:left :right) :top-front + :grasp-translation `(,*bowl-round-grasp-x-offset* 0.0d0 ,*bowl-round-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-y-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*)) + +(man-int:def-object-type-to-gripper-transforms :bowl-round '(:left :right) :top-left + :grasp-translation `(0.0d0 ,*bowl-round-grasp-x-offset* ,*bowl-round-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*)) + +(man-int:def-object-type-to-gripper-transforms :bowl-round '(:left :right) :top-right + :grasp-translation `(0.0d0 ,(- *bowl-round-grasp-x-offset*) ,*bowl-round-grasp-z-offset*) + :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* + :pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-pregrasp-offsets `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*) + :2nd-lift-translation `(0.0 0.0 ,*bowl-round-lift-z-offset*)) + + + ;;;;;;;;;;;;;;;;;;;;;;;;; table setting locations ;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -425,7 +912,8 @@ (urdf-name sink-area-surface) (owl-name "kitchen_sink_block_counter_top") (part-of ?environment-name))) - (side left))) + ;; left in the room is right in the sink-area-surface frame + (side right))) (defun make-location-on-sink-left-front (?environment-name) (desig:a location @@ -434,8 +922,8 @@ (urdf-name sink-area-surface) (owl-name "kitchen_sink_block_counter_top") (part-of ?environment-name))) - (side left) - (side front) + ;; left-front in map frame is right back in sink-area-surface frame + (side (right back)) (range-invert 0.5))) (defun make-location-on-sink-middle-front (?environment-name) @@ -445,8 +933,7 @@ (urdf-name sink-area-surface) (owl-name "kitchen_sink_block_counter_top") (part-of ?environment-name))) - (side left) - (side front) + (side (right back)) (range 0.5))) (defun make-location-in-sink (?object-type ?environment-name) @@ -455,7 +942,7 @@ (type sink) (urdf-name sink-area-sink) (part-of ?environment-name))) - (side right) + (side left) (for (desig:an object (type ?object-type))) ;; the "for" condition for spoon adds a height that is too high to reach ;; so adding a little negative z-offset @@ -470,7 +957,7 @@ (urdf-name sink-area-left-upper-drawer-main) (owl-name "drawer_sinkblock_upper_open") (part-of ?environment-name))) - (side front))) + (side back))) (defun make-location-in-sink-left-bottom-drawer (?environment-name) (desig:a location @@ -478,7 +965,7 @@ (type drawer) (urdf-name sink-area-left-bottom-drawer-main) (part-of ?environment-name))) - (side front))) + (side back))) (defun make-location-in-sink-left-middle-drawer (?environment-name) (desig:a location @@ -487,7 +974,7 @@ (urdf-name sink-area-left-middle-drawer-main) (owl-name "drawer_sinkblock_middle_open") (part-of ?environment-name))) - (side front))) + (side back))) (defun make-location-in-sink-trash-drawer (?object-type ?environment-name) (desig:a location @@ -495,24 +982,55 @@ (type drawer) (urdf-name sink-area-trash-drawer-main) (part-of ?environment-name))) - (z-offset 0.1) - (side front) - (side right) + (z-offset -0.05) + (side (back left)) (range 0.2) (for (desig:an object (type ?object-type))))) +;;;;;;;; dishwasher + +(defun make-location-in-dishwasher-drawer (?object-type ?environment-name) + (let ((?location-in-dishwasher + (desig:a location + (in (desig:an object + (type dishwasher) + (urdf-name sink-area-dish-washer-main) + (part-of ?environment-name))))) + (?attachments + (case ?object-type + (:bowl + '(;; :dish-washer-drawer-left + :dish-washer-drawer-right)) + (:cup + '(:dish-washer-drawer-left-flipped-around-x + :dish-washer-drawer-left-flipped-around-y)) + (:spoon + '(:dish-washer-drawer-center))))) + (desig:a location + (above (desig:an object + (type drawer) + (urdf-name sink-area-dish-washer-tray-bottom) + (part-of ?environment-name) + (location ?location-in-dishwasher))) + (for (desig:an object + (type ?object-type) + ;; need a name because of the attachment + (name some-name))) + (attachments ?attachments)))) + ;;;;;;;; vertical drawer (defun make-location-in-oven-right-drawer (?object-type ?environment-name) (desig:a location - ;; (side front) (in (desig:an object (type drawer) (urdf-name oven-area-area-right-drawer-main) (owl-name "drawer_oven_right_open") (part-of ?environment-name) (level topmost))) - (side front) + (side back) + (range 0.1) + (orientation support-aligned) (for (desig:an object (type ?object-type))))) ;;;;;;;; fridge @@ -545,8 +1063,7 @@ (owl-name "kitchen_island_counter_top") (part-of ?environment-name))) (for (desig:an object (type ?object-type))) - (side back) - (side right) + (side (back right)) (range-invert 0.5) (context table-setting) (object-count 3))) @@ -559,8 +1076,7 @@ (owl-name "kitchen_island_counter_top") (part-of ?environment-name))) (for (desig:an object (type ?object-type))) - (side back) - (side right))) + (side (back right)))) (defun make-cereal-location (?object-type ?environment-name) (desig:a location @@ -573,8 +1089,15 @@ (owl-name "kitchen_island_counter_top") (part-of ?environment-name))) (for (desig:an object (type ?object-type))) - (side back) - (side right))) + (side (back right)))) + +(defun make-location-in-kitchen-island-left-upper-drawer (?environment-name) + (desig:a location + (in (desig:an object + (type drawer) + (urdf-name kitchen-island-left-upper-drawer-main) + (part-of ?environment-name))) + (side back))) ;;;;;;;; dining table @@ -585,7 +1108,7 @@ (urdf-name dining-area-jokkmokk-table-main) (part-of ?environment-name))) (for (desig:an object (type ?object-type))) - (side right) + (side front) (context table-setting) (object-count 2))) @@ -595,7 +1118,7 @@ (type counter-top) (urdf-name dining-area-jokkmokk-table-main) (part-of ?environment-name))) - (side right))) + (side (front right)))) (defun make-location-in-center-of-dining-table (?object-type ?environment-name) (desig:a location @@ -605,20 +1128,28 @@ (part-of ?environment-name))) (for (desig:an object (type ?object-type))) (range 0.2) - (side right))) + (side front))) ;;;;;;;;;; w.r.t. other object (defun make-location-right-of-other-object (?object-type ?other-object-type - ?other-object-location) + ?other-object-location + ;; ?environment-name + ) (let ((?other-object-designator (desig:an object (type ?other-object-type) (location ?other-object-location)))) (desig:a location (right-of ?other-object-designator) + (threshold 0.9) (near ?other-object-designator) (for (desig:an object (type ?object-type))) + ;; Don't add the ON property, otherwise the ORIENTATION will mess up + ;; (on (desig:an object + ;; (type counter-top) + ;; (urdf-name dining-area-jokkmokk-table-main) + ;; (part-of ?environment-name))) (orientation support-aligned)))) (defun make-location-right-of-behind-other-object (?object-type ?other-object-type @@ -629,7 +1160,7 @@ (location ?other-object-location)))) (desig:a location (right-of ?other-object-designator) - ;; (behind ?other-object-designator) + (behind ?other-object-designator) (near ?other-object-designator) (for (desig:an object (type ?object-type)))))) @@ -759,7 +1290,8 @@ ((object-type (eql type)) environment human (context (eql :table-setting))) - (make-location-in-sink-left-bottom-drawer environment))) + ;; (make-location-in-sink-left-bottom-drawer environment) + (make-location-in-kitchen-island-left-upper-drawer environment))) '(:cup)) (mapcar (lambda (type) @@ -861,7 +1393,16 @@ environment human (context (eql :table-cleaning))) (make-location-in-sink object-type environment))) - '(:bowl :cup :spoon :plate :mug :cutlery)) + '(:plate :mug :cutlery)) + +(mapcar (lambda (type) + (defmethod man-int:get-object-destination :heuristics 20 + ((object-type (eql type)) + environment human + (context (eql :table-cleaning))) + (make-location-in-dishwasher-drawer object-type environment))) + '(:bowl :cup :spoon)) + (mapcar (lambda (type) (defmethod man-int:get-object-destination :heuristics 20 @@ -875,15 +1416,26 @@ ;;;;;;;;;;;;;;;;;; Predefined poses for placing on dish-washer-drawer ;;;;;;;;;;;;; (man-int:def-object-type-in-other-object-transform :bowl :drawer - :bowl-dish-washer-drawer-front-1 - :attachment-translation `(-0.115 -0.15 0.22) - :attachment-rot-matrix '((1 0 0) - (0 1 0) - (0 0 1))) + :dish-washer-drawer-left + :attachment-translation `(0.05 -0.15 0.2) + :attachment-rot-matrix man-int:*identity-matrix*) (man-int:def-object-type-in-other-object-transform :bowl :drawer - :bowl-dish-washer-drawer-front-2 - :attachment-translation `(-0.115 0.15 0.22) - :attachment-rot-matrix '((1 0 0) - (0 1 0) - (0 0 1))) + :dish-washer-drawer-right + :attachment-translation `(0.03 0.15 0.2) + :attachment-rot-matrix man-int:*identity-matrix*) + +(man-int:def-object-type-in-other-object-transform :cup :drawer + :dish-washer-drawer-left-flipped-around-x + :attachment-translation `(0.06 -0.19 0.22) + :attachment-rot-matrix man-int:*rotation-around-x-180-matrix*) + +(man-int:def-object-type-in-other-object-transform :cup :drawer + :dish-washer-drawer-left-flipped-around-y + :attachment-translation `(0.06 -0.19 0.22) + :attachment-rot-matrix man-int:*rotation-around-y-180-matrix*) + +(man-int:def-object-type-in-other-object-transform :spoon :drawer + :dish-washer-drawer-center + :attachment-translation `(0.04 0.0 0.03) + :attachment-rot-matrix man-int:*identity-matrix*) diff --git a/cram_demos/cram_object_knowledge/src/retail.lisp b/cram_demos/cram_object_knowledge/src/retail.lisp index e0643d7da1..351f7bbcf2 100644 --- a/cram_demos/cram_object_knowledge/src/retail.lisp +++ b/cram_demos/cram_object_knowledge/src/retail.lisp @@ -30,6 +30,29 @@ (in-package :objects) + +(defun make-arm-transform (object-name arm x y z &optional rot-matrix) + (cl-transforms-stamped:make-transform-stamped + (roslisp-utilities:rosify-underscores-lisp-name object-name) + (ecase arm + (:left cram-tf:*robot-left-tool-frame*) + (:right cram-tf:*robot-right-tool-frame*)) + 0.0 + (cl-transforms:make-3d-vector x y z) + (if rot-matrix + (cl-transforms:matrix->quaternion + (make-array '(3 3) :initial-contents rot-matrix)) + (cl-transforms:make-identity-rotation)))) + +(defun make-base-transform (x y z) + (cl-transforms-stamped:make-transform-stamped + cram-tf:*robot-base-frame* + cram-tf:*robot-base-frame* + 0.0 + (cl-transforms:make-3d-vector x y z) + (cl-transforms:make-identity-rotation))) + + (defparameter *default-retail-z-offset* 0.05 "in meters") (defparameter *default-retail-lift-offsets* `(0.0 0.0 ,*default-retail-z-offset*)) @@ -38,14 +61,30 @@ (def-fact-group retail-object-type-hierarchy (man-int:object-type-direct-subtype) (<- (man-int:object-type-direct-subtype :retail-item ?item-type) (member ?item-type (:dish-washer-tabs - :balea-bottle :deodorant :juice-box - :denkmit :dove :heitmann :somat :basket)))) + :retail-bottle :deodorant :juice-box + :denkmit :dove :heitmann :somat :basket))) + (<- (man-int:object-type-direct-subtype :retail-bottle ?item-type) + (member ?item-type (:retail-bottle-round :retail-bottle-flat))) + (<- (man-int:object-type-direct-subtype :retail-bottle-round ?item-type) + (member ?item-type (:heitmann-citronensaeure :domestos-allzweckreiniger))) + (<- (man-int:object-type-direct-subtype :retail-bottle-flat ?item-type) + (member ?item-type (:balea-bottle :denkmit-entkalker :kuehne-essig-essenz)))) + +(def-fact-group attachment-knowledge (man-int:unidirectional-attachment) + (<- (man-int:unidirectional-attachment ?attachment-type) + (member ?attachment-type (:in-basket-front :in-basket-back :in-basket)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmethod man-int:get-action-gripper-opening :heuristics 20 ((object-type (eql :retail-item))) 0.1) +(defmethod man-int:get-action-gripper-opening + :heuristics 20 ((object-type (eql :balea-bottle))) + 0.06) +(defmethod man-int:get-action-gripper-opening + :heuristics 20 ((object-type (eql :dish-washer-tabs))) + 0.06) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -78,32 +117,35 @@ (defparameter *dish-washer-tabs-grasp-x-offset* 0.0 "in meters") (defparameter *dish-washer-tabs-grasp-z-offset* 0.0 "in meters") -(defparameter *dish-washer-tabs-pregrasp-x-offset* 0.3 "in meters") +(defparameter *dish-washer-tabs-top-grasp-z-offset* 0.05 "in meters") +(defparameter *dish-washer-tabs-pregrasp-x-offset* 0.10 "in meters") ; 0.3 (defparameter *dish-washer-tabs-small-lift-z-offset* 0.01 "in meters") (defparameter *dish-washer-tabs-lift-z-top-grasp-offset* 0.10 "in meters") (defparameter *dish-washer-tabs-lift-z-other-grasp-offset* 0.05 "in meters") +(defparameter *dish-washer-tabs-lift-z-basket-offset* 0.10 "in meters") +(defparameter *dish-washer-tabs-2nd-lift-z-basket-offset* 0.31 "in meters") ;; TOP grasp (man-int:def-object-type-to-gripper-transforms :dish-washer-tabs '(:left :right) :top :grasp-translation `(0.0 0.0 - ,*dish-washer-tabs-grasp-z-offset*) + ,*dish-washer-tabs-top-grasp-z-offset*) :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* :pregrasp-offsets `(0.0 0.0 - ,(+ *dish-washer-tabs-grasp-z-offset* + ,(+ *dish-washer-tabs-top-grasp-z-offset* *dish-washer-tabs-lift-z-top-grasp-offset*)) :2nd-pregrasp-offsets `(0.0 0.0 - ,(+ *dish-washer-tabs-grasp-z-offset* + ,(+ *dish-washer-tabs-top-grasp-z-offset* *dish-washer-tabs-small-lift-z-offset*)) :lift-translation `(0.0 0.0 - ,(+ *dish-washer-tabs-grasp-z-offset* + ,(+ *dish-washer-tabs-top-grasp-z-offset* *dish-washer-tabs-small-lift-z-offset*)) :2nd-lift-translation `(0.0 0.0 - ,(+ *dish-washer-tabs-grasp-z-offset* + ,(+ *dish-washer-tabs-top-grasp-z-offset* *dish-washer-tabs-lift-z-top-grasp-offset*))) ;; BACK grasp robot @@ -130,6 +172,101 @@ ,(+ *dish-washer-tabs-grasp-z-offset* *dish-washer-tabs-lift-z-other-grasp-offset*))) +;; BACK grasp basket +;; (man-int:def-object-type-to-gripper-transforms :dish-washer-tabs '(:left :right) :back +;; :location-type :basket +;; :grasp-translation `(,(- *dish-washer-tabs-grasp-x-offset*) +;; 0.0 +;; ,*dish-washer-tabs-grasp-z-offset*) +;; :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation-2* +;; :pregrasp-offsets `(,(- 0.0 +;; *dish-washer-tabs-grasp-x-offset* +;; *dish-washer-tabs-2nd-lift-z-basket-offset*) +;; 0.0 +;; ,*dish-washer-tabs-grasp-z-offset*) +;; :2nd-pregrasp-offsets `(,(- 0.0 +;; *dish-washer-tabs-grasp-x-offset* +;; *dish-washer-tabs-lift-z-basket-offset*) +;; 0.0 +;; ,*dish-washer-tabs-grasp-z-offset*) +;; :lift-translation `(0.0 +;; 0.0 +;; ,(+ *dish-washer-tabs-grasp-z-offset* +;; *dish-washer-tabs-lift-z-basket-offset*)) +;; :2nd-lift-translation `(0.0 +;; 0.0 +;; ,(+ *dish-washer-tabs-grasp-z-offset* +;; *dish-washer-tabs-2nd-lift-z-basket-offset* +;; 0.0))) +;; grasp +(defmethod man-int:get-object-type-to-gripper-transform + ((object-type (eql :dish-washer-tabs)) + object-name + arm + (grasp (eql :back))) + (make-arm-transform + object-name arm + (- *dish-washer-tabs-grasp-x-offset*) + 0.0 + *dish-washer-tabs-grasp-z-offset* + man-int:*-x-across-z-grasp-rotation-2*)) +;; pregrasp +(defmethod man-int:get-object-type-to-gripper-pregrasp-transforms + ((type (eql :dish-washer-tabs)) + object-name + arm + (grasp (eql :back)) + (location (eql :basket)) + grasp-transform) + (list + (make-arm-transform + object-name arm + (- 0.0 + *dish-washer-tabs-grasp-x-offset* + *dish-washer-tabs-2nd-lift-z-basket-offset*) + 0.0 + *dish-washer-tabs-grasp-z-offset* + man-int:*-x-across-z-grasp-rotation-2*) + (make-arm-transform + object-name arm + (- 0.0 + *dish-washer-tabs-grasp-x-offset* + *dish-washer-tabs-lift-z-basket-offset*) + 0.0 + *dish-washer-tabs-grasp-z-offset* + man-int:*-x-across-z-grasp-rotation-2*) + (make-arm-transform + object-name arm + (- 0.0 + *dish-washer-tabs-grasp-x-offset* + *dish-washer-tabs-lift-z-other-grasp-offset*) + 0.0 + *dish-washer-tabs-grasp-z-offset* + man-int:*-x-across-z-grasp-rotation-2*))) +;; postgrasp +(defmethod man-int:get-object-type-wrt-base-frame-lift-transforms + ((type (eql :dish-washer-tabs)) + arm + (grasp (eql :back)) + (location (eql :basket))) + (list + (make-base-transform + 0.0 + 0.0 + (+ *dish-washer-tabs-grasp-z-offset* + *dish-washer-tabs-lift-z-other-grasp-offset*)) + (make-base-transform + 0.0 + 0.0 + (+ *dish-washer-tabs-grasp-z-offset* + *dish-washer-tabs-lift-z-basket-offset*)) + (make-base-transform + 0.0 + 0.0 + (+ *dish-washer-tabs-grasp-z-offset* + *dish-washer-tabs-2nd-lift-z-basket-offset*)))) + + ;; FRONT grasp robot (man-int:def-object-type-to-gripper-transforms :dish-washer-tabs '(:left :right) :front :location-type :robot @@ -152,28 +289,31 @@ 0.0 ,(+ *dish-washer-tabs-grasp-z-offset* *dish-washer-tabs-lift-z-other-grasp-offset*))) +;; FRONT grasp basket +(man-int:def-object-type-to-gripper-transforms :dish-washer-tabs '(:left :right) :front + :location-type :basket + :grasp-translation `(,*dish-washer-tabs-grasp-x-offset* + 0.0 + ,*dish-washer-tabs-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-z-grasp-rotation-2* + :pregrasp-offsets `(,(+ *dish-washer-tabs-pregrasp-x-offset* + *dish-washer-tabs-2nd-lift-z-basket-offset*) + 0.0 + ,*dish-washer-tabs-grasp-z-offset*) + :2nd-pregrasp-offsets `(,(+ *dish-washer-tabs-pregrasp-x-offset* + *dish-washer-tabs-lift-z-basket-offset*) + 0.0 + ,*dish-washer-tabs-grasp-z-offset*) + :lift-translation `(0.0 + 0.0 + ,(+ *dish-washer-tabs-grasp-z-offset* + *dish-washer-tabs-lift-z-basket-offset*)) + :2nd-lift-translation `(0.0 + 0.0 + ,(+ *dish-washer-tabs-grasp-z-offset* + *dish-washer-tabs-2nd-lift-z-basket-offset*))) ;; BACK grasp shelf -;; util -(defun make-arm-transform (object-name arm x y z &optional rot-matrix) - (cl-transforms-stamped:make-transform-stamped - (roslisp-utilities:rosify-underscores-lisp-name object-name) - (ecase arm - (:left cram-tf:*robot-left-tool-frame*) - (:right cram-tf:*robot-right-tool-frame*)) - 0.0 - (cl-transforms:make-3d-vector x y z) - (if rot-matrix - (cl-transforms:matrix->quaternion - (make-array '(3 3) :initial-contents rot-matrix)) - (cl-transforms:make-identity-rotation)))) -(defun make-base-transform (x y z) - (cl-transforms-stamped:make-transform-stamped - cram-tf:*robot-base-frame* - cram-tf:*robot-base-frame* - 0.0 - (cl-transforms:make-3d-vector x y z) - (cl-transforms:make-identity-rotation))) ;; grasp (defmethod man-int:get-object-type-to-gripper-transform ((object-type (eql :dish-washer-tabs)) @@ -310,24 +450,108 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BALEA-BOTTLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defparameter *balea-bottle-grasp-z-offset* 0.0 "in meters") -(defparameter *balea-bottle-pregrasp-x-offset* 0.2 "in meters") +(defparameter *balea-bottle-top-grasp-z-offset* 0.05 "in meters") +(defparameter *balea-bottle-pregrasp-x-offset* 0.10 "in meters") ;; TOP grasp -(man-int:def-object-type-to-gripper-transforms :balea-bottle '(:left :right) :top +;; (man-int:def-object-type-to-gripper-transforms +;; '(:balea-bottle +;; :denkmit-entkalker +;; :heitmann-citronensaeure +;; :kuehne-essig-essenz +;; :domestos-allzweckreiniger) +;; '(:left :right) :top +;; :grasp-translation `(0.0 +;; 0.0 +;; ,*balea-bottle-top-grasp-z-offset*) +;; :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* +;; :pregrasp-offsets *default-retail-lift-offsets* +;; :2nd-pregrasp-offsets *default-retail-lift-offsets* +;; :lift-translation *default-retail-lift-offsets* +;; :2nd-lift-translation *default-retail-lift-offsets*) + +;; BACK grasp +(man-int:def-object-type-to-gripper-transforms + '(:balea-bottle + :denkmit-entkalker + :heitmann-citronensaeure + :kuehne-essig-essenz + :domestos-allzweckreiniger) + '(:left :right) :back :grasp-translation `(0.0 0.0 ,*balea-bottle-grasp-z-offset*) - :grasp-rot-matrix man-int:*z-across-x-grasp-rotation* - :pregrasp-offsets *default-retail-lift-offsets* - :2nd-pregrasp-offsets *default-retail-lift-offsets* + :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation-2* + :pregrasp-offsets `(,(- *balea-bottle-pregrasp-x-offset*) + 0.0 + ,*default-retail-z-offset*) + :2nd-pregrasp-offsets `(,(- *dish-washer-tabs-pregrasp-x-offset*) + 0.0 + ,*balea-bottle-grasp-z-offset*) :lift-translation *default-retail-lift-offsets* :2nd-lift-translation *default-retail-lift-offsets*) -;; BACK grasp -(man-int:def-object-type-to-gripper-transforms :balea-bottle '(:left :right) :back +;; FRONT grasp +(man-int:def-object-type-to-gripper-transforms + '(:balea-bottle + :denkmit-entkalker + :heitmann-citronensaeure + :kuehne-essig-essenz + :domestos-allzweckreiniger) + '(:left :right) :front + :grasp-translation `(0.0 + 0.0 + ,*balea-bottle-grasp-z-offset*) + :grasp-rot-matrix man-int:*x-across-z-grasp-rotation-2* + :pregrasp-offsets `(,*balea-bottle-pregrasp-x-offset* + 0.0 + ,*default-retail-z-offset*) + :2nd-pregrasp-offsets `(,*balea-bottle-pregrasp-x-offset* + 0.0 + ,*balea-bottle-grasp-z-offset*) + :lift-translation *default-retail-lift-offsets* + :2nd-lift-translation *default-retail-lift-offsets*) + +;; LEFT-SIDE grasp +(man-int:def-object-type-to-gripper-transforms + '(:heitmann-citronensaeure :domestos-allzweckreiniger) '(:left :right) :left-side + :grasp-translation `(0.0 + 0.0 + ,*balea-bottle-grasp-z-offset*) + :grasp-rot-matrix man-int:*y-across-z-grasp-rotation* + :pregrasp-offsets `(0.0 + ,*balea-bottle-pregrasp-x-offset* + ,*default-retail-z-offset*) + :2nd-pregrasp-offsets `(0.0 + ,*balea-bottle-pregrasp-x-offset* + ,*balea-bottle-grasp-z-offset*) + :lift-translation *default-retail-lift-offsets* + :2nd-lift-translation *default-retail-lift-offsets*) + +;; RIGHT-SIDE grasp +(man-int:def-object-type-to-gripper-transforms + '(:heitmann-citronensaeure :domestos-allzweckreiniger) '(:left :right) :right-side :grasp-translation `(0.0 0.0 ,*balea-bottle-grasp-z-offset*) + :grasp-rot-matrix man-int:*-y-across-z-grasp-rotation* + :pregrasp-offsets `(0.0 + ,(- *balea-bottle-pregrasp-x-offset*) + ,*default-retail-z-offset*) + :2nd-pregrasp-offsets `(0.0 + ,(- *balea-bottle-pregrasp-x-offset*) + ,*balea-bottle-grasp-z-offset*) + :lift-translation *default-retail-lift-offsets* + :2nd-lift-translation *default-retail-lift-offsets*) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DOMESTOS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defparameter *domestos-allzweckreiniger-grasp-z-offset* 0.035 "in meters") + +;; BACK grasp +(man-int:def-object-type-to-gripper-transforms :domestos-allzweckreiniger '(:left :right) :back + :grasp-translation `(0.0 0.0 ,*domestos-allzweckreiniger-grasp-z-offset*) :grasp-rot-matrix man-int:*-x-across-z-grasp-rotation-2* :pregrasp-offsets `(,(- *balea-bottle-pregrasp-x-offset*) 0.0 @@ -339,10 +563,8 @@ :2nd-lift-translation *default-retail-lift-offsets*) ;; FRONT grasp -(man-int:def-object-type-to-gripper-transforms :balea-bottle '(:left :right) :front - :grasp-translation `(0.0 - 0.0 - ,*balea-bottle-grasp-z-offset*) +(man-int:def-object-type-to-gripper-transforms :domestos-allzweckreiniger '(:left :right) :front + :grasp-translation `(0.0 0.0 ,*domestos-allzweckreiniger-grasp-z-offset*) :grasp-rot-matrix man-int:*x-across-z-grasp-rotation-2* :pregrasp-offsets `(,*balea-bottle-pregrasp-x-offset* 0.0 @@ -353,6 +575,35 @@ :lift-translation *default-retail-lift-offsets* :2nd-lift-translation *default-retail-lift-offsets*) +;; LEFT-SIDE grasp +(man-int:def-object-type-to-gripper-transforms + '(:heitmann-citronensaeure :domestos-allzweckreiniger) '(:left :right) :left-side + :grasp-translation `(0.0 0.0 ,*domestos-allzweckreiniger-grasp-z-offset*) + :grasp-rot-matrix man-int:*y-across-z-grasp-rotation* + :pregrasp-offsets `(0.0 + ,*balea-bottle-pregrasp-x-offset* + ,*default-retail-z-offset*) + :2nd-pregrasp-offsets `(0.0 + ,*balea-bottle-pregrasp-x-offset* + ,*balea-bottle-grasp-z-offset*) + :lift-translation *default-retail-lift-offsets* + :2nd-lift-translation *default-retail-lift-offsets*) + +;; RIGHT-SIDE grasp +(man-int:def-object-type-to-gripper-transforms + '(:heitmann-citronensaeure :domestos-allzweckreiniger) '(:left :right) :right-side + :grasp-translation `(0.0 0.0 ,*domestos-allzweckreiniger-grasp-z-offset*) + :grasp-rot-matrix man-int:*-y-across-z-grasp-rotation* + :pregrasp-offsets `(0.0 + ,(- *balea-bottle-pregrasp-x-offset*) + ,*default-retail-z-offset*) + :2nd-pregrasp-offsets `(0.0 + ,(- *balea-bottle-pregrasp-x-offset*) + ,*balea-bottle-grasp-z-offset*) + :lift-translation *default-retail-lift-offsets* + :2nd-lift-translation *default-retail-lift-offsets*) + + ;;;;;;;;;;;;;;; DENKMIT, DOVE, HEITMANN and SOMAT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -422,26 +673,37 @@ (man-int:def-object-type-in-other-object-transform :dish-washer-tabs :environment :dish-washer-tabs-shelf-1-front - :attachment-translation `(0.39968 -0.26038335 0.1202) + :attachment-translation `(0.39968 -0.26038335 0.10) ; 0.1202 :attachment-rot-matrix man-int:*rotation-around-z-90-matrix*) (man-int:def-object-type-in-other-object-transform :dish-washer-tabs :environment :dish-washer-tabs-shelf-1-back - :attachment-translation `(0.39968 -0.26038335 0.1202) + :attachment-translation `(0.39968 -0.26038335 0.10) ; 0.1202 :attachment-rot-matrix man-int:*rotation-around-z+90-matrix*) (man-int:def-object-type-in-other-object-transform :dish-washer-tabs :basket :in-basket-front - :attachment-translation `(0.15 0.15 0.05;; -0.02 - ) + :attachment-translation `(0.15 0.15 -0.02) :attachment-rot-matrix '(( 0 0 1) ( 0 1 0) (-1 0 0))) (man-int:def-object-type-in-other-object-transform :dish-washer-tabs :basket :in-basket-back - :attachment-translation `(0.15 0.15 0.05;; -0.02 - ) + :attachment-translation `(0.15 0.15 -0.02) + :attachment-rot-matrix '(( 0 0 -1) + ( 0 -1 0) + (-1 0 0))) +(man-int:def-object-type-in-other-object-transform :dish-washer-tabs :basket + :in-basket-other-front + :attachment-translation `(0.15 -0.15 -0.02) + :attachment-rot-matrix '(( 0 0 1) + ( 0 1 0) + (-1 0 0))) + +(man-int:def-object-type-in-other-object-transform :dish-washer-tabs :basket + :in-basket-other-back + :attachment-translation `(0.15 -0.15 -0.02) :attachment-rot-matrix '(( 0 0 -1) ( 0 -1 0) (-1 0 0))) @@ -477,7 +739,50 @@ (0 1 0) (0 0 1))) + + + + +(man-int:def-object-type-in-other-object-transform :dish-washer-tabs :robot + :kukabot-tray-front + :attachment-translation `(0.1 0.1 0.75) + :attachment-rot-matrix '((0 0 1) + (0 -1 0) + (1 0 0))) + +(man-int:def-object-type-in-other-object-transform :dish-washer-tabs :robot + :kukabot-tray-back + :attachment-translation `(0.1 0.1 0.75) + :attachment-rot-matrix '(( 0 0 1) + ( 0 1 0) + (-1 0 0))) + +(man-int:def-object-type-in-other-object-transform :dish-washer-tabs :environment + :dish-washer-tabs-real-shelf-1-front + :attachment-translation `(0.39968 -0.26038335 0.1902) + :attachment-rot-matrix man-int:*rotation-around-z-90-matrix*) + +(man-int:def-object-type-in-other-object-transform :dish-washer-tabs :environment + :dish-washer-tabs-real-shelf-1-back + :attachment-translation `(0.39968 -0.26038335 0.1902) + :attachment-rot-matrix man-int:*rotation-around-z+90-matrix*) + +(man-int:def-object-type-in-other-object-transform :balea-bottle :environment + :balea-bottle-real-shelf-1-front + :attachment-translation `(;0.33 -0.27 0.175 + -0.05 -0.27 0.175) + :attachment-rot-matrix man-int:*rotation-around-z-90-matrix*) + +(man-int:def-object-type-in-other-object-transform :balea-bottle :environment + :balea-bottle-real-shelf-1-back + :attachment-translation `(;0.33 -0.27 0.175 + -0.05 -0.27 0.175) + :attachment-rot-matrix man-int:*rotation-around-z+90-matrix*) + + + (defmethod man-int:get-z-offset-for-placing-with-dropping (object (other-object (eql :basket)) attachment) - 0.15) + 0.0 ;; 0.15 ; <- we have to pick it back up, so no point in dropping stuff + ) diff --git a/cram_demos/cram_pr2_pick_place_demo/launch/sandbox.launch b/cram_demos/cram_pr2_pick_place_demo/launch/sandbox.launch index e6bf6e5a39..5e1b7f44cb 100644 --- a/cram_demos/cram_pr2_pick_place_demo/launch/sandbox.launch +++ b/cram_demos/cram_pr2_pick_place_demo/launch/sandbox.launch @@ -7,9 +7,9 @@ - + + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> @@ -39,7 +39,7 @@ diff --git a/cram_demos/cram_pr2_pick_place_demo/resource/cup.obj b/cram_demos/cram_pr2_pick_place_demo/resource/cup.obj index 6f38a826b1..5a3e737c4a 100644 --- a/cram_demos/cram_pr2_pick_place_demo/resource/cup.obj +++ b/cram_demos/cram_pr2_pick_place_demo/resource/cup.obj @@ -1,4111 +1,4142 @@ # Blender v2.83.4 OBJ File: '' # www.blender.org -mtllib cup_33.mtl -o Cup_hull_1 -v 0.014889 0.020425 -0.050166 -v -0.014857 -0.020390 -0.048198 -v -0.015384 -0.020122 -0.048198 -v 0.014889 0.020425 -0.048198 -v 0.019895 -0.015647 -0.050166 -v -0.020386 0.014891 -0.050166 -v -0.015648 0.019893 -0.048198 -v 0.020427 -0.014856 -0.048198 -v -0.015384 -0.020122 -0.050166 -v -0.020390 -0.014856 -0.048198 -v 0.020423 0.014891 -0.050166 -v 0.014893 -0.020390 -0.048198 -v -0.014857 0.020425 -0.050166 -v 0.020423 0.014891 -0.048198 -v 0.014893 -0.020390 -0.050166 -v -0.020390 -0.014856 -0.050166 -v -0.020386 0.014891 -0.048198 -v 0.020427 -0.014856 -0.050166 -v -0.014857 0.020425 -0.048198 -v -0.014857 -0.020390 -0.050166 -v 0.018577 0.017260 -0.048198 -v -0.018808 0.016997 -0.050166 -v 0.016999 -0.018807 -0.048198 -v -0.019072 -0.016702 -0.048198 -v 0.017258 0.018579 -0.050166 -v -0.016702 -0.019071 -0.050166 -v -0.018808 0.016997 -0.048198 -v 0.016999 -0.018807 -0.050166 -v -0.016966 0.018839 -0.050166 -v 0.018840 -0.016966 -0.048198 -v -0.019072 -0.016702 -0.050166 -vt 0.090348 0.032302 -vt 0.032302 0.090348 -vt 0.032302 0.090348 +mtllib cup_35.mtl +o cup_hull_1 +v 0.025088 0.031845 -0.075210 +v -0.023772 -0.032617 -0.072262 +v -0.024616 -0.032189 -0.072262 +v 0.023829 0.032689 -0.072262 +v -0.032198 0.024679 -0.075210 +v 0.024672 -0.032189 -0.075210 +v 0.032683 -0.023763 -0.072262 +v -0.025032 0.031845 -0.072262 +v -0.026726 -0.030507 -0.075210 +v -0.032626 -0.023763 -0.072262 +v 0.032676 0.023835 -0.075210 +v -0.023772 0.032689 -0.075210 +v 0.032676 0.023835 -0.072262 +v 0.023829 -0.032617 -0.072262 +v 0.032683 -0.023763 -0.075210 +v -0.032626 0.023835 -0.072262 +v -0.032626 -0.023763 -0.075210 +v -0.023772 -0.032617 -0.075210 +v -0.023772 0.032689 -0.072262 +v 0.023829 0.032689 -0.075210 +v 0.023829 -0.032617 -0.075210 +v -0.032626 0.023835 -0.075210 +v 0.030145 -0.027132 -0.072262 +v 0.029301 0.028048 -0.072262 +v -0.030517 -0.026704 -0.072262 +v -0.030088 0.027211 -0.075210 +v -0.030088 0.027211 -0.072262 +v 0.030145 -0.027132 -0.075210 +v 0.029301 0.028048 -0.075210 +v 0.027198 -0.030085 -0.072262 +v -0.027141 0.030158 -0.075210 +v -0.030517 -0.026704 -0.075210 +vt 0.032302 0.090544 +vt 0.000000 0.135572 +vt 0.032302 0.090544 vt 0.122651 0.006558 vt 0.135572 0.000000 -vt 0.864330 1.000000 -vt 0.864330 1.000000 -vt 0.986981 0.116190 -vt 0.000098 0.864428 -vt 0.116190 0.986981 +vt 0.864428 1.000000 +vt 0.006558 0.877349 +vt 0.883712 0.987079 +vt 0.877349 0.006558 vt 1.000000 0.135572 -vt 0.122651 0.006558 +vt 0.116288 0.987079 +vt 0.090348 0.032302 vt 0.000000 0.135572 vt 0.999902 0.864428 -vt 0.864428 0.000000 vt 0.135572 1.000000 vt 0.999902 0.864428 vt 0.864428 0.000000 -vt 0.000000 0.135572 -vt 0.000098 0.864428 vt 1.000000 0.135572 -vt 0.135572 1.000000 +vt 0.000000 0.864428 vt 0.135572 0.000000 -vt 0.954679 0.922475 -vt 0.038763 0.916014 -vt 0.916014 0.038763 -vt 0.922377 0.954777 -vt 0.038763 0.916014 +vt 0.135572 1.000000 +vt 0.864428 1.000000 +vt 0.864428 0.000000 +vt 0.000000 0.864428 +vt 0.961139 0.083986 +vt 0.948218 0.928935 +vt 0.038861 0.916112 +vt 0.038861 0.916112 +vt 0.961139 0.083986 +vt 0.948218 0.928935 vt 0.916014 0.038763 -vt 0.083888 0.961139 -vt 0.961139 0.083888 -vn -0.7071 -0.7071 0.0000 -vn 0.0000 0.0000 1.0000 +vt 0.083986 0.961237 +vn -0.8125 -0.5829 0.0000 +vn -0.0000 0.0000 1.0000 vn -0.0000 0.0000 -1.0000 -vn -0.4526 -0.8917 0.0000 -vn 0.0000 1.0000 0.0000 vn 1.0000 0.0001 0.0000 +vn -1.0000 0.0000 0.0000 +vn -0.4526 -0.8917 0.0000 +vn -0.5805 -0.8128 -0.0481 vn 0.0000 -1.0000 0.0000 -vn -1.0000 0.0001 0.0000 -vn 0.8301 -0.5576 0.0000 -vn -0.5576 0.8301 0.0000 -vn 0.7888 0.6146 0.0000 -vn -0.8002 0.5998 0.0000 -vn 0.6007 -0.7995 0.0000 -vn -0.8137 -0.5813 0.0000 -vn 0.6146 0.7889 0.0000 -vn 0.6495 0.7570 0.0720 -vn 0.7569 0.6495 -0.0720 -vn -0.6232 -0.7820 0.0000 -vn -0.6786 -0.7317 0.0640 -vn -0.6007 0.7990 -0.0258 -vn -0.6745 0.7360 0.0575 +vn 0.0000 1.0000 0.0000 +vn -0.5566 0.8308 0.0000 +vn 0.5566 0.8308 0.0000 +vn 0.4526 -0.8917 0.0000 +vn -0.8917 0.4526 0.0000 +vn 0.7987 -0.6017 0.0000 +vn 0.6457 0.7614 0.0579 +vn 0.7804 0.6253 0.0000 +vn -0.6792 -0.7307 0.0693 +vn -0.7980 0.6000 0.0558 +vn -0.7682 0.6402 0.0000 +vn 0.6695 0.7428 0.0000 +vn 0.5998 -0.7982 0.0557 +vn 0.6775 -0.7333 -0.0572 +vn 0.7079 -0.7064 0.0000 +vn -0.6005 0.7992 -0.0278 +vn -0.6744 0.7358 0.0614 vn -0.7071 0.7071 0.0000 -vn 0.7990 -0.6008 0.0258 -vn 0.7360 -0.6746 -0.0575 -vn 0.7071 -0.7071 0.0000 +vn -0.7083 -0.7059 0.0000 usemtl None s off -f 26/1/1 24/2/1 31/3/1 +f 25/1/1 17/2/1 32/3/1 f 3/4/2 2/5/2 4/6/2 -f 1/7/3 5/8/3 6/9/3 -f 3/4/2 4/6/2 7/10/2 -f 4/6/2 2/5/2 8/11/2 -f 2/5/4 3/4/4 9/12/4 -f 6/9/3 5/8/3 9/12/3 -f 3/4/2 7/10/2 10/13/2 -f 5/8/3 1/7/3 11/14/3 -f 8/11/2 2/5/2 12/15/2 -f 4/6/5 1/7/5 13/16/5 -f 1/7/3 6/9/3 13/16/3 -f 4/6/2 8/11/2 14/17/2 -f 8/11/6 11/14/6 14/17/6 -f 9/12/3 5/8/3 15/18/3 -f 12/15/7 2/5/7 15/18/7 -f 6/9/3 9/12/3 16/19/3 -f 10/13/8 6/9/8 16/19/8 -f 6/9/8 10/13/8 17/20/8 -f 10/13/2 7/10/2 17/20/2 -f 8/11/9 5/8/9 18/21/9 -f 5/8/3 11/14/3 18/21/3 -f 11/14/6 8/11/6 18/21/6 -f 7/10/2 4/6/2 19/22/2 -f 4/6/5 13/16/5 19/22/5 -f 13/16/10 7/10/10 19/22/10 -f 2/5/4 9/12/4 20/23/4 -f 15/18/7 2/5/7 20/23/7 -f 9/12/3 15/18/3 20/23/3 -f 4/6/2 14/17/2 21/24/2 -f 14/17/11 11/14/11 21/24/11 -f 13/16/3 6/9/3 22/25/3 -f 6/9/12 17/20/12 22/25/12 -f 8/11/2 12/15/2 23/26/2 -f 12/15/13 15/18/13 23/26/13 -f 3/4/2 10/13/2 24/2/2 -f 10/13/14 16/19/14 24/2/14 -f 1/7/15 4/6/15 25/27/15 -f 11/14/3 1/7/3 25/27/3 -f 4/6/16 21/24/16 25/27/16 -f 21/24/17 11/14/17 25/27/17 -f 9/12/18 3/4/18 26/1/18 -f 16/19/3 9/12/3 26/1/3 -f 3/4/19 24/2/19 26/1/19 -f 17/20/2 7/10/2 27/28/2 -f 22/25/12 17/20/12 27/28/12 -f 15/18/3 5/8/3 28/29/3 -f 23/26/13 15/18/13 28/29/13 -f 7/10/20 13/16/20 29/30/20 -f 13/16/3 22/25/3 29/30/3 -f 27/28/21 7/10/21 29/30/21 -f 22/25/22 27/28/22 29/30/22 -f 5/8/23 8/11/23 30/31/23 -f 8/11/2 23/26/2 30/31/2 -f 28/29/24 5/8/24 30/31/24 -f 23/26/25 28/29/25 30/31/25 -f 24/2/14 16/19/14 31/3/14 -f 16/19/3 26/1/3 31/3/3 -o Cup_hull_2 -v 0.020427 0.005943 -0.048198 -v 0.013054 0.012263 0.015036 -v 0.013317 0.011736 0.013909 -v 0.020427 0.012526 0.015036 -v 0.013054 0.012526 -0.048198 -v 0.017003 0.005943 0.015036 -v 0.020427 0.012526 -0.048198 -v 0.016740 0.006206 -0.048198 -v 0.020427 0.005943 0.015036 -v 0.013054 0.012526 0.015036 -v 0.013317 0.011736 -0.048198 -v 0.017003 0.005943 -0.048198 -v 0.016740 0.006206 0.015036 -v 0.013054 0.012263 -0.048198 -vt 1.000000 0.000000 -vt 1.000000 0.035732 +f 5/7/3 1/8/3 6/9/3 +f 4/6/2 2/5/2 7/10/2 +f 3/4/2 4/6/2 8/11/2 +f 5/7/3 6/9/3 9/12/3 +f 3/4/2 8/11/2 10/13/2 +f 6/9/3 1/8/3 11/14/3 +f 1/8/3 5/7/3 12/15/3 +f 4/6/2 7/10/2 13/16/2 +f 7/10/4 11/14/4 13/16/4 +f 7/10/2 2/5/2 14/17/2 +f 6/9/3 11/14/3 15/18/3 +f 11/14/4 7/10/4 15/18/4 +f 10/13/2 8/11/2 16/19/2 +f 10/13/5 16/19/5 17/2/5 +f 5/7/3 9/12/3 17/2/3 +f 2/5/6 3/4/6 18/20/6 +f 3/4/7 9/12/7 18/20/7 +f 9/12/3 6/9/3 18/20/3 +f 14/17/8 2/5/8 18/20/8 +f 8/11/2 4/6/2 19/21/2 +f 4/6/9 12/15/9 19/21/9 +f 12/15/10 8/11/10 19/21/10 +f 4/6/11 1/8/11 20/22/11 +f 1/8/3 12/15/3 20/22/3 +f 12/15/9 4/6/9 20/22/9 +f 6/9/12 14/17/12 21/23/12 +f 18/20/3 6/9/3 21/23/3 +f 14/17/8 18/20/8 21/23/8 +f 16/19/13 5/7/13 22/24/13 +f 17/2/5 16/19/5 22/24/5 +f 5/7/3 17/2/3 22/24/3 +f 7/10/2 14/17/2 23/25/2 +f 15/18/14 7/10/14 23/25/14 +f 1/8/15 4/6/15 24/26/15 +f 4/6/2 13/16/2 24/26/2 +f 13/16/16 11/14/16 24/26/16 +f 9/12/17 3/4/17 25/1/17 +f 3/4/2 10/13/2 25/1/2 +f 10/13/1 17/2/1 25/1/1 +f 12/15/3 5/7/3 26/27/3 +f 5/7/18 16/19/18 27/28/18 +f 16/19/2 8/11/2 27/28/2 +f 26/27/19 5/7/19 27/28/19 +f 6/9/3 15/18/3 28/29/3 +f 15/18/14 23/25/14 28/29/14 +f 11/14/3 1/8/3 29/30/3 +f 1/8/20 24/26/20 29/30/20 +f 24/26/16 11/14/16 29/30/16 +f 14/17/21 6/9/21 30/31/21 +f 23/25/2 14/17/2 30/31/2 +f 6/9/22 28/29/22 30/31/22 +f 28/29/23 23/25/23 30/31/23 +f 8/11/24 12/15/24 31/32/24 +f 12/15/3 26/27/3 31/32/3 +f 27/28/25 8/11/25 31/32/25 +f 26/27/26 27/28/26 31/32/26 +f 17/2/3 9/12/3 32/3/3 +f 9/12/27 25/1/27 32/3/27 +o cup_hull_2 +v 0.020042 0.020472 0.022524 +v 0.025940 0.020894 -0.072261 +v 0.025940 0.012889 -0.072261 +v 0.020042 0.020894 -0.072261 +v 0.025940 0.020894 0.022524 +v 0.025520 0.012889 0.022524 +v 0.025520 0.012889 -0.072261 +v 0.025940 0.012889 0.022524 +v 0.020042 0.020894 0.022524 +v 0.020042 0.020472 -0.072261 vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 0.000000 0.535683 +vt 0.000000 0.947240 +vt 1.000000 0.947240 vt 1.000000 1.000000 +vt 1.000000 0.000000 vt 1.000000 1.000000 -vt 1.000000 0.499951 vt 0.000000 1.000000 vt 0.000000 0.000000 -vt 0.017815 0.035732 -vt 1.000000 0.535683 -vt 0.000000 0.499951 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vn -0.8107 -0.5855 0.0000 vn 0.0000 0.0000 -1.0000 -vn -0.0000 0.0000 1.0000 vn 1.0000 0.0000 0.0000 vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn 0.0000 -1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.8945 -0.4470 0.0000 -vn -0.8503 -0.5263 0.0000 -vn -0.7073 -0.7069 0.0000 -vn -0.8534 -0.5194 0.0435 usemtl None s off -f 36/32/26 42/33/26 45/34/26 -f 35/35/27 33/36/27 37/37/27 -f 35/35/28 32/38/28 38/39/28 -f 32/38/26 36/32/26 38/39/26 -f 36/32/29 35/35/29 38/39/29 -f 36/32/26 32/38/26 39/40/26 -f 32/38/28 35/35/28 40/41/28 -f 35/35/27 37/37/27 40/41/27 -f 37/37/30 32/38/30 40/41/30 -f 33/36/27 35/35/27 41/42/27 -f 35/35/29 36/32/29 41/42/29 -f 36/32/31 33/36/31 41/42/31 -f 34/43/32 33/36/32 42/33/32 -f 36/32/26 39/40/26 42/33/26 -f 39/40/33 34/43/33 42/33/33 -f 32/38/30 37/37/30 43/44/30 -f 39/40/26 32/38/26 43/44/26 -f 37/37/34 39/40/34 43/44/34 -f 33/36/35 34/43/35 44/45/35 -f 37/37/27 33/36/27 44/45/27 -f 34/43/33 39/40/33 44/45/33 -f 39/40/34 37/37/34 44/45/34 -f 33/36/31 36/32/31 45/34/31 -f 42/33/32 33/36/32 45/34/32 -o Cup_hull_3 -v -0.012229 0.013316 -0.048198 -v -0.020392 0.007259 0.015036 -v -0.016442 0.007259 0.015036 -v -0.020392 0.013316 0.015036 -v -0.020392 0.007259 -0.048198 -v -0.020392 0.013316 -0.048198 -v -0.012229 0.013316 0.015036 -v -0.016442 0.007259 -0.048198 -v -0.012229 0.013053 0.015036 -v -0.012229 0.013053 -0.048198 -v -0.016179 0.007523 -0.048198 -v -0.016179 0.007523 0.015036 -vt 1.000000 0.516104 +f 39/33/28 33/34/28 42/35/28 +f 34/36/29 35/37/29 36/38/29 +f 35/37/30 34/36/30 37/39/30 +f 34/36/31 36/38/31 37/39/31 +f 37/39/32 33/34/32 38/40/32 +f 36/38/29 35/37/29 39/33/29 +f 35/37/33 38/40/33 39/33/33 +f 38/40/28 33/34/28 39/33/28 +f 35/37/30 37/39/30 40/41/30 +f 38/40/33 35/37/33 40/41/33 +f 37/39/32 38/40/32 40/41/32 +f 36/38/34 33/34/34 41/42/34 +f 33/34/32 37/39/32 41/42/32 +f 37/39/31 36/38/31 41/42/31 +f 33/34/34 36/38/34 42/35/34 +f 36/38/29 39/33/29 42/35/29 +o cup_hull_3 +v -0.025885 0.012047 0.022524 +v -0.024621 0.021316 -0.072261 +v -0.019565 0.021315 -0.072261 +v -0.024199 0.021316 0.022524 +v -0.026306 0.012047 -0.072261 +v -0.019565 0.020893 0.022524 +v -0.026306 0.021316 0.022524 +v -0.026306 0.021316 -0.072261 +v -0.025885 0.012047 -0.072261 +v -0.026306 0.012047 0.022524 +v -0.019565 0.020893 -0.072261 +v -0.019565 0.021315 0.022524 vt 0.000000 1.000000 -vt 0.000000 0.516104 -vt 0.000000 0.000000 -vt 0.000000 0.483896 -vt 0.000000 0.000000 -vt 1.000000 0.000000 +vt 0.000000 0.954385 +vt 0.000000 0.999902 +vt 1.000000 0.999902 vt 1.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 1.000000 0.483896 -vt 1.000000 1.000000 -vn 0.8137 -0.5813 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn 0.0001 1.0000 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn 0.7084 -0.7059 0.0000 -vn 0.0001 0.0000 -1.0000 -usemtl None -s off -f 56/46/36 54/47/36 57/48/36 -f 47/49/37 48/50/37 49/51/37 -f 48/50/38 47/49/38 50/52/38 -f 47/49/39 49/51/39 50/52/39 -f 49/51/40 46/53/40 51/54/40 -f 46/53/41 50/52/41 51/54/41 -f 50/52/39 49/51/39 51/54/39 -f 49/51/37 48/50/37 52/55/37 -f 46/53/40 49/51/40 52/55/40 -f 50/52/41 46/53/41 53/56/41 -f 48/50/38 50/52/38 53/56/38 -f 46/53/42 52/55/42 54/47/42 -f 52/55/37 48/50/37 54/47/37 -f 53/56/41 46/53/41 55/57/41 -f 46/53/42 54/47/42 55/57/42 -f 48/50/43 53/56/43 56/46/43 -f 53/56/44 55/57/44 56/46/44 -f 55/57/36 54/47/36 56/46/36 -f 54/47/37 48/50/37 57/48/37 -f 48/50/43 56/46/43 57/48/43 -o Cup_hull_4 -v 0.017003 0.005679 0.015036 -v 0.020427 0.005943 -0.048198 -v 0.020427 -0.000377 -0.048198 -v 0.017003 0.005943 -0.048198 -v 0.020427 0.005943 0.015036 -v 0.018057 -0.000377 0.015036 -v 0.018057 -0.000377 -0.048198 -v 0.020427 -0.000377 0.015036 -v 0.017003 0.005943 0.015036 -v 0.017003 0.005415 -0.048198 -v 0.017003 0.005415 0.014751 -vt 1.000000 0.916504 vt 0.000000 0.000000 -vt 0.004503 0.916504 -vt 1.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 vt 0.000000 1.000000 -vt 0.000000 0.958203 +vt 1.000000 1.000000 vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.000000 1.000000 -vn -0.9839 -0.1790 0.0000 +vt 1.000000 0.954385 +vn 0.0000 0.0000 1.0000 +vn 0.0002 1.0000 -0.0000 vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 vn 0.0000 1.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.0001 0.0000 -1.0000 -vn -0.9730 -0.1693 0.1567 +vn 0.0000 -1.0000 0.0000 +vn 0.8137 -0.5813 0.0000 +vn 1.0000 0.0000 0.0000 usemtl None s off -f 67/58/45 63/59/45 68/60/45 -f 59/61/46 60/62/46 61/63/46 -f 60/62/47 59/61/47 62/64/47 -f 59/61/48 61/63/48 62/64/48 -f 62/64/49 58/65/49 63/59/49 -f 61/63/46 60/62/46 64/66/46 -f 60/62/50 63/59/50 64/66/50 -f 60/62/47 62/64/47 65/67/47 -f 63/59/50 60/62/50 65/67/50 -f 62/64/49 63/59/49 65/67/49 -f 61/63/51 58/65/51 66/68/51 -f 58/65/49 62/64/49 66/68/49 -f 62/64/48 61/63/48 66/68/48 -f 58/65/51 61/63/51 67/58/51 -f 61/63/52 64/66/52 67/58/52 -f 64/66/45 63/59/45 67/58/45 -f 63/59/53 58/65/53 68/60/53 -f 58/65/51 67/58/51 68/60/51 -o Cup_hull_5 -v -0.002748 -0.025132 0.032181 -v -0.013281 -0.021446 0.050166 -v -0.013017 -0.021708 0.050166 -v 0.000413 -0.024341 0.050166 -v -0.012753 -0.018548 0.032181 -v 0.000413 -0.022761 0.032181 -v -0.013017 -0.021708 0.032181 -v -0.006961 -0.024342 0.050166 -v -0.012753 -0.020392 0.050166 -v 0.000413 -0.025132 0.050166 -v -0.009330 -0.023552 0.032181 -v 0.000413 -0.025132 0.032181 -v 0.000413 -0.024078 0.048477 -v -0.002485 -0.025132 0.050166 -v -0.013281 -0.018548 0.033306 -v -0.005909 -0.024605 0.032181 -v -0.009856 -0.023288 0.050166 -v 0.000413 -0.022761 0.033306 -v -0.013281 -0.021446 0.032181 -v -0.004591 -0.024868 0.050166 -v -0.013017 -0.018548 0.033306 -v -0.013281 -0.020392 0.050166 -v -0.006961 -0.024342 0.034992 -v -0.004591 -0.024868 0.032181 -v -0.008540 -0.023814 0.050166 -v -0.012753 -0.018548 0.032462 -vt 1.000000 0.038567 -vt 0.937451 0.019284 -vt 0.984338 0.038567 -vt 0.000000 0.000000 -vt 0.000000 0.019284 +f 46/43/35 48/44/35 54/45/35 +f 45/46/36 44/47/36 46/43/36 +f 44/47/37 45/46/37 47/48/37 +f 46/43/35 43/49/35 48/44/35 +f 46/43/38 44/47/38 49/50/38 +f 43/49/35 46/43/35 49/50/35 +f 47/48/39 49/50/39 50/51/39 +f 44/47/37 47/48/37 50/51/37 +f 49/50/38 44/47/38 50/51/38 +f 43/49/40 47/48/40 51/52/40 +f 47/48/37 45/46/37 51/52/37 +f 48/44/41 43/49/41 51/52/41 +f 47/48/40 43/49/40 52/53/40 +f 43/49/35 49/50/35 52/53/35 +f 49/50/39 47/48/39 52/53/39 +f 45/46/42 48/44/42 53/54/42 +f 51/52/37 45/46/37 53/54/37 +f 48/44/41 51/52/41 53/54/41 +f 45/46/36 46/43/36 54/45/36 +f 48/44/42 45/46/42 54/45/42 +o cup_hull_4 +v 0.025941 0.012045 0.022524 +v 0.032261 0.020894 -0.072261 +v 0.027627 0.020894 -0.072261 +v 0.028891 0.000670 -0.072261 +v 0.032683 0.000670 0.022524 +v 0.032683 0.020894 0.022524 +v 0.032683 0.000670 -0.072252 +v 0.025941 0.020892 0.022524 +v 0.025941 0.012045 -0.072261 +v 0.028891 0.000670 0.022524 +v 0.025941 0.020892 -0.072261 +v 0.032683 0.020894 -0.072252 vt 0.000000 1.000000 -vt 1.000000 0.769186 +vt 0.999902 0.000000 +vt 0.999902 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.019284 -vt 0.000000 0.461531 -vt 0.000000 0.038567 -vt 0.000000 1.000000 -vt 1.000000 0.288567 vt 1.000000 1.000000 -vt 0.093872 1.000000 -vt 0.000000 0.788371 -vt 1.000000 0.538371 -vt 0.000000 0.250098 -vt 0.937451 1.000000 vt 1.000000 0.000000 -vt 0.937451 0.000000 -vt 0.000000 0.634593 +vt 0.000000 0.562451 vt 0.000000 0.000000 -vt 0.843677 0.461531 -vt 1.000000 0.634593 -vt 0.000000 0.346222 +vt 0.000000 0.999902 +vt 1.000000 0.562451 +vt 0.000000 0.000000 +vt 1.000000 0.999902 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 1.0000 0.0000 vn 0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn -0.7047 -0.7095 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.4471 -0.8945 0.0000 +vn 0.0024 -0.0004 -1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.2842 0.9474 0.1475 -vn -0.4470 -0.8945 0.0000 -vn 0.3048 0.9524 0.0000 +vn -0.0003 1.0000 0.0000 +vn -0.9680 -0.2510 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.8931 0.1628 -0.4193 -vn -0.1242 -0.9923 0.0018 -vn -0.2169 -0.9762 0.0016 -vn 0.2801 0.9547 0.1000 -vn 0.0000 0.9941 0.1087 -vn -0.3164 -0.9486 0.0000 -vn -0.2941 -0.9555 -0.0207 -vn -0.2424 -0.9702 0.0000 -vn -0.1416 -0.9899 0.0000 -vn -0.1962 -0.9806 0.0000 -vn -0.3167 -0.9485 0.0000 -vn -0.3714 -0.9285 0.0027 -vn 0.2990 0.9507 0.0825 -vn 0.2898 0.9528 0.0907 +vn -0.0012 1.0000 0.0000 +vn 0.0220 0.0000 -0.9998 usemtl None s off -f 73/69/54 89/70/54 94/71/54 -f 70/72/55 71/73/55 72/74/55 -f 69/75/56 73/69/56 74/76/56 -f 71/73/57 70/72/57 75/77/57 -f 73/69/56 69/75/56 75/77/56 -f 72/74/55 71/73/55 76/78/55 -f 70/72/55 72/74/55 77/79/55 -f 74/76/58 72/74/58 78/80/58 -f 72/74/55 76/78/55 78/80/55 -f 75/77/56 69/75/56 79/81/56 -f 71/73/59 75/77/59 79/81/59 -f 69/75/56 74/76/56 80/82/56 -f 78/80/60 69/75/60 80/82/60 -f 74/76/58 78/80/58 80/82/58 -f 72/74/58 74/76/58 81/83/58 -f 77/79/61 72/74/61 81/83/61 -f 69/75/60 78/80/60 82/84/60 -f 78/80/55 76/78/55 82/84/55 -f 79/81/56 69/75/56 84/85/56 -f 76/78/55 71/73/55 85/86/55 -f 71/73/62 79/81/62 85/86/62 -f 74/76/63 73/69/63 86/87/63 -f 81/83/58 74/76/58 86/87/58 -f 75/77/57 70/72/57 87/88/57 -f 73/69/56 75/77/56 87/88/56 -f 70/72/64 83/89/64 87/88/64 -f 83/89/65 73/69/65 87/88/65 -f 69/75/66 82/84/66 88/90/66 -f 82/84/55 76/78/55 88/90/55 -f 76/78/67 84/85/67 88/90/67 -f 77/79/68 81/83/68 89/70/68 -f 73/69/54 83/89/54 89/70/54 -f 83/89/69 77/79/69 89/70/69 -f 70/72/55 77/79/55 90/91/55 -f 83/89/64 70/72/64 90/91/64 -f 77/79/69 83/89/69 90/91/69 -f 76/78/70 79/81/70 91/92/70 -f 79/81/71 84/85/71 91/92/71 -f 84/85/72 76/78/72 91/92/72 -f 84/85/56 69/75/56 92/93/56 -f 69/75/73 88/90/73 92/93/73 -f 88/90/74 84/85/74 92/93/74 -f 79/81/75 76/78/75 93/94/75 -f 76/78/55 85/86/55 93/94/55 -f 85/86/76 79/81/76 93/94/76 -f 86/87/63 73/69/63 94/71/63 -f 81/83/77 86/87/77 94/71/77 -f 89/70/78 81/83/78 94/71/78 -o Cup_hull_6 -v -0.004591 -0.024868 0.018410 -v -0.013281 -0.021443 0.032177 -v -0.013017 -0.021707 0.032177 -v 0.000413 -0.022497 0.031895 -v -0.013017 -0.012229 0.015037 -v 0.000413 -0.018023 0.015037 -v -0.013281 -0.020390 0.015037 -v -0.013281 -0.018286 0.032177 -v 0.000413 -0.025130 0.032177 -v 0.000413 -0.024868 0.017286 -v -0.005909 -0.024605 0.032177 -v -0.009330 -0.023550 0.018410 -v -0.013017 -0.012756 0.017286 -v 0.000413 -0.020654 0.015037 -v 0.000413 -0.018548 0.018130 -v -0.013017 -0.021707 0.018130 -v -0.013281 -0.012229 0.015037 -v -0.009330 -0.023550 0.032177 -v -0.001695 -0.024341 0.016724 -v -0.002485 -0.025130 0.018410 -v -0.002485 -0.025130 0.032177 -v -0.005382 -0.024341 0.017286 -v -0.013017 -0.018286 0.032177 -v 0.000413 -0.025130 0.017848 -v -0.007751 -0.024077 0.018130 -v 0.000413 -0.022761 0.032177 -v 0.000413 -0.018023 0.015881 -v -0.013017 -0.012493 0.016444 -v -0.008804 -0.020654 0.015037 -v -0.013281 -0.021443 0.017848 -v -0.009068 -0.023288 0.017286 -v -0.005909 -0.024605 0.018410 -v -0.004591 -0.024868 0.032177 -v -0.002485 -0.024604 0.017006 -v -0.010910 -0.022761 0.017848 -v 0.000413 -0.024341 0.016724 -v -0.007751 -0.024077 0.032177 -vt 0.000000 0.288567 -vt 0.819561 0.403876 -vt 0.000000 0.403876 -vt 1.000000 0.019284 +f 60/55/43 61/56/43 66/57/43 +f 57/58/44 56/59/44 58/60/44 +f 56/59/45 57/58/45 60/55/45 +f 55/61/46 59/62/46 60/55/46 +f 58/60/47 56/59/47 61/56/47 +f 59/62/48 58/60/48 61/56/48 +f 60/55/43 59/62/43 61/56/43 +f 55/61/46 60/55/46 62/63/46 +f 60/55/49 57/58/49 62/63/49 +f 57/58/44 58/60/44 63/64/44 +f 58/60/50 55/61/50 63/64/50 +f 55/61/51 62/63/51 63/64/51 +f 55/61/50 58/60/50 64/65/50 +f 59/62/46 55/61/46 64/65/46 +f 58/60/48 59/62/48 64/65/48 +f 62/63/52 57/58/52 65/66/52 +f 57/58/44 63/64/44 65/66/44 +f 63/64/51 62/63/51 65/66/51 +f 56/59/45 60/55/45 66/57/45 +f 61/56/53 56/59/53 66/57/53 +o cup_hull_5 +v -0.013664 -0.038092 0.027187 +v -0.016193 -0.023770 0.022542 +v -0.016615 -0.023770 0.022542 +v -0.015771 -0.035143 0.075200 +v -0.004396 -0.028404 0.023393 +v -0.004396 -0.038515 0.075200 +v -0.004396 -0.039780 0.026341 +v -0.016615 -0.036829 0.075200 +v -0.016615 -0.032615 0.022542 +v -0.007346 -0.039780 0.075200 +v -0.016615 -0.036829 0.026764 +v -0.004396 -0.033038 0.022542 +v -0.016193 -0.023770 0.023815 +v -0.007346 -0.039780 0.027187 +v -0.011137 -0.038935 0.075200 +v -0.004396 -0.039780 0.075200 +v -0.016615 -0.035143 0.075200 +v -0.007346 -0.038935 0.025501 +v -0.014929 -0.037672 0.075200 +v -0.011137 -0.038935 0.027604 +v -0.004396 -0.028404 0.022542 +v -0.012401 -0.037672 0.025501 +v -0.004396 -0.038515 0.025078 +v -0.009453 -0.039358 0.075200 +v -0.014929 -0.037672 0.027604 +v -0.014508 -0.033036 0.022542 +v -0.009452 -0.039357 0.027604 +v -0.016615 -0.036407 0.025919 +vt 1.000000 0.447533 +vt 0.943808 0.131656 +vt 0.935879 0.210650 +vt 0.983847 0.710552 +vt 0.000000 0.078994 +vt 0.927851 0.000000 +vt 0.000000 0.289644 +vt 0.000000 0.184319 +vt 1.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.000000 vt 0.000000 0.000000 +vt 0.919824 0.184319 +vt 1.000000 0.421104 +vt 0.975820 1.000000 +vt 0.911796 0.000000 +vt 0.000000 0.052760 vt 0.000000 0.000000 -vt 0.000000 0.019284 -vt 0.016448 1.000000 -vt 0.000000 1.000000 -vt 0.868807 1.000000 -vt 0.000000 0.538371 -vt 1.000000 1.000000 -vt 0.819561 1.000000 -vt 0.819561 0.019284 -vt 1.000000 0.000000 -vt 0.868807 0.019284 -vt 0.000000 0.788371 -vt 0.803211 0.788371 -vt 0.803211 0.634593 -vt 0.000000 0.019284 -vt 0.836009 1.000000 -vt 0.803211 0.288567 -vt 0.000000 1.000000 -vt 0.950754 1.000000 -vt 0.917956 0.019284 -vt 1.000000 0.326938 -vt 0.901606 0.846124 -vt 0.836009 0.000000 -vt 0.868807 0.576840 -vt 0.868807 0.307655 -vt 0.803211 0.538371 -vt 0.000000 0.634593 -vt 0.885158 0.788371 -vt 0.836009 0.173160 -vt 0.901606 1.000000 -vn -0.3164 -0.9486 0.0000 +vt 0.000000 0.289644 +vt 0.943808 0.052760 +vt 0.000000 0.131656 +vt 0.903867 0.052760 +vt 0.911796 0.105423 +vt 1.000000 0.710552 +vt 0.951836 0.078994 +vt 0.000000 0.026331 +vt 0.903867 0.131656 +vt 1.000000 0.421202 +vt 0.903867 0.026429 +vn -0.2639 -0.6414 -0.7204 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn 0.0000 0.0000 -1.0000 vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 1.0000 -0.0000 0.0000 -vn -0.7070 -0.7072 0.0000 -vn -0.6912 0.6814 0.2408 +vn 0.0000 1.0000 0.0000 +vn 0.3656 0.9308 0.0000 +vn 0.3653 0.9137 0.1783 +vn 0.2782 0.9383 0.2054 vn 0.0000 -1.0000 0.0000 -vn -0.1238 -0.9923 0.0000 -vn 0.2885 0.8976 0.3333 -vn 0.0000 0.9375 0.3481 -vn 0.2363 0.7093 0.6641 -vn 0.3961 0.9182 0.0000 -vn 0.3797 0.9008 0.2105 -vn 0.3458 0.8958 0.2794 -vn 0.3704 0.8929 0.2561 -vn 0.0000 0.9828 0.1845 -vn -0.5337 0.8073 0.2518 -vn 0.3813 0.9086 0.1706 -vn -0.0270 -0.4585 -0.8883 -vn 0.0000 -0.4160 -0.9094 -vn -0.4896 -0.8165 -0.3060 -vn -0.2225 -0.7788 -0.5865 -vn -0.2486 -0.8701 -0.4256 -vn -0.1955 -0.9807 0.0000 -vn -0.1861 -0.9335 -0.3064 -vn -0.2756 -0.9613 0.0000 -vn -0.2162 -0.9231 -0.3180 -vn -0.0868 -0.5956 -0.7986 -vn -0.0006 -0.7308 -0.6826 -vn -0.1160 -0.9300 -0.3487 -vn -0.1183 -0.9286 -0.3518 -vn -0.1315 -0.6757 -0.7254 -vn -0.0415 -0.9052 -0.4230 -vn -0.0680 -0.9342 -0.3503 +vn -0.5370 0.8245 0.1781 +vn 0.0000 0.9764 0.2161 +vn -0.1274 -0.8868 -0.4443 vn -0.4472 -0.8945 0.0000 -vn -0.4578 -0.8314 -0.3151 -vn -0.4470 -0.8945 0.0000 -vn -0.4469 -0.8946 0.0000 -vn -0.3480 -0.8951 -0.2786 -vn -0.3632 -0.8403 -0.4024 -vn -0.3449 -0.8911 -0.2950 -vn 0.0000 -0.7297 -0.6837 +vn -0.3161 -0.9487 0.0000 +vn -0.2405 -0.9005 -0.3624 +vn -0.2367 -0.8862 -0.3982 +vn -0.1469 -0.5878 -0.7955 +vn -0.2180 -0.8725 -0.4372 +vn -0.0008 -0.7066 -0.7076 +vn -0.1961 -0.9806 0.0000 +vn -0.2437 -0.9699 0.0000 +vn -0.3643 -0.9128 -0.1848 +vn -0.3161 -0.9487 -0.0027 +vn -0.1098 -0.5490 -0.8286 +vn -0.0001 -0.4202 -0.9074 +vn -0.0530 -0.4985 -0.8653 +vn -0.2359 -0.9431 -0.2343 +vn -0.1970 -0.9804 -0.0000 +vn -0.2427 -0.9701 -0.0000 +vn -0.3040 -0.8525 -0.4251 +vn -0.2981 -0.8496 -0.4350 usemtl None s off -f 112/95/79 119/96/79 131/97/79 -f 99/98/80 100/99/80 101/100/80 -f 101/100/81 96/101/81 102/102/81 -f 96/101/82 97/103/82 102/102/82 -f 100/99/83 98/104/83 103/105/83 -f 102/102/82 97/103/82 103/105/82 -f 100/99/83 103/105/83 104/106/83 -f 103/105/82 97/103/82 105/107/82 -f 101/100/80 100/99/80 108/108/80 -f 100/99/83 104/106/83 108/108/83 -f 98/104/83 100/99/83 109/109/83 -f 97/103/84 96/101/84 110/110/84 -f 99/98/80 101/100/80 111/111/80 -f 101/100/81 102/102/81 111/111/81 -f 102/102/85 107/112/85 111/111/85 -f 105/107/82 97/103/82 112/95/82 -f 103/105/82 105/107/82 115/113/82 -f 114/114/86 103/105/86 115/113/86 -f 95/115/87 114/114/87 115/113/87 -f 102/102/82 103/105/82 117/116/82 -f 98/104/88 107/112/88 117/116/88 -f 107/112/89 102/102/89 117/116/89 -f 104/106/83 103/105/83 118/117/83 -f 103/105/86 114/114/86 118/117/86 -f 112/95/79 106/118/79 119/96/79 -f 103/105/83 98/104/83 120/119/83 -f 98/104/90 117/116/90 120/119/90 -f 117/116/82 103/105/82 120/119/82 -f 100/99/91 99/98/91 121/120/91 -f 109/109/83 100/99/83 121/120/83 -f 109/109/92 121/120/92 122/121/92 -f 107/112/93 98/104/93 122/121/93 -f 98/104/94 109/109/94 122/121/94 -f 99/98/95 111/111/95 122/121/95 -f 111/111/96 107/112/96 122/121/96 -f 121/120/97 99/98/97 122/121/97 -f 101/100/80 108/108/80 123/122/80 -f 113/123/98 101/100/98 123/122/98 -f 108/108/99 113/123/99 123/122/99 -f 96/101/81 101/100/81 124/124/81 -f 110/110/84 96/101/84 124/124/84 -f 101/100/100 110/110/100 124/124/100 -f 101/100/101 116/125/101 125/126/101 -f 116/125/102 119/96/102 125/126/102 -f 95/115/103 105/107/103 126/127/103 -f 116/125/104 95/115/104 126/127/104 -f 105/107/105 119/96/105 126/127/105 -f 119/96/106 116/125/106 126/127/106 -f 105/107/103 95/115/103 127/128/103 -f 95/115/87 115/113/87 127/128/87 -f 115/113/82 105/107/82 127/128/82 -f 101/100/107 113/123/107 128/129/107 -f 113/123/108 104/106/108 128/129/108 -f 114/114/109 95/115/109 128/129/109 -f 95/115/110 116/125/110 128/129/110 -f 116/125/111 101/100/111 128/129/111 -f 104/106/112 118/117/112 128/129/112 -f 118/117/113 114/114/113 128/129/113 -f 97/103/114 110/110/114 129/130/114 -f 110/110/115 101/100/115 129/130/115 -f 112/95/116 97/103/116 129/130/116 -f 106/118/117 112/95/117 129/130/117 -f 119/96/118 106/118/118 129/130/118 -f 101/100/119 125/126/119 129/130/119 -f 125/126/120 119/96/120 129/130/120 -f 108/108/83 104/106/83 130/131/83 -f 104/106/121 113/123/121 130/131/121 -f 113/123/99 108/108/99 130/131/99 -f 105/107/82 112/95/82 131/97/82 -f 119/96/105 105/107/105 131/97/105 -o Cup_hull_7 -v -0.006700 0.024377 0.032460 -v -0.014335 0.019637 0.050164 -v -0.013806 0.019637 0.050164 -v -0.014335 0.017795 0.032460 -v 0.000413 0.024113 0.050164 -v 0.000413 0.022797 0.032460 -v -0.006700 0.024377 0.050164 -v -0.013806 0.021217 0.032460 -v 0.000413 0.025167 0.032460 -v -0.013017 0.021742 0.050164 -v -0.002222 0.025167 0.050164 -v -0.014070 0.017795 0.033306 -v -0.009855 0.023323 0.032460 -v 0.000413 0.025167 0.050164 -v -0.004328 0.024903 0.032460 -v -0.014335 0.020691 0.032460 -v -0.009855 0.023323 0.050164 -v -0.014335 0.020691 0.050164 -v 0.000413 0.022797 0.033586 -v -0.002222 0.025167 0.032460 -v -0.004328 0.024903 0.050164 -v -0.013017 0.021742 0.032460 -v -0.013806 0.021217 0.050164 -v -0.005646 0.024639 0.050164 -vt 0.000000 0.678543 -vt 1.000000 0.678543 -vt 0.000000 0.589174 -vt 0.000000 0.000000 -vt 0.000000 0.035826 +f 75/67/54 88/68/54 94/69/54 +f 71/70/55 72/71/55 73/72/55 +f 72/71/56 70/73/56 74/74/56 +f 69/75/57 68/76/57 75/67/57 +f 74/74/58 69/75/58 75/67/58 +f 72/71/56 74/74/56 76/77/56 +f 74/74/58 75/67/58 77/78/58 +f 71/70/55 73/72/55 78/79/55 +f 75/67/57 68/76/57 78/79/57 +f 68/76/59 69/75/59 79/80/59 +f 71/70/60 68/76/60 79/80/60 +f 72/71/61 71/70/61 79/80/61 +f 70/73/62 72/71/62 79/80/62 +f 73/72/63 76/77/63 80/81/63 +f 76/77/56 74/74/56 81/82/56 +f 73/72/55 72/71/55 82/83/55 +f 76/77/63 73/72/63 82/83/63 +f 72/71/56 76/77/56 82/83/56 +f 69/75/58 74/74/58 83/84/58 +f 74/74/56 70/73/56 83/84/56 +f 79/80/64 69/75/64 83/84/64 +f 70/73/65 79/80/65 83/84/65 +f 73/72/66 80/81/66 84/85/66 +f 74/74/67 77/78/67 85/86/67 +f 81/82/56 74/74/56 85/86/56 +f 81/82/68 85/86/68 86/87/68 +f 67/88/69 80/81/69 86/87/69 +f 68/76/60 71/70/60 87/89/60 +f 78/79/57 68/76/57 87/89/57 +f 71/70/55 78/79/55 87/89/55 +f 80/81/70 67/88/70 88/68/70 +f 75/67/71 84/85/71 88/68/71 +f 84/85/72 80/81/72 88/68/72 +f 78/79/55 73/72/55 89/90/55 +f 73/72/73 84/85/73 89/90/73 +f 80/81/74 76/77/74 90/91/74 +f 76/77/56 81/82/56 90/91/56 +f 81/82/75 86/87/75 90/91/75 +f 77/78/76 67/88/76 91/92/76 +f 85/86/67 77/78/67 91/92/67 +f 86/87/68 85/86/68 91/92/68 +f 67/88/77 86/87/77 91/92/77 +f 75/67/57 78/79/57 92/93/57 +f 84/85/78 75/67/78 92/93/78 +f 78/79/79 89/90/79 92/93/79 +f 89/90/80 84/85/80 92/93/80 +f 86/87/81 80/81/81 93/94/81 +f 80/81/82 90/91/82 93/94/82 +f 90/91/83 86/87/83 93/94/83 +f 67/88/84 77/78/84 94/69/84 +f 77/78/58 75/67/58 94/69/58 +f 88/68/85 67/88/85 94/69/85 +o cup_hull_6 +v -0.034734 -0.020819 0.075208 +v -0.036839 -0.001016 0.050354 +v -0.030099 -0.020819 0.050352 +v -0.037682 -0.014919 0.050354 +v -0.038946 -0.001016 0.075208 +v -0.040209 -0.004387 0.075208 +v -0.040209 -0.001016 0.050354 +v -0.032627 -0.020395 0.075208 +v -0.034313 -0.021240 0.050354 +v -0.038946 -0.011128 0.075208 +v -0.039788 -0.007337 0.050354 +v -0.038524 -0.001437 0.074364 +v -0.032627 -0.021240 0.075208 +v -0.030099 -0.020819 0.051617 +v -0.040209 -0.001016 0.075208 +v -0.037682 -0.014919 0.075208 +v -0.036839 -0.001016 0.052459 +v -0.030099 -0.021238 0.050352 +v -0.038946 -0.011128 0.050354 +v -0.040209 -0.004387 0.050354 +v -0.034734 -0.020819 0.050354 +v -0.039368 -0.009443 0.075208 +v -0.034313 -0.021240 0.075208 +v -0.039788 -0.007337 0.075208 +vt 0.999902 0.687451 +vt 0.000000 0.583301 +vt 0.000000 0.687451 +vt 0.000000 0.020850 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 0.517717 -vt 1.000000 1.000000 -vt 0.000000 0.517717 -vt 1.000000 0.035826 -vt 1.000000 1.000000 -vt 0.000000 0.089370 -vt 0.000000 0.821359 -vt 0.952232 0.017913 -vt 1.000000 0.303739 +vt 0.000000 0.833301 +vt 0.999902 1.000000 +vt 1.000000 0.020850 +vt 0.999902 1.000000 +vt 0.000000 0.041797 +vt 0.000000 0.500000 +vt 0.033966 0.979150 +vt 0.000000 0.000000 +vt 0.949100 0.020850 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 0.000000 0.303739 +vt 0.999902 0.312549 +vt 0.000000 0.312549 +vt 0.915231 1.000000 +vt 1.000000 0.000098 +vt 0.999902 0.000000 +vt 0.999902 0.500000 +vt 0.999902 0.833301 +vt 0.999902 0.020850 vt 0.000000 0.000000 -vt 0.936374 1.000000 -vt 1.000000 0.821359 -vt 1.000000 0.089370 -vt 0.000000 0.035826 -vn -0.1960 0.9806 0.0000 +vn -0.9806 -0.1958 0.0000 vn 0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 -0.9941 0.1086 -vn -0.3146 -0.9441 0.0983 -vn 0.2988 -0.9492 0.0991 -vn 0.3196 -0.9423 -0.0998 -vn -0.3167 0.9485 0.0000 +vn 0.0000 0.0001 -1.0000 vn 0.0000 1.0000 0.0000 +vn 0.9055 0.2952 0.3048 +vn 0.9467 0.3222 0.0000 +vn 0.9492 0.2995 0.0964 +vn 0.9943 0.0000 0.1066 vn -1.0000 0.0000 0.0000 -vn -0.4472 0.8944 0.0000 -vn -0.7056 0.7086 0.0000 -vn 0.3242 -0.9430 0.0749 -vn 0.3265 -0.9452 0.0000 -vn -0.1244 0.9922 0.0000 -vn -0.5540 0.8325 0.0000 -vn -0.2419 0.9703 0.0000 -vn -0.2166 0.9763 -0.0016 +vn -0.8945 -0.4471 0.0000 +vn -0.9487 -0.3163 0.0000 +vn 0.7734 0.6299 0.0716 +vn 0.9447 0.3182 0.0788 +vn -0.0002 0.0000 -1.0000 +vn 0.0005 -1.0000 -0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.9516 -0.2918 0.0968 +vn -0.0004 -0.0001 -1.0000 +vn -0.9900 -0.1412 0.0000 +vn -0.0003 -0.0000 -1.0000 +vn -0.7080 -0.7062 0.0000 +vn -0.0006 -0.0003 -1.0000 +vn -0.0006 -0.0006 -1.0000 +vn -0.9701 -0.2428 0.0000 +vn -0.9762 -0.2169 -0.0019 +vn 0.0000 -1.0000 0.0000 +vn -0.0001 0.0000 1.0000 usemtl None s off -f 152/132/122 146/133/122 155/134/122 -f 133/135/123 134/136/123 136/137/123 -f 135/138/124 132/139/124 137/140/124 -f 133/135/123 136/137/123 138/141/123 -f 132/139/124 135/138/124 139/142/124 -f 137/140/124 132/139/124 140/143/124 -f 136/137/125 137/140/125 140/143/125 -f 133/135/123 138/141/123 141/144/123 -f 138/141/123 136/137/123 142/145/123 -f 134/136/126 133/135/126 143/146/126 -f 133/135/127 135/138/127 143/146/127 -f 136/137/128 134/136/128 143/146/128 -f 135/138/129 137/140/129 143/146/129 -f 138/141/130 132/139/130 144/147/130 -f 132/139/124 139/142/124 144/147/124 -f 136/137/125 140/143/125 145/148/125 -f 142/145/123 136/137/123 145/148/123 -f 140/143/131 142/145/131 145/148/131 -f 140/143/124 132/139/124 146/133/124 -f 135/138/132 133/135/132 147/149/132 -f 139/142/124 135/138/124 147/149/124 -f 141/144/123 138/141/123 148/150/123 -f 138/141/130 144/147/130 148/150/130 -f 144/147/133 141/144/133 148/150/133 -f 133/135/123 141/144/123 149/151/123 -f 147/149/132 133/135/132 149/151/132 -f 139/142/134 147/149/134 149/151/134 -f 137/140/125 136/137/125 150/152/125 -f 136/137/135 143/146/135 150/152/135 -f 143/146/136 137/140/136 150/152/136 -f 142/145/131 140/143/131 151/153/131 -f 140/143/124 146/133/124 151/153/124 -f 146/133/137 142/145/137 151/153/137 -f 138/141/123 142/145/123 152/132/123 -f 142/145/137 146/133/137 152/132/137 -f 139/142/138 141/144/138 153/154/138 -f 144/147/124 139/142/124 153/154/124 -f 141/144/133 144/147/133 153/154/133 -f 141/144/138 139/142/138 154/155/138 -f 149/151/123 141/144/123 154/155/123 -f 139/142/134 149/151/134 154/155/134 -f 132/139/139 138/141/139 155/134/139 -f 146/133/140 132/139/140 155/134/140 -f 138/141/123 152/132/123 155/134/123 -o Cup_hull_8 -v -0.003801 0.024902 0.017846 -v -0.014335 0.017794 0.032458 -v -0.014335 0.020688 0.032458 -v 0.000413 0.022796 0.032458 -v -0.014070 0.011212 0.015036 -v 0.000413 0.018057 0.015036 -v -0.014335 0.020426 0.015036 -v 0.000413 0.025166 0.032458 -v 0.000413 0.024376 0.016722 -v -0.009858 0.023322 0.032458 -v -0.014070 0.011475 0.017004 -v -0.009858 0.023322 0.018409 -v -0.005645 0.024639 0.032458 -v 0.000413 0.018320 0.017285 -v 0.000413 0.022532 0.032179 -v 0.000413 0.020426 0.015036 -v -0.014070 0.017531 0.032179 -v -0.013017 0.021741 0.018409 -v 0.000413 0.025166 0.017846 -v -0.014335 0.011212 0.016161 -v -0.002222 0.025166 0.032458 -v -0.006698 0.024376 0.018128 -v -0.013017 0.021741 0.032458 -v -0.014070 0.011212 0.016161 -v -0.005645 0.024111 0.017004 -v -0.002222 0.025166 0.018409 -v -0.004328 0.024902 0.018409 -v -0.013806 0.021215 0.018128 -v -0.001958 0.024639 0.017004 -v -0.006698 0.024376 0.032458 -v 0.000413 0.018057 0.015880 -v -0.004328 0.024902 0.032458 -v -0.014335 0.011212 0.015036 -v -0.014335 0.020688 0.017285 -v -0.013806 0.021215 0.032458 -v -0.009330 0.023322 0.017565 -vt 0.822516 0.517815 -vt 0.887029 0.589272 -vt 0.854821 0.339370 +f 105/95/86 116/96/86 118/97/86 +f 95/98/87 99/99/87 100/100/87 +f 96/101/88 97/102/88 101/103/88 +f 99/99/89 96/101/89 101/103/89 +f 99/99/87 95/98/87 102/104/87 +f 95/98/87 100/100/87 104/105/87 +f 99/99/90 102/104/90 106/106/90 +f 102/104/87 95/98/87 107/107/87 +f 97/102/91 96/101/91 108/108/91 +f 106/106/92 102/104/92 108/108/92 +f 102/104/93 107/107/93 108/108/93 +f 100/100/87 99/99/87 109/109/87 +f 99/99/89 101/103/89 109/109/89 +f 101/103/94 100/100/94 109/109/94 +f 98/110/95 95/98/95 110/111/95 +f 95/98/87 104/105/87 110/111/87 +f 104/105/96 98/110/96 110/111/96 +f 96/101/89 99/99/89 111/112/89 +f 99/99/97 106/106/97 111/112/97 +f 108/108/91 96/101/91 111/112/91 +f 106/106/98 108/108/98 111/112/98 +f 101/103/99 97/102/99 112/113/99 +f 107/107/100 103/114/100 112/113/100 +f 97/102/101 108/108/101 112/113/101 +f 108/108/102 107/107/102 112/113/102 +f 98/110/96 104/105/96 113/115/96 +f 112/113/103 98/110/103 113/115/103 +f 105/95/103 112/113/103 113/115/103 +f 100/100/94 101/103/94 114/116/94 +f 105/95/104 100/100/104 114/116/104 +f 101/103/99 112/113/99 114/116/99 +f 112/113/105 105/95/105 114/116/105 +f 95/98/95 98/110/95 115/117/95 +f 103/114/106 95/98/106 115/117/106 +f 98/110/107 112/113/107 115/117/107 +f 112/113/108 103/114/108 115/117/108 +f 104/105/87 100/100/87 116/96/87 +f 113/115/109 104/105/109 116/96/109 +f 105/95/110 113/115/110 116/96/110 +f 95/98/106 103/114/106 117/118/106 +f 107/107/87 95/98/87 117/118/87 +f 103/114/111 107/107/111 117/118/111 +f 100/100/104 105/95/104 118/97/104 +f 116/96/112 100/100/112 118/97/112 +o cup_hull_7 +v -0.034733 -0.020395 0.026339 +v -0.040210 -0.004387 0.050348 +v -0.039787 -0.007337 0.050348 +v -0.019565 -0.020819 0.022967 +v -0.033046 -0.001016 0.022548 +v -0.030095 -0.021240 0.050348 +v -0.036417 -0.001016 0.049927 +v -0.040210 -0.001016 0.026758 +v -0.028834 -0.001016 0.023811 +v -0.032625 -0.021240 0.022548 +v -0.034733 -0.020819 0.050348 +v -0.038945 -0.011128 0.027602 +v -0.040210 -0.001016 0.050348 +v -0.019565 -0.021240 0.022548 +v -0.037682 -0.014919 0.050348 +v -0.029677 -0.020819 0.049927 +v -0.038945 -0.003124 0.025073 +v -0.020409 -0.020819 0.025917 +v -0.037682 -0.014919 0.027602 +v -0.040210 -0.004387 0.027602 +v -0.028834 -0.001016 0.022548 +v -0.029677 -0.001016 0.027180 +v -0.038945 -0.009022 0.025917 +v -0.034311 -0.021240 0.050348 +v -0.034733 -0.020819 0.027180 +v -0.038945 -0.011128 0.050348 +v -0.036417 -0.001859 0.050348 +v -0.019987 -0.020819 0.024652 +v -0.039367 -0.009443 0.027602 +v -0.037682 -0.014074 0.026339 +v -0.034311 -0.021240 0.026758 +v -0.038945 -0.001016 0.025073 +v -0.033046 -0.014074 0.022548 +v -0.039787 -0.007337 0.027602 +v -0.020409 -0.021240 0.025917 +vt 0.924320 0.979542 +vt 0.878794 0.959084 +vt 0.878794 0.959084 vt 0.000000 0.000000 +vt 0.000000 0.020458 +vt 0.000000 0.489918 +vt 0.015175 0.183731 +vt 1.000000 0.347005 +vt 0.848541 0.000000 +vt 0.954572 0.550999 +vt 0.000000 0.265270 vt 0.000000 0.000000 -vt 0.000000 1.000000 +vt 1.000000 0.367365 vt 1.000000 1.000000 -vt 1.000000 0.017913 -vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 0.903182 1.000000 -vt 0.000000 0.303543 -vt 0.000000 0.589272 -vt 0.870876 1.000000 -vt 0.016055 1.000000 -vt 1.000000 1.000000 -vt 0.016055 0.017913 -vt 0.887029 0.017913 -vt 0.806363 0.303543 -vt 0.806363 0.089370 -vt 0.838669 1.000000 -vt 0.935389 0.000000 -vt 0.000000 0.821359 -vt 0.000000 0.089370 -vt 0.935389 0.017913 -vt 0.838669 0.714272 -vt 0.806363 0.821359 -vt 0.806363 0.678543 -vt 0.822516 0.035826 -vt 0.887029 0.839272 -vt 0.000000 0.517815 -vt 0.951542 1.000000 -vt 0.000000 0.678543 -vt 1.000000 0.000000 -vt 0.870876 0.000000 -vt 0.000000 0.035826 -vn -0.2516 0.8624 -0.4393 +vt 0.000000 0.122455 +vt 0.015175 0.510180 +vt 0.818191 0.122455 +vt 0.818191 0.061276 +vt 0.818191 0.000000 +vt 0.984923 1.000000 +vt 1.000000 0.550999 +vt 0.833366 0.510180 +vt 0.909144 0.061276 +vt 0.878794 0.061276 +vt 0.000000 0.285728 +vt 0.833366 0.265270 +vt 0.863619 0.265270 +vt 0.000000 0.061276 +vt 0.000000 0.183731 +vt 0.818191 0.040818 +vt 0.863619 0.122455 +vt 0.848541 0.285728 +vt 0.909144 0.061276 +vt 1.000000 0.347005 +vt 0.818191 0.020458 +vn 0.9486 0.0000 0.3165 vn 0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn -1.0000 0.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 0.3927 -0.9197 -vn 0.2065 -0.6089 0.7659 -vn 0.3054 -0.8844 0.3530 -vn 0.2437 -0.7058 0.6652 -vn -0.4409 0.8811 -0.1713 -vn -0.4475 0.8943 0.0000 -vn -0.4642 -0.8213 0.3317 -vn -0.2519 -0.8988 0.3587 vn 0.0000 1.0000 0.0000 -vn -0.3166 0.9486 0.0000 -vn 0.4273 -0.9041 0.0000 -vn 0.3853 -0.8811 0.2743 -vn 0.4112 -0.8771 0.2481 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.0000 -0.9548 0.2972 -vn -0.2012 0.8944 -0.3995 -vn -0.0599 0.9580 -0.2805 -vn -0.1242 0.9923 0.0000 -vn -0.1926 0.9646 -0.1803 -vn -0.2164 0.9763 -0.0020 -vn -0.1234 0.9856 -0.1155 -vn -0.5179 0.8459 -0.1275 -vn -0.5543 0.8323 0.0000 -vn -0.0430 0.5239 -0.8507 -vn -0.0570 0.9105 -0.4095 -vn 0.0223 0.8181 -0.5747 -vn -0.0894 0.6249 -0.7755 -vn -0.1204 0.8415 -0.5266 -vn -0.2415 0.9704 0.0000 -vn 0.4240 -0.8903 0.1661 -vn -0.1964 0.9805 0.0000 -vn -0.7064 0.7078 0.0000 -vn -0.6278 0.7731 -0.0901 -vn -0.3902 0.8877 -0.2442 -vn -0.3262 0.9230 -0.2041 -vn -0.2527 0.8463 -0.4689 +vn 0.8892 0.3026 0.3432 +vn -0.8945 -0.4471 0.0000 +vn -0.9487 -0.3161 0.0000 +vn -0.9899 -0.1417 0.0000 +vn 0.9057 0.4239 0.0000 +vn 0.8384 0.3843 -0.3866 +vn 0.8867 0.4056 0.2218 +vn -0.8410 -0.0766 -0.5356 +vn -0.6255 -0.1105 -0.7724 +vn -0.9090 -0.1012 -0.4043 +vn -0.7065 -0.7077 0.0000 +vn -0.8799 -0.4244 -0.2138 +vn 0.0990 0.4452 0.8899 +vn 0.7959 0.2709 0.5415 +vn 0.5931 0.1935 0.7815 +vn 0.8858 0.3576 0.2956 +vn 0.8867 0.4055 0.2223 +vn 0.8799 0.3973 0.2607 +vn -0.9280 -0.2327 -0.2909 +vn -0.9762 -0.2170 0.0021 +vn -0.9700 -0.2432 0.0000 +vn -0.8387 -0.3912 -0.3790 +vn -0.8720 -0.4067 -0.2723 +vn -0.9282 -0.3092 -0.2070 +vn -0.7784 -0.2429 -0.5789 +vn -0.9130 -0.2548 -0.3186 +vn -0.7791 -0.5439 -0.3118 +vn -0.8016 -0.5339 -0.2689 +vn -0.3936 0.0000 -0.9193 +vn -0.7997 0.0000 -0.6004 +vn -0.4330 -0.0254 -0.9011 +vn -0.9333 -0.1336 -0.3332 +vn -0.9807 -0.1957 0.0000 +vn -0.9406 -0.1877 -0.2828 +vn 0.9428 -0.2350 0.2364 +vn 0.8133 -0.4842 0.3225 +vn 0.9329 0.0000 0.3601 +vn 0.9428 -0.2349 0.2364 usemtl None s off -f 177/156/141 180/157/141 191/158/141 -f 158/159/142 157/160/142 159/161/142 -f 161/162/143 160/163/143 162/164/143 -f 157/160/144 158/159/144 162/164/144 -f 158/159/142 159/161/142 163/165/142 -f 159/161/145 161/162/145 163/165/145 -f 163/165/145 161/162/145 164/166/145 -f 158/159/142 163/165/142 165/167/142 -f 165/167/142 163/165/142 168/168/142 -f 161/162/145 159/161/145 169/169/145 -f 169/169/145 159/161/145 170/170/145 -f 161/162/143 162/164/143 171/171/143 -f 164/166/145 161/162/145 171/171/145 -f 162/164/146 164/166/146 171/171/146 -f 159/161/147 157/160/147 172/172/147 -f 166/173/148 170/170/148 172/172/148 -f 170/170/149 159/161/149 172/172/149 -f 167/174/150 162/164/150 173/175/150 -f 165/167/151 167/174/151 173/175/151 -f 163/165/145 164/166/145 174/176/145 -f 157/160/144 162/164/144 175/177/144 -f 172/172/152 157/160/152 175/177/152 -f 166/173/153 172/172/153 175/177/153 -f 168/168/142 163/165/142 176/178/142 -f 163/165/154 174/176/154 176/178/154 -f 167/174/155 165/167/155 177/156/155 -f 158/159/142 165/167/142 178/179/142 -f 165/167/151 173/175/151 178/179/151 -f 160/163/156 161/162/156 179/180/156 -f 170/170/157 166/173/157 179/180/157 -f 169/169/158 170/170/158 179/180/158 -f 175/177/159 160/163/159 179/180/159 -f 166/173/160 175/177/160 179/180/160 -f 177/156/161 156/181/161 180/157/161 -f 174/176/162 156/181/162 181/182/162 -f 176/178/154 174/176/154 181/182/154 -f 176/178/163 181/182/163 182/183/163 -f 156/181/164 177/156/164 182/183/164 -f 177/156/165 168/168/165 182/183/165 -f 181/182/166 156/181/166 182/183/166 -f 173/175/167 162/164/167 183/184/167 -f 178/179/168 173/175/168 183/184/168 -f 164/166/169 162/164/169 184/185/169 -f 156/181/170 174/176/170 184/185/170 -f 174/176/171 164/166/171 184/185/171 -f 162/164/172 180/157/172 184/185/172 -f 180/157/173 156/181/173 184/185/173 -f 165/167/142 168/168/142 185/186/142 -f 177/156/155 165/167/155 185/186/155 -f 168/168/174 177/156/174 185/186/174 -f 161/162/145 169/169/145 186/187/145 -f 179/180/156 161/162/156 186/187/156 -f 169/169/175 179/180/175 186/187/175 -f 168/168/142 176/178/142 187/188/142 -f 176/178/163 182/183/163 187/188/163 -f 182/183/176 168/168/176 187/188/176 -f 162/164/143 160/163/143 188/189/143 -f 160/163/159 175/177/159 188/189/159 -f 175/177/144 162/164/144 188/189/144 -f 162/164/144 158/159/144 189/190/144 -f 158/159/177 183/184/177 189/190/177 -f 183/184/178 162/164/178 189/190/178 -f 158/159/142 178/179/142 190/191/142 -f 183/184/177 158/159/177 190/191/177 -f 178/179/168 183/184/168 190/191/168 -f 162/164/179 167/174/179 191/158/179 -f 167/174/180 177/156/180 191/158/180 -f 180/157/181 162/164/181 191/158/181 -o Cup_hull_9 -v 0.004625 -0.024868 0.026844 -v 0.008313 -0.016178 0.015036 -v 0.007785 -0.016178 0.015036 -v 0.008313 -0.022761 0.050166 -v 0.000413 -0.024077 0.049041 -v 0.000413 -0.018023 0.015036 -v 0.008313 -0.023814 0.017848 -v 0.000413 -0.025132 0.017848 -v 0.004363 -0.024868 0.050166 -v 0.008313 -0.020655 0.015036 -v 0.007785 -0.024077 0.050166 -v 0.000413 -0.025132 0.050166 -v 0.008049 -0.016178 0.016442 -v 0.000413 -0.020655 0.015036 -v 0.000676 -0.024077 0.049884 -v 0.002520 -0.025132 0.018409 -v 0.000413 -0.018023 0.015882 -v 0.001730 -0.024341 0.016724 -v 0.005942 -0.024604 0.018409 -v 0.007785 -0.022761 0.050166 -v 0.002520 -0.025132 0.050166 -v 0.008313 -0.023814 0.050166 -v 0.005679 -0.024077 0.017006 -v 0.004625 -0.024868 0.048477 -v 0.007785 -0.024077 0.018409 -v 0.000413 -0.024341 0.016724 -v 0.008313 -0.023287 0.017006 -v 0.003309 -0.024868 0.017567 -v 0.000940 -0.024077 0.050166 -v 0.008313 -0.016178 0.016442 -vt 0.959965 1.000000 -vt 0.000000 0.264781 -vt 0.959965 1.000000 +f 146/119/113 136/120/113 153/121/113 +f 120/122/114 121/123/114 124/124/114 +f 125/125/115 123/126/115 126/127/115 +f 123/126/115 125/125/115 127/128/115 +f 124/124/114 121/123/114 129/129/114 +f 120/122/114 124/124/114 131/130/114 +f 126/127/116 120/122/116 131/130/116 +f 125/125/115 126/127/115 131/130/115 +f 128/131/117 123/126/117 132/132/117 +f 124/124/118 128/131/118 132/132/118 +f 129/129/114 121/123/114 133/133/114 +f 125/125/119 134/134/119 136/120/119 +f 129/129/120 133/133/120 137/135/120 +f 133/133/121 130/136/121 137/135/121 +f 121/123/122 120/122/122 138/137/122 +f 120/122/116 126/127/116 138/137/116 +f 127/128/123 122/138/123 139/139/123 +f 123/126/115 127/128/115 139/139/115 +f 122/138/124 132/132/124 139/139/124 +f 132/132/117 123/126/117 139/139/117 +f 122/138/125 127/128/125 140/140/125 +f 127/128/115 125/125/115 140/140/115 +f 126/127/126 135/141/126 141/142/126 +f 135/141/127 128/131/127 141/142/127 +f 138/137/128 126/127/128 141/142/128 +f 128/131/118 124/124/118 142/143/118 +f 124/124/114 129/129/114 142/143/114 +f 142/143/129 129/129/129 143/144/129 +f 137/135/130 119/145/130 143/144/130 +f 129/129/120 137/135/120 143/144/120 +f 133/133/114 121/123/114 144/146/114 +f 130/136/121 133/133/121 144/146/121 +f 131/130/114 124/124/114 145/147/114 +f 125/125/131 131/130/131 145/147/131 +f 134/134/132 125/125/132 145/147/132 +f 124/124/133 134/134/133 145/147/133 +f 125/125/134 136/120/134 146/119/134 +f 122/138/135 140/140/135 146/119/135 +f 140/140/136 125/125/136 146/119/136 +f 141/142/137 130/136/137 147/148/137 +f 144/146/138 121/123/138 147/148/138 +f 130/136/139 144/146/139 147/148/139 +f 128/131/140 119/145/140 148/149/140 +f 119/145/141 137/135/141 148/149/141 +f 137/135/142 130/136/142 148/149/142 +f 141/142/143 128/131/143 148/149/143 +f 130/136/144 141/142/144 148/149/144 +f 119/145/145 128/131/145 149/150/145 +f 128/131/118 142/143/118 149/150/118 +f 142/143/129 143/144/129 149/150/129 +f 143/144/146 119/145/146 149/150/146 +f 126/127/115 123/126/115 150/151/115 +f 123/126/147 135/141/147 150/151/147 +f 135/141/148 126/127/148 150/151/148 +f 123/126/117 128/131/117 151/152/117 +f 135/141/147 123/126/147 151/152/147 +f 128/131/149 135/141/149 151/152/149 +f 121/123/122 138/137/122 152/153/122 +f 138/137/150 141/142/150 152/153/150 +f 147/148/151 121/123/151 152/153/151 +f 141/142/152 147/148/152 152/153/152 +f 132/132/153 122/138/153 153/121/153 +f 124/124/118 132/132/118 153/121/118 +f 134/134/154 124/124/154 153/121/154 +f 136/120/155 134/134/155 153/121/155 +f 122/138/156 146/119/156 153/121/156 +o cup_hull_8 +v -0.039367 0.009519 0.075211 +v -0.029677 0.021316 0.048666 +v -0.034312 0.021316 0.048666 +v -0.036418 -0.001013 0.048666 +v -0.032627 0.020472 0.075211 +v -0.040210 0.004464 0.048666 +v -0.038946 -0.001013 0.075211 +v -0.034313 0.021316 0.075211 +v -0.038103 0.013729 0.048666 +v -0.040210 -0.001013 0.048666 +v -0.040210 -0.001013 0.075211 +v -0.029677 0.020894 0.049931 +v -0.037261 0.015836 0.075211 +v -0.040210 0.004044 0.075211 +v -0.039367 0.009519 0.048666 +v -0.034734 0.020892 0.048666 +v -0.036418 -0.001013 0.049931 +v -0.032206 0.021316 0.072682 +v -0.037261 0.015836 0.048666 +v -0.034734 0.020892 0.075211 +v -0.038524 0.012466 0.075211 +v -0.038524 -0.001013 0.071417 +v -0.039788 0.007415 0.075211 +v -0.032206 0.020894 0.072682 +v -0.039788 0.007415 0.048666 +vt 0.000000 0.377447 +vt 1.000000 0.471711 +vt 1.000000 0.377447 vt 1.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.793951 -vt 0.919930 0.147220 -vt 0.032009 0.117756 -vt 0.919930 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.029464 -vt 0.000000 0.117756 +vt 1.000000 0.000000 +vt 1.000000 0.245301 +vt 0.000000 0.962216 +vt 0.000000 0.471711 vt 0.000000 0.000000 -vt 1.000000 0.500000 -vt 0.008027 0.117756 -vt 0.903974 0.000000 -vt 0.975920 0.793951 -vt 0.951938 0.088293 -vt 0.663861 0.029464 -vt 0.903974 0.058927 -vt 0.000000 0.264781 +vt 0.000000 1.000000 +vt 1.000000 0.660239 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.000000 0.147220 -vt 0.943911 0.117756 -vt 0.048062 0.029464 -vt 0.903974 0.117756 -vt 0.951938 0.088293 -vt 0.943911 0.206049 -vt 0.927956 0.029464 -vt 0.000000 0.117756 -vn 0.0000 0.9815 0.1916 +vt 0.952330 0.981108 +vt 0.000000 0.754601 +vt 0.000000 0.226507 +vt 1.000000 0.981010 +vt 0.952330 0.000000 +vt 0.095243 1.000000 +vt 1.000000 0.754601 +vt 0.000000 0.981010 +vt 0.000000 0.603661 +vt 0.142913 0.000000 +vt 0.095243 0.981108 +vn -0.9806 0.1960 0.0000 vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn -1.0000 -0.0000 0.0000 vn 0.0000 0.0000 1.0000 vn 0.0000 1.0000 0.0000 -vn -0.9093 0.3035 0.2846 vn 0.0000 -1.0000 0.0000 -vn -0.2427 0.9701 0.0000 -vn -0.2377 0.9703 0.0446 -vn -0.4977 0.8532 0.1558 -vn -0.2432 0.9546 0.1719 -vn 0.0000 -0.4164 -0.9092 -vn 0.1524 -0.9883 -0.0071 -vn 0.1244 -0.9922 0.0000 -vn 0.4474 -0.8944 0.0000 -vn 0.0960 -0.5511 -0.8289 -vn 0.2249 -0.9738 0.0349 -vn 0.1964 -0.9805 0.0000 -vn 0.2416 -0.9704 0.0021 -vn 0.1417 -0.9897 0.0220 -vn 0.2697 -0.9439 -0.1905 -vn 0.2747 -0.9615 0.0000 -vn 0.0000 -0.8181 -0.5751 -vn 0.2466 -0.8217 -0.5138 -vn 0.1770 -0.5898 -0.7879 -vn 0.0645 -0.9680 -0.2426 -vn 0.0212 -0.8294 -0.5583 -vn 0.1503 -0.9749 -0.1644 -vn 0.2113 -0.9015 -0.3778 -vn 0.2112 -0.9013 -0.3782 -vn 0.0968 -0.7522 -0.6518 -vn -0.6860 0.3432 0.6416 -vn -0.1968 0.9630 0.1841 -vn -0.1855 0.9647 0.1869 +vn -1.0000 0.0000 0.0000 +vn 0.9529 -0.2877 -0.0959 +vn -0.7090 0.7052 -0.0000 +vn 0.9558 -0.2941 0.0000 +vn 0.4193 0.8378 0.3495 +vn 0.9488 0.2996 0.0999 +vn -0.9285 0.3712 0.0000 +vn -0.8945 0.4471 0.0000 +vn -0.7099 0.7043 0.0000 +vn -0.9364 0.3509 0.0019 +vn -0.9614 0.2752 0.0000 +vn -0.9578 0.2876 -0.0015 +vn 0.9516 -0.2928 0.0932 +vn -0.9923 0.1242 0.0020 +vn 0.9533 -0.2803 0.1122 +vn 0.9864 0.0000 0.1645 +vn 0.9939 0.0000 0.1104 +vn 0.9538 -0.2812 0.1060 +vn -0.9899 0.1415 0.0000 usemtl None s off -f 204/192/182 195/193/182 221/194/182 -f 194/195/183 193/196/183 197/197/183 -f 193/196/184 195/193/184 198/198/184 -f 196/199/185 197/197/185 199/200/185 -f 197/197/183 193/196/183 201/201/183 -f 193/196/184 198/198/184 201/201/184 -f 195/193/186 200/202/186 202/203/186 -f 196/199/185 199/200/185 203/204/185 -f 200/202/186 195/193/186 203/204/186 -f 193/196/187 194/195/187 204/192/187 -f 199/200/185 197/197/185 205/205/185 -f 197/197/183 201/201/183 205/205/183 -f 196/199/188 203/204/188 206/206/188 -f 203/204/189 199/200/189 207/207/189 -f 194/195/190 197/197/190 208/208/190 -f 197/197/185 196/199/185 208/208/185 -f 204/192/191 194/195/191 208/208/191 -f 196/199/192 206/206/192 208/208/192 -f 206/206/193 204/192/193 208/208/193 -f 205/205/194 201/201/194 209/209/194 -f 192/210/195 207/207/195 210/211/195 -f 203/204/186 195/193/186 211/212/186 -f 195/193/182 204/192/182 211/212/182 -f 200/202/186 203/204/186 212/213/186 -f 207/207/196 192/210/196 212/213/196 -f 203/204/189 207/207/189 212/213/189 -f 198/198/184 195/193/184 213/214/184 -f 202/203/197 198/198/197 213/214/197 -f 195/193/186 202/203/186 213/214/186 -f 209/209/198 201/201/198 214/215/198 -f 202/203/199 200/202/199 215/216/199 -f 192/210/200 210/211/200 215/216/200 -f 210/211/201 202/203/201 215/216/201 -f 212/213/196 192/210/196 215/216/196 -f 200/202/202 212/213/202 215/216/202 -f 198/198/197 202/203/197 216/217/197 -f 210/211/203 198/198/203 216/217/203 -f 202/203/204 210/211/204 216/217/204 -f 199/200/185 205/205/185 217/218/185 -f 209/209/205 199/200/205 217/218/205 -f 205/205/194 209/209/194 217/218/194 -f 201/201/184 198/198/184 218/219/184 -f 198/198/206 214/215/206 218/219/206 -f 214/215/207 201/201/207 218/219/207 -f 207/207/208 199/200/208 219/220/208 -f 199/200/209 209/209/209 219/220/209 -f 210/211/210 207/207/210 219/220/210 -f 198/198/211 210/211/211 219/220/211 -f 214/215/212 198/198/212 219/220/212 -f 209/209/213 214/215/213 219/220/213 -f 206/206/214 203/204/214 220/221/214 -f 204/192/215 206/206/215 220/221/215 -f 203/204/186 211/212/186 220/221/186 -f 211/212/216 204/192/216 220/221/216 -f 195/193/184 193/196/184 221/194/184 -f 193/196/187 204/192/187 221/194/187 -o Cup_hull_10 -v 0.021743 -0.013016 0.050164 -v 0.025167 -0.000378 0.032460 -v 0.025167 -0.002222 0.032460 -v 0.017793 -0.014070 0.032460 -v 0.024113 -0.000379 0.050164 -v 0.021743 -0.013016 0.032460 -v 0.022796 -0.000379 0.032460 -v 0.019637 -0.014335 0.050164 -v 0.024640 -0.005645 0.050164 -v 0.024113 -0.007750 0.032460 -v 0.025167 -0.000378 0.050164 -v 0.020691 -0.014335 0.032460 -v 0.023323 -0.009856 0.050164 -v 0.019637 -0.013806 0.050164 -v 0.017793 -0.014070 0.033306 -v 0.020691 -0.014335 0.050164 -v 0.022796 -0.000379 0.033586 -v 0.025167 -0.002222 0.050164 -v 0.024903 -0.004328 0.032460 -v 0.023323 -0.009856 0.032460 -v 0.017793 -0.014335 0.032460 -v 0.024113 -0.007750 0.050164 -v 0.021217 -0.013806 0.032460 -v 0.024903 -0.004328 0.050164 -v 0.024640 -0.005645 0.032460 -v 0.021217 -0.013806 0.050164 -vt 0.000000 0.000000 -vt 1.000000 0.037882 -vt 0.000000 0.037882 +f 176/154/157 168/155/157 178/156/157 +f 156/157/158 155/158/158 157/159/158 +f 156/157/158 157/159/158 159/160/158 +f 158/161/159 154/162/159 160/163/159 +f 155/158/160 156/157/160 161/164/160 +f 154/162/159 158/161/159 161/164/159 +f 156/157/158 159/160/158 162/165/158 +f 159/160/158 157/159/158 163/166/158 +f 157/159/161 160/163/161 163/166/161 +f 163/166/161 160/163/161 164/167/161 +f 160/163/159 154/162/159 164/167/159 +f 159/160/162 163/166/162 164/167/162 +f 157/159/163 155/158/163 165/168/163 +f 154/162/159 161/164/159 166/169/159 +f 164/167/159 154/162/159 167/170/159 +f 159/160/162 164/167/162 167/170/162 +f 162/165/158 159/160/158 168/155/158 +f 161/164/164 156/157/164 169/171/164 +f 156/157/158 162/165/158 169/171/158 +f 160/163/161 157/159/161 170/172/161 +f 157/159/165 165/168/165 170/172/165 +f 155/158/160 161/164/160 171/173/160 +f 161/164/166 158/161/166 171/173/166 +f 165/168/167 155/158/167 171/173/167 +f 162/165/168 166/169/168 172/174/168 +f 169/171/158 162/165/158 172/174/158 +f 166/169/169 169/171/169 172/174/169 +f 166/169/159 161/164/159 173/175/159 +f 161/164/170 169/171/170 173/175/170 +f 169/171/169 166/169/169 173/175/169 +f 154/162/159 166/169/159 174/176/159 +f 166/169/171 162/165/171 174/176/171 +f 168/155/172 154/162/172 174/176/172 +f 162/165/173 168/155/173 174/176/173 +f 160/163/161 170/172/161 175/177/161 +f 170/172/174 165/168/174 175/177/174 +f 167/170/159 154/162/159 176/154/159 +f 159/160/175 167/170/175 176/154/175 +f 154/162/157 168/155/157 176/154/157 +f 158/161/176 160/163/176 177/178/176 +f 171/173/177 158/161/177 177/178/177 +f 165/168/178 171/173/178 177/178/178 +f 160/163/179 175/177/179 177/178/179 +f 175/177/179 165/168/179 177/178/179 +f 168/155/158 159/160/158 178/156/158 +f 159/160/180 176/154/180 178/156/180 +o cup_hull_9 +v -0.040210 0.004464 0.048666 +v -0.019565 0.021316 0.022545 +v -0.032626 0.021316 0.022545 +v -0.033048 -0.001013 0.022545 +v -0.029257 0.020892 0.048241 +v -0.035996 -0.001013 0.047819 +v -0.040210 -0.001013 0.026758 +v -0.028834 -0.001013 0.023388 +v -0.034311 0.021316 0.048666 +v -0.038102 0.013729 0.027180 +v -0.040210 -0.001013 0.048666 +v -0.019565 0.020892 0.023388 +v -0.038102 0.013729 0.048666 +v -0.034733 0.020892 0.027180 +v -0.039787 0.007415 0.027602 +v -0.038945 0.002779 0.025073 +v -0.029677 -0.001013 0.027180 +v -0.029677 0.021316 0.048666 +v -0.028834 -0.001013 0.022545 +v -0.020409 0.020892 0.025917 +v -0.039367 0.009519 0.048666 +v -0.036417 -0.001013 0.048666 +v -0.038945 0.008678 0.025917 +v -0.037259 0.015836 0.048666 +v -0.040210 0.004044 0.027180 +v -0.037259 0.015836 0.027180 +v -0.038945 -0.001013 0.025073 +v -0.034733 0.020892 0.048666 +v -0.033048 0.014151 0.022545 +v -0.034311 0.021316 0.026758 +v -0.038524 0.012466 0.027602 +v -0.038524 0.011622 0.026337 +v -0.039367 0.004044 0.025495 +v -0.039367 0.009519 0.033920 +v -0.020409 0.021316 0.025917 +v -0.039787 0.007415 0.048666 +vt 0.000000 0.471711 +vt 0.806382 0.377447 +vt 0.000000 0.377447 vt 1.000000 1.000000 -vt 1.000000 0.867854 -vt 1.000000 0.018990 -vt 1.000000 0.094460 -vt 1.000000 0.999902 -vt 0.000000 0.094460 -vt 0.000000 0.999902 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.032400 0.000000 +vt 0.838684 0.000000 +vt 0.967698 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.245301 vt 0.000000 0.000000 -vt 0.000000 0.622651 -vt 1.000000 0.471809 +vt 0.000000 0.660239 +vt 0.822533 0.000000 +vt 0.967698 0.981010 vt 0.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 0.320869 -vt 0.000000 0.037882 -vt 0.952232 0.018990 -vt 0.936374 0.999902 -vt 0.000000 0.867854 -vt 1.000000 0.717012 -vt 1.000000 0.320869 -vt 1.000000 0.000000 -vt 0.000000 0.471809 -vt 0.000000 0.717012 -vt 1.000000 0.622651 -vn 0.7093 -0.7049 0.0000 +vt 0.016249 0.981010 +vt 0.870889 0.981010 +vt 0.000000 0.000000 +vt 0.000000 0.754601 +vt 0.822533 0.660239 +vt 0.822533 0.226507 +vt 0.870889 0.434025 +vt 0.822533 0.981010 +vt 0.822533 0.754601 +vt 0.903191 0.000000 +vt 0.903191 0.169832 +vt 0.000000 0.981010 +vt 1.000000 0.679131 +vt 0.838684 1.000000 +vt 0.806382 0.603661 +vt 0.854836 0.565877 +vt 0.887040 0.226507 +vt 0.564507 0.471711 +vt 0.870889 1.000000 +vn -0.9806 0.1958 0.0000 vn 0.0000 0.0000 -1.0000 -vn 0.0000 0.0000 1.0000 -vn 1.0000 0.0000 0.0000 -vn -0.0006 1.0000 0.0000 -vn 0.8944 -0.4472 0.0000 -vn -0.9941 0.0000 0.1087 -vn -0.9392 0.3433 0.0000 -vn -0.9441 0.3147 0.0984 vn 0.0000 -1.0000 0.0000 -vn -0.0013 1.0000 0.0001 -vn -0.9371 0.3410 0.0744 -vn 0.9923 -0.1242 0.0000 -vn 0.9363 -0.3513 0.0000 -vn -0.9444 -0.3139 0.0984 +vn 0.0000 1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn 0.9701 -0.2428 0.0000 -vn 0.8322 -0.5545 0.0000 -vn 0.9806 -0.1962 0.0000 +vn -0.0000 0.0000 1.0000 +vn 0.8906 -0.3639 0.2727 +vn 0.9022 -0.3818 0.2005 +vn 0.9069 -0.3765 -0.1892 +vn 0.9209 -0.3897 0.0000 +vn 0.8921 -0.2813 0.3536 +vn 0.8929 -0.3371 0.2983 +vn 0.8615 -0.2733 0.4279 +vn 0.6019 -0.1817 0.7776 +vn -0.9285 0.3713 0.0000 +vn -0.9922 0.1246 -0.0024 +vn -0.9255 0.1590 -0.3437 +vn -0.8401 0.4198 -0.3436 +vn -0.9285 0.3714 0.0000 +vn -0.8945 0.4470 0.0000 +vn -0.3941 0.0000 -0.9191 +vn -0.7085 0.7057 0.0000 +vn -0.4354 0.0257 -0.8999 +vn -0.8117 0.4855 -0.3247 +vn -0.9484 0.3171 0.0000 +vn -0.9577 0.2878 0.0019 +vn -0.7386 0.1973 -0.6447 +vn -0.9271 0.1793 -0.3293 +vn -0.8346 0.3377 -0.4352 +vn -0.8427 0.3370 -0.4198 +vn -0.9500 0.2598 -0.1732 +vn -0.9577 0.2395 -0.1596 +vn -0.5695 0.0826 -0.8178 +vn -0.6533 0.1275 -0.7463 +vn -0.8938 0.0373 -0.4470 +vn -0.8878 0.1213 -0.4440 +vn -0.7996 -0.0167 -0.6003 +vn -0.7067 0.0000 -0.7075 +vn -0.9700 0.2425 -0.0163 +vn -0.9614 0.2750 0.0000 +vn 0.8733 0.4353 0.2187 +vn 0.8147 0.4754 0.3319 +vn 0.9297 0.0000 0.3684 +vn 0.9485 0.0000 0.3168 +vn -0.9899 0.1417 0.0000 usemtl None s off -f 237/222/217 244/223/217 247/224/217 -f 223/225/218 224/226/218 225/227/218 -f 225/227/218 224/226/218 227/228/218 -f 223/225/218 225/227/218 228/229/218 -f 222/230/219 226/231/219 229/232/219 -f 226/231/219 222/230/219 230/233/219 -f 227/228/218 224/226/218 231/234/218 -f 224/226/220 223/225/220 232/235/220 -f 223/225/221 228/229/221 232/235/221 -f 226/231/219 230/233/219 232/235/219 -f 225/227/218 227/228/218 233/236/218 -f 222/230/222 227/228/222 234/237/222 -f 230/233/219 222/230/219 234/237/219 -f 229/232/219 226/231/219 235/238/219 -f 229/232/223 235/238/223 236/239/223 -f 228/229/224 225/227/224 236/239/224 -f 235/238/225 226/231/225 236/239/225 -f 222/230/219 229/232/219 237/222/219 -f 229/232/226 233/236/226 237/222/226 -f 232/235/221 228/229/221 238/240/221 -f 226/231/227 232/235/227 238/240/227 -f 228/229/224 236/239/224 238/240/224 -f 236/239/228 226/231/228 238/240/228 -f 224/226/220 232/235/220 239/241/220 -f 232/235/219 230/233/219 239/241/219 -f 231/234/218 224/226/218 240/242/218 -f 224/226/229 239/241/229 240/242/229 -f 227/228/218 231/234/218 241/243/218 -f 234/237/222 227/228/222 241/243/222 -f 231/234/230 234/237/230 241/243/230 -f 225/227/218 233/236/218 242/244/218 -f 233/236/226 229/232/226 242/244/226 -f 229/232/231 236/239/231 242/244/231 -f 236/239/232 225/227/232 242/244/232 -f 231/234/233 230/233/233 243/245/233 -f 230/233/219 234/237/219 243/245/219 -f 234/237/230 231/234/230 243/245/230 -f 227/228/234 222/230/234 244/223/234 -f 233/236/218 227/228/218 244/223/218 -f 237/222/217 233/236/217 244/223/217 -f 239/241/219 230/233/219 245/246/219 -f 230/233/235 240/242/235 245/246/235 -f 240/242/229 239/241/229 245/246/229 -f 230/233/233 231/234/233 246/247/233 -f 231/234/218 240/242/218 246/247/218 -f 240/242/235 230/233/235 246/247/235 -f 222/230/219 237/222/219 247/224/219 -f 244/223/234 222/230/234 247/224/234 -o Cup_hull_11 -v 0.024903 -0.004329 0.032460 -v 0.021479 -0.000377 0.016161 -v 0.020426 -0.000379 0.015036 -v 0.020426 -0.014335 0.015036 -v 0.011211 -0.014335 0.016161 -v 0.017530 -0.014071 0.032177 -v 0.022533 -0.000377 0.032177 -v 0.025166 -0.000377 0.017846 -v 0.020690 -0.014335 0.032458 -v 0.018056 -0.000379 0.015036 -v 0.023322 -0.009856 0.018411 -v 0.025166 -0.000377 0.032460 -v 0.011211 -0.014335 0.015036 -v 0.023322 -0.009856 0.032460 -v 0.024375 -0.006699 0.018128 -v 0.018318 -0.000379 0.017285 -v 0.011474 -0.014071 0.017004 -v 0.021743 -0.013016 0.018411 -v 0.024375 -0.000905 0.016724 -v 0.017794 -0.014335 0.032458 -v 0.025166 -0.002222 0.018411 -v 0.024112 -0.007750 0.032460 -v 0.021743 -0.013016 0.032460 -v 0.024375 -0.004329 0.017004 -v 0.011211 -0.014071 0.016161 -v 0.022796 -0.000377 0.032460 -v 0.021216 -0.013807 0.018130 -v 0.024903 -0.004329 0.018411 -v 0.025166 -0.002222 0.032460 -v 0.023586 -0.008277 0.017285 -v 0.018056 -0.000379 0.015880 -v 0.024639 -0.005646 0.032460 -v 0.020690 -0.014335 0.017285 -v 0.011211 -0.014071 0.015036 -v 0.021216 -0.013807 0.032458 -vt 0.822435 0.037784 -vt 0.000000 0.094460 -vt 0.000098 0.037784 -vt 1.000000 0.999902 -vt 0.935395 1.000000 -vt 0.838684 1.000000 -vt 0.016249 1.000000 -vt 0.935395 0.000000 +f 199/179/181 193/180/181 214/181/181 +f 181/182/182 180/183/182 182/184/182 +f 182/184/183 184/185/183 185/186/183 +f 184/185/183 182/184/183 186/187/183 +f 180/183/184 181/182/184 187/188/184 +f 179/189/185 185/186/185 189/190/185 +f 185/186/183 184/185/183 189/190/183 +f 187/188/186 179/189/186 189/190/186 +f 179/189/186 187/188/186 191/191/186 +f 184/185/183 186/187/183 195/192/183 +f 190/193/187 184/185/187 195/192/187 +f 186/187/188 190/193/188 195/192/188 +f 180/183/184 187/188/184 196/194/184 +f 187/188/186 189/190/186 196/194/186 +f 182/184/182 180/183/182 197/195/182 +f 186/187/183 182/184/183 197/195/183 +f 180/183/189 190/193/189 197/195/189 +f 190/193/190 186/187/190 197/195/190 +f 183/196/191 184/185/191 198/197/191 +f 184/185/192 190/193/192 198/197/192 +f 179/189/186 191/191/186 199/179/186 +f 184/185/193 183/196/193 200/198/193 +f 189/190/183 184/185/183 200/198/183 +f 183/196/194 196/194/194 200/198/194 +f 196/194/186 189/190/186 200/198/186 +f 191/191/186 187/188/186 202/199/186 +f 188/200/195 191/191/195 202/199/195 +f 185/186/185 179/189/185 203/201/185 +f 179/189/196 193/180/196 203/201/196 +f 193/180/197 201/202/197 203/201/197 +f 192/203/198 181/182/198 204/204/198 +f 188/200/199 202/199/199 204/204/199 +f 202/199/200 192/203/200 204/204/200 +f 182/184/183 185/186/183 205/205/183 +f 194/206/201 182/184/201 205/205/201 +f 187/188/202 192/203/202 206/207/202 +f 202/199/186 187/188/186 206/207/186 +f 192/203/200 202/199/200 206/207/200 +f 181/182/182 182/184/182 207/208/182 +f 194/206/203 181/182/203 207/208/203 +f 182/184/201 194/206/201 207/208/201 +f 187/188/184 181/182/184 208/209/184 +f 181/182/204 192/203/204 208/209/204 +f 192/203/202 187/188/202 208/209/202 +f 191/191/205 188/200/205 209/210/205 +f 199/179/206 191/191/206 209/210/206 +f 181/182/207 201/202/207 210/211/207 +f 201/202/208 193/180/208 210/211/208 +f 204/204/209 181/182/209 210/211/209 +f 188/200/210 204/204/210 210/211/210 +f 209/210/211 188/200/211 210/211/211 +f 193/180/212 209/210/212 210/211/212 +f 181/182/213 194/206/213 211/212/213 +f 201/202/214 181/182/214 211/212/214 +f 185/186/215 203/201/215 211/212/215 +f 203/201/216 201/202/216 211/212/216 +f 205/205/217 185/186/217 211/212/217 +f 194/206/218 205/205/218 211/212/218 +f 193/180/181 199/179/181 212/213/181 +f 209/210/219 193/180/219 212/213/219 +f 199/179/220 209/210/220 212/213/220 +f 190/193/221 180/183/221 213/214/221 +f 196/194/222 183/196/222 213/214/222 +f 180/183/184 196/194/184 213/214/184 +f 183/196/223 198/197/223 213/214/223 +f 198/197/224 190/193/224 213/214/224 +f 193/180/225 179/189/225 214/181/225 +f 179/189/186 199/179/186 214/181/186 +o cup_hull_10 +v -0.015351 0.037325 0.075200 +v -0.004397 0.039855 0.026341 +v -0.004817 0.039855 0.026341 +v -0.015351 0.024689 0.022542 +v -0.004397 0.038590 0.075200 +v -0.015351 0.037325 0.026764 +v -0.004397 0.028480 0.022542 +v -0.006925 0.039855 0.075200 +v -0.014507 0.035640 0.075200 +v -0.015351 0.032690 0.022542 +v -0.014929 0.024689 0.024233 +v -0.010716 0.039012 0.027187 +v -0.004397 0.032692 0.022542 +v -0.004397 0.039855 0.075200 +v -0.005239 0.038169 0.075200 +v -0.004397 0.028480 0.023815 +v -0.010716 0.039012 0.075200 +v -0.015351 0.035640 0.075200 +v -0.006925 0.039855 0.027187 +v -0.006082 0.038590 0.025078 +v -0.014507 0.037747 0.027187 +v -0.010716 0.038169 0.025501 +v -0.014507 0.037747 0.075200 +v -0.009032 0.039433 0.027187 +v -0.014507 0.036904 0.025501 +v -0.004397 0.037747 0.024656 +v -0.009032 0.039433 0.075200 +v -0.015351 0.024689 0.024233 +v -0.014507 0.024689 0.022542 +vt 1.000000 0.249926 +vt 0.975820 0.249926 vt 1.000000 0.000000 -vt 0.000098 0.000000 -vt 1.000000 0.999902 -vt 0.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 0.716915 -vt 0.000000 0.320869 -vt 0.016249 0.018892 -vt 0.887040 0.018892 -vt 0.806284 0.320869 -vt 0.806284 0.094460 -vt 0.903093 0.962216 -vt 0.000098 0.000000 -vt 0.806284 0.867854 -vt 0.000000 0.471809 -vt 0.822533 0.547083 -vt 0.887040 0.716915 -vt 0.935395 0.018892 -vt 0.870889 0.999902 +vt 0.000000 0.833186 +vt 0.919824 0.833186 +vt 0.927851 1.000000 +vt 0.000000 0.916593 +vt 0.927851 1.000000 vt 0.000000 1.000000 -vt 0.806284 0.716915 -vt 0.000000 0.867854 -vt 0.870889 0.434025 -vt 0.951547 0.999902 -vt 0.000000 0.622553 -vt 0.870889 0.000000 -vt 1.000000 0.018892 -vn 0.8321 -0.5547 0.0000 -vn 0.0010 1.0000 -0.0021 -vn 0.0000 1.0000 -0.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 1.0000 -0.0012 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 0.0000 1.0000 -vn -0.8998 -0.2478 0.3591 -vn -0.8795 0.3213 0.3510 -vn 0.8812 -0.4404 -0.1718 -vn 0.8945 -0.4470 0.0000 -vn 0.3931 0.0000 -0.9195 -vn 0.3488 0.7294 -0.5885 -vn -0.8201 -0.4665 0.3313 -vn 1.0000 0.0000 0.0000 -vn 0.9364 -0.3510 0.0000 -vn 0.9484 -0.3169 -0.0058 -vn 0.0000 -0.0013 1.0000 -vn 0.5751 -0.0666 -0.8153 -vn 0.8266 -0.0458 -0.5610 -vn 0.9275 -0.1094 -0.3575 +vt 0.000000 0.722075 +vt 1.000000 0.527557 +vt 1.000000 0.527655 +vt 0.000000 1.000000 +vt 0.000000 0.888791 +vt 0.967890 0.000000 +vt 0.000000 0.944395 +vt 0.000000 0.722075 +vt 0.911796 1.000000 +vt 0.951836 0.916593 +vt 0.911796 0.860989 +vt 0.911796 0.944395 +vt 0.943808 0.888791 +vt 0.000000 0.860989 +vt 0.911796 0.972198 +vt 0.943808 0.805384 +vt 0.959863 0.860989 +vt 0.000000 0.972198 +vt 0.967890 0.000000 +vn 0.3510 -0.9364 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.8684 0.4306 0.2457 -vn -0.9544 0.0000 0.2986 -vn -0.8736 0.4026 0.2734 -vn -0.7070 0.2583 0.6584 -vn -0.6033 0.2161 0.7677 -vn -0.0004 0.0000 1.0000 -vn 0.8456 -0.5183 -0.1275 -vn 0.9923 -0.1242 0.0000 -vn 0.9237 -0.1641 -0.3461 -vn 0.9300 -0.1164 -0.3485 -vn 0.8884 -0.3554 -0.2906 -vn 0.9131 -0.3265 -0.2442 -vn 0.7927 -0.1996 -0.5760 -vn 0.8765 -0.2063 -0.4350 -vn -0.0004 1.0000 0.0000 -vn -0.0010 1.0000 0.0002 -vn -0.8944 0.4472 0.0000 -vn -0.8809 0.4438 0.1644 -vn 0.9700 -0.2431 0.0000 -vn 0.9805 -0.1963 0.0000 -vn 0.9762 -0.2169 -0.0020 -vn 0.7740 -0.6267 -0.0907 -vn 0.7081 -0.7062 0.0000 -vn 0.0065 -0.0065 1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.2578 -0.9451 0.2009 +vn 0.3394 -0.9233 0.1797 +vn 0.4411 -0.8806 0.1733 +vn 0.0000 -0.9777 0.2101 +vn 0.0000 0.7066 -0.7076 +vn -0.4469 0.8946 0.0000 +vn -0.3020 0.9050 -0.2998 +vn -0.3165 0.9486 0.0000 +vn -0.2738 0.8602 -0.4303 +vn -0.1272 0.7616 -0.6354 +vn -0.1254 0.5515 -0.8247 +vn -0.2428 0.9701 0.0000 +vn -0.1763 0.8809 -0.4393 +vn -0.1962 0.9806 0.0000 +vn -0.2184 0.8727 -0.4366 +vn -0.1805 0.8648 -0.4685 +vn -0.6101 0.5336 -0.5858 +vn -0.2799 0.8388 -0.4670 +vn -0.1967 0.5896 -0.7834 +vn -0.0001 0.3857 -0.9226 +vn 0.1158 0.6203 -0.7758 +vn -0.0182 0.4188 -0.9079 +vn 0.0000 -1.0000 0.0000 +vn 0.3404 -0.9364 0.0848 usemtl None s off -f 274/248/236 270/249/236 282/250/236 -f 250/251/237 249/252/237 255/253/237 -f 249/252/238 254/254/238 255/253/238 -f 252/255/239 251/256/239 256/257/239 -f 249/252/240 250/251/240 257/258/240 -f 250/251/241 251/256/241 257/258/241 -f 255/253/238 254/254/238 259/259/238 -f 251/256/239 252/255/239 260/260/239 -f 257/258/241 251/256/241 260/260/241 -f 248/261/242 259/259/242 261/262/242 -f 252/255/243 253/263/243 264/264/243 -f 253/263/244 254/254/244 264/264/244 -f 251/256/245 258/265/245 265/266/245 -f 258/265/246 261/262/246 265/266/246 -f 251/256/247 250/251/247 266/267/247 -f 250/251/248 255/253/248 266/267/248 -f 253/263/249 252/255/249 267/268/249 -f 252/255/239 256/257/239 267/268/239 -f 255/253/250 259/259/250 268/269/250 -f 248/261/242 261/262/242 269/270/242 -f 261/262/251 258/265/251 269/270/251 -f 258/265/252 262/271/252 269/270/252 -f 261/262/242 259/259/242 270/249/242 -f 265/266/246 261/262/246 270/249/246 -f 267/268/253 256/257/253 270/249/253 -f 251/256/254 266/267/254 271/272/254 -f 266/267/255 255/253/255 271/272/255 -f 255/253/256 268/269/256 271/272/256 -f 260/260/257 252/255/257 272/273/257 -f 254/254/258 263/274/258 272/273/258 -f 252/255/259 264/264/259 272/273/259 -f 264/264/260 254/254/260 272/273/260 -f 254/254/261 253/263/261 273/275/261 -f 259/259/238 254/254/238 273/275/238 -f 253/263/262 267/268/262 273/275/262 -f 270/249/242 259/259/242 273/275/242 -f 267/268/263 270/249/263 273/275/263 -f 251/256/264 265/266/264 274/248/264 -f 265/266/236 270/249/236 274/248/236 -f 268/269/265 248/261/265 275/276/265 -f 262/271/266 271/272/266 275/276/266 -f 271/272/267 268/269/267 275/276/267 -f 259/259/242 248/261/242 276/277/242 -f 248/261/265 268/269/265 276/277/265 -f 268/269/250 259/259/250 276/277/250 -f 258/265/268 251/256/268 277/278/268 -f 262/271/269 258/265/269 277/278/269 -f 251/256/270 271/272/270 277/278/270 -f 271/272/271 262/271/271 277/278/271 -f 254/254/272 249/252/272 278/279/272 -f 249/252/272 257/258/272 278/279/272 -f 263/274/273 254/254/273 278/279/273 -f 257/258/274 272/273/274 278/279/274 -f 272/273/275 263/274/275 278/279/275 -f 248/261/242 269/270/242 279/280/242 -f 269/270/276 262/271/276 279/280/276 -f 275/276/277 248/261/277 279/280/277 -f 262/271/278 275/276/278 279/280/278 -f 256/257/239 251/256/239 280/281/239 -f 251/256/279 274/248/279 280/281/279 -f 274/248/280 256/257/280 280/281/280 -f 257/258/241 260/260/241 281/282/241 -f 260/260/257 272/273/257 281/282/257 -f 272/273/274 257/258/274 281/282/274 -f 270/249/281 256/257/281 282/250/281 -f 256/257/280 274/248/280 282/250/280 -o Cup_hull_12 -v 0.024903 0.004363 0.050164 -v 0.021217 0.013580 0.032460 -v 0.021481 0.013315 0.032460 -v 0.022796 -0.000377 0.032460 -v 0.020164 0.013052 0.050164 -v 0.018320 0.013315 0.032460 -v 0.025167 0.002257 0.032460 -v 0.024113 -0.000377 0.050164 -v 0.023322 0.009891 0.050164 -v 0.024376 0.006732 0.032460 -v 0.025167 -0.000377 0.032460 -v 0.021217 0.013580 0.050164 -v 0.025167 -0.000377 0.050164 -v 0.018320 0.013315 0.033306 -v 0.023060 0.010417 0.032460 -v 0.021743 0.013052 0.050164 -v 0.022796 -0.000377 0.033586 -v 0.018320 0.013580 0.033306 -v 0.024376 0.006732 0.050164 -v 0.025167 0.002257 0.050164 -v 0.020164 0.013580 0.050164 -v 0.024903 0.004363 0.032460 -v 0.022006 0.012525 0.032460 -v 0.023586 0.009103 0.032460 -v 0.024640 0.005682 0.045386 -vt 1.000000 0.339663 -vt 1.000000 0.509397 -vt 0.269871 0.434123 -vt 1.000000 1.000000 -vt 1.000000 0.981010 -vt 1.000000 0.000000 -vt 1.000000 0.981010 -vt 1.000000 0.188724 -vt 0.000000 0.339663 -vt 0.000000 0.962216 +f 221/215/226 230/216/226 243/217/226 +f 218/218/227 215/219/227 220/220/227 +f 216/221/228 219/222/228 221/215/228 +f 216/221/229 217/223/229 222/224/229 +f 215/219/230 219/222/230 222/224/230 +f 219/222/230 215/219/230 223/225/230 +f 218/218/227 220/220/227 224/226/227 +f 221/215/231 218/218/231 224/226/231 +f 216/221/228 221/215/228 227/227/228 +f 221/215/231 224/226/231 227/227/231 +f 219/222/228 216/221/228 228/228/228 +f 216/221/229 222/224/229 228/228/229 +f 222/224/230 219/222/230 228/228/230 +f 219/222/230 223/225/230 229/229/230 +f 223/225/232 225/230/232 229/229/232 +f 229/229/233 225/230/233 230/216/233 +f 221/215/228 219/222/228 230/216/228 +f 219/222/234 229/229/234 230/216/234 +f 215/219/230 222/224/230 231/231/230 +f 215/219/227 218/218/227 232/232/227 +f 223/225/230 215/219/230 232/232/230 +f 225/230/235 223/225/235 232/232/235 +f 222/224/229 217/223/229 233/233/229 +f 217/223/236 216/221/236 234/234/236 +f 220/220/237 215/219/237 235/235/237 +f 226/236/238 220/220/238 235/235/238 +f 231/231/239 226/236/239 235/235/239 +f 220/220/240 226/236/240 236/237/240 +f 217/223/241 234/234/241 236/237/241 +f 234/234/242 224/226/242 236/237/242 +f 215/219/230 231/231/230 237/238/230 +f 235/235/237 215/219/237 237/238/237 +f 231/231/239 235/235/239 237/238/239 +f 226/236/243 231/231/243 238/239/243 +f 233/233/244 217/223/244 238/239/244 +f 222/224/245 233/233/245 238/239/245 +f 236/237/246 226/236/246 238/239/246 +f 217/223/247 236/237/247 238/239/247 +f 224/226/248 220/220/248 239/240/248 +f 220/220/249 236/237/249 239/240/249 +f 236/237/250 224/226/250 239/240/250 +f 216/221/228 227/227/228 240/241/228 +f 227/227/251 224/226/251 240/241/251 +f 234/234/252 216/221/252 240/241/252 +f 224/226/253 234/234/253 240/241/253 +f 231/231/230 222/224/230 241/242/230 +f 222/224/245 238/239/245 241/242/245 +f 238/239/243 231/231/243 241/242/243 +f 218/218/254 225/230/254 242/243/254 +f 232/232/227 218/218/227 242/243/227 +f 225/230/235 232/232/235 242/243/235 +f 218/218/231 221/215/231 243/217/231 +f 225/230/254 218/218/254 243/217/254 +f 230/216/255 225/230/255 243/217/255 +o cup_hull_11 +v 0.016671 -0.036830 0.047404 +v -0.004396 -0.040201 0.075208 +v 0.004455 -0.040201 0.075208 +v 0.020883 -0.029246 0.048248 +v -0.004396 -0.040201 0.047404 +v 0.021306 -0.032617 0.075208 +v -0.004396 -0.035988 0.049092 +v -0.004396 -0.038514 0.075208 +v 0.020883 -0.034724 0.075208 +v 0.009506 -0.039357 0.047404 +v 0.021306 -0.034302 0.047404 +v 0.013718 -0.038094 0.075208 +v -0.004396 -0.035988 0.047404 +v 0.004455 -0.040201 0.047404 +v 0.021306 -0.029246 0.047404 +v 0.020463 -0.032617 0.075208 +v 0.009506 -0.039357 0.075208 +v 0.013718 -0.038094 0.047404 +v 0.015826 -0.037251 0.075208 +v 0.020883 -0.034724 0.047404 +v 0.021306 -0.034302 0.075208 +v 0.007403 -0.039779 0.047404 +v 0.007403 -0.039779 0.075208 +v 0.012455 -0.038514 0.047404 +vt 1.000000 0.704777 +vt 0.000000 0.704777 +vt 1.000000 0.655638 +vt 0.000000 0.344362 vt 0.000000 0.000000 -vt 0.000000 0.735709 vt 1.000000 0.000000 vt 0.000000 1.000000 +vt 0.939311 0.000000 vt 0.000000 0.000000 -vt 0.952232 0.981010 -vt 1.000000 0.773395 -vt 0.000000 0.962216 -vt 0.936374 0.000000 -vt 0.952232 1.000000 -vt 0.000000 0.509397 -vt 0.000000 0.188724 -vt 0.000000 1.000000 -vt 1.000000 0.924432 -vt 1.000000 0.679229 -vn 0.9762 0.2171 -0.0023 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.9505 -0.3107 0.0000 -vn -0.9546 -0.2807 0.1000 -vn 0.7093 0.7049 -0.0001 -vn 0.7079 0.7063 0.0000 -vn 0.8946 0.4468 -0.0000 -vn -0.9483 -0.3085 0.0753 -vn -0.0870 0.9506 -0.2979 -vn 0.0000 1.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.9941 0.0000 0.1087 -vn 0.9922 0.1244 0.0000 -vn 0.8325 0.5540 -0.0041 -vn 0.8945 0.4471 -0.0000 -vn 0.9282 0.3720 -0.0027 -vn 0.9486 0.3164 0.0001 -vn 0.9488 0.3160 0.0000 -vn 0.9761 0.2171 0.0062 -vn 0.9698 0.2438 0.0000 -vn 0.9807 0.1954 0.0000 -usemtl None -s off -f 304/283/282 292/284/282 307/285/282 -f 284/286/283 285/287/283 286/288/283 -f 284/286/283 286/288/283 288/289/283 -f 286/288/283 285/287/283 289/290/283 -f 283/291/284 287/292/284 290/293/284 -f 287/292/284 283/291/284 291/294/284 -f 289/290/283 285/287/283 292/284/283 -f 286/288/283 289/290/283 293/295/283 -f 290/293/285 286/288/285 293/295/285 -f 287/292/284 291/294/284 294/296/284 -f 283/291/284 290/293/284 295/297/284 -f 293/295/286 289/290/286 295/297/286 -f 290/293/285 293/295/285 295/297/285 -f 288/289/287 286/288/287 296/298/287 -f 290/293/288 287/292/288 296/298/288 -f 292/284/283 285/287/283 297/299/283 -f 285/287/289 284/286/289 298/300/289 -f 284/286/290 294/296/290 298/300/290 -f 294/296/284 291/294/284 298/300/284 -f 291/294/291 297/299/291 298/300/291 -f 286/288/285 290/293/285 299/301/285 -f 296/298/287 286/288/287 299/301/287 -f 290/293/292 296/298/292 299/301/292 -f 284/286/293 288/289/293 300/302/293 -f 294/296/294 284/286/294 300/302/294 -f 288/289/295 296/298/295 300/302/295 -f 296/298/296 287/292/296 300/302/296 -f 291/294/284 283/291/284 301/303/284 -f 289/290/297 283/291/297 302/304/297 -f 283/291/284 295/297/284 302/304/284 -f 295/297/286 289/290/286 302/304/286 -f 287/292/284 294/296/284 303/305/284 -f 294/296/294 300/302/294 303/305/294 -f 300/302/296 287/292/296 303/305/296 -f 283/291/297 289/290/297 304/283/297 -f 289/290/283 292/284/283 304/283/283 -f 297/299/283 285/287/283 305/306/283 -f 285/287/298 298/300/298 305/306/298 -f 298/300/299 297/299/299 305/306/299 -f 297/299/300 291/294/300 306/307/300 -f 292/284/283 297/299/283 306/307/283 -f 291/294/301 301/303/301 306/307/301 -f 301/303/302 292/284/302 306/307/302 -f 301/303/303 283/291/303 307/285/303 -f 292/284/304 301/303/304 307/285/304 -f 283/291/305 304/283/305 307/285/305 -o Cup_hull_13 -v 0.022533 0.001203 0.032460 -v 0.020425 0.013580 0.015036 -v 0.024113 0.006469 0.017285 -v 0.018057 -0.000377 0.015036 -v 0.012001 0.013580 0.015880 -v 0.021215 0.013580 0.032458 -v 0.025167 -0.000377 0.032460 -v 0.024903 -0.000377 0.017285 -v 0.018057 0.013315 0.032177 -v 0.022533 -0.000377 0.032177 -v 0.024640 0.005682 0.032460 -v 0.023060 0.010418 0.018409 -v 0.024903 0.004363 0.018409 -v 0.012001 0.013580 0.015036 -v 0.018319 -0.000377 0.017285 -v 0.020425 -0.000377 0.015036 -v 0.023060 0.010418 0.032460 -v 0.012001 0.013315 0.015880 -v 0.021478 0.013315 0.017846 -v 0.025167 0.002257 0.018409 -v 0.024375 0.006732 0.018409 -v 0.018319 0.013580 0.032458 -v 0.024375 0.000677 0.016724 -v 0.025167 0.002257 0.032460 -v 0.022007 0.012525 0.032460 -v 0.012265 0.013315 0.016724 -v 0.025167 -0.000377 0.017848 -v 0.023585 0.009101 0.032460 -v 0.023585 0.009101 0.018130 -v 0.024375 0.004101 0.017004 -v 0.022007 0.012525 0.018409 -v 0.021215 0.013580 0.017846 -v 0.018057 -0.000377 0.015880 -v 0.024903 0.004363 0.032460 -v 0.024375 0.006732 0.032460 -v 0.022797 -0.000377 0.032460 -v 0.024903 0.003048 0.017567 -vt 0.870889 0.000000 -vt 0.887040 0.320869 -vt 0.854738 0.245399 +vt 0.969656 0.983555 +vt 0.000000 0.983555 +vt 1.000000 0.819695 +vt 1.000000 0.540916 vt 1.000000 1.000000 -vt 0.951547 1.000000 -vt 0.000098 1.000000 -vt 0.000000 0.000000 vt 1.000000 0.000000 -vt 0.016249 0.000000 -vt 0.000000 0.113254 -vt 0.000000 0.434123 +vt 1.000000 0.344362 vt 1.000000 1.000000 -vt 0.870889 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.773493 -vt 0.951547 0.981010 -vt 0.806382 0.773493 -vt 0.838684 0.981010 -vt 0.806382 0.339663 -vt 0.806382 0.509397 -vt 0.870889 0.490505 -vt 0.000098 1.000000 -vt 0.016249 0.981010 -vt 0.903093 0.075568 -vt 0.000000 0.188724 -vt 0.806382 0.188724 -vt 0.000000 0.924432 -vt 0.903093 0.981010 -vt 0.838587 0.000000 -vt 0.000000 0.679131 -vt 0.822435 0.679131 -vt 0.806382 0.924432 -vt 0.838684 1.000000 -vt 0.951547 0.000000 -vt 0.000000 0.339663 -vt 0.000000 0.509397 -vt 0.000000 0.000000 -vn 0.7754 0.0517 -0.6294 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn -0.9103 -0.3950 -0.1240 -vn -1.0000 0.0000 0.0000 -vn -0.8884 -0.3842 0.2513 -vn 0.8637 0.4163 -0.2843 -vn 0.9761 0.2172 -0.0021 -vn 0.9402 0.2092 -0.2690 -vn -0.8192 0.4811 0.3122 -vn 0.3931 0.0000 -0.9195 -vn 0.4355 -0.2435 -0.8667 -vn 1.0000 0.0000 0.0000 -vn 0.9922 0.1244 0.0000 -vn 0.8945 0.4471 0.0000 -vn 0.7999 0.6001 0.0035 -vn 0.0000 0.0016 1.0000 -vn -0.0005 -0.0000 1.0000 -vn -0.9208 0.1815 0.3451 -vn -0.8954 -0.2927 0.3356 -vn -0.9544 0.0000 0.2987 -vn -0.8925 -0.3541 0.2793 -vn 0.9287 0.3708 0.0000 -vn 0.9486 0.3164 0.0000 -vn 0.8514 0.3069 -0.4254 -vn 0.8648 0.4076 -0.2933 -vn 0.9203 0.2739 -0.2795 -vn 0.7206 0.1602 -0.6746 -vn 0.5691 0.0670 -0.8196 -vn 0.7744 0.0515 -0.6306 -vn 0.8750 0.4373 -0.2079 -vn 0.8311 0.5561 0.0000 -vn 0.6962 0.6906 -0.1957 -vn 0.7100 0.7043 0.0000 -vn -0.9145 -0.4045 0.0000 -vn -0.9014 -0.3987 0.1686 -vn 0.9807 0.1956 0.0000 -vn 0.9698 0.2439 0.0000 -vn -0.7111 -0.2325 0.6636 -vn -0.6165 -0.1977 0.7621 -vn -0.0008 -0.0001 1.0000 -vn 0.9349 0.1913 -0.2988 -vn 0.9740 0.1222 -0.1907 -vn 0.9047 0.0349 -0.4247 -vn 0.9661 0.0538 -0.2524 -vn 0.8487 0.1544 -0.5059 -usemtl None -s off -f 315/308/306 337/309/306 344/310/306 -f 309/311/307 312/312/307 313/313/307 -f 314/314/308 311/315/308 315/308/308 -f 311/315/308 314/314/308 317/316/308 -f 308/317/309 314/314/309 318/318/309 -f 309/311/310 311/315/310 321/319/310 -f 312/312/307 309/311/307 321/319/307 -f 311/315/308 317/316/308 322/320/308 -f 311/315/310 309/311/310 323/321/310 -f 315/308/308 311/315/308 323/321/308 -f 308/317/309 318/318/309 324/322/309 -f 321/319/311 311/315/311 325/323/311 -f 312/312/312 321/319/312 325/323/312 -f 322/320/313 317/316/313 325/323/313 -f 319/324/314 309/311/314 326/325/314 -f 318/318/315 320/326/315 328/327/315 -f 320/326/316 310/328/316 328/327/316 -f 313/313/307 312/312/307 329/329/307 -f 312/312/317 316/330/317 329/329/317 -f 323/321/318 309/311/318 330/331/318 -f 315/308/319 323/321/319 330/331/319 -f 318/318/309 314/314/309 331/332/309 -f 314/314/320 327/333/320 331/332/320 -f 327/333/321 320/326/321 331/332/321 -f 308/317/309 324/322/309 332/334/309 -f 324/322/322 319/324/322 332/334/322 -f 326/325/323 313/313/323 332/334/323 -f 313/313/324 329/329/324 332/334/324 -f 329/329/325 308/317/325 332/334/325 -f 316/330/326 312/312/326 333/335/326 -f 317/316/327 316/330/327 333/335/327 -f 312/312/328 325/323/328 333/335/328 -f 325/323/329 317/316/329 333/335/329 -f 314/314/308 315/308/308 334/336/308 -f 327/333/320 314/314/320 334/336/320 -f 324/322/309 318/318/309 335/337/309 -f 319/324/330 324/322/330 335/337/330 -f 335/337/331 328/327/331 336/338/331 -f 310/328/332 309/311/332 336/338/332 -f 309/311/333 319/324/333 336/338/333 -f 328/327/334 310/328/334 336/338/334 -f 319/324/330 335/337/330 336/338/330 -f 309/311/335 310/328/335 337/309/335 -f 330/331/336 309/311/336 337/309/336 -f 315/308/337 330/331/337 337/309/337 -f 319/324/338 326/325/338 338/339/338 -f 332/334/322 319/324/322 338/339/322 -f 326/325/339 332/334/339 338/339/339 -f 309/311/307 313/313/307 339/340/307 -f 326/325/340 309/311/340 339/340/340 -f 313/313/341 326/325/341 339/340/341 -f 311/315/308 322/320/308 340/341/308 -f 325/323/342 311/315/342 340/341/342 -f 322/320/343 325/323/343 340/341/343 -f 320/326/344 318/318/344 341/342/344 -f 318/318/309 331/332/309 341/342/309 -f 331/332/321 320/326/321 341/342/321 -f 318/318/345 328/327/345 342/343/345 -f 335/337/309 318/318/309 342/343/309 -f 328/327/331 335/337/331 342/343/331 -f 314/314/309 308/317/309 343/344/309 -f 317/316/308 314/314/308 343/344/308 -f 316/330/346 317/316/346 343/344/346 -f 329/329/347 316/330/347 343/344/347 -f 308/317/348 329/329/348 343/344/348 -f 310/328/349 320/326/349 344/310/349 -f 320/326/350 327/333/350 344/310/350 -f 334/336/351 315/308/351 344/310/351 -f 327/333/352 334/336/352 344/310/352 -f 337/309/353 310/328/353 344/310/353 -o Cup_hull_14 -v 0.008313 0.022796 0.050166 -v 0.001204 0.025166 0.017848 -v 0.003047 0.024902 0.017567 -v 0.008049 0.015951 0.015036 -v 0.000413 0.024112 0.050166 -v 0.000413 0.018058 0.015036 -v 0.008313 0.023849 0.018130 -v 0.004363 0.024902 0.050166 -v 0.000413 0.024376 0.016724 -v 0.008313 0.020427 0.015036 -v 0.000413 0.025166 0.050166 -v 0.008313 0.023849 0.050166 -v 0.005679 0.024639 0.018409 -v 0.008313 0.015951 0.015318 -v 0.000413 0.018058 0.015882 -v 0.000413 0.020428 0.015036 -v 0.002257 0.025166 0.018409 -v 0.008049 0.015951 0.015318 -v 0.007785 0.022796 0.050166 -v 0.000413 0.025166 0.017848 -v 0.006733 0.023849 0.017006 -v 0.006733 0.024377 0.050166 -v 0.002257 0.025166 0.047913 -v 0.004363 0.024902 0.018409 -v 0.006733 0.024377 0.018409 -v 0.003836 0.024112 0.016724 -v 0.008313 0.023323 0.017006 -v 0.005679 0.024639 0.050166 -vt 0.000000 0.914342 -vt 0.903974 0.942829 -vt 0.000000 0.942829 -vt 0.000000 0.885659 -vt 0.000000 0.742830 -vt 0.000000 0.971415 -vt 0.919930 1.000000 -vt 0.927956 0.971415 -vt 0.951938 0.914244 -vt 1.000000 0.228684 -vt 1.000000 0.000000 -vt 1.000000 0.485756 -vt 0.911903 0.857073 +vt 0.000000 0.967208 +vt 0.000000 0.540916 +vt 0.000000 0.786805 +vt 1.000000 0.983555 vt 0.000000 1.000000 -vt 0.000000 0.857073 -vt 0.991973 0.000000 -vt 0.975920 0.228684 -vt 1.000000 0.485854 -vt 0.903974 1.000000 -vt 0.991973 0.000000 -vt 0.000000 0.742830 -vt 0.919930 1.000000 -vt 0.943911 0.857073 -vt 0.064115 1.000000 -vt 0.903974 0.971415 -vt 0.903974 0.914342 -vt 0.951938 0.885659 -vt 0.943911 0.800000 -vn 0.2417 0.9704 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.0259 0.8092 -0.5869 +vt 1.000000 0.459084 +vt 0.000000 0.459084 +vn 0.3158 -0.9488 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 +vn -0.2537 0.9628 0.0931 vn 0.0000 0.0000 -1.0000 +vn -0.2577 0.9662 0.0000 +vn 0.2336 0.9653 0.1170 vn 1.0000 0.0000 0.0000 -vn 0.7297 -0.0430 -0.6824 -vn -0.2660 -0.9640 0.0000 -vn 0.0000 0.3932 -0.9194 -vn 0.1080 0.9732 -0.2030 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -0.9812 0.1928 -vn 0.0000 -1.0000 0.0000 -vn -0.2506 -0.9533 0.1683 -vn -0.1726 -0.9668 0.1886 -vn 0.0000 0.8182 -0.5750 -vn 0.2058 0.9106 -0.3583 -vn 0.3168 0.9485 0.0000 -vn 0.0664 0.9963 0.0544 -vn 0.1241 0.9923 0.0000 -vn 0.1962 0.9806 0.0000 -vn 0.1876 0.9375 -0.2931 -vn 0.1219 0.9741 -0.1904 -vn 0.2431 0.9079 -0.3415 -vn 0.2270 0.9115 -0.3429 -vn 0.0581 0.7547 -0.6535 -vn 0.0347 0.4508 -0.8920 -vn 0.1305 0.7812 -0.6105 -vn 0.1300 0.5392 -0.8321 -vn 0.2887 0.8672 -0.4056 -vn 0.1841 0.5529 -0.8126 +vn -0.2517 0.9596 -0.1261 +vn 0.0000 0.9923 0.1241 +vn -0.2292 0.9663 0.1173 +vn 0.3712 -0.9285 0.0000 +vn 0.4471 -0.8945 0.0000 +vn 0.3935 -0.9193 -0.0020 +vn 0.4473 -0.8944 0.0000 +vn 0.7061 -0.7081 0.0000 +vn 0.1418 -0.9899 0.0000 +vn 0.1965 -0.9805 0.0000 +vn 0.2748 -0.9615 0.0000 +vn 0.2873 -0.9578 0.0014 usemtl None s off -f 366/345/354 357/346/354 372/347/354 -f 349/348/355 345/349/355 352/350/355 -f 346/351/356 347/352/356 353/353/356 -f 350/354/357 349/348/357 353/353/357 -f 348/355/358 350/354/358 354/356/358 -f 351/357/359 345/349/359 354/356/359 -f 349/348/355 352/350/355 355/358/355 -f 353/353/357 349/348/357 355/358/357 -f 345/349/359 351/357/359 356/359/359 -f 352/350/355 345/349/355 356/359/355 -f 354/356/359 345/349/359 358/360/359 -f 348/355/360 354/356/360 358/360/360 -f 349/348/357 350/354/357 359/361/357 -f 350/354/361 348/355/361 359/361/361 -f 350/354/357 353/353/357 360/362/357 -f 354/356/358 350/354/358 360/362/358 -f 353/353/362 354/356/362 360/362/362 -f 347/352/363 346/351/363 361/363/363 -f 346/351/364 355/358/364 361/363/364 -f 358/360/365 345/349/365 362/364/365 -f 348/355/366 358/360/366 362/364/366 -f 359/361/361 348/355/361 362/364/361 -f 349/348/367 359/361/367 362/364/367 -f 345/349/355 349/348/355 363/365/355 -f 362/364/365 345/349/365 363/365/365 -f 349/348/368 362/364/368 363/365/368 -f 346/351/369 353/353/369 364/366/369 -f 355/358/364 346/351/364 364/366/364 -f 353/353/357 355/358/357 364/366/357 -f 347/352/370 357/346/370 365/367/370 -f 356/359/371 351/357/371 366/345/371 -f 352/350/355 356/359/355 366/345/355 -f 355/358/372 352/350/372 367/368/372 -f 361/363/364 355/358/364 367/368/364 -f 352/350/373 361/363/373 367/368/373 -f 352/350/374 357/346/374 368/369/374 -f 357/346/375 347/352/375 368/369/375 -f 347/352/376 361/363/376 368/369/376 -f 361/363/373 352/350/373 368/369/373 -f 351/357/377 365/367/377 369/370/377 -f 365/367/378 357/346/378 369/370/378 -f 366/345/371 351/357/371 369/370/371 -f 357/346/354 366/345/354 369/370/354 -f 353/353/379 347/352/379 370/371/379 -f 354/356/380 353/353/380 370/371/380 -f 347/352/381 365/367/381 370/371/381 -f 365/367/382 354/356/382 370/371/382 -f 351/357/359 354/356/359 371/372/359 -f 365/367/383 351/357/383 371/372/383 -f 354/356/384 365/367/384 371/372/384 -f 357/346/374 352/350/374 372/347/374 -f 352/350/355 366/345/355 372/347/355 -o Cup_hull_15 -v -0.002221 -0.020392 -0.048198 -v -0.020392 -0.014862 0.015036 -v -0.020126 -0.015389 0.015036 -v -0.002221 -0.017758 0.015036 -v -0.013280 -0.011965 -0.048198 -v -0.014860 -0.020392 -0.048198 -v -0.014860 -0.020392 0.015036 -v -0.013280 -0.011965 0.015036 -v -0.020392 -0.011965 -0.048198 -v -0.002221 -0.020392 0.015036 -v -0.002221 -0.017758 -0.048198 -v -0.020392 -0.011965 0.015036 -v -0.020126 -0.015389 -0.048198 -v -0.016704 -0.019073 -0.027679 -v -0.019074 -0.016704 0.015036 -v -0.019074 -0.016704 -0.048198 -v -0.020392 -0.014862 -0.048198 -v -0.015386 -0.020128 0.015036 -v -0.015386 -0.020128 -0.048198 -v -0.016968 -0.018811 0.015036 -v -0.016704 -0.019073 -0.048198 -vt 0.000000 0.188430 -vt 1.000000 0.072533 -vt 1.000000 0.202917 +f 261/244/256 255/245/256 267/246/256 +f 246/247/257 245/248/257 248/249/257 +f 245/248/258 246/247/258 249/250/258 +f 248/249/259 245/248/259 250/251/259 +f 250/251/259 245/248/259 251/252/259 +f 245/248/258 249/250/258 251/252/258 +f 247/253/260 250/251/260 251/252/260 +f 249/250/258 246/247/258 252/254/258 +f 248/249/261 244/255/261 253/256/261 +f 244/255/261 248/249/261 254/257/261 +f 252/254/258 246/247/258 255/245/258 +f 250/251/262 247/253/262 256/258/262 +f 248/249/259 250/251/259 256/258/259 +f 254/257/261 248/249/261 256/258/261 +f 246/247/257 248/249/257 257/259/257 +f 248/249/261 253/256/261 257/259/261 +f 247/253/263 249/250/263 258/260/263 +f 249/250/264 254/257/264 258/260/264 +f 256/258/265 247/253/265 258/260/265 +f 254/257/261 256/258/261 258/260/261 +f 249/250/266 247/253/266 259/261/266 +f 251/252/258 249/250/258 259/261/258 +f 247/253/267 251/252/267 259/261/267 +f 255/245/258 246/247/258 260/262/258 +f 253/256/261 244/255/261 261/244/261 +f 255/245/268 261/244/268 262/263/268 +f 244/255/269 252/254/269 262/263/269 +f 252/254/258 255/245/258 262/263/258 +f 261/244/270 244/255/270 262/263/270 +f 252/254/271 244/255/271 263/264/271 +f 244/255/261 254/257/261 263/264/261 +f 254/257/272 252/254/272 263/264/272 +f 249/250/258 252/254/258 264/265/258 +f 254/257/264 249/250/264 264/265/264 +f 252/254/272 254/257/272 264/265/272 +f 246/247/273 257/259/273 265/266/273 +f 257/259/261 253/256/261 265/266/261 +f 253/256/274 260/262/274 265/266/274 +f 265/266/274 260/262/274 266/267/274 +f 260/262/258 246/247/258 266/267/258 +f 246/247/273 265/266/273 266/267/273 +f 260/262/275 253/256/275 267/246/275 +f 255/245/276 260/262/276 267/246/276 +f 253/256/261 261/244/261 267/246/261 +o cup_hull_12 +v 0.014562 0.037748 0.047823 +v -0.004394 0.038590 0.075211 +v 0.019619 0.033114 0.075211 +v 0.019619 0.030166 0.047823 +v -0.004394 0.036063 0.047823 +v 0.003612 0.040275 0.075211 +v -0.003552 0.040275 0.047823 +v 0.020040 0.035221 0.075211 +v 0.020463 0.034799 0.047823 +v 0.006980 0.039854 0.047823 +v 0.010771 0.039012 0.075211 +v -0.003552 0.040275 0.075211 +v 0.020040 0.030166 0.049509 +v 0.020463 0.033114 0.075211 +v -0.004394 0.039854 0.047823 +v -0.004394 0.036063 0.049509 +v 0.015827 0.037327 0.075211 +v 0.003612 0.040275 0.047823 +v 0.020463 0.030166 0.047823 +v 0.016669 0.036905 0.047823 +v 0.010771 0.039012 0.047823 +v 0.006980 0.039854 0.075211 +v -0.004394 0.039854 0.075211 +v 0.020463 0.034799 0.075211 +v 0.020040 0.035221 0.047823 +v 0.009085 0.039432 0.075211 +vt 0.000000 0.457562 +vt 0.000000 0.610083 +vt 0.000000 0.542242 +vt 1.000000 0.762604 +vt 1.000000 0.966030 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.000000 0.014585 -vt 0.000000 1.000000 -vt 1.000000 0.391347 +vt 0.000000 0.966030 +vt 0.000000 0.322075 +vt 1.000000 0.033872 +vt 0.000000 0.982966 vt 1.000000 1.000000 -vt 1.000000 0.304424 -vt 0.000000 0.304424 -vt 0.000000 0.391347 -vt 1.000000 0.000000 +vt 1.000000 0.457562 +vt 0.000000 0.033872 +vt 0.938430 0.982966 vt 0.000000 1.000000 +vt 1.000000 0.000000 +vt 0.938430 0.000000 +vt 0.000000 0.813510 +vt 1.000000 0.322075 vt 1.000000 1.000000 +vt 1.000000 0.847381 +vt 1.000000 0.610083 vt 0.000000 0.000000 -vt 1.000000 0.014585 -vt 0.000000 0.072533 -vt 1.000000 0.000000 -vt 0.000000 0.275450 -vt 1.000000 0.275450 -vt 0.675509 0.202917 -vn -0.7071 -0.7071 -0.0000 -vn -0.0000 0.0000 1.0000 +vt 0.000000 1.000000 +vt 1.000000 0.982966 +vn 0.0000 0.0000 1.0000 vn 0.0000 0.0000 -1.0000 +vn 0.0000 1.0000 0.0000 +vn -0.2210 -0.9693 0.1076 +vn 0.0000 -0.9935 0.1140 +vn -1.0000 0.0000 0.0000 +vn -0.4478 0.8941 0.0000 +vn -0.2385 -0.9711 0.0000 +vn -0.2336 -0.9677 0.0951 +vn -0.2342 -0.9704 0.0585 +vn 0.1242 0.9923 0.0000 vn 0.0000 -1.0000 0.0000 -vn 0.4640 0.8858 0.0000 -vn -0.0001 1.0000 0.0000 vn 1.0000 0.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.8934 -0.4492 0.0000 -vn -0.7807 -0.6248 0.0000 -vn -0.4482 -0.8939 0.0000 -vn -0.6246 -0.7809 0.0000 -vn -0.7072 -0.7070 0.0000 -vn -0.6398 -0.7685 0.0008 -vn -0.7059 -0.7083 0.0000 +vn 0.3922 -0.9146 0.0985 +vn 0.3712 0.9286 -0.0029 +vn 0.3163 0.9487 -0.0000 +vn 0.3161 0.9487 0.0000 +vn 0.7056 0.7086 0.0000 +vn 0.4472 0.8944 0.0000 +vn 0.4471 0.8945 -0.0000 +vn 0.2169 0.9762 -0.0016 +vn 0.2420 0.9703 0.0000 +vn 0.1964 0.9805 0.0000 usemtl None s off -f 392/373/385 388/374/385 393/375/385 -f 374/376/386 375/377/386 376/378/386 -f 377/379/387 373/380/387 378/381/387 -f 378/381/388 373/380/388 379/382/388 -f 376/378/386 375/377/386 379/382/386 -f 374/376/386 376/378/386 380/383/386 -f 376/378/389 377/379/389 380/383/389 -f 380/383/390 377/379/390 381/384/390 -f 377/379/387 378/381/387 381/384/387 -f 373/380/391 376/378/391 382/385/391 -f 379/382/388 373/380/388 382/385/388 -f 376/378/386 379/382/386 382/385/386 -f 376/378/391 373/380/391 383/386/391 -f 373/380/387 377/379/387 383/386/387 -f 377/379/389 376/378/389 383/386/389 -f 374/376/386 380/383/386 384/387/386 -f 380/383/390 381/384/390 384/387/390 -f 381/384/392 374/376/392 384/387/392 -f 375/377/393 374/376/393 385/388/393 -f 381/384/387 378/381/387 385/388/387 -f 379/382/386 375/377/386 387/389/386 -f 375/377/394 385/388/394 387/389/394 -f 385/388/387 378/381/387 388/374/387 -f 387/389/394 385/388/394 388/374/394 -f 374/376/392 381/384/392 389/390/392 -f 385/388/393 374/376/393 389/390/393 -f 381/384/387 385/388/387 389/390/387 -f 378/381/395 379/382/395 390/391/395 -f 379/382/386 387/389/386 390/391/386 -f 388/374/387 378/381/387 391/392/387 -f 378/381/395 390/391/395 391/392/395 -f 390/391/396 386/393/396 391/392/396 -f 387/389/397 388/374/397 392/373/397 -f 386/393/398 390/391/398 392/373/398 -f 390/391/386 387/389/386 392/373/386 -f 388/374/387 391/392/387 393/375/387 -f 391/392/396 386/393/396 393/375/396 -f 386/393/399 392/373/399 393/375/399 -o Cup_hull_16 -v -0.020127 -0.011963 0.015036 -v -0.018021 -0.000377 -0.048198 -v -0.013545 -0.011700 -0.048198 -v -0.020392 -0.011963 -0.048198 -v -0.020392 -0.000377 0.015029 -v -0.013545 -0.011963 0.015036 -v -0.018021 -0.000377 0.015036 -v -0.020392 -0.000377 -0.048198 -v -0.020392 -0.011963 0.015029 -v -0.013545 -0.011963 -0.048198 -v -0.013545 -0.011700 0.015036 -vt 1.000000 0.022712 -vt 0.000000 1.000000 -vt 0.000000 0.022712 -vt 1.000000 1.000000 -vt 1.000000 0.000000 +f 289/268/277 278/269/277 293/270/277 +f 268/271/278 271/272/278 272/273/278 +f 269/274/277 270/275/277 273/276/277 +f 268/271/278 272/273/278 274/277/278 +f 273/276/277 270/275/277 275/278/277 +f 271/272/278 268/271/278 276/279/278 +f 268/271/278 274/277/278 277/280/278 +f 273/276/277 275/278/277 278/269/277 +f 269/274/277 273/276/277 279/281/277 +f 273/276/279 274/277/279 279/281/279 +f 270/275/280 269/274/280 280/282/280 +f 275/278/277 270/275/277 281/283/277 +f 270/275/281 280/282/281 281/283/281 +f 272/273/282 269/274/282 282/284/282 +f 274/277/278 272/273/278 282/284/278 +f 279/281/283 274/277/283 282/284/283 +f 272/273/284 271/272/284 283/285/284 +f 269/274/282 272/273/282 283/285/282 +f 280/282/285 269/274/285 283/285/285 +f 271/272/286 280/282/286 283/285/286 +f 278/269/277 275/278/277 284/286/277 +f 274/277/279 273/276/279 285/287/279 +f 273/276/287 277/280/287 285/287/287 +f 277/280/278 274/277/278 285/287/278 +f 271/272/278 276/279/278 286/288/278 +f 280/282/288 271/272/288 286/288/288 +f 276/279/289 281/283/289 286/288/289 +f 281/283/290 280/282/290 286/288/290 +f 276/279/278 268/271/278 287/289/278 +f 268/271/291 284/286/291 287/289/291 +f 268/271/278 277/280/278 288/290/278 +f 284/286/292 268/271/292 288/290/292 +f 278/269/293 284/286/293 288/290/293 +f 277/280/287 273/276/287 289/268/287 +f 273/276/277 278/269/277 289/268/277 +f 269/274/277 279/281/277 290/291/277 +f 282/284/282 269/274/282 290/291/282 +f 279/281/283 282/284/283 290/291/283 +f 276/279/294 275/278/294 291/292/294 +f 281/283/289 276/279/289 291/292/289 +f 275/278/277 281/283/277 291/292/277 +f 275/278/294 276/279/294 292/293/294 +f 284/286/295 275/278/295 292/293/295 +f 276/279/278 287/289/278 292/293/278 +f 287/289/296 284/286/296 292/293/296 +f 288/290/297 277/280/297 293/270/297 +f 278/269/298 288/290/298 293/270/298 +f 277/280/299 289/268/299 293/270/299 +o cup_hull_13 +v 0.014563 0.037746 0.027179 +v -0.004396 0.036061 0.047823 +v -0.004396 0.039854 0.047823 +v 0.020461 0.034797 0.047823 +v 0.020040 0.020473 0.022545 +v -0.004396 0.028480 0.022545 +v -0.004396 0.039854 0.026338 +v 0.020461 0.032690 0.022545 +v 0.020461 0.029744 0.047823 +v 0.006980 0.039854 0.047823 +v 0.003191 0.040275 0.027179 +v 0.020040 0.020898 0.025073 +v -0.004396 0.032692 0.022545 +v -0.004396 0.035641 0.047397 +v 0.020040 0.035218 0.027179 +v -0.004396 0.028901 0.025494 +v 0.016670 0.036904 0.047823 +v 0.001926 0.039011 0.025073 +v -0.003552 0.040275 0.047823 +v 0.010771 0.039011 0.027179 +v 0.020461 0.020473 0.022545 +v 0.010771 0.039011 0.047823 +v 0.003612 0.040275 0.047823 +v 0.020040 0.029744 0.047823 +v -0.003552 0.040275 0.027602 +v 0.008664 0.039011 0.025917 +v 0.006980 0.039854 0.027602 +v -0.004396 0.038589 0.025073 +v 0.020461 0.034797 0.026759 +v 0.016670 0.036904 0.027179 +v 0.020040 0.020473 0.023388 +v 0.020040 0.035218 0.047823 +v 0.014986 0.037325 0.026338 +v 0.014563 0.037746 0.047823 +v 0.001926 0.039854 0.025917 +v 0.006138 0.038589 0.025073 +v -0.004396 0.028480 0.023388 +v -0.001865 0.039011 0.025073 +vt 0.866582 0.254332 +vt 0.899961 0.254332 +vt 0.899961 0.101811 vt 0.000000 0.000000 vt 0.000000 0.000000 -vt 0.000098 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.000000 +vt 0.849941 0.000000 +vt 1.000000 0.983064 vt 1.000000 1.000000 -vt 0.000098 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.457660 vt 1.000000 0.000000 -vn 0.9300 0.3677 0.0000 -vn -0.0000 0.0000 -1.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn -0.0026 0.0005 1.0000 -vn 0.0000 1.0000 0.0000 +vt 0.016836 0.000000 +vt 0.883320 0.000000 +vt 0.899961 0.983064 +vt 0.000000 0.847479 +vt 0.000000 0.033970 +vt 1.000000 1.000000 +vt 0.000000 0.610181 +vt 0.816660 0.762702 +vt 0.816660 0.610181 +vt 0.000000 0.322173 +vt 0.816660 0.305237 +vt 0.000000 0.983064 +vt 0.799922 0.033970 +vt 0.866582 0.525404 +vt 0.799922 0.457660 +vt 0.899961 0.000000 +vt 0.833301 1.000000 +vt 0.816660 0.983064 +vt 0.816660 0.847479 +vt 0.966621 0.983064 +vt 0.000000 0.983064 +vt 0.849941 0.779736 +vt 0.000000 0.762702 +vt 0.899961 0.423789 +vt 0.966621 0.000000 +vn 0.0000 0.7074 -0.7069 +vn -0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.0234 0.0000 0.9997 +vn 0.0000 0.0000 -1.0000 vn 1.0000 0.0000 0.0000 +vn -0.2943 -0.9134 0.2811 +vn 0.0000 0.3715 -0.9284 +vn -0.4459 0.8951 0.0000 +vn 0.7464 -0.6248 0.2291 +vn 0.3167 0.9485 0.0000 +vn 0.2171 0.9761 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -0.9320 0.3624 +vn -0.1808 -0.6995 0.6914 +vn -0.2253 -0.9081 0.3531 +vn 0.1761 0.9394 -0.2941 +vn 0.2171 0.9762 0.0000 +vn 0.1239 0.9923 0.0000 +vn 0.1106 0.9939 -0.0023 +vn 0.1403 0.9344 -0.3274 +vn 0.7068 0.7074 0.0000 +vn 0.4086 0.8166 -0.4076 +vn 0.3707 0.9287 0.0000 +vn 0.4475 0.8943 0.0000 +vn 0.4084 0.8164 -0.4082 +vn -0.3114 -0.9503 0.0000 +vn -0.2991 -0.9253 0.2331 +vn 0.0000 -1.0000 0.0000 +vn 0.4397 -0.8709 0.2194 +vn 0.3021 0.9047 -0.3003 +vn 0.2447 0.7707 -0.5884 +vn 0.2591 0.8635 -0.4327 +vn 0.3572 0.8949 -0.2676 +vn 0.4081 0.8164 -0.4085 +vn -0.0202 0.9526 -0.3034 +vn -0.0188 0.9540 -0.2992 +vn 0.1130 0.9031 -0.4143 +vn 0.0937 0.7491 -0.6558 +vn 0.0494 0.4925 -0.8689 +vn 0.1386 0.6550 -0.7428 +vn 0.0708 0.7056 -0.7051 +vn -0.3059 -0.9336 0.1865 +vn -0.1172 0.7019 -0.7026 +vn -0.0657 0.3933 -0.9171 +vn -0.0405 0.7919 -0.6092 usemtl None s off -f 396/394/400 400/395/400 404/396/400 -f 395/397/401 396/394/401 397/398/401 -f 394/399/402 397/398/402 399/400/402 -f 394/399/403 399/400/403 400/395/403 -f 396/394/400 395/397/400 400/395/400 -f 398/401/404 394/399/404 400/395/404 -f 395/397/405 398/401/405 400/395/405 -f 395/397/401 397/398/401 401/402/401 -f 397/398/406 398/401/406 401/402/406 -f 398/401/405 395/397/405 401/402/405 -f 397/398/402 394/399/402 402/403/402 -f 394/399/407 398/401/407 402/403/407 -f 398/401/406 397/398/406 402/403/406 -f 397/398/401 396/394/401 403/404/401 -f 396/394/408 399/400/408 403/404/408 -f 399/400/402 397/398/402 403/404/402 -f 399/400/408 396/394/408 404/396/408 -f 400/395/403 399/400/403 404/396/403 -o Cup_hull_17 -v 0.015424 -0.020127 0.015036 -v 0.020163 -0.000379 -0.048198 -v 0.018057 -0.000379 -0.048198 -v 0.012263 -0.020390 -0.048198 -v 0.020426 -0.014861 -0.048192 -v 0.018057 -0.000379 0.015036 -v 0.012263 -0.013017 0.015036 -v 0.020426 -0.014859 0.015036 -v 0.012263 -0.013017 -0.048198 -v 0.020426 -0.000379 0.015036 -v 0.012263 -0.020390 0.015036 -v 0.014897 -0.020390 -0.048198 -v 0.018846 -0.016967 -0.048198 -v 0.020426 -0.000379 -0.048192 -v 0.018583 -0.017230 0.015036 -v 0.017003 -0.018811 -0.048198 -v 0.014897 -0.020390 0.015036 -v 0.017003 -0.018811 0.015036 -v 0.019899 -0.015651 0.015036 -v 0.015424 -0.020127 -0.044540 -v 0.019899 -0.015651 -0.048198 -vt 0.000000 0.236832 -vt 1.000000 0.171040 -vt 1.000000 0.236832 -vt 1.000000 1.000000 +f 328/294/300 311/295/300 331/296/300 +f 296/297/301 295/298/301 297/299/301 +f 295/298/302 296/297/302 299/300/302 +f 299/300/302 296/297/302 300/301/302 +f 298/302/303 299/300/303 301/303/303 +f 297/299/301 295/298/301 302/304/301 +f 301/303/304 297/299/304 302/304/304 +f 296/297/301 297/299/301 303/305/301 +f 299/300/302 300/301/302 306/306/302 +f 301/303/303 299/300/303 306/306/303 +f 295/298/302 299/300/302 307/307/302 +f 307/307/302 299/300/302 309/308/302 +f 305/309/305 307/307/305 309/308/305 +f 303/305/301 297/299/301 310/310/301 +f 301/303/306 306/306/306 311/295/306 +f 300/301/307 296/297/307 312/311/307 +f 296/297/301 303/305/301 312/311/301 +f 298/302/303 301/303/303 314/312/303 +f 301/303/304 302/304/304 314/312/304 +f 302/304/308 305/309/308 314/312/308 +f 303/305/301 310/310/301 315/313/301 +f 294/314/309 313/315/309 315/313/309 +f 313/315/310 303/305/310 315/313/310 +f 312/311/301 303/305/301 316/316/301 +f 304/317/311 312/311/311 316/316/311 +f 302/304/301 295/298/301 317/318/301 +f 305/309/312 302/304/312 317/318/312 +f 295/298/313 307/307/313 317/318/313 +f 307/307/314 305/309/314 317/318/314 +f 300/301/307 312/311/307 318/319/307 +f 312/311/311 304/317/311 318/319/311 +f 313/315/315 319/320/315 320/321/315 +f 303/305/316 313/315/316 320/321/316 +f 316/316/317 303/305/317 320/321/317 +f 304/317/318 316/316/318 320/321/318 +f 319/320/319 304/317/319 320/321/319 +f 306/306/302 300/301/302 321/322/302 +f 297/299/304 301/303/304 322/323/304 +f 308/324/320 297/299/320 322/323/320 +f 308/324/321 322/323/321 323/325/321 +f 294/314/322 310/310/322 323/325/322 +f 310/310/323 308/324/323 323/325/323 +f 322/323/324 301/303/324 323/325/324 +f 299/300/325 298/302/325 324/326/325 +f 305/309/326 309/308/326 324/326/326 +f 298/302/327 314/312/327 324/326/327 +f 314/312/328 305/309/328 324/326/328 +f 297/299/320 308/324/320 325/327/320 +f 310/310/301 297/299/301 325/327/301 +f 308/324/323 310/310/323 325/327/323 +f 313/315/329 294/314/329 326/328/329 +f 301/303/330 319/320/330 326/328/330 +f 319/320/331 313/315/331 326/328/331 +f 294/314/332 323/325/332 326/328/332 +f 323/325/333 301/303/333 326/328/333 +f 310/310/322 294/314/322 327/329/322 +f 315/313/301 310/310/301 327/329/301 +f 294/314/309 315/313/309 327/329/309 +f 300/301/334 318/319/334 328/294/334 +f 318/319/335 304/317/335 328/294/335 +f 304/317/336 319/320/336 328/294/336 +f 328/294/337 319/320/337 329/330/337 +f 301/303/338 311/295/338 329/330/338 +f 319/320/339 301/303/339 329/330/339 +f 311/295/340 328/294/340 329/330/340 +f 309/308/302 299/300/302 330/331/302 +f 299/300/325 324/326/325 330/331/325 +f 324/326/341 309/308/341 330/331/341 +f 311/295/306 306/306/306 331/296/306 +f 321/322/342 300/301/342 331/296/342 +f 306/306/343 321/322/343 331/296/343 +f 300/301/344 328/294/344 331/296/344 +o cup_hull_14 +v -0.023777 -0.032617 -0.072261 +v -0.032623 -0.023769 0.022524 +v -0.032202 -0.024612 0.022524 +v -0.002711 -0.028403 0.020844 +v -0.021250 -0.019134 -0.072261 +v -0.002711 -0.032617 -0.072261 +v -0.023777 -0.032617 0.022524 +v -0.021250 -0.019134 0.022524 +v -0.032623 -0.019134 -0.072261 +v -0.002711 -0.032617 0.022524 +v -0.003132 -0.028403 -0.072261 +v -0.032623 -0.019134 0.022524 +v -0.032202 -0.024612 -0.072261 +v -0.026726 -0.030508 0.022524 +v -0.027148 -0.030088 -0.072261 +v -0.030518 -0.026717 0.022524 +v -0.032623 -0.023769 -0.072261 +v -0.002711 -0.028824 -0.072261 +v -0.030518 -0.026717 -0.072261 +v -0.002711 -0.028824 0.022524 +v -0.024620 -0.032194 -0.072261 +v -0.024620 -0.032194 0.022524 +v -0.026726 -0.030508 -0.072261 +vt 1.000000 0.183064 +vt 1.000000 0.267548 +vt 1.000000 0.197161 +vt 1.000000 0.295742 +vt 1.000000 0.380225 vt 1.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 0.014097 +vt 0.000000 0.295742 +vt 0.017719 1.000000 +vt 0.000000 0.380225 vt 1.000000 0.000000 vt 0.000000 1.000000 -vt 0.000000 0.013119 -vt 0.000000 0.368416 -vt 0.000000 0.276385 -vt 1.000000 0.368416 -vt 0.000000 1.000000 -vt 0.999902 0.276287 +vt 1.000000 0.985903 vt 0.000000 0.000000 +vt 1.000000 0.014097 +vt 0.000000 0.197161 +vt 0.000000 0.070387 vt 1.000000 0.000000 -vt 0.999902 1.000000 -vt 0.000000 0.157920 -vt 1.000000 0.078911 -vt 0.000000 0.000000 -vt 0.000000 0.078911 -vt 0.942150 0.013119 -vn 0.7809 -0.6247 0.0000 +vt 1.000000 1.000000 +vt 1.000000 0.070387 +vt 0.000000 1.000000 +vt 0.000000 0.267548 vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.4472 0.8944 0.0000 vn 0.0000 1.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn -0.9090 0.4167 0.0000 +vn 1.0000 -0.0000 0.0000 +vn 0.4555 0.8903 -0.0021 vn -1.0000 0.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0235 0.0000 -0.9997 -vn 0.4461 -0.8950 0.0000 -vn 0.7072 -0.7070 0.0000 -vn 0.7071 -0.7071 0.0000 -vn 0.6404 -0.7681 0.0000 -vn 0.8326 -0.5539 0.0000 -vn 0.7682 -0.6403 0.0005 -vn 0.5997 -0.7997 -0.0289 -vn 0.0121 -0.0002 -0.9999 -vn 0.8319 -0.5549 0.0000 +vn -0.8944 -0.4472 0.0000 +vn -0.7069 -0.7073 0.0000 +vn -0.7809 -0.6246 0.0000 +vn 0.7066 0.7077 -0.0032 +vn -0.7071 -0.7071 0.0000 +vn 0.4522 0.8652 0.2169 +vn -0.4478 -0.8941 0.0000 +vn -0.6252 -0.7804 0.0000 +vn -0.7054 -0.7088 0.0000 usemtl None s off -f 423/405/409 417/406/409 425/407/409 -f 407/408/410 406/409/410 408/410/410 -f 406/409/411 407/408/411 410/411/411 -f 405/412/412 410/411/412 411/413/412 -f 410/411/413 407/408/413 411/413/413 -f 410/411/412 405/412/412 412/414/412 -f 407/408/410 408/410/410 413/415/410 -f 411/413/413 407/408/413 413/415/413 -f 408/410/414 411/413/414 413/415/414 -f 406/409/411 410/411/411 414/416/411 -f 412/414/415 409/417/415 414/416/415 -f 410/411/412 412/414/412 414/416/412 -f 405/412/412 411/413/412 415/418/412 -f 411/413/414 408/410/414 415/418/414 -f 408/410/410 406/409/410 416/419/410 -f 415/418/416 408/410/416 416/419/416 -f 416/419/410 406/409/410 417/406/410 -f 409/417/417 406/409/417 418/420/417 -f 406/409/411 414/416/411 418/420/411 -f 414/416/415 409/417/415 418/420/415 -f 412/414/412 405/412/412 419/421/412 -f 416/419/410 417/406/410 420/422/410 -f 405/412/412 415/418/412 421/423/412 -f 416/419/418 405/412/418 421/423/418 -f 415/418/416 416/419/416 421/423/416 -f 419/421/412 405/412/412 422/424/412 -f 417/406/419 419/421/419 422/424/419 -f 420/422/420 417/406/420 422/424/420 -f 405/412/421 420/422/421 422/424/421 -f 409/417/422 412/414/422 423/405/422 -f 412/414/412 419/421/412 423/405/412 -f 419/421/423 417/406/423 423/405/423 -f 405/412/418 416/419/418 424/425/418 -f 420/422/421 405/412/421 424/425/421 -f 416/419/424 420/422/424 424/425/424 -f 406/409/425 409/417/425 425/407/425 -f 417/406/410 406/409/410 425/407/410 -f 409/417/426 423/405/426 425/407/426 -o Cup_hull_18 -v -0.015651 0.019899 -0.048198 -v -0.020392 0.013317 0.015036 -v -0.011965 0.013317 0.015036 -v 0.000413 0.020426 0.015036 -v -0.011965 0.013317 -0.048198 -v 0.000413 0.018056 -0.048198 -v -0.014861 0.020425 0.015036 -v -0.020392 0.014897 -0.048198 -v 0.000413 0.020426 -0.048198 -v 0.000413 0.018056 0.015036 -v -0.020392 0.013317 -0.048198 -v -0.018811 0.017002 0.015036 -v -0.014861 0.020425 -0.048198 -v -0.020392 0.014897 0.015036 -v -0.018811 0.017002 -0.048198 -v -0.017231 0.018583 0.015036 -v -0.020127 0.015424 0.015036 -v -0.016966 0.018846 -0.048198 -v -0.015651 0.019899 0.015036 -v -0.020127 0.015424 -0.045667 -vt 0.000000 0.012725 -vt 1.000000 0.075959 -vt 0.959965 0.012725 +f 346/332/345 352/333/345 354/334/345 +f 332/335/345 336/336/345 337/337/345 +f 333/338/346 334/339/346 338/340/346 +f 332/335/347 337/337/347 338/340/347 +f 335/341/348 336/336/348 339/342/348 +f 333/338/346 338/340/346 339/342/346 +f 336/336/345 332/335/345 340/343/345 +f 339/342/349 336/336/349 340/343/349 +f 337/337/350 335/341/350 341/344/350 +f 338/340/347 337/337/347 341/344/347 +f 339/342/346 338/340/346 341/344/346 +f 336/336/351 335/341/351 342/345/351 +f 337/337/345 336/336/345 342/345/345 +f 333/338/346 339/342/346 343/346/346 +f 340/343/352 333/338/352 343/346/352 +f 339/342/349 340/343/349 343/346/349 +f 334/339/353 333/338/353 344/347/353 +f 340/343/345 332/335/345 344/347/345 +f 338/340/346 334/339/346 345/348/346 +f 344/347/345 332/335/345 346/332/345 +f 346/332/354 345/348/354 347/349/354 +f 334/339/355 344/347/355 347/349/355 +f 345/348/346 334/339/346 347/349/346 +f 333/338/352 340/343/352 348/350/352 +f 344/347/353 333/338/353 348/350/353 +f 340/343/345 344/347/345 348/350/345 +f 335/341/350 337/337/350 349/351/350 +f 342/345/356 335/341/356 349/351/356 +f 337/337/345 342/345/345 349/351/345 +f 344/347/345 346/332/345 350/352/345 +f 346/332/357 347/349/357 350/352/357 +f 347/349/355 344/347/355 350/352/355 +f 335/341/358 339/342/358 351/353/358 +f 341/344/350 335/341/350 351/353/350 +f 339/342/346 341/344/346 351/353/346 +f 332/335/359 338/340/359 352/333/359 +f 346/332/345 332/335/345 352/333/345 +f 338/340/346 345/348/346 353/354/346 +f 352/333/359 338/340/359 353/354/359 +f 345/348/360 352/333/360 353/354/360 +f 345/348/361 346/332/361 354/334/361 +f 352/333/360 345/348/360 354/334/360 +o cup_hull_15 +v -0.025041 0.031848 -0.072261 +v -0.032626 0.021318 0.022524 +v -0.019144 0.021318 0.022524 +v 0.000660 0.032692 0.022524 +v -0.019144 0.021318 -0.072261 +v 0.000660 0.028900 -0.072261 +v -0.023777 0.032691 0.022524 +v -0.032626 0.023845 -0.072261 +v 0.000660 0.032692 -0.072261 +v 0.000660 0.028900 0.022524 +v -0.032626 0.021318 -0.072261 +v -0.030098 0.027214 0.022524 +v -0.023777 0.032691 -0.072261 +v -0.032626 0.023845 0.022524 +v -0.030098 0.027214 -0.072261 +v -0.027146 0.030162 0.022524 +v -0.032203 0.024687 0.022524 +v -0.027146 0.030162 -0.072261 +v -0.032203 0.024687 -0.072261 +v -0.025041 0.031848 0.022524 +vt 0.000000 0.164644 +vt 0.000000 0.265857 +vt 0.000000 0.227878 vt 0.000000 0.000000 vt 0.000000 0.405051 vt 0.000000 1.000000 vt 1.000000 0.405051 vt 1.000000 1.000000 vt 1.000000 0.227878 -vt 0.000000 0.265858 vt 1.000000 0.000000 vt 1.000000 1.000000 vt 0.000000 1.000000 vt 1.000000 0.000000 vt 0.000000 0.075959 -vt 1.000000 0.265858 +vt 1.000000 0.265857 vt 0.000000 0.000000 -vt 0.000000 0.151919 +vt 1.000000 0.075959 +vt 0.000000 0.012725 vt 1.000000 0.164644 -vt 0.000000 0.227878 -vn -0.7682 0.6402 0.0000 +vt 1.000000 0.012725 vn 0.0000 0.0000 1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.3576 -0.9339 0.0000 -vn -0.0000 0.0000 -1.0000 +vn 0.3575 -0.9339 0.0000 +vn 0.0000 0.0000 -1.0000 vn 1.0000 0.0000 0.0000 vn -0.0000 1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.5543 0.8323 0.0000 -vn -0.7072 0.7070 0.0000 -vn -0.8935 0.4490 0.0000 -vn -0.7069 0.7074 -0.0000 -vn -0.6400 0.7684 0.0005 -vn -0.6249 0.7807 0.0000 -vn -0.7991 0.5998 -0.0413 +vn -0.5548 0.8320 0.0000 +vn -0.7067 0.7075 0.0000 +vn -0.8933 0.4495 0.0000 +vn -0.7683 0.6401 0.0000 +vn -0.6251 0.7805 0.0000 usemtl None s off -f 442/426/427 440/427/427 445/428/427 -f 427/429/428 428/430/428 429/431/428 -f 428/430/429 427/429/429 430/432/429 -f 428/430/430 430/432/430 431/433/430 -f 430/432/431 426/434/431 431/433/431 -f 427/429/428 429/431/428 432/435/428 -f 426/434/431 430/432/431 433/436/431 -f 429/431/432 431/433/432 434/437/432 -f 431/433/431 426/434/431 434/437/431 -f 432/435/433 429/431/433 434/437/433 -f 429/431/428 428/430/428 435/438/428 -f 428/430/430 431/433/430 435/438/430 -f 431/433/432 429/431/432 435/438/432 -f 430/432/429 427/429/429 436/439/429 -f 433/436/431 430/432/431 436/439/431 -f 427/429/434 433/436/434 436/439/434 -f 427/429/428 432/435/428 437/440/428 -f 426/434/435 432/435/435 438/441/435 -f 434/437/431 426/434/431 438/441/431 -f 432/435/433 434/437/433 438/441/433 -f 433/436/434 427/429/434 439/442/434 -f 427/429/428 437/440/428 439/442/428 -f 426/434/431 433/436/431 440/427/431 -f 440/427/436 437/440/436 441/443/436 -f 437/440/428 432/435/428 441/443/428 -f 433/436/437 439/442/437 442/426/437 -f 439/442/428 437/440/428 442/426/428 -f 437/440/427 440/427/427 442/426/427 -f 426/434/431 440/427/431 443/444/431 -f 440/427/438 441/443/438 443/444/438 -f 443/444/439 441/443/439 444/445/439 -f 432/435/435 426/434/435 444/445/435 -f 441/443/428 432/435/428 444/445/428 -f 426/434/440 443/444/440 444/445/440 -f 440/427/441 433/436/441 445/428/441 -f 433/436/437 442/426/437 445/428/437 -o Cup_hull_19 -v 0.018056 0.017793 -0.048198 -v 0.000413 0.018056 0.015036 -v 0.012788 0.012527 0.015036 -v 0.014896 0.020427 0.015036 -v 0.000413 0.020426 -0.048198 -v 0.012788 0.012527 -0.048198 -v 0.020427 0.012527 0.015036 -v 0.020427 0.012527 -0.048192 -v 0.014896 0.020427 -0.048198 -v 0.000413 0.020426 0.015036 -v 0.000413 0.018056 -0.048198 -v 0.020427 0.014897 0.015036 -v 0.020427 0.014897 -0.048192 -v 0.018319 0.017529 0.015036 -v 0.015686 0.019898 0.015036 -v 0.019900 0.015686 -0.048198 -v 0.017265 0.018583 -0.048198 -v 0.019900 0.015686 0.015036 -v 0.018583 0.017266 -0.048198 -v 0.015686 0.019898 -0.048198 -v 0.017792 0.018056 0.015036 -vt 1.000000 0.842013 -vt 0.000000 0.763117 -vt 0.000000 0.868344 +f 370/355/362 361/356/362 374/357/362 +f 356/358/362 357/359/362 358/360/362 +f 357/359/363 356/358/363 359/361/363 +f 357/359/364 359/361/364 360/362/364 +f 359/361/365 355/363/365 360/362/365 +f 356/358/362 358/360/362 361/356/362 +f 355/363/365 359/361/365 362/364/365 +f 358/360/366 360/362/366 363/365/366 +f 360/362/365 355/363/365 363/365/365 +f 361/356/367 358/360/367 363/365/367 +f 358/360/362 357/359/362 364/366/362 +f 357/359/364 360/362/364 364/366/364 +f 360/362/366 358/360/366 364/366/366 +f 359/361/363 356/358/363 365/367/363 +f 362/364/365 359/361/365 365/367/365 +f 356/358/368 362/364/368 365/367/368 +f 356/358/362 361/356/362 366/368/362 +f 355/363/369 361/356/369 367/369/369 +f 363/365/365 355/363/365 367/369/365 +f 361/356/367 363/365/367 367/369/367 +f 362/364/368 356/358/368 368/370/368 +f 356/358/362 366/368/362 368/370/362 +f 355/363/365 362/364/365 369/371/365 +f 369/371/370 366/368/370 370/355/370 +f 366/368/362 361/356/362 370/355/362 +f 362/364/371 368/370/371 371/372/371 +f 368/370/362 366/368/362 371/372/362 +f 366/368/372 369/371/372 371/372/372 +f 355/363/365 369/371/365 372/373/365 +f 369/371/370 370/355/370 372/373/370 +f 370/355/373 355/363/373 372/373/373 +f 369/371/365 362/364/365 373/374/365 +f 362/364/371 371/372/371 373/374/371 +f 371/372/372 369/371/372 373/374/372 +f 361/356/369 355/363/369 374/357/369 +f 355/363/373 370/355/373 374/357/373 +o cup_hull_16 +v 0.029310 0.028057 -0.072261 +v 0.000664 0.028900 0.022524 +v 0.019621 0.020894 0.022524 +v 0.023831 0.032692 0.022524 +v 0.000664 0.032692 -0.072261 +v 0.019621 0.020894 -0.072261 +v 0.032679 0.020894 0.022524 +v 0.023831 0.032692 -0.072261 +v 0.032679 0.020894 -0.072261 +v 0.000664 0.032692 0.022524 +v 0.000664 0.028900 -0.072261 +v 0.032679 0.023845 0.022524 +v 0.032679 0.023845 -0.072261 +v 0.028047 0.029320 0.022524 +v 0.031839 0.025108 0.022524 +v 0.025097 0.031848 -0.072261 +v 0.031839 0.025108 -0.072261 +v 0.025097 0.031848 0.022524 +v 0.028047 0.029320 -0.072261 +v 0.029310 0.028057 0.022524 +vt 0.000000 0.973762 +vt 1.000000 0.894752 +vt 0.000000 0.894752 vt 0.000000 0.000000 -vt 0.000000 0.618344 -vt 0.000000 0.723669 -vt 1.000000 0.618344 +vt 0.000000 0.592129 +vt 0.000000 0.723615 +vt 1.000000 0.592129 vt 1.000000 0.000000 -vt 1.000000 0.881558 vt 0.000000 1.000000 -vt 0.999902 1.000000 -vt 1.000000 0.723669 +vt 1.000000 0.723615 +vt 1.000000 1.000000 vt 0.000000 0.000000 vt 1.000000 0.000000 vt 0.000000 1.000000 -vt 0.999902 1.000000 -vt 0.000000 0.894675 -vt 1.000000 0.973669 -vt 0.000000 0.973669 -vt 1.000000 0.907890 -vt 1.000000 0.763117 -vn 0.6585 0.7526 0.0008 +vt 1.000000 1.000000 +vt 0.000000 0.855297 +vt 1.000000 0.763168 +vt 1.000000 0.973762 +vt 0.000000 0.763168 +vt 1.000000 0.855297 +vn 0.7589 0.6512 0.0000 vn 0.0000 0.0000 1.0000 -vn -0.4079 -0.9130 0.0000 +vn -0.3890 -0.9212 0.0000 vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.0001 1.0000 0.0000 +vn 0.0000 1.0000 0.0000 vn -1.0000 0.0000 0.0000 vn 1.0000 0.0000 0.0000 -vn 0.5560 0.8312 0.0000 -vn 0.0008 -0.0018 -1.0000 -vn 0.0117 0.0000 -0.9999 -vn 0.8317 0.5552 -0.0000 -vn 0.8315 0.5555 0.0000 -vn 0.7682 0.6402 0.0000 -vn 0.7069 0.7073 0.0000 -vn -0.0001 0.0000 -1.0000 -vn 0.7590 0.6511 0.0005 -vn 0.6401 0.7683 0.0000 -vn 0.7066 0.7076 0.0000 +vn 0.8327 0.5537 0.0000 +vn 0.5547 0.8321 0.0000 +vn 0.6508 0.7593 0.0000 +vn 0.7072 0.7071 0.0000 +usemtl None +s off +f 389/375/374 375/376/374 394/377/374 +f 376/378/375 377/379/375 378/380/375 +f 377/379/376 376/378/376 380/381/376 +f 379/382/377 375/376/377 380/381/377 +f 377/379/378 380/381/378 381/383/378 +f 378/380/375 377/379/375 381/383/375 +f 375/376/377 379/382/377 382/384/377 +f 379/382/379 378/380/379 382/384/379 +f 380/381/377 375/376/377 383/385/377 +f 381/383/378 380/381/378 383/385/378 +f 376/378/375 378/380/375 384/386/375 +f 378/380/379 379/382/379 384/386/379 +f 379/382/380 376/378/380 384/386/380 +f 376/378/380 379/382/380 385/387/380 +f 380/381/376 376/378/376 385/387/376 +f 379/382/377 380/381/377 385/387/377 +f 378/380/375 381/383/375 386/388/375 +f 381/383/381 383/385/381 386/388/381 +f 386/388/381 383/385/381 387/389/381 +f 383/385/377 375/376/377 387/389/377 +f 378/380/375 386/388/375 388/390/375 +f 388/390/375 386/388/375 389/375/375 +f 386/388/382 387/389/382 389/375/382 +f 375/376/377 382/384/377 390/391/377 +f 382/384/383 378/380/383 390/391/383 +f 387/389/377 375/376/377 391/392/377 +f 389/375/382 387/389/382 391/392/382 +f 375/376/374 389/375/374 391/392/374 +f 378/380/375 388/390/375 392/393/375 +f 390/391/383 378/380/383 392/393/383 +f 388/390/384 390/391/384 392/393/384 +f 388/390/385 375/376/385 393/394/385 +f 375/376/377 390/391/377 393/394/377 +f 390/391/384 388/390/384 393/394/384 +f 375/376/385 388/390/385 394/377/385 +f 388/390/375 389/375/375 394/377/375 +o cup_hull_17 +v -0.017040 -0.036409 0.026339 +v -0.034312 -0.021664 0.067199 +v -0.034312 -0.021242 0.067199 +v -0.016615 -0.034722 0.075211 +v -0.019144 -0.021240 0.022545 +v -0.032623 -0.023770 0.022545 +v -0.024624 -0.032194 0.075211 +v -0.032204 -0.021242 0.075211 +v -0.026726 -0.030508 0.022545 +v -0.016617 -0.023347 0.023390 +v -0.033889 -0.021242 0.026339 +v -0.030518 -0.026719 0.075211 +v -0.018725 -0.035987 0.068462 +v -0.016617 -0.032614 0.022545 +v -0.021674 -0.034301 0.027607 +v -0.016615 -0.036409 0.075211 +v -0.030518 -0.026719 0.022545 +v -0.032623 -0.021242 0.022545 +v -0.033468 -0.022927 0.075211 +v -0.024624 -0.032194 0.022545 +v -0.033466 -0.022929 0.027607 +v -0.026725 -0.030508 0.075211 +v -0.022938 -0.033457 0.075211 +v -0.016617 -0.036409 0.026339 +v -0.017461 -0.036409 0.026762 +v -0.017459 -0.036409 0.075211 +v -0.033889 -0.021242 0.075211 +v -0.032204 -0.024612 0.022545 +v -0.016617 -0.023347 0.022545 +v -0.033889 -0.022085 0.026762 +v -0.021674 -0.034301 0.068462 +v -0.023782 -0.032614 0.022545 +v -0.019144 -0.021240 0.022973 +v -0.032204 -0.024612 0.075211 +v -0.018725 -0.035987 0.058776 +v -0.022938 -0.033457 0.027607 +vt 0.000000 0.642717 +vt 1.000000 0.547475 +vt 0.903876 0.642717 +vt 0.000000 0.547475 +vt 0.000000 1.000000 +vt 0.000000 0.119127 +vt 1.000000 0.095438 +vt 1.000000 0.857087 +vt 1.000000 0.428641 +vt 0.983947 0.999902 +vt 0.152114 0.000000 +vt 0.152114 0.000000 +vt 0.927956 0.023884 +vt 0.000000 0.214370 +vt 1.000000 0.999902 +vt 0.000000 1.000000 +vt 1.000000 0.214370 +vt 1.000000 0.095438 +vt 0.000000 0.047670 +vt 0.903876 0.047768 +vt 0.000000 0.428739 +vt 0.927956 0.976018 +vt 0.927956 0.999902 +vt 0.919930 0.952232 +vt 0.903876 0.714174 +vt 0.128132 0.880775 +vt 0.000000 0.952330 +vt 0.000000 0.023884 +vt 1.000000 0.119127 +vt 1.000000 0.999902 +vt 0.919930 0.023884 +vt 0.128132 0.714174 +vt 1.000000 0.595047 +vt 0.991875 0.857087 +vt 0.000000 0.119127 +vt 0.312059 0.880775 +vn -0.5998 -0.8001 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.6453 0.7462 0.1638 +vn -0.9999 0.0000 -0.0103 +vn -0.0001 1.0000 -0.0000 +vn 1.0000 0.0000 -0.0000 +vn -0.7069 -0.7074 0.0000 +vn -0.9486 0.0000 -0.3166 +vn -0.6254 -0.7803 0.0000 +vn -0.8316 -0.5553 -0.0000 +vn -0.6257 -0.7801 0.0000 +vn -0.7067 -0.7075 0.0000 +vn 0.0000 -0.7070 -0.7072 +vn 0.0000 -1.0000 0.0000 +vn -0.4611 -0.8819 -0.0983 +vn -0.4740 -0.8799 0.0340 +vn -0.3160 -0.9488 0.0000 +vn -0.9986 0.0000 0.0527 +vn -0.9682 -0.2418 0.0638 +vn -0.7809 -0.6247 0.0000 +vn -0.8000 -0.6000 -0.0000 +vn 1.0000 0.0001 0.0000 +vn 0.6403 0.7681 0.0000 +vn -0.9999 -0.0052 -0.0104 +vn -0.9630 -0.1208 -0.2409 +vn -0.8921 -0.4517 -0.0046 +vn -0.8915 -0.4439 -0.0903 +vn -0.8700 -0.4901 -0.0540 +vn -0.4966 -0.8680 0.0000 +vn -0.4965 -0.8679 0.0154 +vn -0.5549 -0.8319 0.0000 +vn -0.3215 -0.8912 -0.3201 +vn -0.4425 -0.8866 -0.1346 +vn 0.6175 0.7713 0.1544 +vn 0.0000 1.0000 0.0000 +vn -0.7999 -0.6002 0.0000 +vn -0.3163 -0.9486 0.0000 +vn -0.4485 -0.8938 -0.0059 +vn -0.5547 -0.8317 -0.0229 usemtl None s off -f 462/446/442 460/447/442 466/448/442 -f 447/449/443 448/450/443 449/451/443 -f 448/450/444 447/449/444 451/452/444 -f 450/453/445 446/454/445 451/452/445 -f 448/450/446 451/452/446 452/455/446 -f 449/451/443 448/450/443 452/455/443 -f 452/455/446 451/452/446 453/456/446 -f 446/454/445 450/453/445 454/457/445 -f 450/453/447 449/451/447 454/457/447 -f 447/449/443 449/451/443 455/458/443 -f 449/451/447 450/453/447 455/458/447 -f 450/453/448 447/449/448 455/458/448 -f 447/449/448 450/453/448 456/459/448 -f 451/452/444 447/449/444 456/459/444 -f 450/453/445 451/452/445 456/459/445 -f 449/451/443 452/455/443 457/460/443 -f 452/455/449 453/456/449 457/460/449 -f 457/460/449 453/456/449 458/461/449 -f 449/451/443 457/460/443 459/462/443 -f 454/457/450 449/451/450 460/447/450 -f 449/451/443 459/462/443 460/447/443 -f 451/452/445 446/454/445 461/463/445 -f 453/456/451 451/452/451 461/463/451 -f 458/461/452 453/456/452 461/463/452 -f 457/460/453 458/461/453 461/463/453 -f 446/454/445 454/457/445 462/446/445 -f 459/462/443 457/460/443 463/464/443 -f 457/460/454 461/463/454 463/464/454 -f 463/464/455 461/463/455 464/465/455 -f 446/454/456 459/462/456 464/465/456 -f 461/463/457 446/454/457 464/465/457 -f 459/462/458 463/464/458 464/465/458 -f 454/457/450 460/447/450 465/466/450 -f 462/446/445 454/457/445 465/466/445 -f 460/447/459 462/446/459 465/466/459 -f 459/462/456 446/454/456 466/448/456 -f 460/447/443 459/462/443 466/448/443 -f 446/454/460 462/446/460 466/448/460 -o Cup_hull_20 -v -0.019075 -0.016703 0.048477 -v -0.021180 -0.009068 0.034429 -v -0.023551 -0.009068 0.034429 -v -0.013281 -0.021182 0.034429 -v -0.013281 -0.020127 0.050166 -v -0.022498 -0.009068 0.050166 -v -0.019075 -0.016703 0.034429 -v -0.013281 -0.018811 0.034429 -v -0.021708 -0.013019 0.050166 -v -0.015389 -0.020127 0.050166 -v -0.020918 -0.014335 0.034429 -v -0.023287 -0.009859 0.050166 -v -0.016705 -0.019074 0.034429 -v -0.013808 -0.021182 0.050166 -v -0.022234 -0.009068 0.049039 -v -0.014335 -0.020917 0.034429 -v -0.021180 -0.009068 0.035553 -v -0.022498 -0.011439 0.034429 -v -0.016705 -0.019074 0.050166 -v -0.013281 -0.018811 0.035553 -v -0.020127 -0.015387 0.050166 -v -0.023551 -0.009068 0.046230 -v -0.013281 -0.021182 0.050166 -v -0.023551 -0.009332 0.034429 -v -0.021708 -0.013019 0.034429 -v -0.023287 -0.009068 0.050166 -v -0.013808 -0.021182 0.034429 +f 417/395/386 414/396/386 430/397/386 +f 401/398/387 398/399/387 402/400/387 +f 400/401/388 399/402/388 403/403/388 +f 402/400/389 398/399/389 404/404/389 +f 396/405/390 397/406/390 405/407/390 +f 397/406/391 399/402/391 405/407/391 +f 401/398/387 402/400/387 406/408/387 +f 403/403/388 399/402/388 408/409/388 +f 398/399/387 401/398/387 410/410/387 +f 408/409/392 398/399/392 410/410/392 +f 400/401/388 403/403/388 411/411/388 +f 403/403/393 406/408/393 411/411/393 +f 399/402/388 400/401/388 412/412/388 +f 405/407/391 399/402/391 412/412/391 +f 400/401/394 405/407/394 412/412/394 +f 406/408/387 402/400/387 413/413/387 +f 401/398/395 403/403/395 414/396/395 +f 403/403/388 408/409/388 414/396/388 +f 413/413/396 396/405/396 415/414/396 +f 403/403/397 401/398/397 416/415/397 +f 401/398/387 406/408/387 416/415/387 +f 406/408/398 403/403/398 416/415/398 +f 410/410/387 401/398/387 417/395/387 +f 401/398/386 414/396/386 417/395/386 +f 395/416/399 408/409/399 418/417/399 +f 410/410/400 395/416/400 418/417/400 +f 408/409/392 410/410/392 418/417/392 +f 395/416/400 410/410/400 419/418/400 +f 409/419/401 414/396/401 419/418/401 +f 417/395/402 407/420/402 420/421/402 +f 410/410/387 417/395/387 420/421/387 +f 407/420/403 419/418/403 420/421/403 +f 419/418/400 410/410/400 420/421/400 +f 397/406/404 396/405/404 421/422/404 +f 396/405/405 413/413/405 421/422/405 +f 413/413/387 402/400/387 421/422/387 +f 400/401/388 411/411/388 422/423/388 +f 411/411/406 406/408/406 422/423/406 +f 413/413/407 415/414/407 422/423/407 +f 404/404/408 398/399/408 423/424/408 +f 399/402/409 404/404/409 423/424/409 +f 398/399/392 408/409/392 423/424/392 +f 408/409/388 399/402/388 423/424/388 +f 396/405/410 405/407/410 424/425/410 +f 405/407/411 400/401/411 424/425/411 +f 415/414/412 396/405/412 424/425/412 +f 400/401/413 422/423/413 424/425/413 +f 422/423/414 415/414/414 424/425/414 +f 409/419/415 407/420/415 425/426/415 +f 407/420/416 417/395/416 425/426/416 +f 417/395/417 409/419/417 425/426/417 +f 408/409/399 395/416/399 426/427/399 +f 414/396/388 408/409/388 426/427/388 +f 395/416/418 419/418/418 426/427/418 +f 419/418/419 414/396/419 426/427/419 +f 399/402/391 397/406/391 427/428/391 +f 402/400/420 404/404/420 427/428/420 +f 404/404/409 399/402/409 427/428/409 +f 397/406/391 421/422/391 427/428/391 +f 421/422/421 402/400/421 427/428/421 +f 406/408/387 413/413/387 428/429/387 +f 422/423/406 406/408/406 428/429/406 +f 413/413/422 422/423/422 428/429/422 +f 407/420/415 409/419/415 429/430/415 +f 419/418/423 407/420/423 429/430/423 +f 409/419/424 419/418/424 429/430/424 +f 414/396/425 409/419/425 430/397/425 +f 409/419/417 417/395/417 430/397/417 +o cup_hull_18 +v -0.032626 0.000670 0.022526 +v -0.026306 0.021316 -0.072261 +v -0.026306 0.011203 -0.072261 +v -0.032626 0.021316 -0.072261 +v -0.026306 0.021316 0.022526 +v -0.032626 0.000670 -0.072261 +v -0.032626 0.021316 0.022526 +v -0.028835 0.000670 0.022526 +v -0.028835 0.000670 -0.072261 +v -0.026306 0.011203 0.022526 vt 0.000000 0.000000 -vt 1.000000 0.021829 -vt 1.000000 0.000000 +vt 1.000000 0.510180 +vt 0.000000 0.510180 vt 1.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.000000 vt 0.000000 1.000000 -vt 1.000000 0.369714 -vt 1.000000 0.195673 -vt 0.000000 0.087020 -vt 0.000000 0.673845 -vt 0.000000 0.087020 -vt 1.000000 0.565192 -vt 0.000000 0.934710 -vt 0.107283 0.369714 -vt 1.000000 0.173943 -vt 0.071554 1.000000 -vt 0.928543 1.000000 -vt 1.000000 0.804229 -vt 0.000000 0.173943 -vt 0.928543 0.195673 -vt 0.000000 0.478367 -vt 0.250098 1.000000 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 1.000000 0.978172 -vt 1.000000 0.673845 vt 0.000000 1.000000 -vn -0.4486 -0.8937 0.0000 +vt 1.000000 0.000000 +vn 0.9724 -0.2334 0.0000 vn 0.0000 0.0000 -1.0000 -vn 0.0000 1.0000 -0.0000 vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 -vn -0.7074 -0.7068 0.0000 -vn 0.7560 0.6300 0.1775 -vn -0.6137 -0.7895 -0.0015 -vn -0.5547 -0.8321 0.0046 -vn 0.7768 0.6297 0.0000 -vn 0.7728 0.6317 0.0604 -vn -0.8945 -0.4471 0.0000 -vn -0.6248 -0.7808 0.0000 -vn 0.7756 0.6287 0.0566 -vn -0.7810 -0.6246 0.0000 -vn -0.7892 -0.6141 -0.0014 -vn -0.8318 -0.5551 0.0047 -vn -0.7311 -0.6784 0.0731 vn 0.0000 -1.0000 0.0000 -vn -0.0001 0.0000 -1.0000 -vn -0.8946 -0.4469 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.9579 -0.2870 0.0064 -vn -0.8574 -0.5147 0.0000 -vn -0.8943 -0.4474 0.0000 -vn -0.9978 0.0000 0.0668 usemtl None s off -f 480/467/461 482/468/461 493/469/461 -f 469/470/462 468/471/462 470/472/462 -f 468/471/463 469/470/463 472/473/463 -f 469/470/462 470/472/462 473/474/462 -f 470/472/462 468/471/462 474/475/462 -f 471/476/464 470/472/464 474/475/464 -f 471/476/465 472/473/465 475/477/465 -f 471/476/465 475/477/465 476/478/465 -f 469/470/462 473/474/462 477/479/462 -f 475/477/465 472/473/465 478/480/465 -f 467/481/466 473/474/466 479/482/466 -f 473/474/462 470/472/462 479/482/462 -f 471/476/465 476/478/465 480/467/465 -f 468/471/463 472/473/463 481/483/463 -f 472/473/467 471/476/467 481/483/467 -f 479/482/462 470/472/462 482/468/462 -f 476/478/468 479/482/468 482/468/468 -f 480/467/469 476/478/469 482/468/469 -f 474/475/470 468/471/470 483/484/470 -f 468/471/463 481/483/463 483/484/463 -f 481/483/471 471/476/471 483/484/471 -f 469/470/462 477/479/462 484/485/462 -f 475/477/472 478/480/472 484/485/472 -f 476/478/465 475/477/465 485/486/465 -f 467/481/466 479/482/466 485/486/466 -f 479/482/473 476/478/473 485/486/473 -f 471/476/464 474/475/464 486/487/464 -f 474/475/470 483/484/470 486/487/470 -f 483/484/474 471/476/474 486/487/474 -f 473/474/475 467/481/475 487/488/475 -f 477/479/476 473/474/476 487/488/476 -f 475/477/477 477/479/477 487/488/477 -f 467/481/478 485/486/478 487/488/478 -f 485/486/465 475/477/465 487/488/465 -f 472/473/463 469/470/463 488/489/463 -f 470/472/464 471/476/464 489/490/464 -f 480/467/479 470/472/479 489/490/479 -f 471/476/465 480/467/465 489/490/465 -f 469/470/480 484/485/480 490/491/480 -f 484/485/481 478/480/481 490/491/481 -f 488/489/482 469/470/482 490/491/482 -f 478/480/483 488/489/483 490/491/483 -f 477/479/484 475/477/484 491/492/484 -f 484/485/462 477/479/462 491/492/462 -f 475/477/485 484/485/485 491/492/485 -f 478/480/465 472/473/465 492/493/465 -f 472/473/463 488/489/463 492/493/463 -f 488/489/486 478/480/486 492/493/486 -f 470/472/479 480/467/479 493/469/479 -f 482/468/462 470/472/462 493/469/462 -o Cup_hull_21 -v -0.016705 -0.019073 0.034427 -v -0.015388 -0.009068 0.015038 -v -0.020391 -0.009068 0.015038 -v -0.013281 -0.020391 0.015038 -v -0.023552 -0.009332 0.034427 -v -0.013281 -0.018548 0.034143 -v -0.020127 -0.015387 0.015038 -v -0.020918 -0.009068 0.034143 -v -0.013281 -0.011966 0.015038 -v -0.023552 -0.009068 0.018410 -v -0.013808 -0.021182 0.018129 -v -0.013281 -0.021182 0.034427 -v -0.020918 -0.014335 0.034427 -v -0.016969 -0.018811 0.015038 -v -0.021708 -0.013019 0.018129 -v -0.015915 -0.009068 0.017568 -v -0.019075 -0.016704 0.034427 -v -0.014335 -0.020917 0.034427 -v -0.015388 -0.020126 0.015038 -v -0.021181 -0.009068 0.034427 -v -0.013281 -0.012492 0.017287 -v -0.022760 -0.009859 0.017006 -v -0.019075 -0.016704 0.015038 -v -0.023552 -0.009068 0.034427 -v -0.023552 -0.009332 0.018410 -v -0.021708 -0.013019 0.034427 -v -0.013281 -0.021182 0.017568 -v -0.013281 -0.018811 0.034427 -v -0.020391 -0.014861 0.015038 -v -0.020918 -0.014335 0.018410 -v -0.013808 -0.021182 0.034427 -v -0.022497 -0.009068 0.016725 -v -0.014335 -0.020917 0.018410 -vt 0.000000 0.021829 -vt 1.000000 0.087118 -vt 0.826057 0.021829 -vt 1.000000 1.000000 +f 438/431/426 433/432/426 440/433/426 +f 432/434/427 433/432/427 434/435/427 +f 433/432/428 432/434/428 435/436/428 +f 432/434/429 434/435/429 435/436/429 +f 434/435/427 433/432/427 436/437/427 +f 431/438/430 434/435/430 436/437/430 +f 434/435/430 431/438/430 437/439/430 +f 431/438/431 435/436/431 437/439/431 +f 435/436/429 434/435/429 437/439/429 +f 435/436/431 431/438/431 438/431/431 +f 431/438/432 436/437/432 438/431/432 +f 438/431/432 436/437/432 439/440/432 +f 436/437/427 433/432/427 439/440/427 +f 433/432/426 438/431/426 439/440/426 +f 433/432/428 435/436/428 440/433/428 +f 435/436/431 438/431/431 440/433/431 +o cup_hull_19 +v -0.015774 0.036902 0.026342 +v -0.033890 0.021316 0.052032 +v -0.033887 0.021316 0.075211 +v -0.015774 0.023847 0.022542 +v -0.015353 0.035639 0.075211 +v -0.030096 0.027217 0.022542 +v -0.023361 0.033111 0.075211 +v -0.032626 0.021316 0.022542 +v -0.019146 0.021316 0.023388 +v -0.032205 0.021316 0.075211 +v -0.023779 0.032689 0.022542 +v -0.030096 0.027217 0.075211 +v -0.015776 0.037325 0.075211 +v -0.015351 0.032688 0.022542 +v -0.033890 0.022161 0.027182 +v -0.015351 0.024267 0.023810 +v -0.020832 0.034794 0.027605 +v -0.027149 0.030161 0.022542 +v -0.015351 0.037327 0.027605 +v -0.032205 0.024689 0.075211 +v -0.027147 0.030161 0.075211 +v -0.020832 0.034796 0.075211 +v -0.032203 0.024687 0.022542 +v -0.033887 0.022159 0.075211 +v -0.015774 0.037327 0.027605 +v -0.015776 0.035217 0.075211 +v -0.025042 0.031846 0.022542 +v -0.015353 0.037325 0.075211 +v -0.033890 0.021316 0.026342 +v -0.019146 0.021316 0.022542 +v -0.023358 0.033109 0.026764 +v -0.025042 0.031848 0.075211 +vt 1.000000 0.477291 +vt 1.000000 0.363645 +vt 0.000000 0.477291 +vt 0.000000 0.000196 +vt 0.000000 0.999902 +vt 0.000000 0.567933 +vt 0.440094 0.000000 +vt 1.000000 0.068226 +vt 1.000000 0.204679 +vt 1.000000 0.977193 +vt 0.983947 0.795321 +vt 0.000000 0.090936 +vt 1.000000 0.545419 +vt 0.000000 0.204679 +vt 0.000000 0.977095 +vt 0.927858 0.977193 vt 1.000000 1.000000 -vt 1.000000 0.065290 -vt 1.000000 0.478367 -vt 0.014683 1.000000 -vt 1.000000 0.760768 -vt 0.014683 0.217404 -vt 0.826057 1.000000 -vt 0.000000 0.978172 -vt 0.000000 0.174041 -vt 0.000000 0.000000 -vt 0.000000 0.565192 -vt 1.000000 0.195673 -vt 0.869518 1.000000 -vt 0.000000 0.369616 -vt 0.000000 1.000000 -vt 0.884005 0.717306 -vt 1.000000 0.369616 -vt 0.000000 1.000000 -vt 0.826057 0.978172 -vt 0.840544 0.673845 -vt 0.898493 0.934710 -vt 0.000000 0.673845 -vt 0.869518 0.000000 -vt 0.840544 0.000000 -vt 0.000000 0.195673 -vt 1.000000 0.521731 -vt 0.826057 0.565192 -vt 0.000000 0.000000 -vt 0.912980 1.000000 -vn -0.6004 -0.7997 0.0000 +vt 0.975920 1.000000 +vt 0.903876 1.000000 +vt 0.000000 0.090936 +vt 0.000000 0.363743 +vt 0.000000 0.704385 +vt 0.903876 0.704385 +vt 1.000000 0.091034 +vt 0.911903 0.000000 +vt 0.000000 0.000196 +vt 0.903876 0.977193 +vt 0.000000 0.977095 +vt 0.000000 0.999902 +vt 0.927858 0.000000 +vt 1.000000 0.795321 +vt 0.919832 0.568128 +vn -0.6245 0.7810 -0.0000 +vn -0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 vn 0.0000 0.0000 -1.0000 +vn 0.0001 0.6696 -0.7427 +vn 0.6087 -0.7912 0.0591 +vn 0.5965 -0.7884 0.1503 +vn 0.9521 -0.0455 -0.3024 +vn -0.7068 0.7074 0.0000 +vn 0.7875 0.4544 -0.4164 +vn 1.0000 -0.0000 0.0000 +vn -0.7679 0.6406 0.0000 +vn -0.7066 0.7076 0.0000 +vn -0.5543 0.8323 -0.0000 +vn -0.7684 0.6400 -0.0000 +vn -0.8316 0.5554 -0.0000 +vn -1.0000 0.0000 0.0002 +vn -1.0000 0.0022 0.0001 +vn -0.8327 0.5538 0.0001 +vn -0.3283 0.8953 -0.3011 +vn -0.4450 0.8887 -0.1104 +vn 0.0000 0.9478 -0.3187 vn 0.0000 1.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.7581 0.6107 0.2288 -vn -0.7893 -0.6140 0.0011 -vn -0.7070 -0.7072 0.0000 -vn -0.6396 -0.7687 -0.0017 -vn -0.6140 -0.7893 0.0012 -vn 0.8012 0.5826 0.1364 -vn 0.7884 0.5929 0.1641 -vn 0.7832 0.5852 0.2102 -vn -0.7813 -0.6242 0.0000 -vn -0.7073 -0.7069 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.8944 -0.4473 0.0000 -vn -0.8713 0.0000 -0.4908 +vn -0.4474 0.8943 0.0000 +vn -0.4478 0.8942 -0.0000 +vn 0.0002 0.0000 1.0000 +vn 0.6976 -0.6996 0.1548 +vn 0.6370 -0.7528 0.1656 +vn -1.0000 -0.0000 0.0000 +vn -0.9422 0.1182 -0.3136 +vn -0.9488 0.2227 -0.2239 +vn 0.6004 -0.7997 0.0000 +vn -0.5481 0.8360 -0.0285 +vn -0.5549 0.8319 -0.0001 +vn -0.5550 0.8314 -0.0274 +vn -0.5999 0.8000 -0.0001 vn 0.0001 0.0000 1.0000 -vn -0.8574 -0.5147 0.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.1189 -0.9477 -0.2963 -vn -0.2242 -0.9516 -0.2102 -vn 0.6737 0.5426 0.5017 -vn 0.6308 0.5114 0.5836 -vn -0.8882 -0.4454 -0.1129 -vn -0.8916 -0.4368 -0.1194 -vn -0.8797 -0.2601 -0.3981 -vn -0.7995 -0.6007 0.0000 -vn -0.8532 -0.5202 -0.0377 -vn -0.4486 -0.8937 0.0000 -vn -0.8440 0.0935 -0.5281 -vn -0.6252 0.0000 -0.7804 -vn -0.6798 -0.0338 -0.7326 -vn -0.4726 -0.8793 -0.0586 +vn -0.6252 0.7805 0.0000 +vn -0.6009 0.7993 -0.0000 usemtl None s off -f 511/494/487 512/495/487 526/496/487 -f 496/497/488 495/498/488 497/499/488 -f 496/497/488 497/499/488 500/500/488 -f 495/498/489 496/497/489 501/501/489 -f 497/499/488 495/498/488 502/502/488 -f 499/503/490 497/499/490 502/502/490 -f 501/501/489 496/497/489 503/504/489 -f 498/505/491 494/506/491 505/507/491 -f 497/499/490 499/503/490 505/507/490 -f 494/506/491 498/505/491 506/508/491 -f 500/500/488 497/499/488 507/509/488 -f 495/498/489 501/501/489 509/510/489 -f 501/501/492 499/503/492 509/510/492 -f 494/506/491 506/508/491 510/511/491 -f 506/508/493 500/500/493 510/511/493 -f 507/509/494 494/506/494 510/511/494 -f 505/507/491 494/506/491 511/494/491 -f 507/509/488 497/499/488 512/495/488 -f 494/506/495 507/509/495 512/495/495 -f 511/494/496 494/506/496 512/495/496 -f 501/501/489 503/504/489 513/512/489 -f 498/505/491 505/507/491 513/512/491 -f 502/502/497 495/498/497 514/513/497 -f 499/503/490 502/502/490 514/513/490 -f 495/498/498 509/510/498 514/513/498 -f 509/510/499 499/503/499 514/513/499 -f 500/500/488 507/509/488 516/514/488 -f 510/511/500 500/500/500 516/514/500 -f 507/509/501 510/511/501 516/514/501 -f 503/504/502 498/505/502 517/515/502 -f 498/505/491 513/512/491 517/515/491 -f 513/512/489 503/504/489 517/515/489 -f 498/505/502 503/504/502 518/516/502 -f 508/517/503 498/505/503 518/516/503 -f 503/504/504 515/518/504 518/516/504 -f 506/508/505 498/505/505 519/519/505 -f 498/505/503 508/517/503 519/519/503 -f 508/517/506 506/508/506 519/519/506 -f 497/499/490 505/507/490 520/520/490 -f 505/507/507 504/521/507 520/520/507 -f 512/495/508 497/499/508 520/520/508 -f 504/521/509 512/495/509 520/520/509 -f 499/503/510 501/501/510 521/522/510 -f 505/507/490 499/503/490 521/522/490 -f 501/501/511 513/512/511 521/522/511 -f 513/512/491 505/507/491 521/522/491 -f 496/497/488 500/500/488 522/523/488 -f 500/500/512 508/517/512 522/523/512 -f 508/517/513 518/516/513 522/523/513 -f 518/516/514 515/518/514 522/523/514 -f 500/500/515 506/508/515 523/524/515 -f 508/517/516 500/500/516 523/524/516 -f 506/508/506 508/517/506 523/524/506 -f 504/521/507 505/507/507 524/525/507 -f 505/507/491 511/494/491 524/525/491 -f 511/494/517 504/521/517 524/525/517 -f 503/504/489 496/497/489 525/526/489 -f 515/518/518 503/504/518 525/526/518 -f 496/497/519 522/523/519 525/526/519 -f 522/523/520 515/518/520 525/526/520 -f 504/521/517 511/494/517 526/496/517 -f 512/495/521 504/521/521 526/496/521 -o Cup_hull_22 -v -0.024078 -0.007750 0.050164 -v -0.023025 -0.000378 0.033584 -v -0.025132 -0.000378 0.033584 -v -0.021182 -0.009067 0.033584 -v -0.024078 -0.000642 0.050164 -v -0.023814 -0.008540 0.033584 -v -0.022499 -0.009067 0.050164 -v -0.025132 -0.002485 0.050164 -v -0.024868 -0.004592 0.033584 -v -0.025132 -0.000378 0.050164 -v -0.021182 -0.008803 0.034991 -v -0.023551 -0.009067 0.050164 -v -0.023551 -0.009067 0.033584 -v -0.024604 -0.005907 0.050164 -v -0.023025 -0.000378 0.034991 -v -0.022499 -0.008540 0.050164 -v -0.025132 -0.002485 0.033584 -v -0.024604 -0.005907 0.033584 -v -0.024868 -0.004592 0.050164 -v -0.024078 -0.000378 0.048758 -v -0.021182 -0.008540 0.033584 -vt 0.915133 1.000000 -vt 0.915133 0.030345 -vt 1.000000 0.060689 +f 467/441/433 458/442/433 472/443/433 +f 443/444/434 445/445/434 447/446/434 +f 443/444/435 442/447/435 448/448/435 +f 446/449/436 444/450/436 448/448/436 +f 443/444/435 448/448/435 449/451/435 +f 445/445/434 443/444/434 450/452/434 +f 443/444/435 449/451/435 450/452/435 +f 444/450/436 446/449/436 451/453/436 +f 443/444/434 447/446/434 452/454/434 +f 447/446/434 445/445/434 453/455/434 +f 451/453/437 441/456/437 454/457/437 +f 444/450/436 451/453/436 454/457/436 +f 449/451/438 444/450/438 456/458/438 +f 450/452/439 449/451/439 456/458/439 +f 444/450/440 454/457/440 456/458/440 +f 451/453/436 446/449/436 458/442/436 +f 446/449/441 452/454/441 458/442/441 +f 454/457/442 441/456/442 459/459/442 +f 445/445/443 456/458/443 459/459/443 +f 456/458/443 454/457/443 459/459/443 +f 443/444/434 452/454/434 460/460/434 +f 452/454/444 446/449/444 460/460/444 +f 452/454/434 447/446/434 461/461/434 +f 458/442/445 452/454/445 461/461/445 +f 447/446/434 453/455/434 462/462/434 +f 457/463/446 447/446/446 462/462/446 +f 446/449/436 448/448/436 463/464/436 +f 460/460/447 446/449/447 463/464/447 +f 455/465/448 460/460/448 463/464/448 +f 442/447/449 443/444/449 464/466/449 +f 455/465/450 442/447/450 464/466/450 +f 443/444/434 460/460/434 464/466/434 +f 460/460/451 455/465/451 464/466/451 +f 441/456/452 451/453/452 465/467/452 +f 451/453/453 457/463/453 465/467/453 +f 459/459/454 441/456/454 465/467/454 +f 453/455/455 459/459/455 465/467/455 +f 462/462/456 453/455/456 465/467/456 +f 457/463/457 462/462/457 465/467/457 +f 445/445/458 450/452/458 466/468/458 +f 456/458/459 445/445/459 466/468/459 +f 450/452/460 456/458/460 466/468/460 +f 451/453/436 458/442/436 467/441/436 +f 453/455/434 445/445/434 468/469/434 +f 445/445/443 459/459/443 468/469/443 +f 459/459/455 453/455/455 468/469/455 +f 448/448/435 442/447/435 469/470/435 +f 442/447/461 455/465/461 469/470/461 +f 463/464/462 448/448/462 469/470/462 +f 455/465/463 463/464/463 469/470/463 +f 448/448/436 444/450/436 470/471/436 +f 444/450/464 449/451/464 470/471/464 +f 449/451/435 448/448/435 470/471/435 +f 457/463/465 451/453/465 471/472/465 +f 447/446/466 457/463/466 471/472/466 +f 451/453/467 467/441/467 471/472/467 +f 467/441/468 447/446/468 471/472/468 +f 461/461/469 447/446/469 472/443/469 +f 458/442/470 461/461/470 472/443/470 +f 447/446/471 467/441/471 472/443/471 +o cup_hull_20 +v 0.026362 -0.011126 0.022524 +v 0.032683 0.000667 -0.072261 +v 0.032683 -0.011971 -0.072261 +v 0.032683 0.000667 0.022524 +v 0.028891 0.000667 -0.072261 +v 0.026362 -0.011971 -0.072261 +v 0.032683 -0.011971 0.022524 +v 0.028891 0.000667 0.022524 +v 0.026362 -0.011971 0.022524 +v 0.026362 -0.010705 -0.072261 +v 0.026362 -0.010705 0.020844 +vt 1.000000 0.100147 +vt 0.000000 0.066862 +vt 0.017719 0.100147 +vt 1.000000 0.000000 vt 1.000000 1.000000 +vt 0.000000 1.000000 vt 1.000000 1.000000 vt 1.000000 0.000000 -vt 1.000000 0.060689 -vt 0.000000 0.969655 -vt 0.000000 0.151527 vt 0.000000 0.000000 -vt 0.000000 0.757537 -vt 1.000000 0.515074 vt 0.000000 1.000000 vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.363645 -vt 0.000000 0.060689 -vt 1.000000 0.757537 -vt 1.000000 0.363645 -vt 0.000000 0.515074 -vt 0.084769 1.000000 -vn 0.9761 0.2136 0.0400 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 0.0000 vn 0.0000 0.0000 -1.0000 -vn -0.0000 0.0000 1.0000 vn 0.0000 1.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn 0.9183 -0.3892 0.0729 -vn -0.9285 -0.3714 0.0029 +vn 0.0000 0.0000 1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.8947 -0.4467 0.0000 -vn 0.9744 0.2132 0.0713 -vn 0.9773 0.1954 0.0814 -vn 0.9963 0.0000 0.0865 -vn -0.9922 -0.1244 0.0000 -vn -0.9578 -0.2874 -0.0015 -vn -0.9615 -0.2747 0.0000 -vn -0.9806 -0.1962 0.0000 -vn 0.2388 0.9544 0.1790 -vn 0.9238 0.3764 0.0706 -vn 1.0000 0.0000 0.0000 -vn 0.9754 0.2203 0.0000 +vn -0.9762 0.2170 0.0000 +vn -0.9764 0.2094 0.0524 usemtl None s off -f 541/527/522 537/528/522 547/529/522 -f 529/530/523 528/531/523 530/532/523 -f 529/530/523 530/532/523 532/533/523 -f 531/534/524 527/535/524 533/536/524 -f 527/535/524 531/534/524 534/537/524 -f 529/530/523 532/533/523 535/538/523 -f 528/531/525 529/530/525 536/539/525 -f 534/537/524 531/534/524 536/539/524 -f 529/530/526 534/537/526 536/539/526 -f 533/536/527 530/532/527 537/528/527 -f 527/535/528 532/533/528 538/540/528 -f 530/532/529 533/536/529 538/540/529 -f 533/536/524 527/535/524 538/540/524 -f 532/533/523 530/532/523 539/541/523 -f 538/540/530 532/533/530 539/541/530 -f 530/532/529 538/540/529 539/541/529 -f 527/535/524 534/537/524 540/542/524 -f 528/531/525 536/539/525 541/527/525 -f 531/534/531 537/528/531 541/527/531 -f 531/534/524 533/536/524 542/543/524 -f 537/528/532 531/534/532 542/543/532 -f 533/536/533 537/528/533 542/543/533 -f 534/537/526 529/530/526 543/544/526 -f 529/530/523 535/538/523 543/544/523 -f 535/538/534 534/537/534 543/544/534 -f 532/533/535 527/535/535 544/545/535 -f 535/538/523 532/533/523 544/545/523 -f 527/535/536 540/542/536 544/545/536 -f 540/542/537 535/538/537 544/545/537 -f 534/537/534 535/538/534 545/546/534 -f 540/542/524 534/537/524 545/546/524 -f 535/538/537 540/542/537 545/546/537 -f 536/539/538 531/534/538 546/547/538 -f 541/527/525 536/539/525 546/547/525 -f 531/534/539 541/527/539 546/547/539 -f 530/532/523 528/531/523 547/529/523 -f 537/528/540 530/532/540 547/529/540 -f 528/531/541 541/527/541 547/529/541 -o Cup_hull_23 -v -0.015652 -0.009067 0.015036 -v -0.025131 -0.002485 0.033582 -v -0.024868 -0.004592 0.033582 -v -0.024868 -0.003275 0.017567 -v -0.018022 -0.000378 0.015037 -v -0.020918 -0.009066 0.033301 -v -0.023550 -0.009066 0.017846 -v -0.022761 -0.000378 0.033301 -v -0.025131 -0.000378 0.017846 -v -0.020655 -0.008803 0.015037 -v -0.023550 -0.009066 0.033582 -v -0.015915 -0.008804 0.017004 -v -0.025131 -0.000378 0.033582 -v -0.020655 -0.000378 0.015037 -v -0.018549 -0.000378 0.018128 -v -0.024605 -0.005907 0.018409 -v -0.024341 -0.000378 0.016722 -v -0.025131 -0.002485 0.018409 -v -0.024078 -0.007750 0.033582 -v -0.024341 -0.004592 0.017004 -v -0.021181 -0.008277 0.033582 -v -0.020918 -0.008803 0.033301 -v -0.023024 -0.009066 0.017004 -v -0.023814 -0.008540 0.018409 -v -0.018022 -0.000378 0.015880 -v -0.022761 -0.000906 0.033582 -v -0.024868 -0.004592 0.018409 -v -0.024605 -0.005907 0.033582 -v -0.015652 -0.008804 0.015880 -v -0.020392 -0.009066 0.015037 -vt 0.893882 0.222222 -vt 0.999902 0.472149 -vt 0.999902 0.499951 -vt 0.015174 0.250024 -vt 0.999902 0.749976 -vt 0.848458 0.000000 +f 482/473/472 473/474/472 483/475/472 +f 475/476/473 474/477/473 476/478/473 +f 474/477/474 475/476/474 477/479/474 +f 476/478/475 474/477/475 477/479/475 +f 477/479/474 475/476/474 478/480/474 +f 475/476/473 476/478/473 479/481/473 +f 476/478/476 473/474/476 479/481/476 +f 478/480/477 475/476/477 479/481/477 +f 473/474/476 476/478/476 480/482/476 +f 476/478/475 477/479/475 480/482/475 +f 473/474/472 478/480/472 481/483/472 +f 479/481/476 473/474/476 481/483/476 +f 478/480/477 479/481/477 481/483/477 +f 478/480/472 473/474/472 482/473/472 +f 477/479/474 478/480/474 482/473/474 +f 480/482/478 477/479/478 482/473/478 +f 480/482/478 482/473/478 483/475/478 +f 473/474/479 480/482/479 483/475/479 +o cup_hull_21 +v 0.008666 -0.038093 0.025073 +v -0.004396 -0.040201 0.047402 +v -0.004396 -0.035986 0.047402 +v -0.004396 -0.033039 0.022545 +v 0.008666 -0.027561 0.023810 +v 0.008666 -0.035143 0.047402 +v -0.004396 -0.040201 0.027601 +v 0.007401 -0.039779 0.047402 +v -0.004396 -0.028404 0.022968 +v 0.004450 -0.040201 0.027601 +v 0.008666 -0.033039 0.022545 +v -0.003132 -0.038935 0.025073 +v -0.004396 -0.035565 0.046976 +v 0.008666 -0.039356 0.026759 +v 0.008666 -0.027561 0.022545 +v 0.008666 -0.039356 0.047402 +v -0.004396 -0.029248 0.026759 +v 0.008243 -0.027984 0.025496 +v 0.004450 -0.040201 0.047402 +v 0.008243 -0.034722 0.046555 +v 0.003186 -0.039779 0.025917 +v -0.004396 -0.028404 0.022545 +v 0.003186 -0.038935 0.025073 +v 0.007401 -0.039779 0.027601 +v -0.004396 -0.039779 0.026338 +vt 0.898297 0.096809 +vt 0.864330 0.580462 +vt 0.847396 0.000000 vt 0.000000 0.000000 -vt 0.000000 0.027704 -vt 0.000000 0.166716 -vt 1.000000 1.000000 -vt 0.015174 0.444445 -vt 0.848458 0.166716 -vt 0.893882 0.972198 vt 0.000000 0.000000 -vt 0.999902 0.472149 -vt 0.833284 0.694371 -vt 0.863534 0.027704 -vt 0.909055 0.083309 -vt 0.818111 0.000000 -vt 0.000000 0.111111 -vt 0.818111 0.055507 -vt 0.893882 0.083309 -vt 0.000000 0.416642 -vt 0.015174 0.444445 -vt 0.818111 0.138913 -vt 0.954479 0.749976 -vt 0.000000 0.250024 -vt 0.818111 0.027704 -vt 0.000000 0.055507 -vt 0.954479 1.000000 -vn -0.5131 -0.5145 -0.6870 -vn 0.0000 1.0000 0.0000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.898297 1.000000 +vt 0.949099 1.000000 +vt 0.796593 0.000000 +vt 0.000000 0.903191 +vt 0.982968 0.000000 +vt 0.796593 0.677271 +vt 1.000000 1.000000 +vt 0.017130 0.000000 +vt 0.830462 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.830462 0.000000 +vt 0.881265 0.967600 +vt 0.000000 0.677271 +vt 0.034064 0.967600 +vt 1.000000 0.000000 +vt 0.898297 0.580462 +vt 0.796593 0.903191 +vn -0.0320 -0.8165 -0.5765 +vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn 1.0000 0.0000 0.0000 vn 0.0000 -1.0000 0.0000 -vn -0.0001 -1.0000 0.0000 -vn 0.6427 -0.7434 0.1853 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0002 -1.0000 -vn -0.0004 0.0000 -1.0000 -vn 0.9313 0.2566 0.2585 -vn -0.8181 -0.0187 -0.5748 -vn -0.4157 0.0000 -0.9095 -vn -0.9923 -0.1237 0.0000 -vn -0.9683 -0.0645 -0.2414 -vn -0.9078 -0.2076 -0.3645 -vn -0.8945 -0.2302 -0.3832 -vn -0.7764 -0.0420 -0.6288 -vn -0.5198 -0.0569 -0.8524 -vn 0.1013 -0.3039 0.9473 -vn 0.9560 0.0000 0.2935 -vn 0.9357 0.2047 0.2872 -vn 0.7299 0.0000 0.6835 -vn -0.0001 -1.0000 -0.0001 -vn -0.8229 -0.2422 -0.5140 -vn -0.6161 -0.1813 -0.7665 -vn -0.8942 -0.4476 0.0000 -vn -0.9427 -0.2831 -0.1766 -vn -0.9283 -0.3718 0.0032 -vn -0.9577 -0.2876 -0.0017 -vn 0.9390 0.2641 0.2202 -vn 0.1042 0.4682 0.8774 -vn 0.9069 0.1984 0.3717 -vn 0.8662 0.1856 0.4639 -vn -0.9805 -0.1965 0.0000 -vn -0.9373 -0.1878 -0.2936 -vn -0.9743 -0.1214 -0.1898 -vn -0.9615 -0.2749 0.0000 -vn 0.9615 0.2623 -0.0817 -vn 0.7851 -0.5914 0.1841 -vn 0.9626 0.2708 0.0000 -vn -0.0004 -0.0004 -1.0000 -vn -0.0002 -1.0000 -0.0002 +vn 0.0000 -0.3941 -0.9191 +vn -0.0458 0.7106 0.7021 +vn -0.0645 0.9979 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.3174 -0.9483 0.0000 +vn -0.0768 0.9732 0.2166 +vn -0.0656 0.9524 0.2976 +vn -0.0747 0.9715 0.2251 +vn 0.1415 -0.9899 0.0000 +vn 0.3170 0.9029 0.2902 +vn -0.0437 0.8858 0.4619 +vn -0.0533 0.9511 0.3043 +vn 0.2534 0.9214 0.2948 +vn 0.0000 -0.9700 -0.2431 +vn 0.1521 -0.7910 -0.5926 +vn 0.1226 -0.9371 -0.3269 +vn 0.0686 -0.4464 -0.8922 +vn 0.0000 -0.7073 -0.7069 +vn 0.1081 -0.7031 -0.7028 +vn 0.1361 -0.9520 -0.2741 +vn -0.4783 -0.4307 -0.7653 +vn -0.0176 -0.9483 -0.3169 usemtl None s off -f 570/548/542 557/549/542 577/550/542 -f 555/551/543 552/552/543 556/553/543 -f 549/554/544 550/555/544 558/556/544 -f 548/557/545 553/558/545 558/556/545 -f 554/559/546 548/557/546 558/556/546 -f 553/558/547 548/557/547 559/560/547 -f 556/553/548 549/554/548 560/561/548 -f 555/551/543 556/553/543 560/561/543 -f 549/554/544 558/556/544 560/561/544 -f 552/552/549 548/557/549 561/562/549 -f 556/553/543 552/552/543 561/562/543 -f 548/557/550 557/549/550 561/562/550 -f 552/552/543 555/551/543 562/563/543 -f 555/551/551 559/560/551 562/563/551 -f 551/564/552 556/553/552 564/565/552 -f 556/553/543 561/562/543 564/565/543 -f 561/562/553 557/549/553 564/565/553 -f 550/555/554 549/554/554 565/566/554 -f 549/554/548 556/553/548 565/566/548 -f 556/553/555 551/564/555 565/566/555 -f 558/556/544 550/555/544 566/567/544 -f 563/568/556 551/564/556 567/569/556 -f 554/559/557 563/568/557 567/569/557 -f 551/564/558 564/565/558 567/569/558 -f 564/565/559 557/549/559 567/569/559 -f 558/556/560 553/558/560 568/570/560 -f 560/561/544 558/556/544 568/570/544 -f 553/558/561 559/560/561 569/571/561 -f 559/560/562 555/551/562 569/571/562 -f 568/570/563 553/558/563 569/571/563 -f 548/557/564 554/559/564 570/548/564 -f 554/559/565 567/569/565 570/548/565 -f 567/569/566 557/549/566 570/548/566 -f 554/559/567 558/556/567 571/572/567 -f 563/568/568 554/559/568 571/572/568 -f 558/556/569 566/567/569 571/572/569 -f 566/567/570 563/568/570 571/572/570 -f 552/552/543 562/563/543 572/573/543 -f 562/563/571 559/560/571 572/573/571 -f 555/551/572 560/561/572 573/574/572 -f 560/561/544 568/570/544 573/574/544 -f 569/571/573 555/551/573 573/574/573 -f 568/570/574 569/571/574 573/574/574 -f 563/568/575 550/555/575 574/575/575 -f 551/564/576 563/568/576 574/575/576 -f 550/555/554 565/566/554 574/575/554 -f 565/566/577 551/564/577 574/575/577 -f 550/555/575 563/568/575 575/576/575 -f 566/567/544 550/555/544 575/576/544 -f 563/568/578 566/567/578 575/576/578 -f 548/557/579 552/552/579 576/577/579 -f 559/560/580 548/557/580 576/577/580 -f 552/552/581 572/573/581 576/577/581 -f 572/573/571 559/560/571 576/577/571 -f 557/549/582 548/557/582 577/550/582 -f 548/557/583 570/548/583 577/550/583 -o Cup_hull_24 -v -0.025132 0.002520 0.050166 -v -0.021182 0.008313 0.032181 -v -0.023814 0.008313 0.032181 -v -0.022762 -0.000376 0.032181 -v -0.022762 0.008313 0.050166 -v -0.025132 -0.000376 0.032181 -v -0.024341 -0.000376 0.050166 -v -0.024078 0.007785 0.050166 -v -0.024604 0.005941 0.032181 -v -0.021182 0.007785 0.032744 -v -0.025132 -0.000376 0.050166 -v -0.025132 0.002520 0.032181 -v -0.024078 0.000677 0.050166 -v -0.022762 -0.000376 0.033306 -v -0.024604 0.005941 0.050166 -v -0.022762 0.007785 0.050166 -v -0.023814 0.008313 0.050166 -v -0.024078 0.007785 0.032181 -v -0.024868 0.004362 0.050166 -vt 0.000000 0.727068 -vt 1.000000 0.727068 -vt 0.000000 0.545276 +f 495/484/480 504/485/480 508/486/480 +f 485/487/481 486/488/481 487/489/481 +f 486/488/482 485/487/482 489/490/482 +f 484/491/483 488/492/483 489/490/483 +f 485/487/481 487/489/481 490/493/481 +f 489/490/482 485/487/482 491/494/482 +f 487/489/481 486/488/481 492/495/481 +f 485/487/484 490/493/484 493/496/484 +f 488/492/483 484/491/483 494/497/483 +f 487/489/485 494/497/485 495/484/485 +f 486/488/486 489/490/486 496/498/486 +f 492/495/481 486/488/481 496/498/481 +f 484/491/483 489/490/483 497/499/483 +f 492/495/487 488/492/487 498/500/487 +f 494/497/488 487/489/488 498/500/488 +f 488/492/483 494/497/483 498/500/483 +f 489/490/482 491/494/482 499/501/482 +f 497/499/483 489/490/483 499/501/483 +f 491/494/489 497/499/489 499/501/489 +f 488/492/490 492/495/490 500/502/490 +f 492/495/481 496/498/481 500/502/481 +f 500/502/491 496/498/491 501/503/491 +f 488/492/492 500/502/492 501/503/492 +f 491/494/482 485/487/482 502/504/482 +f 485/487/484 493/496/484 502/504/484 +f 493/496/493 491/494/493 502/504/493 +f 489/490/494 488/492/494 503/505/494 +f 496/498/495 489/490/495 503/505/495 +f 501/503/496 496/498/496 503/505/496 +f 488/492/497 501/503/497 503/505/497 +f 493/496/498 490/493/498 504/485/498 +f 484/491/499 497/499/499 504/485/499 +f 497/499/500 493/496/500 504/485/500 +f 487/489/481 492/495/481 505/506/481 +f 498/500/488 487/489/488 505/506/488 +f 492/495/487 498/500/487 505/506/487 +f 494/497/501 484/491/501 506/507/501 +f 495/484/485 494/497/485 506/507/485 +f 504/485/502 495/484/502 506/507/502 +f 484/491/503 504/485/503 506/507/503 +f 491/494/493 493/496/493 507/508/493 +f 497/499/489 491/494/489 507/508/489 +f 493/496/504 497/499/504 507/508/504 +f 490/493/481 487/489/481 508/486/481 +f 487/489/505 495/484/505 508/486/505 +f 504/485/506 490/493/506 508/486/506 +o cup_hull_22 +v 0.020884 -0.029247 0.047399 +v 0.021306 -0.019555 0.022543 +v 0.021306 -0.032614 0.022543 +v 0.008666 -0.027563 0.022545 +v 0.008666 -0.039358 0.047399 +v 0.008666 -0.038934 0.025915 +v 0.021305 -0.034299 0.047399 +v 0.008666 -0.034722 0.046976 +v 0.015829 -0.037249 0.027178 +v 0.020884 -0.020398 0.025915 +v 0.008666 -0.033035 0.022545 +v 0.020884 -0.034722 0.027178 +v 0.015829 -0.037249 0.047399 +v 0.008666 -0.027983 0.025915 +v 0.009510 -0.039358 0.027599 +v 0.021305 -0.029247 0.047399 +v 0.012458 -0.038513 0.047399 +v 0.020884 -0.019555 0.023387 +v 0.013723 -0.038093 0.027178 +v 0.009088 -0.034722 0.047399 +v 0.020884 -0.034722 0.047399 +v 0.020884 -0.028827 0.046555 +v 0.021306 -0.034301 0.026755 +v 0.009510 -0.039358 0.047399 +v 0.009088 -0.038513 0.025495 +v 0.011616 -0.038513 0.026336 +v 0.008666 -0.027563 0.024229 +v 0.016248 -0.036829 0.026336 +vt 0.813510 0.063919 +vt 0.847381 0.042678 +vt 0.847381 0.127741 vt 1.000000 1.000000 +vt 1.000000 0.340544 +vt 0.999902 0.595634 +vt 0.000000 0.000000 +vt 0.864317 0.021437 +vt 0.000000 0.510572 +vt 0.000000 0.255481 +vt 0.017034 0.234142 +vt 0.999902 0.319303 +vt 0.813510 0.106500 +vt 0.813510 0.234142 +vt 0.000000 0.106500 +vt 0.864317 0.574393 +vt 0.796574 0.000000 +vt 0.000000 0.510572 +vt 0.864317 0.957420 +vt 0.000000 0.042678 +vt 0.966030 1.000000 +vt 0.000000 0.234142 +vt 0.000000 0.234142 +vt 0.033970 0.531813 +vt 0.830543 0.255384 +vt 0.000000 0.000000 +vt 0.881253 0.042678 +vt 0.932159 0.595634 +vn 0.3188 -0.8768 -0.3599 +vn -0.0002 0.0000 -1.0000 +vn -1.0000 -0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.4472 -0.8944 0.0000 +vn -0.4206 -0.9071 -0.0179 +vn 0.7216 0.6450 0.2515 +vn -0.5170 0.8161 -0.2584 +vn 0.5350 0.8015 0.2673 +vn -0.4930 0.8253 0.2753 +vn -0.5107 0.8189 0.2620 +vn 0.3717 -0.9283 0.0000 +vn 0.3511 -0.9363 0.0025 +vn 0.2876 -0.9578 -0.0019 +vn -0.7069 0.0643 0.7044 +vn -0.3978 0.8494 0.3469 +vn 0.0000 0.8951 0.4459 +vn 0.1646 0.9132 0.3729 +vn -0.3836 0.8266 0.4118 +vn -0.3896 0.8352 0.3882 +vn 1.0000 0.0000 0.0000 +vn 0.4836 -0.8126 -0.3253 +vn 1.0000 0.0000 0.0001 +vn 0.7087 -0.7055 0.0001 +vn 0.7060 -0.7082 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.2755 -0.9613 0.0000 +vn 0.0156 -0.4730 -0.8809 +vn -0.3484 -0.4650 -0.8139 +vn 0.1787 -0.9291 -0.3238 +vn 0.2649 -0.9452 -0.1908 +vn 0.2095 -0.7487 -0.6290 +vn 0.1958 -0.7848 -0.5880 +vn -0.5481 0.8364 0.0000 +vn -0.5265 0.8249 0.2058 +vn 0.4396 -0.8321 -0.3382 +vn 0.4364 -0.8728 -0.2187 +vn 0.3581 -0.8943 -0.2684 +vn 0.2945 -0.8100 -0.5071 +usemtl None +s off +f 527/509/507 534/510/507 536/511/507 +f 510/512/508 511/513/508 512/514/508 +f 513/515/509 512/514/509 514/516/509 +f 509/517/510 513/515/510 515/518/510 +f 512/514/509 513/515/509 516/519/509 +f 512/514/508 511/513/508 519/520/508 +f 514/516/509 512/514/509 519/520/509 +f 517/521/511 520/522/511 521/523/511 +f 515/518/510 513/515/510 521/523/510 +f 512/514/509 516/519/509 522/524/509 +f 513/515/512 514/516/512 523/525/512 +f 509/517/510 515/518/510 524/526/510 +f 510/512/513 518/527/513 524/526/513 +f 521/523/510 513/515/510 525/528/510 +f 510/512/514 512/514/514 526/529/514 +f 518/527/515 510/512/515 526/529/515 +f 516/519/516 518/527/516 526/529/516 +f 522/524/517 516/519/517 526/529/517 +f 517/521/518 521/523/518 527/509/518 +f 521/523/519 525/528/519 527/509/519 +f 525/528/520 523/525/520 527/509/520 +f 513/515/510 509/517/510 528/530/510 +f 516/519/521 513/515/521 528/530/521 +f 521/523/511 520/522/511 529/531/511 +f 515/518/510 521/523/510 529/531/510 +f 518/527/522 516/519/522 530/532/522 +f 509/517/523 524/526/523 530/532/523 +f 524/526/524 518/527/524 530/532/524 +f 528/530/525 509/517/525 530/532/525 +f 516/519/526 528/530/526 530/532/526 +f 511/513/527 510/512/527 531/533/527 +f 520/522/528 511/513/528 531/533/528 +f 510/512/529 524/526/529 531/533/529 +f 524/526/529 515/518/529 531/533/529 +f 515/518/530 529/531/530 531/533/530 +f 529/531/531 520/522/531 531/533/531 +f 513/515/532 523/525/532 532/534/532 +f 525/528/510 513/515/510 532/534/510 +f 523/525/533 525/528/533 532/534/533 +f 519/520/534 511/513/534 533/535/534 +f 514/516/535 519/520/535 533/535/535 +f 523/525/536 514/516/536 534/510/536 +f 527/509/537 523/525/537 534/510/537 +f 533/535/538 511/513/538 534/510/538 +f 514/516/539 533/535/539 534/510/539 +f 512/514/509 522/524/509 535/536/509 +f 526/529/540 512/514/540 535/536/540 +f 522/524/541 526/529/541 535/536/541 +f 511/513/542 520/522/542 536/511/542 +f 520/522/543 517/521/543 536/511/543 +f 517/521/544 527/509/544 536/511/544 +f 534/510/545 511/513/545 536/511/545 +o cup_hull_23 +v 0.027628 -0.029667 0.075211 +v 0.038160 -0.013235 0.051615 +v 0.038160 -0.013657 0.051615 +v 0.021306 -0.030088 0.051615 +v 0.036474 -0.013235 0.075211 +v 0.027207 -0.030088 0.051615 +v 0.021306 -0.032195 0.075211 +v 0.034366 -0.013235 0.052881 +v 0.034788 -0.020819 0.075211 +v 0.022151 -0.033881 0.051615 +v 0.032261 -0.024611 0.051615 +v 0.022151 -0.033881 0.075211 +v 0.037738 -0.014500 0.075211 +v 0.034788 -0.020819 0.051615 +v 0.030154 -0.027139 0.075211 +v 0.021306 -0.033881 0.051615 +v 0.034367 -0.013235 0.051615 +v 0.024678 -0.032195 0.075211 +v 0.037317 -0.015763 0.075211 +v 0.021306 -0.030088 0.053304 +v 0.038160 -0.013235 0.071418 +v 0.032261 -0.024611 0.075211 +v 0.036053 -0.013657 0.075211 +v 0.021306 -0.033881 0.075211 +v 0.030154 -0.027139 0.051615 +v 0.024678 -0.032195 0.051615 +v 0.037317 -0.015763 0.051615 +vt 0.000000 0.877545 +vt 1.000000 0.632635 +vt 1.000000 0.877545 vt 1.000000 1.000000 -vt 1.000000 0.000000 +vt 1.000000 0.979542 +vt 1.000000 0.183731 +vt 1.000000 0.183731 +vt 0.000000 0.204092 vt 0.000000 1.000000 +vt 0.000000 0.081637 +vt 0.946359 1.000000 +vt 0.000000 0.632635 vt 1.000000 0.000000 +vt 1.000000 0.449002 vt 0.000000 0.000000 -vt 0.000000 0.333333 -vt 0.000000 0.939207 -vt 0.968677 0.939207 +vt 0.000000 0.938724 +vt 0.000000 0.326547 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 0.081637 +vt 0.928446 0.183731 +vt 0.160728 1.000000 +vt 0.000000 0.449002 +vt 0.000000 0.979542 vt 0.000000 0.000000 -vt 1.000000 0.333333 -vt 0.000000 0.121194 -vt 0.937451 0.000000 -vt 0.000000 0.939207 -vt 0.000000 1.000000 -vt 1.000000 0.939207 -vn -0.9864 0.1644 0.0000 +vt 1.000000 0.326547 +vt 1.000000 0.081637 +vn 0.8944 -0.4473 0.0000 vn 0.0000 0.0000 -1.0000 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -1.0000 -0.0000 vn 0.0000 0.0000 1.0000 -vn 0.9703 -0.1765 -0.1655 -vn 0.9919 0.0929 0.0871 +vn 0.0000 1.0000 0.0000 +vn 0.8321 -0.5547 0.0000 vn -1.0000 0.0000 0.0000 -vn 0.9791 -0.1835 0.0879 -vn 0.9818 -0.1901 0.0000 -vn 0.9662 -0.2416 0.0905 -vn -0.9615 0.2747 0.0000 -vn 0.9959 0.0000 0.0903 -vn 0.9794 -0.1813 0.0888 -vn -0.8950 0.4461 0.0000 -vn -0.9899 0.1419 0.0000 -vn -0.9883 0.1524 -0.0011 +vn 0.0000 -1.0000 0.0000 +vn -0.7904 0.6126 -0.0010 +vn 0.6508 -0.7593 0.0019 +vn 0.5548 -0.8320 0.0000 +vn 0.9487 -0.3160 0.0057 +vn -0.7884 0.6124 0.0589 +vn -0.7904 0.6125 0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.9541 -0.2994 0.0064 +vn 0.6749 0.6742 0.3000 +vn 0.7682 -0.6402 0.0000 +vn -0.0001 0.0000 1.0000 +vn -0.7070 0.7041 0.0668 +vn -0.7806 0.6210 0.0707 +vn 0.7074 -0.7069 -0.0000 +vn 0.7074 -0.7068 0.0000 +vn 0.6402 -0.7682 0.0000 +vn 0.9284 -0.3717 0.0000 usemtl None s off -f 592/578/584 586/579/584 596/580/584 -f 580/581/585 579/582/585 581/583/585 -f 579/582/586 580/581/586 582/584/586 -f 580/581/585 581/583/585 583/585/585 -f 583/585/587 581/583/587 584/586/587 -f 582/584/588 578/587/588 584/586/588 -f 578/587/588 582/584/588 585/588/588 -f 580/581/585 583/585/585 586/579/585 -f 581/583/589 579/582/589 587/589/589 -f 579/582/590 582/584/590 587/589/590 -f 578/587/591 583/585/591 588/590/591 -f 583/585/587 584/586/587 588/590/587 -f 584/586/588 578/587/588 588/590/588 -f 583/585/591 578/587/591 589/591/591 -f 586/579/585 583/585/585 589/591/585 -f 582/584/588 584/586/588 590/592/588 -f 587/589/592 590/592/592 591/593/592 -f 584/586/587 581/583/587 591/593/587 -f 581/583/593 587/589/593 591/593/593 -f 590/592/594 584/586/594 591/593/594 -f 578/587/588 585/588/588 592/578/588 -f 585/588/595 586/579/595 592/578/595 -f 587/589/596 582/584/596 593/594/596 -f 582/584/588 590/592/588 593/594/588 -f 590/592/597 587/589/597 593/594/597 -f 582/584/586 580/581/586 594/595/586 -f 580/581/598 585/588/598 594/595/598 -f 585/588/588 582/584/588 594/595/588 -f 585/588/598 580/581/598 595/596/598 -f 580/581/585 586/579/585 595/596/585 -f 586/579/595 585/588/595 595/596/595 -f 589/591/599 578/587/599 596/580/599 -f 586/579/600 589/591/600 596/580/600 -f 578/587/588 592/578/588 596/580/588 -o Cup_hull_25 -v -0.023551 0.007522 0.017006 -v -0.025132 -0.000376 0.032177 -v -0.022760 -0.000376 0.032177 -v -0.020655 -0.000376 0.015037 -v -0.016179 0.008313 0.016444 -v -0.023814 0.008313 0.032177 -v -0.025132 -0.000376 0.017848 -v -0.018023 -0.000376 0.015881 -v -0.020917 0.008313 0.031895 -v -0.020655 0.008313 0.015037 -v -0.024604 0.005941 0.018410 -v -0.016179 0.007785 0.015037 -v -0.025132 0.002520 0.032177 -v -0.023814 0.008313 0.017848 -v -0.022497 -0.000376 0.031895 -v -0.024340 0.001730 0.016724 -v -0.025132 0.002520 0.018410 -v -0.024604 0.005941 0.032177 -v -0.018023 -0.000376 0.015037 -v -0.016179 0.008048 0.016444 -v -0.018549 -0.000376 0.018130 -v -0.020917 0.008048 0.031895 -v -0.021180 0.008313 0.032177 -v -0.024340 0.004362 0.017006 -v -0.024340 -0.000376 0.016724 -v -0.024077 0.007785 0.032177 -v -0.016179 0.008313 0.015037 -v -0.024077 0.007785 0.018410 -v -0.024867 0.004362 0.018130 -v -0.024867 0.001730 0.017286 -vt 0.803211 0.000000 -vt 0.819561 0.029561 -vt 0.868807 0.029561 -vt 0.000000 0.264879 -vt 0.000000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.147220 -vt 0.836009 0.000000 -vt 0.950754 0.794048 -vt 0.917956 1.000000 -vt 0.016448 0.470732 -vt 1.000000 0.500000 +f 555/537/546 550/538/546 563/539/546 +f 538/540/547 539/541/547 540/542/547 +f 540/542/547 539/541/547 542/543/547 +f 537/544/548 541/545/548 543/546/548 +f 541/545/549 538/540/549 544/547/549 +f 541/545/548 537/544/548 545/548/548 +f 540/542/547 542/543/547 546/549/547 +f 542/543/547 539/541/547 547/550/547 +f 537/544/548 543/546/548 548/551/548 +f 541/545/548 545/548/548 549/552/548 +f 547/550/547 539/541/547 550/538/547 +f 545/548/550 547/550/550 550/538/550 +f 545/548/548 537/544/548 551/553/548 +f 543/546/551 540/542/551 552/554/551 +f 540/542/547 546/549/547 552/554/547 +f 546/549/552 548/551/552 552/554/552 +f 538/540/547 540/542/547 553/555/547 +f 544/547/549 538/540/549 553/555/549 +f 540/542/553 544/547/553 553/555/553 +f 542/543/554 537/544/554 554/556/554 +f 537/544/548 548/551/548 554/556/548 +f 548/551/555 546/549/555 554/556/555 +f 539/541/556 549/552/556 555/537/556 +f 549/552/548 545/548/548 555/537/548 +f 545/548/546 550/538/546 555/537/546 +f 540/542/551 543/546/551 556/557/551 +f 543/546/557 544/547/557 556/557/557 +f 544/547/558 540/542/558 556/557/558 +f 539/541/559 538/540/559 557/558/559 +f 538/540/549 541/545/549 557/558/549 +f 549/552/560 539/541/560 557/558/560 +f 541/545/561 549/552/561 557/558/561 +f 547/550/550 545/548/550 558/559/550 +f 545/548/548 551/553/548 558/559/548 +f 551/553/562 547/550/562 558/559/562 +f 543/546/563 541/545/563 559/560/563 +f 541/545/564 544/547/564 559/560/564 +f 544/547/565 543/546/565 559/560/565 +f 548/551/548 543/546/548 560/561/548 +f 543/546/551 552/554/551 560/561/551 +f 552/554/552 548/551/552 560/561/552 +f 537/544/566 542/543/566 561/562/566 +f 542/543/547 547/550/547 561/562/547 +f 551/553/567 537/544/567 561/562/567 +f 547/550/562 551/553/562 561/562/562 +f 546/549/547 542/543/547 562/563/547 +f 542/543/568 554/556/568 562/563/568 +f 554/556/555 546/549/555 562/563/555 +f 550/538/547 539/541/547 563/539/547 +f 539/541/569 555/537/569 563/539/569 +o cup_hull_24 +v 0.022150 -0.033881 0.051615 +v 0.029733 -0.013235 0.022542 +v 0.037737 -0.013237 0.026336 +v 0.023836 -0.032616 0.022542 +v 0.038159 -0.013657 0.051615 +v 0.021307 -0.019136 0.023390 +v 0.033946 -0.013237 0.050770 +v 0.032260 -0.024609 0.022542 +v 0.021307 -0.029667 0.051191 +v 0.030154 -0.027139 0.051615 +v 0.021307 -0.032616 0.022542 +v 0.025942 -0.013235 0.025493 +v 0.034788 -0.020819 0.051615 +v 0.037316 -0.015765 0.027181 +v 0.027206 -0.030088 0.022542 +v 0.025099 -0.013657 0.022542 +v 0.032683 -0.013237 0.022542 +v 0.024677 -0.032195 0.051615 +v 0.021307 -0.033881 0.026336 +v 0.034367 -0.013237 0.051615 +v 0.021307 -0.033881 0.051615 +v 0.034788 -0.020819 0.027599 +v 0.032260 -0.024609 0.051615 +v 0.021307 -0.019136 0.022542 +v 0.038159 -0.013237 0.051615 +v 0.027206 -0.030088 0.051615 +v 0.030154 -0.027137 0.022542 +v 0.022150 -0.033881 0.027181 +v 0.038159 -0.013657 0.027599 +v 0.024677 -0.032195 0.022542 +v 0.037316 -0.015765 0.051615 +v 0.021307 -0.030088 0.051615 +v 0.032683 -0.023766 0.022542 +v 0.036473 -0.013237 0.025072 +v 0.021307 -0.019977 0.025917 +vt 0.014585 0.204092 +vt 0.898493 1.000000 +vt 0.883908 0.673453 +vt 1.000000 0.061276 vt 1.000000 1.000000 +vt 1.000000 0.449099 +vt 0.000000 0.979542 vt 0.000000 0.000000 -vt 0.836009 0.147220 -vt 0.885158 0.176586 -vt 0.016448 0.294244 -vt 0.901606 0.088391 -vt 0.000000 0.058927 -vt 1.000000 0.794048 -vt 0.917956 1.000000 -vt 0.819561 0.735219 -vt 0.016448 0.470732 -vt 0.000000 0.441366 -vt 0.885158 0.088391 -vt 0.901606 0.088391 -vt 0.000000 0.117756 -vt 0.803211 0.058927 -vt 1.000000 1.000000 -vt 0.803211 0.117756 -vn -0.9527 0.0929 -0.2895 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 1.0000 -0.0000 +vt 0.000000 0.326547 +vt 1.000000 0.061276 +vt 0.970830 0.714174 +vt 0.029072 0.999902 +vt 0.000000 0.632635 +vt 1.000000 0.183731 +vt 1.000000 0.979542 +vt 1.000000 0.999902 +vt 0.000000 0.081637 +vt 0.869518 0.000000 +vt 0.000000 0.999902 +vt 0.000000 0.000000 +vt 0.826057 0.632635 +vt 0.840446 0.877447 +vt 0.000000 0.449099 +vt 1.000000 0.714174 +vt 0.869518 0.999902 +vt 0.000000 0.999902 +vt 0.000000 0.183731 +vt 1.000000 0.326645 +vt 0.840446 0.000000 +vt 0.826057 0.979542 +vt 1.000000 0.081637 +vt 0.000000 0.877447 +vt 0.000000 0.183731 +vt 1.000000 0.489918 +vt 0.912980 0.999902 +vn -0.7983 0.5624 0.2156 vn -0.0000 0.0000 -1.0000 +vn -0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.5764 0.4982 -0.6477 -vn -0.4161 0.0000 -0.9093 -vn 0.9754 -0.2204 0.0000 -vn 0.9561 0.0000 0.2932 -vn 0.9755 -0.2162 0.0405 +vn -0.7659 0.5954 0.2426 +vn -0.0902 0.9892 -0.1158 +vn -0.8026 0.5782 0.1465 +vn 0.0000 -0.9486 -0.3164 +vn -0.7334 0.5735 0.3650 +vn -0.0004 1.0000 0.0002 +vn 0.0000 -1.0000 0.0000 +vn 0.8320 -0.5548 0.0000 +vn 0.8860 -0.4519 -0.1041 +vn 0.8943 -0.4474 0.0000 +vn 0.7685 -0.6398 0.0000 +vn -0.8222 0.5691 0.0000 +vn 0.0003 1.0000 -0.0000 +vn 0.0000 1.0000 0.0001 +vn 0.7072 -0.7070 0.0000 +vn 0.6403 -0.7681 0.0000 +vn 0.7683 -0.6401 -0.0000 +vn 0.7074 -0.7068 -0.0000 +vn 0.5549 -0.8319 0.0000 +vn 0.1929 -0.9622 -0.1923 +vn 0.8804 -0.2755 -0.3859 +vn 0.9285 -0.3713 0.0000 +vn 0.7234 0.6904 -0.0121 vn 1.0000 0.0000 0.0000 -vn 0.9397 -0.2105 0.2695 -vn 0.9492 -0.2226 0.2223 -vn 0.7245 -0.1359 0.6757 -vn 0.9410 -0.1765 0.2886 -vn 0.6667 -0.1212 0.7354 -vn 0.7313 0.0000 0.6820 -vn -0.5831 0.1457 -0.7992 -vn -0.8571 0.2142 -0.4686 -vn -0.5422 0.0895 -0.8355 -vn -0.8946 0.4468 0.0000 -vn -0.9615 0.2747 0.0000 -vn -0.9441 0.2698 -0.1895 -vn -0.9058 0.2155 -0.3647 -vn -0.9898 0.1423 0.0000 -vn -0.9864 0.1642 0.0000 -vn -0.9883 0.1524 0.0014 -vn -0.8860 0.2066 -0.4151 -vn -0.8973 0.1348 -0.4203 -vn -0.9635 0.0510 -0.2626 -vn -0.7278 0.0730 -0.6819 -vn -0.8167 -0.0508 -0.5748 -vn -0.7298 0.0000 -0.6837 +vn 0.4455 -0.8916 -0.0813 +vn -0.6756 0.5236 0.5191 +vn 0.8755 -0.2778 -0.3953 +vn 0.8876 -0.4448 -0.1195 +vn 0.5551 0.0000 -0.8318 +vn 0.0005 1.0000 -0.0005 +vn 0.0007 1.0000 -0.0010 +vn 0.7046 -0.0844 -0.7046 +vn -0.8038 0.5645 0.1878 usemtl None s off -f 613/597/601 625/598/601 626/599/601 -f 599/600/602 598/601/602 600/602/602 -f 598/601/603 599/600/603 602/603/603 -f 600/602/602 598/601/602 603/604/602 -f 599/600/602 600/602/602 604/605/602 -f 601/606/604 602/603/604 605/607/604 -f 602/603/604 601/606/604 606/608/604 -f 600/602/605 606/608/605 608/609/605 -f 598/601/603 602/603/603 609/610/603 -f 603/604/606 598/601/606 609/610/606 -f 602/603/604 606/608/604 610/611/604 -f 606/608/607 597/612/607 610/611/607 -f 599/600/602 604/605/602 611/613/602 -f 606/608/608 600/602/608 612/614/608 -f 603/604/606 609/610/606 613/597/606 -f 609/610/603 602/603/603 614/615/603 -f 604/605/602 600/602/602 615/616/602 -f 600/602/605 608/609/605 615/616/605 -f 608/609/609 604/605/609 615/616/609 -f 601/606/610 605/607/610 616/617/610 -f 604/605/611 608/609/611 616/617/611 -f 608/609/612 601/606/612 616/617/612 -f 616/617/613 611/613/613 617/618/613 -f 611/613/602 604/605/602 617/618/602 -f 604/605/614 616/617/614 617/618/614 -f 599/600/615 611/613/615 618/619/615 -f 616/617/610 605/607/610 618/619/610 -f 611/613/616 616/617/616 618/619/616 -f 602/603/603 599/600/603 619/620/603 -f 605/607/604 602/603/604 619/620/604 -f 599/600/617 618/619/617 619/620/617 -f 618/619/618 605/607/618 619/620/618 -f 597/612/619 606/608/619 620/621/619 -f 610/611/620 597/612/620 620/621/620 -f 606/608/621 612/614/621 620/621/621 -f 600/602/602 603/604/602 621/622/602 -f 612/614/608 600/602/608 621/622/608 -f 602/603/622 610/611/622 622/623/622 -f 614/615/603 602/603/603 622/623/603 -f 607/624/623 614/615/623 622/623/623 -f 606/608/604 601/606/604 623/625/604 -f 601/606/612 608/609/612 623/625/612 -f 608/609/605 606/608/605 623/625/605 -f 610/611/624 607/624/624 624/626/624 -f 622/623/622 610/611/622 624/626/622 -f 607/624/623 622/623/623 624/626/623 -f 607/624/625 610/611/625 625/598/625 -f 613/597/626 609/610/626 625/598/626 -f 614/615/627 607/624/627 625/598/627 -f 609/610/628 614/615/628 625/598/628 -f 610/611/629 620/621/629 625/598/629 -f 625/598/630 620/621/630 626/599/630 -f 603/604/631 613/597/631 626/599/631 -f 620/621/632 612/614/632 626/599/632 -f 621/622/633 603/604/633 626/599/633 -f 612/614/634 621/622/634 626/599/634 -o Cup_hull_26 -v -0.020654 0.014632 0.050164 -v -0.014335 0.020690 0.033584 -v -0.014335 0.017793 0.033584 -v -0.023815 0.008313 0.033584 -v -0.022761 0.008313 0.050164 -v -0.014335 0.019373 0.050164 -v -0.021180 0.008578 0.034149 -v -0.020127 0.015422 0.033584 -v -0.015388 0.020163 0.050164 -v -0.023288 0.009895 0.050164 -v -0.021708 0.013055 0.033584 -v -0.016968 0.018846 0.033584 -v -0.018549 0.017265 0.050164 -v -0.023815 0.008313 0.050164 -v -0.021444 0.008313 0.033584 -v -0.014335 0.020690 0.050164 -v -0.021708 0.013055 0.050164 -v -0.023288 0.009895 0.033584 -v -0.022497 0.008578 0.050164 -v -0.014598 0.020690 0.033584 -v -0.014335 0.017793 0.034430 -v -0.021444 0.008313 0.035272 -v -0.018812 0.017002 0.033584 -v -0.016968 0.018846 0.050164 -v -0.023815 0.008578 0.050164 -v -0.015388 0.020163 0.033584 -v -0.023815 0.008578 0.033584 -v -0.019865 0.015685 0.050164 -v -0.014598 0.020690 0.050164 -vt 0.000000 1.000000 +f 572/564/570 575/565/570 598/566/570 +f 567/567/571 565/568/571 571/569/571 +f 568/570/572 564/571/572 573/572/572 +f 565/568/571 567/567/571 574/573/571 +f 572/564/573 569/574/573 574/573/573 +f 572/564/574 570/575/574 575/565/574 +f 568/570/572 573/572/572 576/576/572 +f 567/567/571 571/569/571 578/577/571 +f 565/568/571 574/573/571 579/578/571 +f 575/565/575 565/568/575 579/578/575 +f 569/574/576 575/565/576 579/578/576 +f 571/569/571 565/568/571 580/579/571 +f 573/572/572 564/571/572 581/580/572 +f 574/573/577 567/567/577 582/581/577 +f 572/564/573 574/573/573 582/581/573 +f 564/571/572 568/570/572 583/582/572 +f 570/575/578 572/564/578 583/582/578 +f 575/565/579 570/575/579 583/582/579 +f 582/581/580 564/571/580 584/583/580 +f 572/564/573 582/581/573 584/583/573 +f 564/571/572 583/582/572 584/583/572 +f 576/576/581 571/569/581 585/584/581 +f 571/569/582 577/585/582 585/584/582 +f 577/585/583 576/576/583 585/584/583 +f 573/572/584 571/569/584 586/586/584 +f 571/569/581 576/576/581 586/586/581 +f 576/576/572 573/572/572 586/586/572 +f 574/573/573 569/574/573 587/587/573 +f 579/578/571 574/573/571 587/587/571 +f 569/574/585 579/578/585 587/587/585 +f 566/588/586 565/568/586 588/589/586 +f 565/568/587 575/565/587 588/589/587 +f 583/582/572 568/570/572 588/589/572 +f 575/565/587 583/582/587 588/589/587 +f 578/577/588 573/572/588 589/590/588 +f 573/572/572 581/580/572 589/590/572 +f 581/580/589 578/577/589 589/590/589 +f 571/569/590 573/572/590 590/591/590 +f 578/577/571 571/569/571 590/591/571 +f 573/572/591 578/577/591 590/591/591 +f 581/580/592 564/571/592 591/592/592 +f 564/571/580 582/581/580 591/592/580 +f 582/581/593 567/567/593 591/592/593 +f 577/585/594 566/588/594 592/593/594 +f 568/570/595 577/585/595 592/593/595 +f 566/588/596 588/589/596 592/593/596 +f 588/589/597 568/570/597 592/593/597 +f 567/567/571 578/577/571 593/594/571 +f 578/577/589 581/580/589 593/594/589 +f 581/580/592 591/592/592 593/594/592 +f 591/592/598 567/567/598 593/594/598 +f 568/570/572 576/576/572 594/595/572 +f 577/585/595 568/570/595 594/595/595 +f 576/576/583 577/585/583 594/595/583 +f 583/582/599 572/564/599 595/596/599 +f 572/564/573 584/583/573 595/596/573 +f 584/583/572 583/582/572 595/596/572 +f 566/588/600 577/585/600 596/597/600 +f 577/585/601 571/569/601 596/597/601 +f 571/569/571 580/579/571 596/597/571 +f 596/597/602 580/579/602 597/598/602 +f 565/568/603 566/588/603 597/598/603 +f 580/579/604 565/568/604 597/598/604 +f 566/588/605 596/597/605 597/598/605 +f 569/574/573 572/564/573 598/566/573 +f 575/565/606 569/574/606 598/566/606 +o cup_hull_25 +v 0.038581 -0.011969 0.075211 +v 0.040266 0.000668 0.050772 +v 0.040266 -0.003545 0.050772 +v 0.034368 -0.012390 0.050772 +v 0.038581 0.000668 0.075211 +v 0.036897 0.000668 0.050772 +v 0.038159 -0.013233 0.050772 +v 0.036475 -0.013233 0.075211 +v 0.040266 0.000668 0.075211 +v 0.039845 -0.006914 0.075211 +v 0.039423 -0.009020 0.050772 +v 0.034368 -0.013233 0.050772 +v 0.038159 -0.013233 0.075211 +v 0.036475 -0.012390 0.075211 +v 0.040266 -0.003545 0.075211 +v 0.036897 0.000668 0.052459 +v 0.038581 -0.012390 0.070996 +v 0.034368 -0.012390 0.051196 +v 0.038581 -0.012390 0.050772 +v 0.039845 -0.006914 0.050772 +v 0.039423 -0.009020 0.075211 +vt 0.172475 0.060689 +vt 1.000000 0.303054 +vt 0.000000 0.303054 vt 1.000000 1.000000 +vt 1.000000 0.696946 +vt 1.000000 0.060689 vt 0.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.765955 vt 1.000000 0.000000 -vt 0.000000 0.893598 -vt 0.000000 0.510572 -vt 0.000000 0.000000 -vt 1.000000 0.574393 -vt 0.000000 0.957420 -vt 0.000000 0.127839 -vt 1.000000 0.383124 -vt 1.000000 0.851018 -vt 0.000000 0.723277 +vt 0.000000 0.090936 vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.454581 vt 1.000000 0.000000 -vt 0.965936 0.021437 -vt 0.000000 0.383124 -vt 1.000000 0.127839 -vt 0.000000 0.021437 -vt 0.949002 0.765955 -vt 0.898199 0.000000 -vt 1.000000 0.702036 -vt 0.000000 0.851018 -vt 0.000000 0.021437 -vt 1.000000 0.957420 -vt 1.000000 0.021437 -vt 0.000000 0.595634 +vt 0.000000 0.000000 +vt 0.000000 0.060689 +vt 0.000000 0.696946 +vt 0.930991 1.000000 +vt 0.982674 0.060689 +vt 1.000000 0.060689 +vt 1.000000 0.454581 +vn 0.9701 -0.2425 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 1.0000 0.0000 -vn -0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn 1.0000 0.0000 0.0000 vn 0.0000 -1.0000 0.0000 -vn 0.7967 -0.5975 -0.0911 -vn -0.8316 0.5553 0.0000 -vn -0.8317 0.5552 0.0000 -vn -0.8944 0.4473 0.0000 -vn 0.8027 -0.5963 0.0000 -vn 0.8012 -0.5966 0.0471 -vn 0.7095 -0.7047 0.0000 -vn 0.7081 -0.7034 0.0626 -vn 0.7958 -0.6018 0.0670 -vn 0.8011 -0.5955 0.0598 -vn -0.7073 0.7070 0.0000 -vn -0.6402 0.7682 0.0000 -vn -0.7071 0.7071 0.0000 +vn 0.9923 -0.1241 0.0000 +vn -0.9818 0.1901 0.0000 +vn 0.9482 -0.3161 0.0315 +vn 0.8946 -0.4469 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.9284 0.3716 0.0000 -vn -0.5551 0.8318 0.0000 -vn -0.8000 0.6001 0.0032 -vn 0.0001 0.0000 1.0000 -vn -0.7686 0.6397 0.0020 -vn -0.7684 0.6400 0.0021 +vn -0.9954 -0.0431 0.0858 +vn -0.9836 0.1586 0.0863 +vn -0.9962 0.0000 0.0874 +vn -0.9805 0.1829 0.0726 +vn 0.0001 0.0000 -1.0000 +vn 0.9806 -0.1962 0.0000 +vn -0.0001 0.0000 1.0000 +vn 0.9612 -0.2746 0.0274 usemtl None s off -f 642/627/635 646/628/635 655/629/635 -f 628/630/636 629/631/636 630/632/636 -f 629/631/637 628/630/637 632/633/637 -f 627/634/638 631/635/638 632/633/638 -f 628/630/636 630/632/636 634/636/636 -f 627/634/638 632/633/638 635/637/638 -f 631/635/638 627/634/638 636/638/638 -f 634/636/636 630/632/636 637/639/636 -f 628/630/636 634/636/636 638/640/636 -f 627/634/638 635/637/638 639/641/638 -f 630/632/639 631/635/639 640/642/639 -f 631/635/638 636/638/638 640/642/638 -f 630/632/636 629/631/636 641/643/636 -f 631/635/639 630/632/639 641/643/639 -f 629/631/640 633/644/640 641/643/640 -f 632/633/637 628/630/637 642/627/637 -f 635/637/638 632/633/638 642/627/638 -f 627/634/641 634/636/641 643/645/641 -f 636/638/638 627/634/638 643/645/638 -f 634/636/642 637/639/642 643/645/642 -f 637/639/643 636/638/643 643/645/643 -f 637/639/636 630/632/636 644/646/636 -f 636/638/643 637/639/643 644/646/643 -f 632/633/638 631/635/638 645/647/638 -f 628/630/636 638/640/636 646/628/636 -f 642/627/635 628/630/635 646/628/635 -f 629/631/637 632/633/637 647/648/637 -f 633/644/644 629/631/644 647/648/644 -f 633/644/645 647/648/645 648/649/645 -f 631/635/639 641/643/639 648/649/639 -f 641/643/646 633/644/646 648/649/646 -f 645/647/647 631/635/647 648/649/647 -f 632/633/648 645/647/648 648/649/648 -f 647/648/649 632/633/649 648/649/649 -f 638/640/636 634/636/636 649/650/636 -f 649/650/650 639/641/650 650/651/650 -f 635/637/651 638/640/651 650/651/651 -f 639/641/638 635/637/638 650/651/638 -f 638/640/652 649/650/652 650/651/652 -f 630/632/653 640/642/653 651/652/653 -f 640/642/638 636/638/638 651/652/638 -f 636/638/654 644/646/654 651/652/654 -f 638/640/651 635/637/651 652/653/651 -f 646/628/636 638/640/636 652/653/636 -f 635/637/655 646/628/655 652/653/655 -f 644/646/636 630/632/636 653/654/636 -f 630/632/653 651/652/653 653/654/653 -f 651/652/654 644/646/654 653/654/654 -f 634/636/656 627/634/656 654/655/656 -f 627/634/657 639/641/657 654/655/657 -f 649/650/658 634/636/658 654/655/658 -f 639/641/659 649/650/659 654/655/659 -f 635/637/638 642/627/638 655/629/638 -f 646/628/655 635/637/655 655/629/655 -o Cup_hull_27 -v -0.023550 0.008578 0.017568 -v -0.014335 0.020690 0.017848 -v -0.014335 0.020426 0.015039 -v -0.015915 0.008313 0.015882 -v -0.021180 0.008313 0.033582 -v -0.014335 0.020690 0.033582 -v -0.021708 0.013055 0.033582 -v -0.020127 0.015422 0.015039 -v -0.014335 0.017529 0.033301 -v -0.014335 0.010684 0.015039 -v -0.023815 0.008313 0.033582 -v -0.016968 0.018845 0.033582 -v -0.020654 0.008313 0.015039 -v -0.023288 0.009895 0.018411 -v -0.017233 0.018582 0.015039 -v -0.018812 0.017002 0.033582 -v -0.015388 0.020163 0.016724 -v -0.021708 0.013055 0.018411 -v -0.023815 0.008313 0.018411 -v -0.023288 0.009895 0.033582 -v -0.016179 0.008313 0.017005 -v -0.020127 0.015422 0.033582 -v -0.014598 0.020690 0.033582 -v -0.015915 0.008313 0.015039 -v -0.014335 0.010947 0.016443 -v -0.018812 0.017002 0.015039 -v -0.014335 0.017793 0.033582 -v -0.020391 0.014895 0.015039 -v -0.023815 0.008578 0.018411 -v -0.015388 0.020163 0.033582 -v -0.022761 0.008313 0.016724 -v -0.014862 0.020426 0.015039 -v -0.014598 0.020690 0.017848 -v -0.023815 0.008578 0.033582 -vt 0.000000 0.127839 -vt 0.818191 0.021437 -vt 0.000000 0.021437 -vt 1.000000 0.978661 -vt 0.848541 1.000000 +f 615/599/607 609/600/607 619/601/607 +f 600/602/608 601/603/608 602/604/608 +f 603/605/609 600/602/609 604/606/609 +f 600/602/608 602/604/608 604/606/608 +f 602/604/608 601/603/608 605/607/608 +f 599/608/610 603/605/610 606/609/610 +f 601/603/611 600/602/611 607/610/611 +f 603/605/610 599/608/610 607/610/610 +f 600/602/609 603/605/609 607/610/609 +f 607/610/610 599/608/610 608/611/610 +f 605/607/608 601/603/608 609/600/608 +f 602/604/608 605/607/608 610/612/608 +f 605/607/612 606/609/612 610/612/612 +f 606/609/612 605/607/612 611/613/612 +f 599/608/610 606/609/610 611/613/610 +f 606/609/610 603/605/610 612/614/610 +f 601/603/611 607/610/611 613/615/611 +f 608/611/613 601/603/613 613/615/613 +f 607/610/610 608/611/610 613/615/610 +f 603/605/609 604/606/609 614/616/609 +f 604/606/614 602/604/614 614/616/614 +f 599/608/615 611/613/615 615/599/615 +f 611/613/616 605/607/616 615/599/616 +f 602/604/617 610/612/617 616/617/617 +f 610/612/618 606/609/618 616/617/618 +f 612/614/619 603/605/619 616/617/619 +f 606/609/620 612/614/620 616/617/620 +f 614/616/614 602/604/614 616/617/614 +f 603/605/621 614/616/621 616/617/621 +f 605/607/608 609/600/608 617/618/608 +f 615/599/616 605/607/616 617/618/616 +f 609/600/607 615/599/607 617/618/607 +f 601/603/613 608/611/613 618/619/613 +f 609/600/622 601/603/622 618/619/622 +f 608/611/623 609/600/623 618/619/623 +f 608/611/624 599/608/624 619/601/624 +f 609/600/623 608/611/623 619/601/623 +f 599/608/625 615/599/625 619/601/625 +o cup_hull_26 +v 0.039843 -0.006913 0.027179 +v 0.025941 -0.013233 0.024651 +v 0.025941 -0.012812 0.024651 +v 0.034366 -0.013233 0.050772 +v 0.036472 0.000668 0.050350 +v 0.028891 0.000668 0.022542 +v 0.037316 -0.013233 0.025493 +v 0.039843 0.000668 0.025913 +v 0.039843 -0.006913 0.050772 +v 0.040267 0.000668 0.050772 +v 0.038159 -0.013233 0.050772 +v 0.032683 -0.013233 0.022542 +v 0.025941 -0.013233 0.022542 +v 0.032683 0.000668 0.022542 +v 0.029734 0.000668 0.027179 +v 0.038581 -0.012390 0.032236 +v 0.040267 -0.003545 0.027599 +v 0.039002 -0.001860 0.025071 +v 0.033945 -0.012812 0.049930 +v 0.026363 -0.012812 0.026339 +v 0.038159 -0.013233 0.026759 +v 0.040267 0.000668 0.026759 +v 0.040267 -0.003545 0.050772 +v 0.039002 -0.006913 0.025493 +v 0.039424 -0.009020 0.050772 +v 0.036896 0.000668 0.050772 +v 0.028891 0.000668 0.023811 +v 0.039424 -0.009020 0.027179 +v 0.038581 -0.012390 0.050772 +v 0.038159 -0.008598 0.025071 +v 0.039002 0.000668 0.025071 +vt 0.910435 0.911707 +vt 1.000000 0.470634 +vt 0.910435 0.911707 +vt 0.000000 0.588097 +vt 0.925313 0.000000 +vt 0.895458 0.794049 +vt 1.000000 0.205951 +vt 0.014977 0.735121 +vt 0.880580 0.970439 vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 0.000000 0.383125 -vt 0.015175 0.744616 -vt 1.000000 0.574393 -vt 1.000000 0.191562 -vt 0.954572 0.000000 -vt 0.000000 0.000000 -vt 0.000000 0.850920 +vt 0.000000 0.970439 +vt 0.000000 0.852878 +vt 1.000000 0.470634 +vt 0.925313 0.000000 vt 1.000000 0.000000 -vt 1.000000 0.829679 -vt 0.000000 0.702036 -vt 0.909144 0.957420 -vt 0.818191 0.383125 -vt 0.818191 0.127839 -vt 0.818191 0.000000 -vt 0.893969 0.000000 -vt 0.000000 0.574393 +vt 0.835748 0.264781 +vt 0.835748 0.970439 +vt 0.820869 1.000000 +vt 0.029855 0.558731 +vt 0.865505 0.029464 +vt 0.850626 0.852878 +vt 0.656617 0.882341 +vt 0.850626 1.000000 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 0.924320 0.212803 -vt 1.000000 0.702036 -vt 0.000000 0.765955 -vt 1.000000 0.531813 -vt 0.863619 0.021437 -vt 0.000000 0.957420 -vt 0.909144 0.000000 -vt 1.000000 0.978661 -vt 0.848541 1.000000 -vn -0.9284 0.3716 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.7069 0.7073 0.0001 -vn -0.6500 0.7600 -0.0015 -vn -0.8317 0.5552 0.0000 -vn -0.8895 0.4449 -0.1046 -vn -0.8944 0.4473 0.0000 -vn 0.7835 -0.5747 0.2364 -vn -0.7686 0.6397 0.0000 +vt 0.895458 0.911707 +vt 0.000000 0.941171 +vt 0.000000 0.764683 +vt 0.955070 0.205951 +vt 0.835748 0.941171 +vt 0.000000 0.882341 +vt 0.910435 0.852878 +vn 0.3715 0.0000 -0.9284 +vn 0.0000 -1.0000 -0.0000 vn 0.0000 1.0000 0.0000 -vn 0.8321 -0.5546 0.0000 -vn 0.8439 -0.5274 0.0988 -vn 0.8227 -0.5347 0.1929 -vn 0.8217 -0.5309 0.2073 -vn -0.7072 0.7070 0.0000 -vn 0.7105 -0.5131 0.4816 -vn -0.8895 0.4448 -0.1047 -vn -0.9014 0.3608 -0.2395 -vn -0.9541 0.0000 -0.2995 +vn 0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.8985 0.3365 -0.2821 -vn -0.6405 0.7679 0.0000 -vn -0.5551 0.8318 0.0000 -vn -0.6501 -0.6421 -0.4063 -vn -0.7153 0.0799 -0.6942 -vn -0.6244 0.0250 -0.7807 -vn 0.0000 0.9956 -0.0936 -vn -0.6125 0.7875 -0.0684 -vn -0.5241 0.8511 -0.0309 +vn -0.9774 0.2074 -0.0415 +vn 0.0000 0.0000 -1.0000 +vn 0.9922 -0.1247 0.0000 +vn -0.9022 -0.3183 0.2910 +vn -0.8545 0.1446 0.4989 +vn -0.9387 0.1666 0.3017 +vn -0.9701 0.0000 0.2425 +vn -0.9373 0.2174 0.2726 +vn -0.9186 -0.2626 0.2953 +vn 0.8943 -0.4474 0.0000 +vn 0.9299 -0.0719 -0.3608 +vn 1.0000 0.0000 0.0000 +vn 0.7806 -0.0521 -0.6229 +vn 0.8126 -0.2167 -0.5411 +vn 0.8922 -0.0745 -0.4454 +vn 0.8917 -0.0742 -0.4466 +vn 0.9808 -0.1952 0.0000 +vn -0.7008 0.1275 0.7019 +vn -0.9769 0.2138 0.0000 +vn -0.9460 0.2218 0.2365 +vn -0.9459 0.2218 0.2367 +vn 0.9582 -0.2847 -0.0300 +vn 0.8809 -0.1753 -0.4397 +vn 0.8546 -0.2092 -0.4754 +vn 0.9701 -0.2426 0.0000 +vn 0.5292 -0.1720 -0.8309 +vn 0.4581 -0.0573 -0.8871 +vn 0.7185 -0.1916 -0.6686 +vn 0.5547 -0.0694 -0.8292 +vn 0.7077 0.0000 -0.7065 usemtl None s off -f 675/656/660 684/657/660 689/658/660 -f 658/659/661 657/660/661 661/661/661 -f 660/662/662 661/661/662 662/663/662 -f 658/659/661 661/661/661 664/664/661 -f 663/665/663 658/659/663 665/666/663 -f 658/659/661 664/664/661 665/666/661 -f 659/667/664 660/662/664 666/668/664 -f 660/662/662 662/663/662 666/668/662 -f 662/663/662 661/661/662 667/669/662 -f 663/665/663 665/666/663 668/670/663 -f 659/667/664 666/668/664 668/670/664 -f 658/659/663 663/665/663 670/671/663 -f 667/669/665 670/671/665 671/672/665 -f 662/663/662 667/669/662 671/672/662 -f 670/671/666 667/669/666 672/673/666 -f 662/663/667 663/665/667 673/674/667 -f 663/665/668 669/675/668 673/674/668 -f 669/675/669 662/663/669 673/674/669 -f 668/670/664 666/668/664 674/676/664 -f 666/668/662 662/663/662 675/656/662 -f 662/663/669 669/675/669 675/656/669 -f 660/662/664 659/667/664 676/677/664 -f 664/664/670 660/662/670 676/677/670 -f 663/665/667 662/663/667 677/678/667 -f 662/663/662 671/672/662 677/678/662 -f 671/672/671 663/665/671 677/678/671 -f 661/661/672 657/660/672 678/679/672 -f 667/669/662 661/661/662 678/679/662 -f 665/666/673 659/667/673 679/680/673 -f 668/670/663 665/666/663 679/680/663 -f 659/667/664 668/670/664 679/680/664 -f 659/667/674 665/666/674 680/681/674 -f 665/666/661 664/664/661 680/681/661 -f 676/677/675 659/667/675 680/681/675 -f 664/664/676 676/677/676 680/681/676 -f 670/671/663 663/665/663 681/682/663 -f 671/672/677 670/671/677 681/682/677 -f 663/665/671 671/672/671 681/682/671 -f 661/661/662 660/662/662 682/683/662 -f 660/662/678 664/664/678 682/683/678 -f 664/664/661 661/661/661 682/683/661 -f 663/665/663 668/670/663 683/684/663 -f 669/675/679 663/665/679 683/684/679 -f 669/675/680 683/684/680 684/657/680 -f 656/685/681 674/676/681 684/657/681 -f 674/676/682 666/668/682 684/657/682 -f 675/656/660 669/675/660 684/657/660 -f 683/684/683 656/685/683 684/657/683 -f 672/673/684 667/669/684 685/686/684 -f 667/669/662 678/679/662 685/686/662 -f 678/679/685 672/673/685 685/686/685 -f 674/676/686 656/685/686 686/687/686 -f 668/670/664 674/676/664 686/687/664 -f 656/685/687 683/684/687 686/687/687 -f 683/684/688 668/670/688 686/687/688 -f 657/660/689 658/659/689 687/688/689 -f 658/659/663 670/671/663 687/688/663 -f 670/671/690 672/673/690 687/688/690 -f 678/679/672 657/660/672 688/689/672 -f 672/673/685 678/679/685 688/689/685 -f 657/660/689 687/688/689 688/689/689 -f 687/688/691 672/673/691 688/689/691 -f 666/668/662 675/656/662 689/658/662 -f 684/657/682 666/668/682 689/658/682 -o Cup_hull_28 -v 0.018582 -0.017233 0.015041 -v 0.008313 -0.023815 0.050164 -v 0.008579 -0.023815 0.050164 -v 0.019372 -0.014335 0.050164 -v 0.008313 -0.015916 0.015041 -v 0.008313 -0.023815 0.018414 -v 0.020425 -0.014335 0.015041 -v 0.015421 -0.020128 0.050164 -v 0.010685 -0.014335 0.015041 -v 0.015421 -0.020128 0.015041 -v 0.020689 -0.014598 0.050164 -v 0.008579 -0.022497 0.050164 -v 0.013054 -0.021707 0.018414 -v 0.008313 -0.020653 0.015041 -v 0.018055 -0.017759 0.050164 -v 0.008313 -0.015916 0.015883 -v 0.013056 -0.021707 0.050164 -v 0.009895 -0.023288 0.018132 -v 0.020688 -0.014599 0.017850 -v 0.017002 -0.018812 0.015041 -v 0.009105 -0.023023 0.017008 -v 0.020689 -0.014335 0.050164 -v 0.019898 -0.015651 0.050164 -v 0.009896 -0.023288 0.050164 -v 0.017001 -0.018812 0.050164 -v 0.008313 -0.022760 0.050164 -v 0.019899 -0.015652 0.015041 -v 0.018581 -0.017233 0.050164 -v 0.010948 -0.014335 0.016444 -v 0.008578 -0.023815 0.018414 -v 0.014896 -0.020391 0.015041 -v 0.020688 -0.014335 0.017850 -v 0.008578 -0.023550 0.017568 -vt 1.000000 0.531911 -vt 0.911992 0.127839 -vt 0.928047 0.021437 -vt 0.000000 0.000000 -vt 0.000000 0.021535 -vt 0.000000 0.893598 +f 637/620/626 633/621/626 650/622/626 +f 623/623/627 621/624/627 626/625/627 +f 625/626/628 624/627/628 627/628/628 +f 627/628/628 624/627/628 629/629/628 +f 623/623/629 628/630/629 629/629/629 +f 623/623/627 626/625/627 630/631/627 +f 628/630/629 623/623/629 630/631/629 +f 626/625/627 621/624/627 631/632/627 +f 621/624/630 622/633/630 632/634/630 +f 622/633/631 625/626/631 632/634/631 +f 631/632/627 621/624/627 632/634/627 +f 625/626/632 631/632/632 632/634/632 +f 625/626/628 627/628/628 633/621/628 +f 631/632/632 625/626/632 633/621/632 +f 624/627/628 625/626/628 634/635/628 +f 628/630/633 620/636/633 636/637/633 +f 631/632/626 633/621/626 637/620/626 +f 621/624/634 623/623/634 638/638/634 +f 623/623/635 624/627/635 638/638/635 +f 638/638/636 624/627/636 639/639/636 +f 622/633/637 621/624/637 639/639/637 +f 624/627/638 634/635/638 639/639/638 +f 621/624/639 638/638/639 639/639/639 +f 630/631/627 626/625/627 640/640/627 +f 635/641/640 630/631/640 640/640/640 +f 627/628/628 629/629/628 641/642/628 +f 636/637/641 620/636/641 641/642/641 +f 629/629/642 636/637/642 641/642/642 +f 629/629/629 628/630/629 642/643/629 +f 628/630/633 636/637/633 642/643/633 +f 636/637/642 629/629/642 642/643/642 +f 637/620/643 627/628/643 643/644/643 +f 640/640/644 626/625/644 643/644/644 +f 641/642/645 620/636/645 643/644/645 +f 627/628/646 641/642/646 643/644/646 +f 620/636/647 628/630/647 644/645/647 +f 628/630/629 630/631/629 644/645/629 +f 624/627/648 623/623/648 645/646/648 +f 623/623/629 629/629/629 645/646/629 +f 629/629/628 624/627/628 645/646/628 +f 625/626/649 622/633/649 646/647/649 +f 634/635/628 625/626/628 646/647/628 +f 622/633/650 639/639/650 646/647/650 +f 639/639/651 634/635/651 646/647/651 +f 635/641/652 640/640/652 647/648/652 +f 643/644/653 620/636/653 647/648/653 +f 640/640/654 643/644/654 647/648/654 +f 620/636/647 644/645/647 647/648/647 +f 644/645/655 635/641/655 647/648/655 +f 630/631/640 635/641/640 648/649/640 +f 644/645/629 630/631/629 648/649/629 +f 635/641/655 644/645/655 648/649/655 +f 626/625/656 631/632/656 649/650/656 +f 631/632/657 637/620/657 649/650/657 +f 643/644/658 626/625/658 649/650/658 +f 637/620/659 643/644/659 649/650/659 +f 633/621/628 627/628/628 650/622/628 +f 627/628/660 637/620/660 650/622/660 +o cup_hull_27 +v 0.040266 0.003620 0.075211 +v 0.037317 0.015417 0.048666 +v 0.037738 0.014574 0.048666 +v 0.036475 0.000670 0.048666 +v 0.035633 0.015417 0.075211 +v 0.033105 0.015417 0.048666 +v 0.040266 0.000670 0.048666 +v 0.038581 0.000670 0.075211 +v 0.037738 0.014574 0.075211 +v 0.039423 0.009094 0.048666 +v 0.033105 0.014995 0.050355 +v 0.040266 0.000670 0.075211 +v 0.039002 0.010782 0.075211 +v 0.040266 0.003620 0.048666 +v 0.035633 0.014574 0.075211 +v 0.036475 0.000670 0.050355 +v 0.039845 0.006992 0.075211 +v 0.037317 0.015417 0.075211 +v 0.039002 0.010782 0.048666 +v 0.039845 0.006992 0.048666 +vt 0.000000 0.428739 +vt 1.000000 0.200078 +vt 1.000000 0.428739 +vt 1.000000 1.000000 +vt 1.000000 0.942835 vt 1.000000 0.000000 -vt 0.903965 0.000000 -vt 1.000000 0.829777 -vt 1.000000 0.978661 -vt 0.000000 0.574393 -vt 1.000000 0.191660 -vt 1.000000 0.574393 vt 0.000000 1.000000 -vt 0.000000 0.021535 +vt 1.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 0.787197 -vt 0.976016 0.000000 -vt 0.000000 0.383222 -vt 0.903965 0.383124 -vt 1.000000 0.702134 -vt 0.000000 1.000000 -vt 0.920020 0.999902 -vt 0.000000 0.936081 -vt 0.000000 0.127937 -vt 0.000000 0.702036 vt 0.000000 0.000000 -vt 1.000000 0.936179 -vt 0.000000 0.829679 -vt 0.960059 0.212901 -vt 0.903965 0.021437 -vt 0.944004 0.064017 -vt 0.920020 0.999902 -vn 0.3165 -0.8917 -0.3237 -vn 0.0000 0.0000 1.0000 -vn -1.0000 -0.0000 0.0000 -vn 0.0000 -1.0000 0.0000 +vt 0.000000 0.200078 +vt 0.000000 0.942835 +vt 1.000000 0.571261 +vt 0.936374 0.971417 +vt 0.000000 0.000000 +vt 0.000000 0.685689 +vt 0.000000 0.942835 +vt 0.936374 0.000000 +vt 0.000000 1.000000 +vt 1.000000 0.685689 +vn 0.9923 0.1240 0.0000 vn 0.0000 0.0000 -1.0000 vn 0.0000 1.0000 0.0000 -vn -0.5547 0.8321 0.0000 -vn -0.5958 0.7878 0.1559 -vn 0.5550 -0.8318 0.0000 -vn 0.5548 -0.8320 -0.0000 -vn 0.4476 -0.8942 -0.0000 -vn 0.4524 -0.8865 -0.0974 -vn 0.6397 -0.7686 0.0000 -vn 0.7070 -0.7072 0.0000 -vn 1.0000 0.0000 -0.0000 -vn 0.3716 -0.9284 -0.0000 -vn 0.6400 -0.7683 0.0000 -vn 0.7069 -0.7073 0.0000 -vn -0.6949 0.7052 0.1408 -vn 0.9220 -0.3679 -0.1209 -vn 0.8005 -0.5993 -0.0000 -vn 0.7996 -0.6005 0.0000 -vn 0.7684 -0.6399 0.0000 -vn 0.7074 -0.7068 0.0000 -vn 0.7683 -0.6401 0.0000 -vn -0.5306 0.8372 0.1326 -vn -0.5274 0.8438 0.0988 -vn 0.4439 -0.8887 -0.1148 -vn 0.0253 -0.6334 -0.7734 -vn 0.9957 0.0000 -0.0932 -vn -0.8238 -0.4136 -0.3877 -vn -0.1297 -0.6585 -0.7413 -vn 0.0000 -0.9544 -0.2984 -vn 0.3032 -0.9095 -0.2844 -vn 0.1567 -0.7887 -0.5944 +vn 0.0000 -1.0000 -0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.8945 0.4471 0.0000 +vn -0.9306 0.3551 0.0886 +vn -0.9734 -0.2225 -0.0555 +vn 1.0000 0.0000 0.0000 +vn 0.9487 0.3162 0.0000 +vn -0.9949 0.0000 0.1012 +vn -0.9738 -0.2065 0.0955 +vn -0.9734 -0.2290 0.0000 +vn -0.9701 -0.2283 0.0822 +vn 0.9762 0.2171 0.0017 +vn 0.9702 0.2422 0.0000 +vn 0.9805 0.1966 0.0000 usemtl None s off -f 720/690/692 707/691/692 722/692/692 -f 691/693/693 692/694/693 693/695/693 -f 691/693/694 694/696/694 695/697/694 -f 692/694/695 691/693/695 695/697/695 -f 690/698/696 694/696/696 696/699/696 -f 693/695/693 692/694/693 697/700/693 -f 693/695/697 696/699/697 698/701/697 -f 696/699/696 694/696/696 698/701/696 -f 694/696/696 690/698/696 699/702/696 -f 693/695/693 697/700/693 700/703/693 -f 691/693/693 693/695/693 701/704/693 -f 695/697/694 694/696/694 703/705/694 -f 694/696/696 699/702/696 703/705/696 -f 700/703/693 697/700/693 704/706/693 -f 694/696/694 691/693/694 705/707/694 -f 698/701/698 694/696/698 705/707/698 -f 701/704/699 693/695/699 705/707/699 -f 697/700/693 692/694/693 706/708/693 -f 699/702/700 697/700/700 706/708/700 -f 702/709/701 699/702/701 706/708/701 -f 702/709/702 706/708/702 707/691/702 -f 699/702/703 702/709/703 707/691/703 -f 699/702/696 690/698/696 709/710/696 -f 697/700/704 699/702/704 709/710/704 -f 690/698/705 704/706/705 709/710/705 -f 696/699/697 693/695/697 711/711/697 -f 693/695/693 700/703/693 711/711/693 -f 700/703/706 708/712/706 711/711/706 -f 700/703/693 704/706/693 712/713/693 -f 706/708/693 692/694/693 713/714/693 -f 707/691/702 706/708/702 713/714/702 -f 692/694/707 707/691/707 713/714/707 -f 704/706/693 697/700/693 714/715/693 -f 697/700/708 709/710/708 714/715/708 -f 709/710/709 704/706/709 714/715/709 -f 691/693/693 701/704/693 715/716/693 -f 705/707/694 691/693/694 715/716/694 -f 701/704/710 705/707/710 715/716/710 -f 690/698/696 696/699/696 716/717/696 -f 696/699/711 708/712/711 716/717/711 -f 708/712/712 700/703/712 716/717/712 -f 700/703/713 712/713/713 716/717/713 -f 716/717/714 712/713/714 717/718/714 -f 704/706/715 690/698/715 717/718/715 -f 712/713/693 704/706/693 717/718/693 -f 690/698/716 716/717/716 717/718/716 -f 693/695/697 698/701/697 718/719/697 -f 705/707/717 693/695/717 718/719/717 -f 698/701/718 705/707/718 718/719/718 -f 692/694/695 695/697/695 719/720/695 -f 707/691/707 692/694/707 719/720/707 -f 703/705/696 699/702/696 720/690/696 -f 699/702/719 707/691/719 720/690/719 -f 710/721/720 703/705/720 720/690/720 -f 708/712/721 696/699/721 721/722/721 -f 696/699/697 711/711/697 721/722/697 -f 711/711/706 708/712/706 721/722/706 -f 695/697/722 703/705/722 722/692/722 -f 703/705/723 710/721/723 722/692/723 -f 719/720/724 695/697/724 722/692/724 -f 707/691/725 719/720/725 722/692/725 -f 710/721/726 720/690/726 722/692/726 -o Cup_hull_29 -v -0.020392 -0.000377 0.015036 -v -0.016441 0.007259 -0.048198 -v -0.016441 0.006732 -0.048198 -v -0.020392 0.007259 -0.048198 -v -0.016441 0.007259 0.015036 -v -0.018022 -0.000377 -0.048198 -v -0.020392 0.007259 0.015036 -v -0.018022 -0.000377 0.015036 -v -0.020392 -0.000377 -0.048198 -v -0.016441 0.006732 0.013624 -vt 0.000000 0.000000 -vt 1.000000 0.930991 -vt 0.022318 0.930991 -vt 1.000000 1.000000 -vt 1.000000 1.000000 +f 667/651/661 664/652/661 670/653/661 +f 652/654/662 653/655/662 654/656/662 +f 655/657/663 652/654/663 656/658/663 +f 652/654/662 654/656/662 656/658/662 +f 654/656/662 653/655/662 657/659/662 +f 654/656/664 657/659/664 658/660/664 +f 651/661/665 655/657/665 658/660/665 +f 653/655/666 652/654/666 659/662/666 +f 655/657/665 651/661/665 659/662/665 +f 657/659/662 653/655/662 660/663/662 +f 655/657/667 656/658/667 661/664/667 +f 656/658/668 654/656/668 661/664/668 +f 657/659/669 651/661/669 662/665/669 +f 658/660/664 657/659/664 662/665/664 +f 651/661/665 658/660/665 662/665/665 +f 659/662/665 651/661/665 663/666/665 +f 653/655/670 659/662/670 663/666/670 +f 651/661/669 657/659/669 664/652/669 +f 657/659/662 660/663/662 664/652/662 +f 658/660/665 655/657/665 665/667/665 +f 655/657/671 661/664/671 665/667/671 +f 661/664/672 658/660/672 665/667/672 +f 654/656/664 658/660/664 666/668/664 +f 661/664/673 654/656/673 666/668/673 +f 658/660/674 661/664/674 666/668/674 +f 663/666/665 651/661/665 667/651/665 +f 660/663/675 663/666/675 667/651/675 +f 651/661/661 664/652/661 667/651/661 +f 652/654/663 655/657/663 668/669/663 +f 659/662/666 652/654/666 668/669/666 +f 655/657/665 659/662/665 668/669/665 +f 660/663/662 653/655/662 669/670/662 +f 653/655/670 663/666/670 669/670/670 +f 663/666/676 660/663/676 669/670/676 +f 664/652/662 660/663/662 670/653/662 +f 660/663/677 667/651/677 670/653/677 +o cup_hull_28 +v 0.039844 0.006991 0.027600 +v 0.024678 0.014995 0.024652 +v 0.024678 0.015417 0.024652 +v 0.033103 0.015417 0.048666 +v 0.036052 0.000670 0.048241 +v 0.028891 0.000670 0.022545 +v 0.036895 0.015417 0.025917 +v 0.039002 0.010782 0.048666 +v 0.040265 0.000671 0.026758 +v 0.040265 0.000671 0.048666 +v 0.032680 0.015417 0.022545 +v 0.037316 0.015417 0.048666 +v 0.024678 0.015417 0.022545 +v 0.039002 0.000670 0.025073 +v 0.029313 0.000670 0.025917 +v 0.037738 0.014574 0.027180 +v 0.032680 0.000670 0.022545 +v 0.032680 0.014995 0.048241 +v 0.040265 0.003620 0.048666 +v 0.039002 0.006992 0.025495 +v 0.039002 0.010782 0.027180 +v 0.040265 0.003620 0.027600 +v 0.039844 0.006992 0.048666 +v 0.036474 0.000670 0.048666 +v 0.037738 0.014574 0.048666 +v 0.037738 0.012043 0.025495 +v 0.039423 0.009094 0.027180 +v 0.037316 0.015417 0.026758 +v 0.028891 0.000670 0.023810 +v 0.024678 0.014574 0.022545 +v 0.025943 0.014995 0.028443 +vt 0.016249 0.729711 +vt 0.016249 0.513363 +vt 0.774178 0.081155 +vt 0.919342 0.000000 +vt 0.000000 0.540480 +vt 0.870889 0.783749 +vt 0.000000 0.918943 vt 0.000000 1.000000 +vt 1.000000 0.513363 +vt 0.000000 0.810769 +vt 0.919342 0.000000 vt 1.000000 0.000000 -vt 0.000000 0.000000 +vt 1.000000 0.270289 +vt 0.903191 0.918943 +vt 0.838684 1.000000 +vt 0.870889 0.297308 +vt 1.000000 0.513363 vt 0.000000 1.000000 +vt 0.887040 0.918943 +vt 0.822533 0.837885 +vt 0.822533 0.918943 +vt 0.806480 1.000000 +vt 0.000000 0.972981 +vt 0.806480 0.972981 +vt 0.000000 0.756730 +vt 0.000000 0.837885 +vt 0.887040 0.837885 +vt 0.822533 0.945962 +vt 0.838684 0.810769 +vt 0.951547 0.270289 vt 1.000000 0.000000 -vn 0.9762 -0.2170 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 +vn -0.9240 -0.2175 0.3144 vn 0.0000 1.0000 0.0000 -vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.9765 -0.2021 0.0755 +vn 0.0011 -1.0000 0.0000 +vn -0.9209 -0.2733 0.2780 +vn 0.3714 0.0000 -0.9285 +vn -0.8045 0.5225 0.2822 +vn 1.0000 0.0000 0.0000 +vn 0.7994 0.0400 -0.5994 +vn 0.4849 0.0582 -0.8726 +vn 0.9487 0.3161 0.0000 +vn 0.9192 0.1080 -0.3787 +vn 0.9923 0.1240 -0.0000 +vn 0.9923 0.1239 0.0000 +vn 0.0004 -1.0000 0.0000 +vn -0.6265 -0.1432 0.7661 +vn -0.7001 -0.1648 0.6947 +vn 0.8939 0.4482 0.0000 +vn 0.6056 0.2461 -0.7568 +vn 0.5677 0.1420 -0.8109 +vn 0.8564 0.2693 -0.4405 +vn 0.8516 0.2130 -0.4790 +vn 0.9702 0.2421 0.0000 +vn 0.8521 0.2127 -0.4782 +vn 0.9292 0.1161 -0.3509 +vn 0.9214 0.1133 -0.3716 +vn 0.9762 0.2170 0.0021 +vn 0.9805 0.1963 -0.0000 +vn 0.8601 0.2737 -0.4306 +vn 0.9039 0.3011 -0.3038 +vn -0.9393 -0.2873 0.1878 +vn -0.9569 -0.2848 0.0570 +vn -0.9570 -0.2900 0.0000 +vn -0.9486 0.0000 0.3165 +vn -0.9241 -0.2260 0.3083 +vn -0.9452 0.0568 0.3216 usemtl None s off -f 730/723/727 725/724/727 732/725/727 -f 724/726/728 725/724/728 726/727/728 -f 725/724/729 724/726/729 727/728/729 -f 724/726/730 726/727/730 727/728/730 -f 726/727/728 725/724/728 728/729/728 -f 726/727/731 723/730/731 729/731/731 -f 723/730/732 727/728/732 729/731/732 -f 727/728/730 726/727/730 729/731/730 -f 727/728/732 723/730/732 730/723/732 -f 728/729/727 725/724/727 730/723/727 -f 723/730/733 728/729/733 730/723/733 -f 723/730/731 726/727/731 731/732/731 -f 726/727/728 728/729/728 731/732/728 -f 728/729/733 723/730/733 731/732/733 -f 725/724/729 727/728/729 732/725/729 -f 727/728/734 730/723/734 732/725/734 -o Cup_hull_30 -v 0.017529 0.018321 0.034429 -v 0.008314 0.022795 0.050166 -v 0.008314 0.023587 0.050166 -v 0.021217 0.013580 0.050166 -v 0.018582 0.013580 0.034429 -v 0.008314 0.021480 0.034429 -v 0.015686 0.019899 0.050166 -v 0.009894 0.023322 0.034429 -v 0.019899 0.013580 0.050166 -v 0.021217 0.013844 0.034429 -v 0.019899 0.015687 0.050166 -v 0.012527 0.022006 0.050166 -v 0.013843 0.021216 0.034429 -v 0.008314 0.023587 0.034429 -v 0.008314 0.021480 0.035553 -v 0.009105 0.023587 0.050166 -v 0.008314 0.022533 0.048477 -v 0.017793 0.018057 0.050166 -v 0.019899 0.015687 0.034429 -v 0.018582 0.013580 0.035553 -v 0.021217 0.013580 0.034429 -v 0.015686 0.019899 0.034429 -v 0.021217 0.013844 0.050166 -v 0.018319 0.017530 0.034429 -v 0.012527 0.022006 0.034429 -v 0.014633 0.020688 0.050166 -v 0.010421 0.023059 0.050166 -v 0.009105 0.023587 0.034429 -v 0.018319 0.017530 0.050166 -v 0.020689 0.014634 0.050166 -vt 0.000000 0.897905 -vt 0.000000 1.000000 -vt 0.000000 0.959084 -vt 0.000000 0.000000 +f 675/671/678 688/672/678 701/673/678 +f 673/674/679 674/675/679 677/676/679 +f 678/677/680 674/675/680 680/678/680 +f 673/674/679 677/676/679 681/679/679 +f 677/676/679 674/675/679 682/680/679 +f 674/675/680 678/677/680 682/680/680 +f 672/681/681 673/674/681 683/682/681 +f 673/674/679 681/679/679 683/682/679 +f 681/679/682 676/683/682 683/682/682 +f 675/671/683 676/683/683 684/684/683 +f 679/685/684 680/678/684 684/684/684 +f 675/671/685 672/681/685 685/686/685 +f 676/683/683 675/671/683 685/686/683 +f 676/683/682 681/679/682 687/687/682 +f 684/684/683 676/683/683 687/687/683 +f 681/679/686 684/684/686 687/687/686 +f 674/675/687 673/674/687 688/672/687 +f 678/677/680 680/678/680 689/688/680 +f 680/678/688 679/685/688 689/688/688 +f 679/685/689 684/684/689 690/689/689 +f 684/684/690 681/679/690 690/689/690 +f 686/690/691 678/677/691 691/691/691 +f 689/688/688 679/685/688 692/692/688 +f 679/685/692 690/689/692 692/692/692 +f 678/677/680 689/688/680 693/693/680 +f 692/692/693 671/694/693 693/693/693 +f 689/688/694 692/692/694 693/693/694 +f 680/678/680 674/675/680 694/695/680 +f 675/671/683 684/684/683 694/695/683 +f 684/684/695 680/678/695 694/695/695 +f 674/675/696 688/672/696 694/695/696 +f 688/672/697 675/671/697 694/695/697 +f 682/680/680 678/677/680 695/696/680 +f 678/677/691 686/690/691 695/696/691 +f 686/690/698 682/680/698 695/696/698 +f 681/679/699 677/676/699 696/697/699 +f 690/689/700 681/679/700 696/697/700 +f 677/676/701 691/691/701 696/697/701 +f 691/691/702 690/689/702 696/697/702 +f 691/691/703 678/677/703 697/698/703 +f 690/689/704 691/691/704 697/698/704 +f 671/694/705 692/692/705 697/698/705 +f 692/692/706 690/689/706 697/698/706 +f 678/677/707 693/693/707 697/698/707 +f 693/693/708 671/694/708 697/698/708 +f 677/676/679 682/680/679 698/699/679 +f 682/680/698 686/690/698 698/699/698 +f 691/691/709 677/676/709 698/699/709 +f 686/690/710 691/691/710 698/699/710 +f 685/686/711 672/681/711 699/700/711 +f 676/683/683 685/686/683 699/700/683 +f 672/681/681 683/682/681 700/701/681 +f 683/682/682 676/683/682 700/701/682 +f 699/700/712 672/681/712 700/701/712 +f 676/683/713 699/700/713 700/701/713 +f 673/674/714 672/681/714 701/673/714 +f 672/681/715 675/671/715 701/673/715 +f 688/672/716 673/674/716 701/673/716 +o cup_hull_29 +v 0.033945 0.022160 0.075211 +v 0.021308 0.034378 0.051615 +v 0.022151 0.033953 0.051615 +v 0.033523 0.015417 0.051615 +v 0.020465 0.032690 0.075211 +v 0.033945 0.022160 0.051615 +v 0.035631 0.015417 0.075211 +v 0.020465 0.030584 0.051615 +v 0.028048 0.029320 0.075211 +v 0.037317 0.015840 0.051615 +v 0.021308 0.034378 0.075211 +v 0.029312 0.028054 0.051615 +v 0.037317 0.015840 0.075211 +v 0.035211 0.015417 0.073945 +v 0.020465 0.034378 0.051615 +v 0.033523 0.015417 0.053304 +v 0.031839 0.025107 0.075211 +v 0.025100 0.031848 0.051615 +v 0.023414 0.033112 0.075211 +v 0.037317 0.015417 0.051615 +v 0.035211 0.020051 0.051615 +v 0.020465 0.030584 0.052881 +v 0.020465 0.034378 0.075211 +v 0.031839 0.025107 0.051615 +v 0.035211 0.020051 0.075211 +v 0.037317 0.015417 0.075211 +v 0.027626 0.029741 0.051615 +v 0.025100 0.031848 0.075211 +v 0.029312 0.028054 0.075211 +v 0.033102 0.023425 0.051615 +vt 1.000000 0.511061 +vt 0.000000 0.511061 +vt 1.000000 0.422377 +vt 1.000000 1.000000 +vt 1.000000 0.977584 +vt 1.000000 0.000000 +vt 1.000000 0.355619 +vt 0.000000 0.355619 +vt 0.000000 0.911022 vt 0.000000 0.000000 +vt 1.000000 0.799922 +vt 0.000000 0.733262 +vt 1.000000 0.022318 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 0.714174 -vt 1.000000 0.795810 -vt 0.000000 0.571359 -vt 1.000000 0.122455 -vt 0.000000 0.897905 +vt 1.000000 0.666503 +vt 0.000000 0.022318 +vt 0.053641 0.000000 vt 1.000000 1.000000 -vt 0.000000 0.326547 -vt 1.000000 0.428543 +vt 0.928446 0.000000 +vt 1.000000 0.866582 +vt 0.000000 0.933242 vt 1.000000 0.000000 -vt 0.928543 0.000000 -vt 0.000000 0.061276 -vt 0.107283 0.000000 -vt 0.000000 0.734632 -vt 1.000000 0.897905 -vt 0.928543 0.795810 -vt 1.000000 1.000000 -vt 1.000000 0.571359 -vt 1.000000 0.775450 -vt 1.000000 0.326547 -vt 0.000000 0.489722 -vt 0.000000 0.163273 -vt 1.000000 0.061276 -vt 0.000000 0.775450 -vn 0.0001 0.0000 1.0000 +vt 1.000000 0.244421 +vt 0.946359 0.799922 +vt 0.000000 1.000000 +vt 0.000000 0.244421 +vt 0.000000 0.000000 +vt 1.000000 0.755482 +vt 0.000000 0.866582 +vt 0.000000 0.666503 +vn 0.7994 0.6007 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 0.0000 1.0000 +vn 0.4502 0.8929 0.0000 +vn 0.0000 -1.0000 -0.0000 +vn -0.7291 -0.6401 0.2423 vn -1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn -0.7578 -0.6525 0.0000 +vn -0.7569 -0.6506 0.0619 +vn 0.5150 0.8572 0.0030 +vn 0.5809 0.8140 -0.0021 +vn 1.0000 0.0000 0.0000 +vn 0.8575 0.5146 0.0000 +vn 0.8943 0.4474 0.0000 +vn -0.7572 -0.6502 0.0613 +vn 0.7591 0.6509 0.0000 +vn 0.7074 0.7069 -0.0000 +vn 0.6405 0.7679 0.0000 +vn 0.5998 0.8001 0.0000 +vn 0.6510 0.7591 0.0019 +vn 0.7077 0.7065 0.0000 +vn -0.0001 0.0000 1.0000 +vn 0.8323 0.5543 0.0000 +vn 0.8136 0.5815 0.0021 +usemtl None +s off +f 725/702/717 718/703/717 731/704/717 +f 703/705/718 704/706/718 705/707/718 +f 705/707/718 704/706/718 707/708/718 +f 702/709/719 706/710/719 708/711/719 +f 703/705/718 705/707/718 709/712/718 +f 706/710/719 702/709/719 710/713/719 +f 705/707/718 707/708/718 711/714/718 +f 704/706/720 703/705/720 712/715/720 +f 706/710/719 710/713/719 712/715/719 +f 707/708/718 704/706/718 713/716/718 +f 702/709/719 708/711/719 714/717/719 +f 705/707/721 708/711/721 715/718/721 +f 708/711/722 706/710/722 715/718/722 +f 703/705/718 709/712/718 716/719/718 +f 709/712/723 706/710/723 716/719/723 +f 712/715/724 703/705/724 716/719/724 +f 709/712/725 705/707/725 717/720/725 +f 705/707/721 715/718/721 717/720/721 +f 715/718/726 706/710/726 717/720/726 +f 710/713/719 702/709/719 718/703/719 +f 713/716/718 704/706/718 719/721/718 +f 704/706/727 712/715/727 720/722/727 +f 712/715/719 710/713/719 720/722/719 +f 719/721/728 704/706/728 720/722/728 +f 708/711/721 705/707/721 721/723/721 +f 705/707/718 711/714/718 721/723/718 +f 711/714/729 714/717/729 721/723/729 +f 707/708/730 702/709/730 722/724/730 +f 711/714/718 707/708/718 722/724/718 +f 714/717/731 711/714/731 722/724/731 +f 706/710/723 709/712/723 723/725/723 +f 709/712/725 717/720/725 723/725/725 +f 717/720/732 706/710/732 723/725/732 +f 706/710/719 712/715/719 724/726/719 +f 716/719/723 706/710/723 724/726/723 +f 712/715/724 716/719/724 724/726/724 +f 707/708/718 713/716/718 725/702/718 +f 713/716/733 718/703/733 725/702/733 +f 702/709/719 714/717/719 726/727/719 +f 722/724/730 702/709/730 726/727/730 +f 714/717/731 722/724/731 726/727/731 +f 714/717/719 708/711/719 727/728/719 +f 708/711/721 721/723/721 727/728/721 +f 721/723/729 714/717/729 727/728/729 +f 710/713/734 713/716/734 728/729/734 +f 713/716/718 719/721/718 728/729/718 +f 728/729/735 719/721/735 729/730/735 +f 720/722/719 710/713/719 729/730/719 +f 719/721/736 720/722/736 729/730/736 +f 710/713/737 728/729/737 729/730/737 +f 713/716/738 710/713/738 730/731/738 +f 710/713/739 718/703/739 730/731/739 +f 718/703/733 713/716/733 730/731/733 +f 702/709/740 707/708/740 731/704/740 +f 718/703/741 702/709/741 731/704/741 +f 707/708/718 725/702/718 731/704/718 +o cup_hull_30 +v 0.035210 0.020053 0.051615 +v 0.020887 0.034378 0.026336 +v 0.020464 0.034378 0.026336 +v 0.024257 0.015417 0.022542 +v 0.020464 0.030584 0.051615 +v 0.036894 0.015840 0.026336 +v 0.033104 0.015417 0.051191 +v 0.029311 0.028054 0.022542 +v 0.023414 0.033112 0.051615 +v 0.020464 0.020053 0.022542 +v 0.037315 0.015417 0.051615 +v 0.032683 0.015417 0.022542 +v 0.029311 0.028054 0.051615 +v 0.023835 0.032690 0.022542 +v 0.032683 0.023845 0.022542 +v 0.020464 0.034378 0.051615 +v 0.024677 0.015417 0.025493 +v 0.020464 0.032690 0.022542 +v 0.037315 0.015840 0.027599 +v 0.031840 0.025107 0.051615 +v 0.027627 0.029741 0.036450 +v 0.033945 0.022158 0.027181 +v 0.020464 0.020474 0.025072 +v 0.037315 0.015417 0.027599 +v 0.020464 0.030161 0.050770 +v 0.025100 0.031848 0.022542 +v 0.022150 0.033953 0.027181 +v 0.021307 0.034378 0.051615 +v 0.027627 0.029741 0.051615 +v 0.035210 0.020053 0.027181 +v 0.031840 0.025107 0.022542 +v 0.033524 0.015417 0.051615 +v 0.033104 0.023424 0.051615 +v 0.037315 0.015840 0.051615 +v 0.025100 0.031848 0.051615 +v 0.028048 0.029320 0.022542 +vt 0.521633 0.755482 +vt 0.000000 0.755482 +vt 1.000000 0.733262 +vt 0.000000 0.799922 +vt 0.000000 0.244518 +vt 0.000000 0.933242 +vt 0.869518 1.000000 +vt 1.000000 0.244518 +vt 1.000000 0.666503 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 0.014585 0.000000 +vt 1.000000 0.000000 +vt 0.000000 0.666503 +vt 0.869518 1.000000 +vt 1.000000 0.911022 +vt 1.000000 0.444499 +vt 0.869518 0.022318 +vt 0.000000 1.000000 +vt 0.898493 0.000000 +vt 1.000000 0.911022 +vt 0.826057 0.022318 +vt 0.000000 0.511061 +vt 0.912980 0.266738 +vt 0.826057 0.000000 +vt 0.029072 0.777604 +vt 1.000000 0.866582 +vt 0.840446 0.977584 +vt 0.000000 1.000000 +vt 0.840446 0.244518 +vt 0.840446 0.355521 +vt 1.000000 0.511061 +vt 0.000000 0.000000 +vt 0.000000 0.422279 +vt 0.000000 0.022318 +vt 0.000000 0.866582 +vn 0.7077 0.7065 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 -0.0000 0.0000 vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.6098 -0.7926 0.0000 +vn 0.0000 0.9137 -0.4064 +vn 0.6693 0.0000 -0.7430 vn 0.0000 1.0000 0.0000 -vn -0.6179 -0.7769 0.1208 -vn -0.6160 -0.7851 0.0640 -vn 0.6581 0.7529 0.0016 -vn -0.6089 -0.7914 0.0549 +vn 0.8957 0.3299 -0.2982 +vn 0.7589 0.6512 0.0000 +vn -0.7698 -0.6297 0.1049 +vn -0.7682 -0.6308 0.1095 +vn 0.4531 -0.7889 -0.4151 vn 1.0000 0.0000 0.0000 -vn 0.6504 0.7596 0.0000 -vn 0.7070 0.7072 -0.0000 -vn 0.7593 0.6508 0.0000 -vn 0.4472 0.8945 0.0000 -vn 0.5144 0.8575 0.0000 -vn 0.5305 0.8477 0.0018 -vn 0.5997 0.8002 0.0000 -vn 0.5816 0.8135 -0.0019 -vn 0.4471 0.8945 0.0000 -vn 0.3723 0.9281 0.0031 -vn 0.3177 0.9482 0.0000 -vn 0.7073 0.7069 0.0000 -vn 0.8001 0.5998 0.0000 -vn 0.8136 0.5814 -0.0019 -vn 0.8316 0.5554 0.0000 +vn 0.9488 0.0000 -0.3159 +vn -0.7268 -0.6142 0.3075 +vn -0.7399 -0.6274 0.2426 +vn -0.7570 -0.6114 0.2305 +vn 0.3826 0.9173 -0.1107 +vn 0.5789 0.8154 -0.0019 +vn 0.5541 0.8321 -0.0252 +vn 0.3220 0.9467 -0.0054 +vn 0.5150 0.8572 0.0029 +vn 0.6403 0.7681 0.0000 +vn 0.8946 0.4469 0.0000 +vn 0.8919 0.4324 -0.1324 +vn 0.8571 0.5152 0.0000 +vn 0.8562 0.5147 -0.0457 +vn 0.8313 0.5553 -0.0242 +vn -0.6057 -0.5216 0.6009 +vn 0.8480 0.5300 0.0017 +vn 0.7998 0.6003 0.0000 +vn 0.8154 0.5789 -0.0019 +vn 0.5998 0.8001 0.0000 +vn 0.6510 0.7591 -0.0033 usemtl None s off -f 743/733/735 755/734/735 762/735/735 -f 735/736/736 734/737/736 736/738/736 -f 734/737/737 735/736/737 738/739/737 -f 733/740/738 737/741/738 738/739/738 -f 735/736/736 736/738/736 739/742/736 -f 733/740/738 738/739/738 740/743/738 -f 736/738/736 734/737/736 741/744/736 -f 737/741/739 736/738/739 741/744/739 -f 737/741/738 733/740/738 742/745/738 -f 739/742/736 736/738/736 743/733/736 -f 735/736/736 739/742/736 744/746/736 -f 733/740/738 740/743/738 745/747/738 -f 738/739/737 735/736/737 746/748/737 -f 740/743/738 738/739/738 746/748/738 -f 734/737/737 738/739/737 747/749/737 -f 738/739/740 737/741/740 747/749/740 -f 735/736/736 744/746/736 748/750/736 -f 746/748/741 735/736/741 748/750/741 -f 741/744/742 734/737/742 749/751/742 -f 734/737/737 747/749/737 749/751/737 -f 747/749/743 741/744/743 749/751/743 -f 733/740/744 739/742/744 750/752/744 -f 739/742/736 743/733/736 750/752/736 -f 742/745/738 733/740/738 751/753/738 -f 737/741/739 741/744/739 752/754/739 -f 747/749/740 737/741/740 752/754/740 -f 741/744/745 747/749/745 752/754/745 -f 736/738/739 737/741/739 753/755/739 -f 742/745/746 736/738/746 753/755/746 -f 737/741/738 742/745/738 753/755/738 -f 739/742/747 733/740/747 754/756/747 -f 733/740/738 745/747/738 754/756/738 -f 736/738/746 742/745/746 755/734/746 -f 743/733/736 736/738/736 755/734/736 -f 733/740/748 750/752/748 756/757/748 -f 743/733/749 751/753/749 756/757/749 -f 751/753/738 733/740/738 756/757/738 -f 740/743/750 744/746/750 757/758/750 -f 745/747/738 740/743/738 757/758/738 -f 744/746/751 745/747/751 757/758/751 -f 744/746/736 739/742/736 758/759/736 -f 745/747/752 744/746/752 758/759/752 -f 739/742/753 754/756/753 758/759/753 -f 754/756/754 745/747/754 758/759/754 -f 744/746/755 740/743/755 759/760/755 -f 748/750/736 744/746/736 759/760/736 -f 740/743/756 748/750/756 759/760/756 -f 740/743/738 746/748/738 760/761/738 -f 748/750/757 740/743/757 760/761/757 -f 746/748/741 748/750/741 760/761/741 -f 750/752/736 743/733/736 761/762/736 -f 756/757/758 750/752/758 761/762/758 -f 743/733/749 756/757/749 761/762/749 -f 751/753/759 743/733/759 762/735/759 -f 742/745/760 751/753/760 762/735/760 -f 755/734/761 742/745/761 762/735/761 -o Cup_hull_31 -v 0.019899 0.015687 0.015038 -v 0.008313 0.021479 0.034427 -v 0.008313 0.023586 0.034427 -v 0.021215 0.013581 0.034427 -v 0.008577 0.015687 0.015038 -v 0.008313 0.023586 0.017568 -v 0.014633 0.020689 0.034427 -v 0.012262 0.013581 0.017568 -v 0.014896 0.020425 0.015038 -v 0.020425 0.013581 0.015038 -v 0.018319 0.013581 0.034143 -v 0.018319 0.017531 0.034427 -v 0.010421 0.023059 0.018129 -v 0.008313 0.020425 0.015038 -v 0.008313 0.016214 0.017006 -v 0.009894 0.023322 0.034427 -v 0.011737 0.013581 0.015038 -v 0.017793 0.018057 0.015038 -v 0.021215 0.013844 0.018410 -v 0.020689 0.014634 0.034427 -v 0.012526 0.022005 0.018129 -v 0.008313 0.021215 0.033862 -v 0.015685 0.019899 0.034427 -v 0.012526 0.022005 0.034427 -v 0.009104 0.023586 0.018129 -v 0.015686 0.019899 0.015038 -v 0.018583 0.013581 0.034427 -v 0.013844 0.021215 0.018410 -v 0.017529 0.018320 0.034427 -v 0.008841 0.022795 0.016725 -v 0.019899 0.015687 0.034427 -v 0.009104 0.023586 0.034427 -v 0.021215 0.013581 0.018410 -v 0.018319 0.017531 0.015038 -v 0.020425 0.014897 0.015038 -v 0.008313 0.015951 0.015038 -v 0.021215 0.013844 0.034427 -vt 0.826057 1.000000 -vt 0.000000 0.959275 +f 752/732/742 760/733/742 767/734/742 +f 736/735/743 732/736/743 740/737/743 +f 736/735/744 734/738/744 741/739/744 +f 739/740/745 735/741/745 741/739/745 +f 732/736/743 736/735/743 742/742/743 +f 738/743/746 735/741/746 742/742/746 +f 735/741/745 739/740/745 743/744/745 +f 742/742/746 735/741/746 743/744/746 +f 740/737/743 732/736/743 744/745/743 +f 734/738/747 733/746/747 745/747/747 +f 739/740/745 741/739/745 745/747/745 +f 743/744/745 739/740/745 746/748/745 +f 737/749/748 743/744/748 746/748/748 +f 733/746/749 734/738/749 747/750/749 +f 734/738/744 736/735/744 747/750/744 +f 736/735/743 740/737/743 747/750/743 +f 735/741/746 738/743/746 748/751/746 +f 741/739/744 734/738/744 749/752/744 +f 734/738/747 745/747/747 749/752/747 +f 745/747/745 741/739/745 749/752/745 +f 737/749/750 746/748/750 750/753/750 +f 744/745/743 732/736/743 751/754/743 +f 739/740/751 744/745/751 751/754/751 +f 741/739/752 735/741/752 754/755/752 +f 736/735/744 741/739/744 754/755/744 +f 735/741/753 748/751/753 754/755/753 +f 743/744/754 737/749/754 755/756/754 +f 742/742/746 743/744/746 755/756/746 +f 750/753/755 742/742/755 755/756/755 +f 737/749/756 750/753/756 755/756/756 +f 738/743/757 736/735/757 756/757/757 +f 748/751/758 738/743/758 756/757/758 +f 736/735/744 754/755/744 756/757/744 +f 754/755/759 748/751/759 756/757/759 +f 739/740/745 745/747/745 757/758/745 +f 745/747/760 733/746/760 758/759/760 +f 740/737/761 757/758/761 758/759/761 +f 757/758/762 745/747/762 758/759/762 +f 733/746/749 747/750/749 759/760/749 +f 747/750/743 740/737/743 759/760/743 +f 758/759/763 733/746/763 759/760/763 +f 740/737/764 758/759/764 759/760/764 +f 740/737/743 744/745/743 760/733/743 +f 752/732/765 757/758/765 760/733/765 +f 732/736/766 750/753/766 761/761/766 +f 750/753/767 746/748/767 761/761/767 +f 753/762/768 732/736/768 761/761/768 +f 746/748/769 753/762/769 761/761/769 +f 746/748/745 739/740/745 762/763/745 +f 739/740/751 751/754/751 762/763/751 +f 753/762/770 746/748/770 762/763/770 +f 736/735/771 738/743/771 763/764/771 +f 742/742/743 736/735/743 763/764/743 +f 738/743/746 742/742/746 763/764/746 +f 751/754/743 732/736/743 764/765/743 +f 732/736/772 753/762/772 764/765/772 +f 762/763/773 751/754/773 764/765/773 +f 753/762/774 762/763/774 764/765/774 +f 732/736/743 742/742/743 765/766/743 +f 750/753/766 732/736/766 765/766/766 +f 742/742/755 750/753/755 765/766/755 +f 757/758/775 740/737/775 766/767/775 +f 740/737/743 760/733/743 766/767/743 +f 760/733/765 757/758/765 766/767/765 +f 744/745/742 739/740/742 767/734/742 +f 739/740/745 757/758/745 767/734/745 +f 757/758/776 752/732/776 767/734/776 +f 760/733/742 744/745/742 767/734/742 +o cup_hull_31 +v -0.022093 -0.017869 -0.072261 +v -0.032625 -0.019134 0.022524 +v -0.023779 -0.019134 0.022524 +v -0.032625 -0.010707 0.022524 +v -0.032625 -0.019134 -0.072261 +v -0.026727 -0.010707 -0.072261 +v -0.026307 -0.011128 0.022524 +v -0.032625 -0.010707 -0.072261 +v -0.021671 -0.019133 0.022524 +v -0.021671 -0.019133 -0.072261 +v -0.026727 -0.010707 0.022524 +v -0.022093 -0.017869 0.020844 +v -0.026307 -0.011128 -0.072261 +v -0.021671 -0.018712 0.022524 +v -0.021671 -0.018712 -0.072261 vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 1.000000 vt 0.000000 0.000000 +vt 0.000000 0.807636 vt 0.000000 0.000000 -vt 0.000000 1.000000 -vt 0.869518 0.000000 -vt 0.000000 0.489868 -vt 1.000000 0.897993 -vt 1.000000 0.020460 -vt 1.000000 0.510230 -vt 1.000000 0.938815 -vt 0.869518 0.306118 -vt 0.014683 0.775526 -vt 0.000000 0.775526 vt 1.000000 0.000000 -vt 0.898493 0.000000 -vt 0.000000 0.122565 -vt 1.000000 0.265394 -vt 1.000000 0.734802 -vt 0.840544 0.163387 -vt 0.840544 0.326579 -vt 0.029170 0.000000 -vt 0.000000 0.571415 -vt 0.000000 0.326579 -vt 0.840544 0.061282 -vt 1.000000 0.571512 -vt 0.000000 0.795986 -vt 0.826057 0.428683 -vt 0.000000 0.714342 -vt 0.912980 0.040920 -vt 0.000000 0.897993 -vt 0.000000 0.061282 -vt 0.826057 1.000000 -vt 1.000000 0.775526 -vt 1.000000 0.938815 +vt 1.000000 0.961527 +vt 1.000000 0.538424 +vt 0.000000 0.576799 vt 1.000000 0.000000 -vn 0.8325 0.5541 0.0000 +vt 0.000000 1.000000 +vt 0.000000 0.538424 +vt 0.017719 0.961527 +vt 1.000000 0.576799 +vn 1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 -1.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0001 -1.0000 -0.0000 +vn 0.0004 -1.0000 0.0000 +vn 0.7081 0.7061 0.0000 +vn 0.8479 0.5301 0.0000 +vn 0.8945 0.4471 0.0000 +vn 0.8523 0.5209 0.0476 +vn 0.0001 0.0000 -1.0000 +usemtl None +s off +f 781/768/777 777/769/777 782/770/777 +f 769/771/778 770/772/778 771/773/778 +f 770/772/779 769/771/779 772/774/779 +f 769/771/780 771/773/780 772/774/780 +f 768/775/781 772/774/781 773/776/781 +f 771/773/778 770/772/778 774/777/778 +f 772/774/780 771/773/780 775/778/780 +f 771/773/782 773/776/782 775/778/782 +f 773/776/781 772/774/781 775/778/781 +f 774/777/778 770/772/778 776/779/778 +f 772/774/781 768/775/781 777/769/781 +f 770/772/783 772/774/783 777/769/783 +f 776/779/784 770/772/784 777/769/784 +f 773/776/782 771/773/782 778/780/782 +f 771/773/778 774/777/778 778/780/778 +f 774/777/785 773/776/785 778/780/785 +f 768/775/786 774/777/786 779/781/786 +f 768/775/781 773/776/781 780/782/781 +f 774/777/786 768/775/786 780/782/786 +f 773/776/785 774/777/785 780/782/785 +f 774/777/778 776/779/778 781/768/778 +f 776/779/777 777/769/777 781/768/777 +f 768/775/787 779/781/787 781/768/787 +f 779/781/788 774/777/788 781/768/788 +f 777/769/789 768/775/789 782/770/789 +f 768/775/787 781/768/787 782/770/787 +o cup_hull_32 +v -0.027571 -0.010707 0.022524 +v -0.028835 0.000670 -0.072261 +v -0.026728 -0.009863 -0.072261 +v -0.032626 -0.010707 -0.072261 +v -0.032626 0.000670 0.022524 +v -0.032626 -0.010707 0.022524 +v -0.028835 0.000670 0.022524 +v -0.032626 0.000670 -0.072261 +v -0.026728 -0.009863 0.021688 +v -0.026728 -0.010706 -0.072261 +v -0.026728 -0.010706 0.022524 +vt 0.000000 0.000000 +vt 1.000000 0.000098 +vt 0.000000 0.000098 +vt 1.000000 1.000000 +vt 1.000000 0.074197 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.008811 0.074197 +vn 0.0013 -1.0000 0.0000 +vn -0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.5631 -0.8140 0.1424 -vn -0.5630 -0.8004 0.2057 -vn -0.5511 -0.8266 0.1144 -vn 0.8154 0.5789 -0.0018 -vn 0.4447 0.8885 -0.1132 -vn -0.5754 -0.7414 0.3454 -vn -0.5946 -0.7708 0.2287 -vn 0.4476 0.8943 0.0000 -vn 0.4476 0.8942 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.9806 0.1962 0.0000 vn 0.0000 1.0000 0.0000 -vn 0.2744 0.8807 -0.3862 -vn 0.3600 0.9000 -0.2456 -vn 0.3714 0.9285 -0.0030 -vn 0.6002 0.7999 0.0000 -vn -0.5307 -0.6901 0.4921 -vn 0.5196 0.8536 -0.0379 -vn 0.5299 0.8481 0.0018 -vn 0.5140 0.8578 0.0000 -vn 0.5792 0.8152 -0.0017 -vn 0.5537 0.8324 -0.0223 -vn 0.7071 0.7071 0.0000 -vn 0.6583 0.7528 -0.0013 -vn 0.6504 0.7596 0.0000 -vn 0.1198 0.7605 -0.6382 -vn -0.2966 0.5968 -0.7456 -vn 0.0000 0.5799 -0.8147 -vn 0.7592 0.6508 0.0000 -vn 0.7999 0.6001 0.0000 -vn 0.0001 0.0000 1.0000 -vn 0.3161 0.9487 0.0000 -vn 0.9737 0.0000 -0.2279 +vn 0.0002 -1.0000 -0.0000 vn 1.0000 0.0000 0.0000 -vn 0.7075 0.7067 0.0000 -vn 0.8320 0.5544 -0.0217 -vn -0.7033 -0.7046 0.0943 +vn 0.9671 0.1791 0.1808 usemtl None s off -f 781/763/762 782/764/762 799/765/762 -f 765/766/763 764/767/763 766/768/763 -f 764/767/764 765/766/764 768/769/764 -f 765/766/763 766/768/763 769/770/763 -f 763/771/765 767/772/765 771/773/765 -f 767/772/765 763/771/765 772/774/765 -f 766/768/766 770/775/766 772/774/766 -f 770/775/766 766/768/766 773/776/766 -f 769/770/763 766/768/763 774/777/763 -f 764/767/764 768/769/764 776/778/764 -f 771/773/765 767/772/765 776/778/765 -f 767/772/767 770/775/767 777/779/767 -f 770/775/768 773/776/768 777/779/768 -f 764/767/764 776/778/764 777/779/764 -f 765/766/763 769/770/763 778/780/763 -f 770/775/769 767/772/769 779/781/769 -f 767/772/765 772/774/765 779/781/765 -f 772/774/766 770/775/766 779/781/766 -f 763/771/765 771/773/765 780/782/765 -f 774/777/763 766/768/763 782/764/763 -f 781/763/770 763/771/770 782/764/770 -f 771/773/771 775/783/771 783/784/771 -f 773/776/772 764/767/772 784/785/772 -f 764/767/764 777/779/764 784/785/764 -f 777/779/773 773/776/773 784/785/773 -f 769/770/763 774/777/763 785/786/763 -f 778/780/763 769/770/763 786/787/763 -f 775/783/774 778/780/774 786/787/774 -f 783/784/775 775/783/775 786/787/775 -f 768/769/776 765/766/776 787/788/776 -f 771/773/777 768/769/777 787/788/777 -f 775/783/778 771/773/778 787/788/778 -f 778/780/779 775/783/779 787/788/779 -f 780/782/765 771/773/765 788/789/765 -f 769/770/780 785/786/780 788/789/780 -f 766/768/763 764/767/763 789/790/763 -f 764/767/781 773/776/781 789/790/781 -f 773/776/766 766/768/766 789/790/766 -f 771/773/782 783/784/782 790/791/782 -f 786/787/783 769/770/783 790/791/783 -f 783/784/784 786/787/784 790/791/784 -f 769/770/785 788/789/785 790/791/785 -f 788/789/786 771/773/786 790/791/786 -f 774/777/787 780/782/787 791/792/787 -f 785/786/763 774/777/763 791/792/763 -f 780/782/788 788/789/788 791/792/788 -f 788/789/789 785/786/789 791/792/789 -f 768/769/790 771/773/790 792/793/790 -f 776/778/791 768/769/791 792/793/791 -f 771/773/792 776/778/792 792/793/792 -f 763/771/793 774/777/793 793/794/793 -f 782/764/794 763/771/794 793/794/794 -f 774/777/795 782/764/795 793/794/795 -f 765/766/763 778/780/763 794/795/763 -f 787/788/776 765/766/776 794/795/776 -f 778/780/796 787/788/796 794/795/796 -f 766/768/766 772/774/766 795/796/766 -f 772/774/797 781/763/797 795/796/797 -f 781/763/798 766/768/798 795/796/798 -f 774/777/793 763/771/793 796/797/793 -f 763/771/765 780/782/765 796/797/765 -f 780/782/799 774/777/799 796/797/799 -f 772/774/765 763/771/765 797/798/765 -f 763/771/800 781/763/800 797/798/800 -f 781/763/797 772/774/797 797/798/797 -f 776/778/765 767/772/765 798/799/765 -f 767/772/801 777/779/801 798/799/801 -f 777/779/764 776/778/764 798/799/764 -f 766/768/798 781/763/798 799/765/798 -f 782/764/763 766/768/763 799/765/763 -o Cup_hull_32 -v 0.004626 -0.019601 -0.043977 -v -0.002221 -0.020391 0.015036 -v 0.001203 -0.020392 -0.005762 -v 0.004626 -0.017495 0.015036 -v -0.002221 -0.017758 -0.048198 -v -0.002221 -0.020391 -0.048198 -v -0.002221 -0.017758 0.014751 -v 0.004626 -0.020392 0.015036 -v 0.004625 -0.017495 -0.048198 -v 0.004625 -0.020392 -0.048198 -v 0.003308 -0.017495 0.013624 -v 0.003308 -0.017495 -0.048198 -v -0.002221 -0.018022 0.015036 -vt 0.000000 1.000000 -vt 0.004503 0.000000 +f 783/783/790 792/784/790 793/785/790 +f 784/786/791 785/787/791 786/788/791 +f 786/788/792 783/783/792 788/789/792 +f 783/783/793 787/790/793 788/789/793 +f 787/790/794 786/788/794 788/789/794 +f 785/787/795 784/786/795 789/791/795 +f 787/790/793 783/783/793 789/791/793 +f 784/786/796 787/790/796 789/791/796 +f 784/786/791 786/788/791 790/792/791 +f 786/788/794 787/790/794 790/792/794 +f 787/790/796 784/786/796 790/792/796 +f 785/787/795 789/791/795 791/793/795 +f 786/788/791 785/787/791 792/784/791 +f 783/783/797 786/788/797 792/784/797 +f 785/787/798 791/793/798 792/784/798 +f 792/784/798 791/793/798 793/785/798 +f 789/791/793 783/783/793 793/785/793 +f 791/793/799 789/791/799 793/785/799 +o cup_hull_33 +v 0.008666 -0.027561 -0.072261 +v -0.002711 -0.032617 0.022524 +v 0.008665 -0.032617 0.022524 +v -0.002711 -0.032617 -0.072261 +v -0.002711 -0.028825 0.022524 +v 0.008666 -0.032617 -0.072261 +v 0.008665 -0.027561 0.022524 +v -0.002711 -0.028825 -0.072261 +v 0.007401 -0.027561 -0.072261 +v 0.007401 -0.027561 0.021688 +vt 1.000000 0.888802 vt 0.000000 0.000000 +vt 0.008811 0.888802 +vt 0.000000 0.999902 vt 0.000000 0.000000 vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 0.999902 vt 1.000000 0.000000 -vt 0.328896 0.500000 -vt 0.000000 1.000000 -vt 0.933242 1.000000 -vt 1.000000 0.999902 -vt 1.000000 0.999902 -vt 0.022318 0.807557 -vt 1.000000 0.807557 -vn -0.0564 0.7329 0.6780 +vn -0.1241 0.9923 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.0001 -1.0000 0.0000 -vn -0.0000 -1.0000 0.0000 -vn -0.0000 0.0000 1.0000 vn 1.0000 0.0000 0.0000 -vn 1.0000 0.0003 -0.0000 vn 0.0000 0.0000 -1.0000 -vn 1.0000 -0.0008 -0.0000 -vn 1.0000 0.0000 -0.0002 -vn -0.0399 0.9985 0.0373 -vn -0.0475 0.9989 0.0000 -vn 0.0000 1.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn -0.1090 0.9803 0.1649 usemtl None s off -f 803/800/802 806/801/802 812/802/802 -f 801/803/803 804/804/803 805/805/803 -f 802/806/804 801/803/804 805/805/804 -f 804/804/803 801/803/803 806/801/803 -f 801/803/805 802/806/805 807/807/805 -f 803/800/806 801/803/806 807/807/806 -f 800/808/807 803/800/807 807/807/807 -f 803/800/808 800/808/808 808/809/808 -f 805/805/809 804/804/809 808/809/809 -f 802/806/805 805/805/805 809/810/805 -f 807/807/805 802/806/805 809/810/805 -f 800/808/810 807/807/810 809/810/810 -f 808/809/811 800/808/811 809/810/811 -f 805/805/809 808/809/809 809/810/809 -f 806/801/812 803/800/812 810/811/812 -f 804/804/813 806/801/813 810/811/813 -f 803/800/814 808/809/814 810/811/814 -f 810/811/814 808/809/814 811/812/814 -f 808/809/809 804/804/809 811/812/809 -f 804/804/813 810/811/813 811/812/813 -f 801/803/806 803/800/806 812/802/806 -f 806/801/803 801/803/803 812/802/803 -o Cup_hull_33 -v 0.011736 -0.013546 -0.048198 -v 0.004626 -0.020391 0.015036 -v 0.007524 -0.020392 0.007726 -v 0.012262 -0.013282 0.015036 -v 0.012263 -0.020392 -0.048192 -v 0.004626 -0.017231 -0.048198 -v 0.012262 -0.020392 0.015036 -v 0.004626 -0.020391 -0.048198 -v 0.004626 -0.017231 0.014751 -v 0.011999 -0.013282 -0.048192 -v 0.012263 -0.013282 -0.048192 -v 0.011473 -0.013546 0.008289 -v 0.011999 -0.013282 0.015036 -v 0.011473 -0.013546 -0.043420 -v 0.004890 -0.017231 0.015036 -vt 0.000000 0.965446 -vt 0.004503 0.000000 -vt 0.000000 0.034554 +f 802/794/800 798/795/800 803/796/800 +f 796/797/801 795/798/801 797/799/801 +f 795/798/802 796/797/802 798/795/802 +f 797/799/803 795/798/803 798/795/803 +f 794/800/804 796/797/804 799/801/804 +f 796/797/801 797/799/801 799/801/801 +f 797/799/805 794/800/805 799/801/805 +f 796/797/804 794/800/804 800/802/804 +f 798/795/802 796/797/802 800/802/802 +f 794/800/805 797/799/805 801/803/805 +f 797/799/803 798/795/803 801/803/803 +f 800/802/806 794/800/806 802/794/806 +f 801/803/800 798/795/800 802/794/800 +f 794/800/805 801/803/805 802/794/805 +f 798/795/807 800/802/807 803/796/807 +f 800/802/806 802/794/806 803/796/806 +o cup_hull_34 +v 0.008666 -0.027561 0.022524 +v 0.019199 -0.021662 -0.072261 +v 0.019199 -0.032616 -0.072261 +v 0.019199 -0.021662 0.022524 +v 0.008666 -0.027139 -0.072261 +v 0.019199 -0.032616 0.022524 +v 0.008666 -0.032617 -0.072261 +v 0.008666 -0.032617 0.022524 +v 0.017934 -0.022083 0.021688 +v 0.008666 -0.027139 0.021262 +v 0.017934 -0.022083 -0.072261 +v 0.018778 -0.021662 0.022524 +v 0.018778 -0.021662 -0.072261 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000098 +vt 0.000000 1.000000 +vt 1.000000 0.500000 +vt 0.000000 0.000098 +vt 0.000000 0.461531 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.115603 0.379405 -vt 0.000000 0.999902 +vt 0.008811 0.961531 +vt 0.013314 0.500000 +vt 1.000000 0.961531 +vn 0.0000 1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn -0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0001 -1.0000 0.0000 +vn -0.4789 0.8779 0.0000 +vn -0.4470 0.8946 0.0000 +vn -0.4800 0.8763 0.0426 +vn -0.4841 0.8299 0.2772 +vn -0.4470 0.8945 0.0000 +usemtl None +s off +f 815/804/808 805/805/808 816/806/808 +f 806/807/809 805/805/809 807/808/809 +f 805/805/810 806/807/810 808/809/810 +f 806/807/809 807/808/809 809/810/809 +f 807/808/811 804/811/811 809/810/811 +f 804/811/812 808/809/812 810/812/812 +f 808/809/810 806/807/810 810/812/810 +f 806/807/813 809/810/813 810/812/813 +f 810/812/813 809/810/813 811/813/813 +f 809/810/811 804/811/811 811/813/811 +f 804/811/812 810/812/812 811/813/812 +f 812/814/814 808/809/814 813/815/814 +f 808/809/812 804/811/812 813/815/812 +f 805/805/810 808/809/810 814/816/810 +f 808/809/814 812/814/814 814/816/814 +f 814/816/815 812/814/815 815/804/815 +f 807/808/808 805/805/808 815/804/808 +f 804/811/811 807/808/811 815/804/811 +f 812/814/816 813/815/816 815/804/816 +f 813/815/817 804/811/817 815/804/817 +f 805/805/810 814/816/810 816/806/810 +f 814/816/818 815/804/818 816/806/818 +o cup_hull_35 +v 0.024678 -0.032194 0.022524 +v 0.032683 -0.011971 -0.072261 +v 0.032683 -0.023767 -0.072261 +v 0.019199 -0.021243 -0.072261 +v 0.032683 -0.011971 0.022524 +v 0.025941 -0.011973 0.022524 +v 0.019199 -0.032615 -0.072261 +v 0.019199 -0.021243 0.022524 +v 0.032683 -0.023767 0.022524 +v 0.025941 -0.011973 -0.072261 +v 0.019199 -0.032615 0.022524 +v 0.023835 -0.032615 -0.072261 +v 0.030154 -0.027138 -0.072261 +v 0.030154 -0.027138 0.022524 +v 0.027204 -0.030087 -0.072261 +v 0.023835 -0.032615 0.022524 +v 0.032260 -0.024610 0.022524 +v 0.027204 -0.030087 0.022524 +v 0.024678 -0.032194 -0.072261 +v 0.032260 -0.024610 -0.072261 +vt 0.000000 0.387763 +vt 1.000000 0.265296 +vt 1.000000 0.387763 +vt 1.000000 1.000000 +vt 1.000000 0.428585 +vt 1.000000 0.550857 +vt 0.000000 1.000000 vt 0.000000 0.999902 -vt 0.999902 1.000000 +vt 0.000000 0.020362 vt 1.000000 0.000000 -vt 1.000000 0.930991 +vt 0.000000 0.550857 +vt 0.000000 0.428585 +vt 1.000000 0.999902 +vt 0.000000 0.000000 vt 1.000000 0.000000 -vt 0.999902 0.965446 -vt 0.999902 1.000000 -vt 0.106695 0.896535 -vt 0.924432 0.896535 -vn -0.4428 0.7971 0.4104 -vn -0.0001 -1.0000 0.0001 -vn 0.0000 0.0000 1.0000 +vt 0.000000 0.265296 +vt 1.000000 0.122467 +vt 0.000000 0.000000 +vt 0.000000 0.122467 +vt 1.000000 0.020362 +vn 0.7683 -0.6401 0.0000 +vn 0.0000 0.0000 -1.0000 vn 1.0000 0.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.0002 -1.0000 0.0000 -vn 0.0008 -0.0008 -1.0000 -vn -0.0001 -1.0000 -0.0000 +vn -0.0003 1.0000 0.0000 +vn -0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.0000 0.0000 -1.0000 -vn -0.0252 0.0485 -0.9985 -vn 0.0000 1.0000 -0.0000 -vn 0.0118 0.0000 -0.9999 -vn 0.0000 0.0235 -0.9997 -vn -0.4740 0.8805 0.0000 -vn -0.4481 0.8940 0.0000 -vn -0.4722 0.8815 0.0024 -vn -0.4722 0.8815 -0.0034 -vn -0.7321 0.0611 0.6785 +vn -0.8087 0.5882 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.7070 -0.7073 0.0000 +vn 0.4461 -0.8950 0.0000 +vn 0.8940 -0.4480 0.0000 +vn 0.6407 -0.7678 0.0000 usemtl None s off -f 825/813/815 821/814/815 827/815/815 -f 814/816/816 815/817/816 819/818/816 -f 816/819/817 814/816/817 819/818/817 -f 817/820/818 816/819/818 819/818/818 -f 815/817/819 817/820/819 819/818/819 -f 815/817/820 814/816/820 820/821/820 -f 813/822/821 817/820/821 820/821/821 -f 817/820/822 815/817/822 820/821/822 -f 814/816/823 818/823/823 820/821/823 -f 818/823/824 813/822/824 820/821/824 -f 818/823/823 814/816/823 821/814/823 -f 813/822/825 818/823/825 822/824/825 -f 822/824/826 816/819/826 823/825/826 -f 817/820/827 813/822/827 823/825/827 -f 816/819/818 817/820/818 823/825/818 -f 813/822/828 822/824/828 823/825/828 -f 818/823/829 821/814/829 824/826/829 -f 822/824/830 824/826/830 825/813/830 -f 814/816/817 816/819/817 825/813/817 -f 816/819/826 822/824/826 825/813/826 -f 824/826/831 821/814/831 825/813/831 -f 822/824/832 818/823/832 826/827/832 -f 818/823/829 824/826/829 826/827/829 -f 824/826/830 822/824/830 826/827/830 -f 821/814/833 814/816/833 827/815/833 -f 814/816/817 825/813/817 827/815/817 +f 833/817/819 829/818/819 836/819/819 +f 818/820/820 819/821/820 820/822/820 +f 819/821/821 818/820/821 821/823/821 +f 821/823/822 818/820/822 822/824/822 +f 817/825/823 821/823/823 822/824/823 +f 820/822/820 819/821/820 823/826/820 +f 820/822/824 823/826/824 824/827/824 +f 822/824/825 820/822/825 824/827/825 +f 817/825/823 822/824/823 824/827/823 +f 821/823/823 817/825/823 825/828/823 +f 819/821/821 821/823/821 825/828/821 +f 818/820/820 820/822/820 826/829/820 +f 822/824/822 818/820/822 826/829/822 +f 820/822/825 822/824/825 826/829/825 +f 824/827/824 823/826/824 827/830/824 +f 817/825/823 824/827/823 827/830/823 +f 823/826/820 819/821/820 828/831/820 +f 827/830/826 823/826/826 828/831/826 +f 828/831/820 819/821/820 829/818/820 +f 825/828/823 817/825/823 830/832/823 +f 829/818/827 830/832/827 831/833/827 +f 828/831/820 829/818/820 831/833/820 +f 817/825/823 827/830/823 832/834/823 +f 828/831/828 817/825/828 832/834/828 +f 827/830/826 828/831/826 832/834/826 +f 819/821/829 825/828/829 833/817/829 +f 825/828/823 830/832/823 833/817/823 +f 830/832/819 829/818/819 833/817/819 +f 830/832/823 817/825/823 834/835/823 +f 831/833/827 830/832/827 834/835/827 +f 817/825/830 831/833/830 834/835/830 +f 817/825/828 828/831/828 835/836/828 +f 831/833/830 817/825/830 835/836/830 +f 828/831/820 831/833/820 835/836/820 +f 829/818/820 819/821/820 836/819/820 +f 819/821/829 833/817/829 836/819/829 diff --git a/cram_demos/cram_pr2_pick_place_demo/src/demo.lisp b/cram_demos/cram_pr2_pick_place_demo/src/demo.lisp index d439b799dd..210229a600 100644 --- a/cram_demos/cram_pr2_pick_place_demo/src/demo.lisp +++ b/cram_demos/cram_pr2_pick_place_demo/src/demo.lisp @@ -35,11 +35,16 @@ )) (defparameter *object-colors* - '((:spoon . "black") - (:breakfast-cereal . "yellow") - (:milk . "blue") - (:bowl . "red") - (:cup . "red"))) + '((:spoon . "Black") + ;; (:spoon . "Blue") + ;; (:breakfast-cereal . "Yellow") + ;; (:milk . "Blue") + (:bowl . "Red") + (:cup . "Red"))) + +(defparameter *object-materials* + '(;; (:spoon . "Steel") + )) (defparameter *object-grasps* '((:spoon . :top) @@ -48,6 +53,9 @@ (:cup . :top) (:bowl . :top))) +(defparameter *object-arms* + '((:milk . :left))) + (defun park-robot () (cpl:with-failure-handling ((cpl:plan-failure (e) @@ -75,14 +83,15 @@ (type going) (target (desig:a location (pose ?pose)))))))) +(defun start-logging () + (ccl::start-episode)) + +(defun stop-logging () + (ccl::stop-episode)) + (defun initialize () (sb-ext:gc :full t) - ;;(when ccl::*is-logging-enabled* - ;; (setf ccl::*is-client-connected* nil) - ;; (ccl::connect-to-cloud-logger) - ;; (ccl::reset-logged-owl)) - ;; (setf proj-reasoning::*projection-checks-enabled* t) (btr:detach-all-objects (btr:get-robot-object)) @@ -111,7 +120,10 @@ 0.0 (btr:joint-state (btr:get-environment-object) "sink_area_trash_drawer_main_joint") - 0) + 0.0 + (btr:joint-state (btr:get-environment-object) + "kitchen_island_left_upper_drawer_main_joint") + 0.0) (btr-belief::publish-environment-joint-state (btr:joint-states (btr:get-environment-object))) @@ -124,9 +136,6 @@ (defun finalize () ;; (setf proj-reasoning::*projection-reasoning-enabled* nil) - ;;(when ccl::*is-logging-enabled* - ;; (ccl::export-log-to-owl "ease_milestone_2018.owl") - ;; (ccl::export-belief-state-to-owl "ease_milestone_2018_belief.owl")) (sb-ext:gc :full t)) @@ -142,9 +151,6 @@ (park-robot) - ;; (an object - ;; (obj-part "drawer_sinkblock_upper_handle")) - (dolist (?object-type list-of-objects) (let* ((?arm-to-use (cdr (assoc ?object-type *object-grasping-arms*))) @@ -152,13 +158,17 @@ (cdr (assoc ?object-type *object-cad-models*))) (?color (cdr (assoc ?object-type *object-colors*))) + (?material + (cdr (assoc ?object-type *object-materials*))) (?object-to-fetch (desig:an object (type ?object-type) (desig:when ?cad-model (cad-model ?cad-model)) (desig:when ?color - (color ?color))))) + (color ?color)) + (desig:when ?material + (material ?material))))) (cpl:with-failure-handling ((common-fail:high-level-failure (e) diff --git a/cram_demos/cram_pr2_pick_place_demo/src/milestone-projection-demo.lisp b/cram_demos/cram_pr2_pick_place_demo/src/milestone-projection-demo.lisp index 67b5ea2018..53e1db7c83 100644 --- a/cram_demos/cram_pr2_pick_place_demo/src/milestone-projection-demo.lisp +++ b/cram_demos/cram_pr2_pick_place_demo/src/milestone-projection-demo.lisp @@ -30,13 +30,18 @@ (in-package :demo) +;; (setf cram-tf:*tf-broadcasting-enabled* t) + (defparameter *demo-object-spawning-poses* '((:bowl "sink_area_left_middle_drawer_main" - ((0.10 -0.1505 -0.062256) (0 0 -1 0))) + ((0.10 -0.1005 -0.062256) (0 0 -1 0))) + ;; (:cup + ;; "sink_area_left_bottom_drawer_main" + ;; ((0.11 0.12 -0.0547167) (0 0 -1 0))) (:cup - "sink_area_left_bottom_drawer_main" - ((0.11 0.12 -0.0547167) (0 0 -1 0))) + "kitchen_island_left_upper_drawer_main" + ((0.11 0.08 -0.026367) (0 0 -1 0))) (:spoon ;; "oven_area_area_middle_upper_drawer_main" "sink_area_left_upper_drawer_main" @@ -44,7 +49,7 @@ ;; So far only this orientation works (:breakfast-cereal "oven_area_area_right_drawer_board_3_link" - ((0.123 -0.03 0.11) (0.0087786 0.005395 -0.838767 -0.544393))) + ((0.10 -0.03 0.11) (0.0087786 0.005395 -0.838767 -0.544393))) ;; ((:breakfast-cereal . ((1.398 1.490 1.2558) (0 0 0.7071 0.7071))) ;; (:breakfast-cereal . ((1.1 1.49 1.25) (0 0 0.7071 0.7071))) (:milk @@ -54,7 +59,60 @@ ((-0.01 -0.05 0.094) (0 0 0 1))))) -(defparameter *delivery-poses-relative* +(defparameter *delivery-poses-dining-table-relative* + `((:bowl + "dining_area_jokkmokk_table_main" + ((-0.46 -0.012 0.449148565530777d0 ;; 0.7991485595703125d0 + ) + (0.0d0 0.0d0 0.4550555463557553d0 0.8904630535462239d0))) + (:cup + "dining_area_jokkmokk_table_main" + ((-0.283 -0.0975 0.47413769364356995d0 ;; 0.8241376876831055d0 + ) + (0.0d0 0.0d0 0.9542005181967461d0 0.299167797520156d0))) + (:spoon + "dining_area_jokkmokk_table_main" + ((-0.46 -0.2016 0.4052567223707835d0 ;; 0.755256716410319d0 + ) + (0 0 0 1))) + (:milk + "dining_area_jokkmokk_table_main" + ((-0.012 -0.031 0.4862768868605296d0 ;; 0.8362768809000651d0 + ) + (-0.00932157 0.00720728 0.965580536 0.25983724))) + (:breakfast-cereal + "dining_area_jokkmokk_table_main" + ((-0.012 -0.23 0.5004792590936025d0 ;; 0.850479253133138d0 + ) + (-0.0079082 0.00397635 0.08238571 0.9965611543))))) + + +(defparameter *delivery-poses-dining-table-absolute* + `((:bowl . ((-3.368202972412109d0 -0.15089993476867675d0 0.7991479237874349d0) + (3.7803240502398694d-6 + -5.186260023037903d-5 + 0.9513682126998901d0 + 0.30805596709251404d0))) + (:cup . ((-3.2824996948242187d0 0.02729039788246155d0 0.8241376876831055d0) + (-8.372070442419499d-5 + -1.31627733935602d-4 + 0.8862651586532593d0 + -0.46317803859710693d0))) + (:spoon . ((-3.1784092712402346d0 -0.14934446016947428d0 0.755256716410319d0) + (0.02845500223338604d0 + 0.028393128886818886d0 + 0.7164095640182495d0 + 0.696520984172821d0))) + (:milk . ((-3.3491180419921873d0 0.29785102208455405d0 0.8362768809000651d0) + (0 0 1 0))) + (:breakfast-cereal . ((-3.150148 0.298135248819987d0 0.850479253133138d0) + (-0.008403636515140533d0 + -0.002780231647193432d0 + 0.7629306316375732d0 + 0.6464196443557739d0))))) + + +(defparameter *delivery-poses-relative-kitchen-island* `((:bowl "kitchen_island_surface" ((0.24 -0.5 0.0432199478149414d0) @@ -95,13 +153,13 @@ (:breakfast-cereal . ((1.15 -0.5 0.8) (0 0 1 0))))) -(defun attach-object-to-the-world (object-type) - (when *demo-object-spawning-poses* +(defun attach-object-to-the-world (object-type spawning-poses-relative) + (when spawning-poses-relative (btr:attach-object (btr:get-environment-object) (btr:object btr:*current-bullet-world* (intern (format nil "~a-1" object-type) :keyword)) :link (second (find object-type - *demo-object-spawning-poses* + spawning-poses-relative :key #'car))))) (defun make-poses-list-relative (spawning-poses-list) @@ -149,7 +207,8 @@ Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame and returns a list i ;; (btr:simulate btr:*current-bullet-world* 100) objects) - (mapcar #'attach-object-to-the-world object-types)) + (mapcar (alexandria:rcurry #'attach-object-to-the-world spawning-poses-relative) + object-types)) @@ -168,41 +227,54 @@ Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame and returns a list i (dolist (?object-type object-list) (let* ((?deliver-pose (cram-tf:ensure-pose-in-frame (btr:ensure-pose - (cdr (assoc ?object-type *delivery-poses*))) + (cdr (assoc ?object-type + *delivery-poses-dining-table-absolute*))) cram-tf:*fixed-frame*)) (?deliver-location (a location (pose ?deliver-pose))) (?color (cdr (assoc ?object-type *object-colors*))) + (?arm (cdr (assoc ?object-type *object-arms*))) + (?material (cdr (assoc ?object-type *object-materials*))) ;; (?grasp (cdr (assoc ?object-type *object-grasps*))) (?object (an object (type ?object-type) ;; (location ?fetch-location) (desig:when ?color - (color ?color))))) + (color ?color)) + (desig:when ?material + (material ?material))))) (exe:perform (an action (type transporting) (object ?object) (context :table-setting) ;; (grasps (:back :top :front)) - ;; (arms (left right)) + (desig:when ?arm + (arms (?arm))) ;; (desig:when ?grasp ;; (grasp ?grasp)) - ;; (target ?deliver-location) + (target ?deliver-location) ))))) -(defun cleaning-demo (&optional (object-list '(:milk :breakfast-cereal - :bowl :spoon :cup))) +(defun cleaning-demo (&optional (object-list '(:breakfast-cereal :milk + :spoon :cup :bowl))) "Cleans up object to the designated locations by iterating over `object-list' " ;; (setup-for-demo object-list) - (when cram-projection:*projection-environment* + (initialize) + (when (or cram-projection:*projection-environment* + ;; dont want to add dependency on sim PMs, thus this stupid hack + (roslisp:get-param "/base_simulator/sim_frequency" nil)) (spawn-objects-on-fixed-spots :object-types object-list - :spawning-poses-relative *delivery-poses-relative*)) + :spawning-poses-relative *delivery-poses-dining-table-relative*)) (dolist (?object-type object-list) - (exe:perform - (desig:an action - (type transporting) - (object (desig:an object (type ?object-type))) - (context table-cleaning))))) + (let ((?grasps (when (eq ?object-type :cup) + '(:front :back :left-side :right-side)))) + (exe:perform + (desig:an action + (type transporting) + (object (desig:an object (type ?object-type))) + (context table-cleaning) + (desig:when ?grasps + (grasps ?grasps))))))) diff --git a/cram_demos/cram_pr2_shopping_demo/launch/world.launch b/cram_demos/cram_pr2_shopping_demo/launch/world.launch index bc59eca846..4ff8d8c6cf 100644 --- a/cram_demos/cram_pr2_shopping_demo/launch/world.launch +++ b/cram_demos/cram_pr2_shopping_demo/launch/world.launch @@ -6,13 +6,13 @@ - + - + @@ -31,7 +31,7 @@ @@ -57,7 +57,7 @@ diff --git a/cram_demos/cram_projection_demos/cram-projection-demos.asd b/cram_demos/cram_projection_demos/cram-projection-demos.asd index 3878ff9571..998108fb5c 100644 --- a/cram_demos/cram_projection_demos/cram-projection-demos.asd +++ b/cram_demos/cram_projection_demos/cram-projection-demos.asd @@ -45,7 +45,7 @@ cram-executive ; for the plan ;; cram-language ;; cram-projection - ;; cram-utilities + cram-utilities ; for RANDOM-WITH-MINIMUM ;; cram_common cram-tf ; to set the default timeout to a small number, tf utils @@ -73,6 +73,8 @@ cram-pr2-description cram-boxy-description cram-donbot-description + cram-kukabot-description + cram-tiago-description ;; cram-hsrb-description ) :components @@ -81,6 +83,12 @@ ((:file "package") (:file "costmaps" :depends-on ("package")) (:file "setup" :depends-on ("package")) - (:file "assembly-demo" :depends-on ("package" "setup")) - (:file "household-demo" :depends-on ("package" "setup")) - (:file "retail-demo" :depends-on ("package" "setup")))))) + (:file "utils" :depends-on ("package")) + (:file "assembly-demo" :depends-on ("package" "utils")) + (:file "household-demo" :depends-on ("package" "utils")) + (:file "retail-demo" :depends-on ("package" "utils")) + (:file "storage-demo" :depends-on ("package" "utils" + ;; for toy parts colors + "assembly-demo" + ;; for clearing grasps + "household-demo")))))) diff --git a/cram_demos/cram_projection_demos/launch/apartment_tiago.launch b/cram_demos/cram_projection_demos/launch/apartment_tiago.launch new file mode 100644 index 0000000000..a3bc6588a1 --- /dev/null +++ b/cram_demos/cram_projection_demos/launch/apartment_tiago.launch @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/launch/everything.launch b/cram_demos/cram_projection_demos/launch/everything.launch index d6a2f92e9e..fdfb2963cb 100644 --- a/cram_demos/cram_projection_demos/launch/everything.launch +++ b/cram_demos/cram_projection_demos/launch/everything.launch @@ -3,10 +3,14 @@ + + + + @@ -25,14 +29,25 @@ - + + + + + + + + + + @@ -52,13 +67,30 @@ + + + + + + + + + + + + command="$(find xacro)/xacro + '$(find iai_apartment)/urdf/apartment.urdf'"/> @@ -104,7 +136,7 @@ - + diff --git a/cram_demos/cram_projection_demos/launch/household_kukabot.launch b/cram_demos/cram_projection_demos/launch/household_kukabot.launch new file mode 100644 index 0000000000..39f38c9065 --- /dev/null +++ b/cram_demos/cram_projection_demos/launch/household_kukabot.launch @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/launch/household_tiago.launch b/cram_demos/cram_projection_demos/launch/household_tiago.launch new file mode 100644 index 0000000000..9664d86628 --- /dev/null +++ b/cram_demos/cram_projection_demos/launch/household_tiago.launch @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/launch/retail_kukabot.launch b/cram_demos/cram_projection_demos/launch/retail_kukabot.launch new file mode 100644 index 0000000000..e107673e7a --- /dev/null +++ b/cram_demos/cram_projection_demos/launch/retail_kukabot.launch @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/launch/retail_tiago.launch b/cram_demos/cram_projection_demos/launch/retail_tiago.launch new file mode 100644 index 0000000000..fee9077870 --- /dev/null +++ b/cram_demos/cram_projection_demos/launch/retail_tiago.launch @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/package.xml b/cram_demos/cram_projection_demos/package.xml index 8f3b74191c..20a7b67307 100644 --- a/cram_demos/cram_projection_demos/package.xml +++ b/cram_demos/cram_projection_demos/package.xml @@ -46,6 +46,7 @@ cram_pr2_description cram_boxy_description cram_donbot_description + cram_kukabot_description diff --git a/cram_demos/cram_projection_demos/resource/household/cup.obj b/cram_demos/cram_projection_demos/resource/household/cup.obj index 6f38a826b1..5a3e737c4a 100644 --- a/cram_demos/cram_projection_demos/resource/household/cup.obj +++ b/cram_demos/cram_projection_demos/resource/household/cup.obj @@ -1,4111 +1,4142 @@ # Blender v2.83.4 OBJ File: '' # www.blender.org -mtllib cup_33.mtl -o Cup_hull_1 -v 0.014889 0.020425 -0.050166 -v -0.014857 -0.020390 -0.048198 -v -0.015384 -0.020122 -0.048198 -v 0.014889 0.020425 -0.048198 -v 0.019895 -0.015647 -0.050166 -v -0.020386 0.014891 -0.050166 -v -0.015648 0.019893 -0.048198 -v 0.020427 -0.014856 -0.048198 -v -0.015384 -0.020122 -0.050166 -v -0.020390 -0.014856 -0.048198 -v 0.020423 0.014891 -0.050166 -v 0.014893 -0.020390 -0.048198 -v -0.014857 0.020425 -0.050166 -v 0.020423 0.014891 -0.048198 -v 0.014893 -0.020390 -0.050166 -v -0.020390 -0.014856 -0.050166 -v -0.020386 0.014891 -0.048198 -v 0.020427 -0.014856 -0.050166 -v -0.014857 0.020425 -0.048198 -v -0.014857 -0.020390 -0.050166 -v 0.018577 0.017260 -0.048198 -v -0.018808 0.016997 -0.050166 -v 0.016999 -0.018807 -0.048198 -v -0.019072 -0.016702 -0.048198 -v 0.017258 0.018579 -0.050166 -v -0.016702 -0.019071 -0.050166 -v -0.018808 0.016997 -0.048198 -v 0.016999 -0.018807 -0.050166 -v -0.016966 0.018839 -0.050166 -v 0.018840 -0.016966 -0.048198 -v -0.019072 -0.016702 -0.050166 -vt 0.090348 0.032302 -vt 0.032302 0.090348 -vt 0.032302 0.090348 +mtllib cup_35.mtl +o cup_hull_1 +v 0.025088 0.031845 -0.075210 +v -0.023772 -0.032617 -0.072262 +v -0.024616 -0.032189 -0.072262 +v 0.023829 0.032689 -0.072262 +v -0.032198 0.024679 -0.075210 +v 0.024672 -0.032189 -0.075210 +v 0.032683 -0.023763 -0.072262 +v -0.025032 0.031845 -0.072262 +v -0.026726 -0.030507 -0.075210 +v -0.032626 -0.023763 -0.072262 +v 0.032676 0.023835 -0.075210 +v -0.023772 0.032689 -0.075210 +v 0.032676 0.023835 -0.072262 +v 0.023829 -0.032617 -0.072262 +v 0.032683 -0.023763 -0.075210 +v -0.032626 0.023835 -0.072262 +v -0.032626 -0.023763 -0.075210 +v -0.023772 -0.032617 -0.075210 +v -0.023772 0.032689 -0.072262 +v 0.023829 0.032689 -0.075210 +v 0.023829 -0.032617 -0.075210 +v -0.032626 0.023835 -0.075210 +v 0.030145 -0.027132 -0.072262 +v 0.029301 0.028048 -0.072262 +v -0.030517 -0.026704 -0.072262 +v -0.030088 0.027211 -0.075210 +v -0.030088 0.027211 -0.072262 +v 0.030145 -0.027132 -0.075210 +v 0.029301 0.028048 -0.075210 +v 0.027198 -0.030085 -0.072262 +v -0.027141 0.030158 -0.075210 +v -0.030517 -0.026704 -0.075210 +vt 0.032302 0.090544 +vt 0.000000 0.135572 +vt 0.032302 0.090544 vt 0.122651 0.006558 vt 0.135572 0.000000 -vt 0.864330 1.000000 -vt 0.864330 1.000000 -vt 0.986981 0.116190 -vt 0.000098 0.864428 -vt 0.116190 0.986981 +vt 0.864428 1.000000 +vt 0.006558 0.877349 +vt 0.883712 0.987079 +vt 0.877349 0.006558 vt 1.000000 0.135572 -vt 0.122651 0.006558 +vt 0.116288 0.987079 +vt 0.090348 0.032302 vt 0.000000 0.135572 vt 0.999902 0.864428 -vt 0.864428 0.000000 vt 0.135572 1.000000 vt 0.999902 0.864428 vt 0.864428 0.000000 -vt 0.000000 0.135572 -vt 0.000098 0.864428 vt 1.000000 0.135572 -vt 0.135572 1.000000 +vt 0.000000 0.864428 vt 0.135572 0.000000 -vt 0.954679 0.922475 -vt 0.038763 0.916014 -vt 0.916014 0.038763 -vt 0.922377 0.954777 -vt 0.038763 0.916014 +vt 0.135572 1.000000 +vt 0.864428 1.000000 +vt 0.864428 0.000000 +vt 0.000000 0.864428 +vt 0.961139 0.083986 +vt 0.948218 0.928935 +vt 0.038861 0.916112 +vt 0.038861 0.916112 +vt 0.961139 0.083986 +vt 0.948218 0.928935 vt 0.916014 0.038763 -vt 0.083888 0.961139 -vt 0.961139 0.083888 -vn -0.7071 -0.7071 0.0000 -vn 0.0000 0.0000 1.0000 +vt 0.083986 0.961237 +vn -0.8125 -0.5829 0.0000 +vn -0.0000 0.0000 1.0000 vn -0.0000 0.0000 -1.0000 -vn -0.4526 -0.8917 0.0000 -vn 0.0000 1.0000 0.0000 vn 1.0000 0.0001 0.0000 +vn -1.0000 0.0000 0.0000 +vn -0.4526 -0.8917 0.0000 +vn -0.5805 -0.8128 -0.0481 vn 0.0000 -1.0000 0.0000 -vn -1.0000 0.0001 0.0000 -vn 0.8301 -0.5576 0.0000 -vn -0.5576 0.8301 0.0000 -vn 0.7888 0.6146 0.0000 -vn -0.8002 0.5998 0.0000 -vn 0.6007 -0.7995 0.0000 -vn -0.8137 -0.5813 0.0000 -vn 0.6146 0.7889 0.0000 -vn 0.6495 0.7570 0.0720 -vn 0.7569 0.6495 -0.0720 -vn -0.6232 -0.7820 0.0000 -vn -0.6786 -0.7317 0.0640 -vn -0.6007 0.7990 -0.0258 -vn -0.6745 0.7360 0.0575 +vn 0.0000 1.0000 0.0000 +vn -0.5566 0.8308 0.0000 +vn 0.5566 0.8308 0.0000 +vn 0.4526 -0.8917 0.0000 +vn -0.8917 0.4526 0.0000 +vn 0.7987 -0.6017 0.0000 +vn 0.6457 0.7614 0.0579 +vn 0.7804 0.6253 0.0000 +vn -0.6792 -0.7307 0.0693 +vn -0.7980 0.6000 0.0558 +vn -0.7682 0.6402 0.0000 +vn 0.6695 0.7428 0.0000 +vn 0.5998 -0.7982 0.0557 +vn 0.6775 -0.7333 -0.0572 +vn 0.7079 -0.7064 0.0000 +vn -0.6005 0.7992 -0.0278 +vn -0.6744 0.7358 0.0614 vn -0.7071 0.7071 0.0000 -vn 0.7990 -0.6008 0.0258 -vn 0.7360 -0.6746 -0.0575 -vn 0.7071 -0.7071 0.0000 +vn -0.7083 -0.7059 0.0000 usemtl None s off -f 26/1/1 24/2/1 31/3/1 +f 25/1/1 17/2/1 32/3/1 f 3/4/2 2/5/2 4/6/2 -f 1/7/3 5/8/3 6/9/3 -f 3/4/2 4/6/2 7/10/2 -f 4/6/2 2/5/2 8/11/2 -f 2/5/4 3/4/4 9/12/4 -f 6/9/3 5/8/3 9/12/3 -f 3/4/2 7/10/2 10/13/2 -f 5/8/3 1/7/3 11/14/3 -f 8/11/2 2/5/2 12/15/2 -f 4/6/5 1/7/5 13/16/5 -f 1/7/3 6/9/3 13/16/3 -f 4/6/2 8/11/2 14/17/2 -f 8/11/6 11/14/6 14/17/6 -f 9/12/3 5/8/3 15/18/3 -f 12/15/7 2/5/7 15/18/7 -f 6/9/3 9/12/3 16/19/3 -f 10/13/8 6/9/8 16/19/8 -f 6/9/8 10/13/8 17/20/8 -f 10/13/2 7/10/2 17/20/2 -f 8/11/9 5/8/9 18/21/9 -f 5/8/3 11/14/3 18/21/3 -f 11/14/6 8/11/6 18/21/6 -f 7/10/2 4/6/2 19/22/2 -f 4/6/5 13/16/5 19/22/5 -f 13/16/10 7/10/10 19/22/10 -f 2/5/4 9/12/4 20/23/4 -f 15/18/7 2/5/7 20/23/7 -f 9/12/3 15/18/3 20/23/3 -f 4/6/2 14/17/2 21/24/2 -f 14/17/11 11/14/11 21/24/11 -f 13/16/3 6/9/3 22/25/3 -f 6/9/12 17/20/12 22/25/12 -f 8/11/2 12/15/2 23/26/2 -f 12/15/13 15/18/13 23/26/13 -f 3/4/2 10/13/2 24/2/2 -f 10/13/14 16/19/14 24/2/14 -f 1/7/15 4/6/15 25/27/15 -f 11/14/3 1/7/3 25/27/3 -f 4/6/16 21/24/16 25/27/16 -f 21/24/17 11/14/17 25/27/17 -f 9/12/18 3/4/18 26/1/18 -f 16/19/3 9/12/3 26/1/3 -f 3/4/19 24/2/19 26/1/19 -f 17/20/2 7/10/2 27/28/2 -f 22/25/12 17/20/12 27/28/12 -f 15/18/3 5/8/3 28/29/3 -f 23/26/13 15/18/13 28/29/13 -f 7/10/20 13/16/20 29/30/20 -f 13/16/3 22/25/3 29/30/3 -f 27/28/21 7/10/21 29/30/21 -f 22/25/22 27/28/22 29/30/22 -f 5/8/23 8/11/23 30/31/23 -f 8/11/2 23/26/2 30/31/2 -f 28/29/24 5/8/24 30/31/24 -f 23/26/25 28/29/25 30/31/25 -f 24/2/14 16/19/14 31/3/14 -f 16/19/3 26/1/3 31/3/3 -o Cup_hull_2 -v 0.020427 0.005943 -0.048198 -v 0.013054 0.012263 0.015036 -v 0.013317 0.011736 0.013909 -v 0.020427 0.012526 0.015036 -v 0.013054 0.012526 -0.048198 -v 0.017003 0.005943 0.015036 -v 0.020427 0.012526 -0.048198 -v 0.016740 0.006206 -0.048198 -v 0.020427 0.005943 0.015036 -v 0.013054 0.012526 0.015036 -v 0.013317 0.011736 -0.048198 -v 0.017003 0.005943 -0.048198 -v 0.016740 0.006206 0.015036 -v 0.013054 0.012263 -0.048198 -vt 1.000000 0.000000 -vt 1.000000 0.035732 +f 5/7/3 1/8/3 6/9/3 +f 4/6/2 2/5/2 7/10/2 +f 3/4/2 4/6/2 8/11/2 +f 5/7/3 6/9/3 9/12/3 +f 3/4/2 8/11/2 10/13/2 +f 6/9/3 1/8/3 11/14/3 +f 1/8/3 5/7/3 12/15/3 +f 4/6/2 7/10/2 13/16/2 +f 7/10/4 11/14/4 13/16/4 +f 7/10/2 2/5/2 14/17/2 +f 6/9/3 11/14/3 15/18/3 +f 11/14/4 7/10/4 15/18/4 +f 10/13/2 8/11/2 16/19/2 +f 10/13/5 16/19/5 17/2/5 +f 5/7/3 9/12/3 17/2/3 +f 2/5/6 3/4/6 18/20/6 +f 3/4/7 9/12/7 18/20/7 +f 9/12/3 6/9/3 18/20/3 +f 14/17/8 2/5/8 18/20/8 +f 8/11/2 4/6/2 19/21/2 +f 4/6/9 12/15/9 19/21/9 +f 12/15/10 8/11/10 19/21/10 +f 4/6/11 1/8/11 20/22/11 +f 1/8/3 12/15/3 20/22/3 +f 12/15/9 4/6/9 20/22/9 +f 6/9/12 14/17/12 21/23/12 +f 18/20/3 6/9/3 21/23/3 +f 14/17/8 18/20/8 21/23/8 +f 16/19/13 5/7/13 22/24/13 +f 17/2/5 16/19/5 22/24/5 +f 5/7/3 17/2/3 22/24/3 +f 7/10/2 14/17/2 23/25/2 +f 15/18/14 7/10/14 23/25/14 +f 1/8/15 4/6/15 24/26/15 +f 4/6/2 13/16/2 24/26/2 +f 13/16/16 11/14/16 24/26/16 +f 9/12/17 3/4/17 25/1/17 +f 3/4/2 10/13/2 25/1/2 +f 10/13/1 17/2/1 25/1/1 +f 12/15/3 5/7/3 26/27/3 +f 5/7/18 16/19/18 27/28/18 +f 16/19/2 8/11/2 27/28/2 +f 26/27/19 5/7/19 27/28/19 +f 6/9/3 15/18/3 28/29/3 +f 15/18/14 23/25/14 28/29/14 +f 11/14/3 1/8/3 29/30/3 +f 1/8/20 24/26/20 29/30/20 +f 24/26/16 11/14/16 29/30/16 +f 14/17/21 6/9/21 30/31/21 +f 23/25/2 14/17/2 30/31/2 +f 6/9/22 28/29/22 30/31/22 +f 28/29/23 23/25/23 30/31/23 +f 8/11/24 12/15/24 31/32/24 +f 12/15/3 26/27/3 31/32/3 +f 27/28/25 8/11/25 31/32/25 +f 26/27/26 27/28/26 31/32/26 +f 17/2/3 9/12/3 32/3/3 +f 9/12/27 25/1/27 32/3/27 +o cup_hull_2 +v 0.020042 0.020472 0.022524 +v 0.025940 0.020894 -0.072261 +v 0.025940 0.012889 -0.072261 +v 0.020042 0.020894 -0.072261 +v 0.025940 0.020894 0.022524 +v 0.025520 0.012889 0.022524 +v 0.025520 0.012889 -0.072261 +v 0.025940 0.012889 0.022524 +v 0.020042 0.020894 0.022524 +v 0.020042 0.020472 -0.072261 vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 0.000000 0.535683 +vt 0.000000 0.947240 +vt 1.000000 0.947240 vt 1.000000 1.000000 +vt 1.000000 0.000000 vt 1.000000 1.000000 -vt 1.000000 0.499951 vt 0.000000 1.000000 vt 0.000000 0.000000 -vt 0.017815 0.035732 -vt 1.000000 0.535683 -vt 0.000000 0.499951 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vn -0.8107 -0.5855 0.0000 vn 0.0000 0.0000 -1.0000 -vn -0.0000 0.0000 1.0000 vn 1.0000 0.0000 0.0000 vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn 0.0000 -1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.8945 -0.4470 0.0000 -vn -0.8503 -0.5263 0.0000 -vn -0.7073 -0.7069 0.0000 -vn -0.8534 -0.5194 0.0435 usemtl None s off -f 36/32/26 42/33/26 45/34/26 -f 35/35/27 33/36/27 37/37/27 -f 35/35/28 32/38/28 38/39/28 -f 32/38/26 36/32/26 38/39/26 -f 36/32/29 35/35/29 38/39/29 -f 36/32/26 32/38/26 39/40/26 -f 32/38/28 35/35/28 40/41/28 -f 35/35/27 37/37/27 40/41/27 -f 37/37/30 32/38/30 40/41/30 -f 33/36/27 35/35/27 41/42/27 -f 35/35/29 36/32/29 41/42/29 -f 36/32/31 33/36/31 41/42/31 -f 34/43/32 33/36/32 42/33/32 -f 36/32/26 39/40/26 42/33/26 -f 39/40/33 34/43/33 42/33/33 -f 32/38/30 37/37/30 43/44/30 -f 39/40/26 32/38/26 43/44/26 -f 37/37/34 39/40/34 43/44/34 -f 33/36/35 34/43/35 44/45/35 -f 37/37/27 33/36/27 44/45/27 -f 34/43/33 39/40/33 44/45/33 -f 39/40/34 37/37/34 44/45/34 -f 33/36/31 36/32/31 45/34/31 -f 42/33/32 33/36/32 45/34/32 -o Cup_hull_3 -v -0.012229 0.013316 -0.048198 -v -0.020392 0.007259 0.015036 -v -0.016442 0.007259 0.015036 -v -0.020392 0.013316 0.015036 -v -0.020392 0.007259 -0.048198 -v -0.020392 0.013316 -0.048198 -v -0.012229 0.013316 0.015036 -v -0.016442 0.007259 -0.048198 -v -0.012229 0.013053 0.015036 -v -0.012229 0.013053 -0.048198 -v -0.016179 0.007523 -0.048198 -v -0.016179 0.007523 0.015036 -vt 1.000000 0.516104 +f 39/33/28 33/34/28 42/35/28 +f 34/36/29 35/37/29 36/38/29 +f 35/37/30 34/36/30 37/39/30 +f 34/36/31 36/38/31 37/39/31 +f 37/39/32 33/34/32 38/40/32 +f 36/38/29 35/37/29 39/33/29 +f 35/37/33 38/40/33 39/33/33 +f 38/40/28 33/34/28 39/33/28 +f 35/37/30 37/39/30 40/41/30 +f 38/40/33 35/37/33 40/41/33 +f 37/39/32 38/40/32 40/41/32 +f 36/38/34 33/34/34 41/42/34 +f 33/34/32 37/39/32 41/42/32 +f 37/39/31 36/38/31 41/42/31 +f 33/34/34 36/38/34 42/35/34 +f 36/38/29 39/33/29 42/35/29 +o cup_hull_3 +v -0.025885 0.012047 0.022524 +v -0.024621 0.021316 -0.072261 +v -0.019565 0.021315 -0.072261 +v -0.024199 0.021316 0.022524 +v -0.026306 0.012047 -0.072261 +v -0.019565 0.020893 0.022524 +v -0.026306 0.021316 0.022524 +v -0.026306 0.021316 -0.072261 +v -0.025885 0.012047 -0.072261 +v -0.026306 0.012047 0.022524 +v -0.019565 0.020893 -0.072261 +v -0.019565 0.021315 0.022524 vt 0.000000 1.000000 -vt 0.000000 0.516104 -vt 0.000000 0.000000 -vt 0.000000 0.483896 -vt 0.000000 0.000000 -vt 1.000000 0.000000 +vt 0.000000 0.954385 +vt 0.000000 0.999902 +vt 1.000000 0.999902 vt 1.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 1.000000 0.483896 -vt 1.000000 1.000000 -vn 0.8137 -0.5813 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn 0.0001 1.0000 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn 0.7084 -0.7059 0.0000 -vn 0.0001 0.0000 -1.0000 -usemtl None -s off -f 56/46/36 54/47/36 57/48/36 -f 47/49/37 48/50/37 49/51/37 -f 48/50/38 47/49/38 50/52/38 -f 47/49/39 49/51/39 50/52/39 -f 49/51/40 46/53/40 51/54/40 -f 46/53/41 50/52/41 51/54/41 -f 50/52/39 49/51/39 51/54/39 -f 49/51/37 48/50/37 52/55/37 -f 46/53/40 49/51/40 52/55/40 -f 50/52/41 46/53/41 53/56/41 -f 48/50/38 50/52/38 53/56/38 -f 46/53/42 52/55/42 54/47/42 -f 52/55/37 48/50/37 54/47/37 -f 53/56/41 46/53/41 55/57/41 -f 46/53/42 54/47/42 55/57/42 -f 48/50/43 53/56/43 56/46/43 -f 53/56/44 55/57/44 56/46/44 -f 55/57/36 54/47/36 56/46/36 -f 54/47/37 48/50/37 57/48/37 -f 48/50/43 56/46/43 57/48/43 -o Cup_hull_4 -v 0.017003 0.005679 0.015036 -v 0.020427 0.005943 -0.048198 -v 0.020427 -0.000377 -0.048198 -v 0.017003 0.005943 -0.048198 -v 0.020427 0.005943 0.015036 -v 0.018057 -0.000377 0.015036 -v 0.018057 -0.000377 -0.048198 -v 0.020427 -0.000377 0.015036 -v 0.017003 0.005943 0.015036 -v 0.017003 0.005415 -0.048198 -v 0.017003 0.005415 0.014751 -vt 1.000000 0.916504 vt 0.000000 0.000000 -vt 0.004503 0.916504 -vt 1.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 vt 0.000000 1.000000 -vt 0.000000 0.958203 +vt 1.000000 1.000000 vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.000000 1.000000 -vn -0.9839 -0.1790 0.0000 +vt 1.000000 0.954385 +vn 0.0000 0.0000 1.0000 +vn 0.0002 1.0000 -0.0000 vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 vn 0.0000 1.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.0001 0.0000 -1.0000 -vn -0.9730 -0.1693 0.1567 +vn 0.0000 -1.0000 0.0000 +vn 0.8137 -0.5813 0.0000 +vn 1.0000 0.0000 0.0000 usemtl None s off -f 67/58/45 63/59/45 68/60/45 -f 59/61/46 60/62/46 61/63/46 -f 60/62/47 59/61/47 62/64/47 -f 59/61/48 61/63/48 62/64/48 -f 62/64/49 58/65/49 63/59/49 -f 61/63/46 60/62/46 64/66/46 -f 60/62/50 63/59/50 64/66/50 -f 60/62/47 62/64/47 65/67/47 -f 63/59/50 60/62/50 65/67/50 -f 62/64/49 63/59/49 65/67/49 -f 61/63/51 58/65/51 66/68/51 -f 58/65/49 62/64/49 66/68/49 -f 62/64/48 61/63/48 66/68/48 -f 58/65/51 61/63/51 67/58/51 -f 61/63/52 64/66/52 67/58/52 -f 64/66/45 63/59/45 67/58/45 -f 63/59/53 58/65/53 68/60/53 -f 58/65/51 67/58/51 68/60/51 -o Cup_hull_5 -v -0.002748 -0.025132 0.032181 -v -0.013281 -0.021446 0.050166 -v -0.013017 -0.021708 0.050166 -v 0.000413 -0.024341 0.050166 -v -0.012753 -0.018548 0.032181 -v 0.000413 -0.022761 0.032181 -v -0.013017 -0.021708 0.032181 -v -0.006961 -0.024342 0.050166 -v -0.012753 -0.020392 0.050166 -v 0.000413 -0.025132 0.050166 -v -0.009330 -0.023552 0.032181 -v 0.000413 -0.025132 0.032181 -v 0.000413 -0.024078 0.048477 -v -0.002485 -0.025132 0.050166 -v -0.013281 -0.018548 0.033306 -v -0.005909 -0.024605 0.032181 -v -0.009856 -0.023288 0.050166 -v 0.000413 -0.022761 0.033306 -v -0.013281 -0.021446 0.032181 -v -0.004591 -0.024868 0.050166 -v -0.013017 -0.018548 0.033306 -v -0.013281 -0.020392 0.050166 -v -0.006961 -0.024342 0.034992 -v -0.004591 -0.024868 0.032181 -v -0.008540 -0.023814 0.050166 -v -0.012753 -0.018548 0.032462 -vt 1.000000 0.038567 -vt 0.937451 0.019284 -vt 0.984338 0.038567 -vt 0.000000 0.000000 -vt 0.000000 0.019284 +f 46/43/35 48/44/35 54/45/35 +f 45/46/36 44/47/36 46/43/36 +f 44/47/37 45/46/37 47/48/37 +f 46/43/35 43/49/35 48/44/35 +f 46/43/38 44/47/38 49/50/38 +f 43/49/35 46/43/35 49/50/35 +f 47/48/39 49/50/39 50/51/39 +f 44/47/37 47/48/37 50/51/37 +f 49/50/38 44/47/38 50/51/38 +f 43/49/40 47/48/40 51/52/40 +f 47/48/37 45/46/37 51/52/37 +f 48/44/41 43/49/41 51/52/41 +f 47/48/40 43/49/40 52/53/40 +f 43/49/35 49/50/35 52/53/35 +f 49/50/39 47/48/39 52/53/39 +f 45/46/42 48/44/42 53/54/42 +f 51/52/37 45/46/37 53/54/37 +f 48/44/41 51/52/41 53/54/41 +f 45/46/36 46/43/36 54/45/36 +f 48/44/42 45/46/42 54/45/42 +o cup_hull_4 +v 0.025941 0.012045 0.022524 +v 0.032261 0.020894 -0.072261 +v 0.027627 0.020894 -0.072261 +v 0.028891 0.000670 -0.072261 +v 0.032683 0.000670 0.022524 +v 0.032683 0.020894 0.022524 +v 0.032683 0.000670 -0.072252 +v 0.025941 0.020892 0.022524 +v 0.025941 0.012045 -0.072261 +v 0.028891 0.000670 0.022524 +v 0.025941 0.020892 -0.072261 +v 0.032683 0.020894 -0.072252 vt 0.000000 1.000000 -vt 1.000000 0.769186 +vt 0.999902 0.000000 +vt 0.999902 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.019284 -vt 0.000000 0.461531 -vt 0.000000 0.038567 -vt 0.000000 1.000000 -vt 1.000000 0.288567 vt 1.000000 1.000000 -vt 0.093872 1.000000 -vt 0.000000 0.788371 -vt 1.000000 0.538371 -vt 0.000000 0.250098 -vt 0.937451 1.000000 vt 1.000000 0.000000 -vt 0.937451 0.000000 -vt 0.000000 0.634593 +vt 0.000000 0.562451 vt 0.000000 0.000000 -vt 0.843677 0.461531 -vt 1.000000 0.634593 -vt 0.000000 0.346222 +vt 0.000000 0.999902 +vt 1.000000 0.562451 +vt 0.000000 0.000000 +vt 1.000000 0.999902 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 1.0000 0.0000 vn 0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn -0.7047 -0.7095 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.4471 -0.8945 0.0000 +vn 0.0024 -0.0004 -1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.2842 0.9474 0.1475 -vn -0.4470 -0.8945 0.0000 -vn 0.3048 0.9524 0.0000 +vn -0.0003 1.0000 0.0000 +vn -0.9680 -0.2510 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.8931 0.1628 -0.4193 -vn -0.1242 -0.9923 0.0018 -vn -0.2169 -0.9762 0.0016 -vn 0.2801 0.9547 0.1000 -vn 0.0000 0.9941 0.1087 -vn -0.3164 -0.9486 0.0000 -vn -0.2941 -0.9555 -0.0207 -vn -0.2424 -0.9702 0.0000 -vn -0.1416 -0.9899 0.0000 -vn -0.1962 -0.9806 0.0000 -vn -0.3167 -0.9485 0.0000 -vn -0.3714 -0.9285 0.0027 -vn 0.2990 0.9507 0.0825 -vn 0.2898 0.9528 0.0907 +vn -0.0012 1.0000 0.0000 +vn 0.0220 0.0000 -0.9998 usemtl None s off -f 73/69/54 89/70/54 94/71/54 -f 70/72/55 71/73/55 72/74/55 -f 69/75/56 73/69/56 74/76/56 -f 71/73/57 70/72/57 75/77/57 -f 73/69/56 69/75/56 75/77/56 -f 72/74/55 71/73/55 76/78/55 -f 70/72/55 72/74/55 77/79/55 -f 74/76/58 72/74/58 78/80/58 -f 72/74/55 76/78/55 78/80/55 -f 75/77/56 69/75/56 79/81/56 -f 71/73/59 75/77/59 79/81/59 -f 69/75/56 74/76/56 80/82/56 -f 78/80/60 69/75/60 80/82/60 -f 74/76/58 78/80/58 80/82/58 -f 72/74/58 74/76/58 81/83/58 -f 77/79/61 72/74/61 81/83/61 -f 69/75/60 78/80/60 82/84/60 -f 78/80/55 76/78/55 82/84/55 -f 79/81/56 69/75/56 84/85/56 -f 76/78/55 71/73/55 85/86/55 -f 71/73/62 79/81/62 85/86/62 -f 74/76/63 73/69/63 86/87/63 -f 81/83/58 74/76/58 86/87/58 -f 75/77/57 70/72/57 87/88/57 -f 73/69/56 75/77/56 87/88/56 -f 70/72/64 83/89/64 87/88/64 -f 83/89/65 73/69/65 87/88/65 -f 69/75/66 82/84/66 88/90/66 -f 82/84/55 76/78/55 88/90/55 -f 76/78/67 84/85/67 88/90/67 -f 77/79/68 81/83/68 89/70/68 -f 73/69/54 83/89/54 89/70/54 -f 83/89/69 77/79/69 89/70/69 -f 70/72/55 77/79/55 90/91/55 -f 83/89/64 70/72/64 90/91/64 -f 77/79/69 83/89/69 90/91/69 -f 76/78/70 79/81/70 91/92/70 -f 79/81/71 84/85/71 91/92/71 -f 84/85/72 76/78/72 91/92/72 -f 84/85/56 69/75/56 92/93/56 -f 69/75/73 88/90/73 92/93/73 -f 88/90/74 84/85/74 92/93/74 -f 79/81/75 76/78/75 93/94/75 -f 76/78/55 85/86/55 93/94/55 -f 85/86/76 79/81/76 93/94/76 -f 86/87/63 73/69/63 94/71/63 -f 81/83/77 86/87/77 94/71/77 -f 89/70/78 81/83/78 94/71/78 -o Cup_hull_6 -v -0.004591 -0.024868 0.018410 -v -0.013281 -0.021443 0.032177 -v -0.013017 -0.021707 0.032177 -v 0.000413 -0.022497 0.031895 -v -0.013017 -0.012229 0.015037 -v 0.000413 -0.018023 0.015037 -v -0.013281 -0.020390 0.015037 -v -0.013281 -0.018286 0.032177 -v 0.000413 -0.025130 0.032177 -v 0.000413 -0.024868 0.017286 -v -0.005909 -0.024605 0.032177 -v -0.009330 -0.023550 0.018410 -v -0.013017 -0.012756 0.017286 -v 0.000413 -0.020654 0.015037 -v 0.000413 -0.018548 0.018130 -v -0.013017 -0.021707 0.018130 -v -0.013281 -0.012229 0.015037 -v -0.009330 -0.023550 0.032177 -v -0.001695 -0.024341 0.016724 -v -0.002485 -0.025130 0.018410 -v -0.002485 -0.025130 0.032177 -v -0.005382 -0.024341 0.017286 -v -0.013017 -0.018286 0.032177 -v 0.000413 -0.025130 0.017848 -v -0.007751 -0.024077 0.018130 -v 0.000413 -0.022761 0.032177 -v 0.000413 -0.018023 0.015881 -v -0.013017 -0.012493 0.016444 -v -0.008804 -0.020654 0.015037 -v -0.013281 -0.021443 0.017848 -v -0.009068 -0.023288 0.017286 -v -0.005909 -0.024605 0.018410 -v -0.004591 -0.024868 0.032177 -v -0.002485 -0.024604 0.017006 -v -0.010910 -0.022761 0.017848 -v 0.000413 -0.024341 0.016724 -v -0.007751 -0.024077 0.032177 -vt 0.000000 0.288567 -vt 0.819561 0.403876 -vt 0.000000 0.403876 -vt 1.000000 0.019284 +f 60/55/43 61/56/43 66/57/43 +f 57/58/44 56/59/44 58/60/44 +f 56/59/45 57/58/45 60/55/45 +f 55/61/46 59/62/46 60/55/46 +f 58/60/47 56/59/47 61/56/47 +f 59/62/48 58/60/48 61/56/48 +f 60/55/43 59/62/43 61/56/43 +f 55/61/46 60/55/46 62/63/46 +f 60/55/49 57/58/49 62/63/49 +f 57/58/44 58/60/44 63/64/44 +f 58/60/50 55/61/50 63/64/50 +f 55/61/51 62/63/51 63/64/51 +f 55/61/50 58/60/50 64/65/50 +f 59/62/46 55/61/46 64/65/46 +f 58/60/48 59/62/48 64/65/48 +f 62/63/52 57/58/52 65/66/52 +f 57/58/44 63/64/44 65/66/44 +f 63/64/51 62/63/51 65/66/51 +f 56/59/45 60/55/45 66/57/45 +f 61/56/53 56/59/53 66/57/53 +o cup_hull_5 +v -0.013664 -0.038092 0.027187 +v -0.016193 -0.023770 0.022542 +v -0.016615 -0.023770 0.022542 +v -0.015771 -0.035143 0.075200 +v -0.004396 -0.028404 0.023393 +v -0.004396 -0.038515 0.075200 +v -0.004396 -0.039780 0.026341 +v -0.016615 -0.036829 0.075200 +v -0.016615 -0.032615 0.022542 +v -0.007346 -0.039780 0.075200 +v -0.016615 -0.036829 0.026764 +v -0.004396 -0.033038 0.022542 +v -0.016193 -0.023770 0.023815 +v -0.007346 -0.039780 0.027187 +v -0.011137 -0.038935 0.075200 +v -0.004396 -0.039780 0.075200 +v -0.016615 -0.035143 0.075200 +v -0.007346 -0.038935 0.025501 +v -0.014929 -0.037672 0.075200 +v -0.011137 -0.038935 0.027604 +v -0.004396 -0.028404 0.022542 +v -0.012401 -0.037672 0.025501 +v -0.004396 -0.038515 0.025078 +v -0.009453 -0.039358 0.075200 +v -0.014929 -0.037672 0.027604 +v -0.014508 -0.033036 0.022542 +v -0.009452 -0.039357 0.027604 +v -0.016615 -0.036407 0.025919 +vt 1.000000 0.447533 +vt 0.943808 0.131656 +vt 0.935879 0.210650 +vt 0.983847 0.710552 +vt 0.000000 0.078994 +vt 0.927851 0.000000 +vt 0.000000 0.289644 +vt 0.000000 0.184319 +vt 1.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.000000 vt 0.000000 0.000000 +vt 0.919824 0.184319 +vt 1.000000 0.421104 +vt 0.975820 1.000000 +vt 0.911796 0.000000 +vt 0.000000 0.052760 vt 0.000000 0.000000 -vt 0.000000 0.019284 -vt 0.016448 1.000000 -vt 0.000000 1.000000 -vt 0.868807 1.000000 -vt 0.000000 0.538371 -vt 1.000000 1.000000 -vt 0.819561 1.000000 -vt 0.819561 0.019284 -vt 1.000000 0.000000 -vt 0.868807 0.019284 -vt 0.000000 0.788371 -vt 0.803211 0.788371 -vt 0.803211 0.634593 -vt 0.000000 0.019284 -vt 0.836009 1.000000 -vt 0.803211 0.288567 -vt 0.000000 1.000000 -vt 0.950754 1.000000 -vt 0.917956 0.019284 -vt 1.000000 0.326938 -vt 0.901606 0.846124 -vt 0.836009 0.000000 -vt 0.868807 0.576840 -vt 0.868807 0.307655 -vt 0.803211 0.538371 -vt 0.000000 0.634593 -vt 0.885158 0.788371 -vt 0.836009 0.173160 -vt 0.901606 1.000000 -vn -0.3164 -0.9486 0.0000 +vt 0.000000 0.289644 +vt 0.943808 0.052760 +vt 0.000000 0.131656 +vt 0.903867 0.052760 +vt 0.911796 0.105423 +vt 1.000000 0.710552 +vt 0.951836 0.078994 +vt 0.000000 0.026331 +vt 0.903867 0.131656 +vt 1.000000 0.421202 +vt 0.903867 0.026429 +vn -0.2639 -0.6414 -0.7204 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn 0.0000 0.0000 -1.0000 vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 1.0000 -0.0000 0.0000 -vn -0.7070 -0.7072 0.0000 -vn -0.6912 0.6814 0.2408 +vn 0.0000 1.0000 0.0000 +vn 0.3656 0.9308 0.0000 +vn 0.3653 0.9137 0.1783 +vn 0.2782 0.9383 0.2054 vn 0.0000 -1.0000 0.0000 -vn -0.1238 -0.9923 0.0000 -vn 0.2885 0.8976 0.3333 -vn 0.0000 0.9375 0.3481 -vn 0.2363 0.7093 0.6641 -vn 0.3961 0.9182 0.0000 -vn 0.3797 0.9008 0.2105 -vn 0.3458 0.8958 0.2794 -vn 0.3704 0.8929 0.2561 -vn 0.0000 0.9828 0.1845 -vn -0.5337 0.8073 0.2518 -vn 0.3813 0.9086 0.1706 -vn -0.0270 -0.4585 -0.8883 -vn 0.0000 -0.4160 -0.9094 -vn -0.4896 -0.8165 -0.3060 -vn -0.2225 -0.7788 -0.5865 -vn -0.2486 -0.8701 -0.4256 -vn -0.1955 -0.9807 0.0000 -vn -0.1861 -0.9335 -0.3064 -vn -0.2756 -0.9613 0.0000 -vn -0.2162 -0.9231 -0.3180 -vn -0.0868 -0.5956 -0.7986 -vn -0.0006 -0.7308 -0.6826 -vn -0.1160 -0.9300 -0.3487 -vn -0.1183 -0.9286 -0.3518 -vn -0.1315 -0.6757 -0.7254 -vn -0.0415 -0.9052 -0.4230 -vn -0.0680 -0.9342 -0.3503 +vn -0.5370 0.8245 0.1781 +vn 0.0000 0.9764 0.2161 +vn -0.1274 -0.8868 -0.4443 vn -0.4472 -0.8945 0.0000 -vn -0.4578 -0.8314 -0.3151 -vn -0.4470 -0.8945 0.0000 -vn -0.4469 -0.8946 0.0000 -vn -0.3480 -0.8951 -0.2786 -vn -0.3632 -0.8403 -0.4024 -vn -0.3449 -0.8911 -0.2950 -vn 0.0000 -0.7297 -0.6837 +vn -0.3161 -0.9487 0.0000 +vn -0.2405 -0.9005 -0.3624 +vn -0.2367 -0.8862 -0.3982 +vn -0.1469 -0.5878 -0.7955 +vn -0.2180 -0.8725 -0.4372 +vn -0.0008 -0.7066 -0.7076 +vn -0.1961 -0.9806 0.0000 +vn -0.2437 -0.9699 0.0000 +vn -0.3643 -0.9128 -0.1848 +vn -0.3161 -0.9487 -0.0027 +vn -0.1098 -0.5490 -0.8286 +vn -0.0001 -0.4202 -0.9074 +vn -0.0530 -0.4985 -0.8653 +vn -0.2359 -0.9431 -0.2343 +vn -0.1970 -0.9804 -0.0000 +vn -0.2427 -0.9701 -0.0000 +vn -0.3040 -0.8525 -0.4251 +vn -0.2981 -0.8496 -0.4350 usemtl None s off -f 112/95/79 119/96/79 131/97/79 -f 99/98/80 100/99/80 101/100/80 -f 101/100/81 96/101/81 102/102/81 -f 96/101/82 97/103/82 102/102/82 -f 100/99/83 98/104/83 103/105/83 -f 102/102/82 97/103/82 103/105/82 -f 100/99/83 103/105/83 104/106/83 -f 103/105/82 97/103/82 105/107/82 -f 101/100/80 100/99/80 108/108/80 -f 100/99/83 104/106/83 108/108/83 -f 98/104/83 100/99/83 109/109/83 -f 97/103/84 96/101/84 110/110/84 -f 99/98/80 101/100/80 111/111/80 -f 101/100/81 102/102/81 111/111/81 -f 102/102/85 107/112/85 111/111/85 -f 105/107/82 97/103/82 112/95/82 -f 103/105/82 105/107/82 115/113/82 -f 114/114/86 103/105/86 115/113/86 -f 95/115/87 114/114/87 115/113/87 -f 102/102/82 103/105/82 117/116/82 -f 98/104/88 107/112/88 117/116/88 -f 107/112/89 102/102/89 117/116/89 -f 104/106/83 103/105/83 118/117/83 -f 103/105/86 114/114/86 118/117/86 -f 112/95/79 106/118/79 119/96/79 -f 103/105/83 98/104/83 120/119/83 -f 98/104/90 117/116/90 120/119/90 -f 117/116/82 103/105/82 120/119/82 -f 100/99/91 99/98/91 121/120/91 -f 109/109/83 100/99/83 121/120/83 -f 109/109/92 121/120/92 122/121/92 -f 107/112/93 98/104/93 122/121/93 -f 98/104/94 109/109/94 122/121/94 -f 99/98/95 111/111/95 122/121/95 -f 111/111/96 107/112/96 122/121/96 -f 121/120/97 99/98/97 122/121/97 -f 101/100/80 108/108/80 123/122/80 -f 113/123/98 101/100/98 123/122/98 -f 108/108/99 113/123/99 123/122/99 -f 96/101/81 101/100/81 124/124/81 -f 110/110/84 96/101/84 124/124/84 -f 101/100/100 110/110/100 124/124/100 -f 101/100/101 116/125/101 125/126/101 -f 116/125/102 119/96/102 125/126/102 -f 95/115/103 105/107/103 126/127/103 -f 116/125/104 95/115/104 126/127/104 -f 105/107/105 119/96/105 126/127/105 -f 119/96/106 116/125/106 126/127/106 -f 105/107/103 95/115/103 127/128/103 -f 95/115/87 115/113/87 127/128/87 -f 115/113/82 105/107/82 127/128/82 -f 101/100/107 113/123/107 128/129/107 -f 113/123/108 104/106/108 128/129/108 -f 114/114/109 95/115/109 128/129/109 -f 95/115/110 116/125/110 128/129/110 -f 116/125/111 101/100/111 128/129/111 -f 104/106/112 118/117/112 128/129/112 -f 118/117/113 114/114/113 128/129/113 -f 97/103/114 110/110/114 129/130/114 -f 110/110/115 101/100/115 129/130/115 -f 112/95/116 97/103/116 129/130/116 -f 106/118/117 112/95/117 129/130/117 -f 119/96/118 106/118/118 129/130/118 -f 101/100/119 125/126/119 129/130/119 -f 125/126/120 119/96/120 129/130/120 -f 108/108/83 104/106/83 130/131/83 -f 104/106/121 113/123/121 130/131/121 -f 113/123/99 108/108/99 130/131/99 -f 105/107/82 112/95/82 131/97/82 -f 119/96/105 105/107/105 131/97/105 -o Cup_hull_7 -v -0.006700 0.024377 0.032460 -v -0.014335 0.019637 0.050164 -v -0.013806 0.019637 0.050164 -v -0.014335 0.017795 0.032460 -v 0.000413 0.024113 0.050164 -v 0.000413 0.022797 0.032460 -v -0.006700 0.024377 0.050164 -v -0.013806 0.021217 0.032460 -v 0.000413 0.025167 0.032460 -v -0.013017 0.021742 0.050164 -v -0.002222 0.025167 0.050164 -v -0.014070 0.017795 0.033306 -v -0.009855 0.023323 0.032460 -v 0.000413 0.025167 0.050164 -v -0.004328 0.024903 0.032460 -v -0.014335 0.020691 0.032460 -v -0.009855 0.023323 0.050164 -v -0.014335 0.020691 0.050164 -v 0.000413 0.022797 0.033586 -v -0.002222 0.025167 0.032460 -v -0.004328 0.024903 0.050164 -v -0.013017 0.021742 0.032460 -v -0.013806 0.021217 0.050164 -v -0.005646 0.024639 0.050164 -vt 0.000000 0.678543 -vt 1.000000 0.678543 -vt 0.000000 0.589174 -vt 0.000000 0.000000 -vt 0.000000 0.035826 +f 75/67/54 88/68/54 94/69/54 +f 71/70/55 72/71/55 73/72/55 +f 72/71/56 70/73/56 74/74/56 +f 69/75/57 68/76/57 75/67/57 +f 74/74/58 69/75/58 75/67/58 +f 72/71/56 74/74/56 76/77/56 +f 74/74/58 75/67/58 77/78/58 +f 71/70/55 73/72/55 78/79/55 +f 75/67/57 68/76/57 78/79/57 +f 68/76/59 69/75/59 79/80/59 +f 71/70/60 68/76/60 79/80/60 +f 72/71/61 71/70/61 79/80/61 +f 70/73/62 72/71/62 79/80/62 +f 73/72/63 76/77/63 80/81/63 +f 76/77/56 74/74/56 81/82/56 +f 73/72/55 72/71/55 82/83/55 +f 76/77/63 73/72/63 82/83/63 +f 72/71/56 76/77/56 82/83/56 +f 69/75/58 74/74/58 83/84/58 +f 74/74/56 70/73/56 83/84/56 +f 79/80/64 69/75/64 83/84/64 +f 70/73/65 79/80/65 83/84/65 +f 73/72/66 80/81/66 84/85/66 +f 74/74/67 77/78/67 85/86/67 +f 81/82/56 74/74/56 85/86/56 +f 81/82/68 85/86/68 86/87/68 +f 67/88/69 80/81/69 86/87/69 +f 68/76/60 71/70/60 87/89/60 +f 78/79/57 68/76/57 87/89/57 +f 71/70/55 78/79/55 87/89/55 +f 80/81/70 67/88/70 88/68/70 +f 75/67/71 84/85/71 88/68/71 +f 84/85/72 80/81/72 88/68/72 +f 78/79/55 73/72/55 89/90/55 +f 73/72/73 84/85/73 89/90/73 +f 80/81/74 76/77/74 90/91/74 +f 76/77/56 81/82/56 90/91/56 +f 81/82/75 86/87/75 90/91/75 +f 77/78/76 67/88/76 91/92/76 +f 85/86/67 77/78/67 91/92/67 +f 86/87/68 85/86/68 91/92/68 +f 67/88/77 86/87/77 91/92/77 +f 75/67/57 78/79/57 92/93/57 +f 84/85/78 75/67/78 92/93/78 +f 78/79/79 89/90/79 92/93/79 +f 89/90/80 84/85/80 92/93/80 +f 86/87/81 80/81/81 93/94/81 +f 80/81/82 90/91/82 93/94/82 +f 90/91/83 86/87/83 93/94/83 +f 67/88/84 77/78/84 94/69/84 +f 77/78/58 75/67/58 94/69/58 +f 88/68/85 67/88/85 94/69/85 +o cup_hull_6 +v -0.034734 -0.020819 0.075208 +v -0.036839 -0.001016 0.050354 +v -0.030099 -0.020819 0.050352 +v -0.037682 -0.014919 0.050354 +v -0.038946 -0.001016 0.075208 +v -0.040209 -0.004387 0.075208 +v -0.040209 -0.001016 0.050354 +v -0.032627 -0.020395 0.075208 +v -0.034313 -0.021240 0.050354 +v -0.038946 -0.011128 0.075208 +v -0.039788 -0.007337 0.050354 +v -0.038524 -0.001437 0.074364 +v -0.032627 -0.021240 0.075208 +v -0.030099 -0.020819 0.051617 +v -0.040209 -0.001016 0.075208 +v -0.037682 -0.014919 0.075208 +v -0.036839 -0.001016 0.052459 +v -0.030099 -0.021238 0.050352 +v -0.038946 -0.011128 0.050354 +v -0.040209 -0.004387 0.050354 +v -0.034734 -0.020819 0.050354 +v -0.039368 -0.009443 0.075208 +v -0.034313 -0.021240 0.075208 +v -0.039788 -0.007337 0.075208 +vt 0.999902 0.687451 +vt 0.000000 0.583301 +vt 0.000000 0.687451 +vt 0.000000 0.020850 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 0.517717 -vt 1.000000 1.000000 -vt 0.000000 0.517717 -vt 1.000000 0.035826 -vt 1.000000 1.000000 -vt 0.000000 0.089370 -vt 0.000000 0.821359 -vt 0.952232 0.017913 -vt 1.000000 0.303739 +vt 0.000000 0.833301 +vt 0.999902 1.000000 +vt 1.000000 0.020850 +vt 0.999902 1.000000 +vt 0.000000 0.041797 +vt 0.000000 0.500000 +vt 0.033966 0.979150 +vt 0.000000 0.000000 +vt 0.949100 0.020850 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 0.000000 0.303739 +vt 0.999902 0.312549 +vt 0.000000 0.312549 +vt 0.915231 1.000000 +vt 1.000000 0.000098 +vt 0.999902 0.000000 +vt 0.999902 0.500000 +vt 0.999902 0.833301 +vt 0.999902 0.020850 vt 0.000000 0.000000 -vt 0.936374 1.000000 -vt 1.000000 0.821359 -vt 1.000000 0.089370 -vt 0.000000 0.035826 -vn -0.1960 0.9806 0.0000 +vn -0.9806 -0.1958 0.0000 vn 0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 -0.9941 0.1086 -vn -0.3146 -0.9441 0.0983 -vn 0.2988 -0.9492 0.0991 -vn 0.3196 -0.9423 -0.0998 -vn -0.3167 0.9485 0.0000 +vn 0.0000 0.0001 -1.0000 vn 0.0000 1.0000 0.0000 +vn 0.9055 0.2952 0.3048 +vn 0.9467 0.3222 0.0000 +vn 0.9492 0.2995 0.0964 +vn 0.9943 0.0000 0.1066 vn -1.0000 0.0000 0.0000 -vn -0.4472 0.8944 0.0000 -vn -0.7056 0.7086 0.0000 -vn 0.3242 -0.9430 0.0749 -vn 0.3265 -0.9452 0.0000 -vn -0.1244 0.9922 0.0000 -vn -0.5540 0.8325 0.0000 -vn -0.2419 0.9703 0.0000 -vn -0.2166 0.9763 -0.0016 +vn -0.8945 -0.4471 0.0000 +vn -0.9487 -0.3163 0.0000 +vn 0.7734 0.6299 0.0716 +vn 0.9447 0.3182 0.0788 +vn -0.0002 0.0000 -1.0000 +vn 0.0005 -1.0000 -0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.9516 -0.2918 0.0968 +vn -0.0004 -0.0001 -1.0000 +vn -0.9900 -0.1412 0.0000 +vn -0.0003 -0.0000 -1.0000 +vn -0.7080 -0.7062 0.0000 +vn -0.0006 -0.0003 -1.0000 +vn -0.0006 -0.0006 -1.0000 +vn -0.9701 -0.2428 0.0000 +vn -0.9762 -0.2169 -0.0019 +vn 0.0000 -1.0000 0.0000 +vn -0.0001 0.0000 1.0000 usemtl None s off -f 152/132/122 146/133/122 155/134/122 -f 133/135/123 134/136/123 136/137/123 -f 135/138/124 132/139/124 137/140/124 -f 133/135/123 136/137/123 138/141/123 -f 132/139/124 135/138/124 139/142/124 -f 137/140/124 132/139/124 140/143/124 -f 136/137/125 137/140/125 140/143/125 -f 133/135/123 138/141/123 141/144/123 -f 138/141/123 136/137/123 142/145/123 -f 134/136/126 133/135/126 143/146/126 -f 133/135/127 135/138/127 143/146/127 -f 136/137/128 134/136/128 143/146/128 -f 135/138/129 137/140/129 143/146/129 -f 138/141/130 132/139/130 144/147/130 -f 132/139/124 139/142/124 144/147/124 -f 136/137/125 140/143/125 145/148/125 -f 142/145/123 136/137/123 145/148/123 -f 140/143/131 142/145/131 145/148/131 -f 140/143/124 132/139/124 146/133/124 -f 135/138/132 133/135/132 147/149/132 -f 139/142/124 135/138/124 147/149/124 -f 141/144/123 138/141/123 148/150/123 -f 138/141/130 144/147/130 148/150/130 -f 144/147/133 141/144/133 148/150/133 -f 133/135/123 141/144/123 149/151/123 -f 147/149/132 133/135/132 149/151/132 -f 139/142/134 147/149/134 149/151/134 -f 137/140/125 136/137/125 150/152/125 -f 136/137/135 143/146/135 150/152/135 -f 143/146/136 137/140/136 150/152/136 -f 142/145/131 140/143/131 151/153/131 -f 140/143/124 146/133/124 151/153/124 -f 146/133/137 142/145/137 151/153/137 -f 138/141/123 142/145/123 152/132/123 -f 142/145/137 146/133/137 152/132/137 -f 139/142/138 141/144/138 153/154/138 -f 144/147/124 139/142/124 153/154/124 -f 141/144/133 144/147/133 153/154/133 -f 141/144/138 139/142/138 154/155/138 -f 149/151/123 141/144/123 154/155/123 -f 139/142/134 149/151/134 154/155/134 -f 132/139/139 138/141/139 155/134/139 -f 146/133/140 132/139/140 155/134/140 -f 138/141/123 152/132/123 155/134/123 -o Cup_hull_8 -v -0.003801 0.024902 0.017846 -v -0.014335 0.017794 0.032458 -v -0.014335 0.020688 0.032458 -v 0.000413 0.022796 0.032458 -v -0.014070 0.011212 0.015036 -v 0.000413 0.018057 0.015036 -v -0.014335 0.020426 0.015036 -v 0.000413 0.025166 0.032458 -v 0.000413 0.024376 0.016722 -v -0.009858 0.023322 0.032458 -v -0.014070 0.011475 0.017004 -v -0.009858 0.023322 0.018409 -v -0.005645 0.024639 0.032458 -v 0.000413 0.018320 0.017285 -v 0.000413 0.022532 0.032179 -v 0.000413 0.020426 0.015036 -v -0.014070 0.017531 0.032179 -v -0.013017 0.021741 0.018409 -v 0.000413 0.025166 0.017846 -v -0.014335 0.011212 0.016161 -v -0.002222 0.025166 0.032458 -v -0.006698 0.024376 0.018128 -v -0.013017 0.021741 0.032458 -v -0.014070 0.011212 0.016161 -v -0.005645 0.024111 0.017004 -v -0.002222 0.025166 0.018409 -v -0.004328 0.024902 0.018409 -v -0.013806 0.021215 0.018128 -v -0.001958 0.024639 0.017004 -v -0.006698 0.024376 0.032458 -v 0.000413 0.018057 0.015880 -v -0.004328 0.024902 0.032458 -v -0.014335 0.011212 0.015036 -v -0.014335 0.020688 0.017285 -v -0.013806 0.021215 0.032458 -v -0.009330 0.023322 0.017565 -vt 0.822516 0.517815 -vt 0.887029 0.589272 -vt 0.854821 0.339370 +f 105/95/86 116/96/86 118/97/86 +f 95/98/87 99/99/87 100/100/87 +f 96/101/88 97/102/88 101/103/88 +f 99/99/89 96/101/89 101/103/89 +f 99/99/87 95/98/87 102/104/87 +f 95/98/87 100/100/87 104/105/87 +f 99/99/90 102/104/90 106/106/90 +f 102/104/87 95/98/87 107/107/87 +f 97/102/91 96/101/91 108/108/91 +f 106/106/92 102/104/92 108/108/92 +f 102/104/93 107/107/93 108/108/93 +f 100/100/87 99/99/87 109/109/87 +f 99/99/89 101/103/89 109/109/89 +f 101/103/94 100/100/94 109/109/94 +f 98/110/95 95/98/95 110/111/95 +f 95/98/87 104/105/87 110/111/87 +f 104/105/96 98/110/96 110/111/96 +f 96/101/89 99/99/89 111/112/89 +f 99/99/97 106/106/97 111/112/97 +f 108/108/91 96/101/91 111/112/91 +f 106/106/98 108/108/98 111/112/98 +f 101/103/99 97/102/99 112/113/99 +f 107/107/100 103/114/100 112/113/100 +f 97/102/101 108/108/101 112/113/101 +f 108/108/102 107/107/102 112/113/102 +f 98/110/96 104/105/96 113/115/96 +f 112/113/103 98/110/103 113/115/103 +f 105/95/103 112/113/103 113/115/103 +f 100/100/94 101/103/94 114/116/94 +f 105/95/104 100/100/104 114/116/104 +f 101/103/99 112/113/99 114/116/99 +f 112/113/105 105/95/105 114/116/105 +f 95/98/95 98/110/95 115/117/95 +f 103/114/106 95/98/106 115/117/106 +f 98/110/107 112/113/107 115/117/107 +f 112/113/108 103/114/108 115/117/108 +f 104/105/87 100/100/87 116/96/87 +f 113/115/109 104/105/109 116/96/109 +f 105/95/110 113/115/110 116/96/110 +f 95/98/106 103/114/106 117/118/106 +f 107/107/87 95/98/87 117/118/87 +f 103/114/111 107/107/111 117/118/111 +f 100/100/104 105/95/104 118/97/104 +f 116/96/112 100/100/112 118/97/112 +o cup_hull_7 +v -0.034733 -0.020395 0.026339 +v -0.040210 -0.004387 0.050348 +v -0.039787 -0.007337 0.050348 +v -0.019565 -0.020819 0.022967 +v -0.033046 -0.001016 0.022548 +v -0.030095 -0.021240 0.050348 +v -0.036417 -0.001016 0.049927 +v -0.040210 -0.001016 0.026758 +v -0.028834 -0.001016 0.023811 +v -0.032625 -0.021240 0.022548 +v -0.034733 -0.020819 0.050348 +v -0.038945 -0.011128 0.027602 +v -0.040210 -0.001016 0.050348 +v -0.019565 -0.021240 0.022548 +v -0.037682 -0.014919 0.050348 +v -0.029677 -0.020819 0.049927 +v -0.038945 -0.003124 0.025073 +v -0.020409 -0.020819 0.025917 +v -0.037682 -0.014919 0.027602 +v -0.040210 -0.004387 0.027602 +v -0.028834 -0.001016 0.022548 +v -0.029677 -0.001016 0.027180 +v -0.038945 -0.009022 0.025917 +v -0.034311 -0.021240 0.050348 +v -0.034733 -0.020819 0.027180 +v -0.038945 -0.011128 0.050348 +v -0.036417 -0.001859 0.050348 +v -0.019987 -0.020819 0.024652 +v -0.039367 -0.009443 0.027602 +v -0.037682 -0.014074 0.026339 +v -0.034311 -0.021240 0.026758 +v -0.038945 -0.001016 0.025073 +v -0.033046 -0.014074 0.022548 +v -0.039787 -0.007337 0.027602 +v -0.020409 -0.021240 0.025917 +vt 0.924320 0.979542 +vt 0.878794 0.959084 +vt 0.878794 0.959084 vt 0.000000 0.000000 +vt 0.000000 0.020458 +vt 0.000000 0.489918 +vt 0.015175 0.183731 +vt 1.000000 0.347005 +vt 0.848541 0.000000 +vt 0.954572 0.550999 +vt 0.000000 0.265270 vt 0.000000 0.000000 -vt 0.000000 1.000000 +vt 1.000000 0.367365 vt 1.000000 1.000000 -vt 1.000000 0.017913 -vt 1.000000 0.000000 -vt 0.000000 1.000000 -vt 0.903182 1.000000 -vt 0.000000 0.303543 -vt 0.000000 0.589272 -vt 0.870876 1.000000 -vt 0.016055 1.000000 -vt 1.000000 1.000000 -vt 0.016055 0.017913 -vt 0.887029 0.017913 -vt 0.806363 0.303543 -vt 0.806363 0.089370 -vt 0.838669 1.000000 -vt 0.935389 0.000000 -vt 0.000000 0.821359 -vt 0.000000 0.089370 -vt 0.935389 0.017913 -vt 0.838669 0.714272 -vt 0.806363 0.821359 -vt 0.806363 0.678543 -vt 0.822516 0.035826 -vt 0.887029 0.839272 -vt 0.000000 0.517815 -vt 0.951542 1.000000 -vt 0.000000 0.678543 -vt 1.000000 0.000000 -vt 0.870876 0.000000 -vt 0.000000 0.035826 -vn -0.2516 0.8624 -0.4393 +vt 0.000000 0.122455 +vt 0.015175 0.510180 +vt 0.818191 0.122455 +vt 0.818191 0.061276 +vt 0.818191 0.000000 +vt 0.984923 1.000000 +vt 1.000000 0.550999 +vt 0.833366 0.510180 +vt 0.909144 0.061276 +vt 0.878794 0.061276 +vt 0.000000 0.285728 +vt 0.833366 0.265270 +vt 0.863619 0.265270 +vt 0.000000 0.061276 +vt 0.000000 0.183731 +vt 0.818191 0.040818 +vt 0.863619 0.122455 +vt 0.848541 0.285728 +vt 0.909144 0.061276 +vt 1.000000 0.347005 +vt 0.818191 0.020458 +vn 0.9486 0.0000 0.3165 vn 0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn -1.0000 0.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 0.3927 -0.9197 -vn 0.2065 -0.6089 0.7659 -vn 0.3054 -0.8844 0.3530 -vn 0.2437 -0.7058 0.6652 -vn -0.4409 0.8811 -0.1713 -vn -0.4475 0.8943 0.0000 -vn -0.4642 -0.8213 0.3317 -vn -0.2519 -0.8988 0.3587 vn 0.0000 1.0000 0.0000 -vn -0.3166 0.9486 0.0000 -vn 0.4273 -0.9041 0.0000 -vn 0.3853 -0.8811 0.2743 -vn 0.4112 -0.8771 0.2481 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.0000 -0.9548 0.2972 -vn -0.2012 0.8944 -0.3995 -vn -0.0599 0.9580 -0.2805 -vn -0.1242 0.9923 0.0000 -vn -0.1926 0.9646 -0.1803 -vn -0.2164 0.9763 -0.0020 -vn -0.1234 0.9856 -0.1155 -vn -0.5179 0.8459 -0.1275 -vn -0.5543 0.8323 0.0000 -vn -0.0430 0.5239 -0.8507 -vn -0.0570 0.9105 -0.4095 -vn 0.0223 0.8181 -0.5747 -vn -0.0894 0.6249 -0.7755 -vn -0.1204 0.8415 -0.5266 -vn -0.2415 0.9704 0.0000 -vn 0.4240 -0.8903 0.1661 -vn -0.1964 0.9805 0.0000 -vn -0.7064 0.7078 0.0000 -vn -0.6278 0.7731 -0.0901 -vn -0.3902 0.8877 -0.2442 -vn -0.3262 0.9230 -0.2041 -vn -0.2527 0.8463 -0.4689 +vn 0.8892 0.3026 0.3432 +vn -0.8945 -0.4471 0.0000 +vn -0.9487 -0.3161 0.0000 +vn -0.9899 -0.1417 0.0000 +vn 0.9057 0.4239 0.0000 +vn 0.8384 0.3843 -0.3866 +vn 0.8867 0.4056 0.2218 +vn -0.8410 -0.0766 -0.5356 +vn -0.6255 -0.1105 -0.7724 +vn -0.9090 -0.1012 -0.4043 +vn -0.7065 -0.7077 0.0000 +vn -0.8799 -0.4244 -0.2138 +vn 0.0990 0.4452 0.8899 +vn 0.7959 0.2709 0.5415 +vn 0.5931 0.1935 0.7815 +vn 0.8858 0.3576 0.2956 +vn 0.8867 0.4055 0.2223 +vn 0.8799 0.3973 0.2607 +vn -0.9280 -0.2327 -0.2909 +vn -0.9762 -0.2170 0.0021 +vn -0.9700 -0.2432 0.0000 +vn -0.8387 -0.3912 -0.3790 +vn -0.8720 -0.4067 -0.2723 +vn -0.9282 -0.3092 -0.2070 +vn -0.7784 -0.2429 -0.5789 +vn -0.9130 -0.2548 -0.3186 +vn -0.7791 -0.5439 -0.3118 +vn -0.8016 -0.5339 -0.2689 +vn -0.3936 0.0000 -0.9193 +vn -0.7997 0.0000 -0.6004 +vn -0.4330 -0.0254 -0.9011 +vn -0.9333 -0.1336 -0.3332 +vn -0.9807 -0.1957 0.0000 +vn -0.9406 -0.1877 -0.2828 +vn 0.9428 -0.2350 0.2364 +vn 0.8133 -0.4842 0.3225 +vn 0.9329 0.0000 0.3601 +vn 0.9428 -0.2349 0.2364 usemtl None s off -f 177/156/141 180/157/141 191/158/141 -f 158/159/142 157/160/142 159/161/142 -f 161/162/143 160/163/143 162/164/143 -f 157/160/144 158/159/144 162/164/144 -f 158/159/142 159/161/142 163/165/142 -f 159/161/145 161/162/145 163/165/145 -f 163/165/145 161/162/145 164/166/145 -f 158/159/142 163/165/142 165/167/142 -f 165/167/142 163/165/142 168/168/142 -f 161/162/145 159/161/145 169/169/145 -f 169/169/145 159/161/145 170/170/145 -f 161/162/143 162/164/143 171/171/143 -f 164/166/145 161/162/145 171/171/145 -f 162/164/146 164/166/146 171/171/146 -f 159/161/147 157/160/147 172/172/147 -f 166/173/148 170/170/148 172/172/148 -f 170/170/149 159/161/149 172/172/149 -f 167/174/150 162/164/150 173/175/150 -f 165/167/151 167/174/151 173/175/151 -f 163/165/145 164/166/145 174/176/145 -f 157/160/144 162/164/144 175/177/144 -f 172/172/152 157/160/152 175/177/152 -f 166/173/153 172/172/153 175/177/153 -f 168/168/142 163/165/142 176/178/142 -f 163/165/154 174/176/154 176/178/154 -f 167/174/155 165/167/155 177/156/155 -f 158/159/142 165/167/142 178/179/142 -f 165/167/151 173/175/151 178/179/151 -f 160/163/156 161/162/156 179/180/156 -f 170/170/157 166/173/157 179/180/157 -f 169/169/158 170/170/158 179/180/158 -f 175/177/159 160/163/159 179/180/159 -f 166/173/160 175/177/160 179/180/160 -f 177/156/161 156/181/161 180/157/161 -f 174/176/162 156/181/162 181/182/162 -f 176/178/154 174/176/154 181/182/154 -f 176/178/163 181/182/163 182/183/163 -f 156/181/164 177/156/164 182/183/164 -f 177/156/165 168/168/165 182/183/165 -f 181/182/166 156/181/166 182/183/166 -f 173/175/167 162/164/167 183/184/167 -f 178/179/168 173/175/168 183/184/168 -f 164/166/169 162/164/169 184/185/169 -f 156/181/170 174/176/170 184/185/170 -f 174/176/171 164/166/171 184/185/171 -f 162/164/172 180/157/172 184/185/172 -f 180/157/173 156/181/173 184/185/173 -f 165/167/142 168/168/142 185/186/142 -f 177/156/155 165/167/155 185/186/155 -f 168/168/174 177/156/174 185/186/174 -f 161/162/145 169/169/145 186/187/145 -f 179/180/156 161/162/156 186/187/156 -f 169/169/175 179/180/175 186/187/175 -f 168/168/142 176/178/142 187/188/142 -f 176/178/163 182/183/163 187/188/163 -f 182/183/176 168/168/176 187/188/176 -f 162/164/143 160/163/143 188/189/143 -f 160/163/159 175/177/159 188/189/159 -f 175/177/144 162/164/144 188/189/144 -f 162/164/144 158/159/144 189/190/144 -f 158/159/177 183/184/177 189/190/177 -f 183/184/178 162/164/178 189/190/178 -f 158/159/142 178/179/142 190/191/142 -f 183/184/177 158/159/177 190/191/177 -f 178/179/168 183/184/168 190/191/168 -f 162/164/179 167/174/179 191/158/179 -f 167/174/180 177/156/180 191/158/180 -f 180/157/181 162/164/181 191/158/181 -o Cup_hull_9 -v 0.004625 -0.024868 0.026844 -v 0.008313 -0.016178 0.015036 -v 0.007785 -0.016178 0.015036 -v 0.008313 -0.022761 0.050166 -v 0.000413 -0.024077 0.049041 -v 0.000413 -0.018023 0.015036 -v 0.008313 -0.023814 0.017848 -v 0.000413 -0.025132 0.017848 -v 0.004363 -0.024868 0.050166 -v 0.008313 -0.020655 0.015036 -v 0.007785 -0.024077 0.050166 -v 0.000413 -0.025132 0.050166 -v 0.008049 -0.016178 0.016442 -v 0.000413 -0.020655 0.015036 -v 0.000676 -0.024077 0.049884 -v 0.002520 -0.025132 0.018409 -v 0.000413 -0.018023 0.015882 -v 0.001730 -0.024341 0.016724 -v 0.005942 -0.024604 0.018409 -v 0.007785 -0.022761 0.050166 -v 0.002520 -0.025132 0.050166 -v 0.008313 -0.023814 0.050166 -v 0.005679 -0.024077 0.017006 -v 0.004625 -0.024868 0.048477 -v 0.007785 -0.024077 0.018409 -v 0.000413 -0.024341 0.016724 -v 0.008313 -0.023287 0.017006 -v 0.003309 -0.024868 0.017567 -v 0.000940 -0.024077 0.050166 -v 0.008313 -0.016178 0.016442 -vt 0.959965 1.000000 -vt 0.000000 0.264781 -vt 0.959965 1.000000 +f 146/119/113 136/120/113 153/121/113 +f 120/122/114 121/123/114 124/124/114 +f 125/125/115 123/126/115 126/127/115 +f 123/126/115 125/125/115 127/128/115 +f 124/124/114 121/123/114 129/129/114 +f 120/122/114 124/124/114 131/130/114 +f 126/127/116 120/122/116 131/130/116 +f 125/125/115 126/127/115 131/130/115 +f 128/131/117 123/126/117 132/132/117 +f 124/124/118 128/131/118 132/132/118 +f 129/129/114 121/123/114 133/133/114 +f 125/125/119 134/134/119 136/120/119 +f 129/129/120 133/133/120 137/135/120 +f 133/133/121 130/136/121 137/135/121 +f 121/123/122 120/122/122 138/137/122 +f 120/122/116 126/127/116 138/137/116 +f 127/128/123 122/138/123 139/139/123 +f 123/126/115 127/128/115 139/139/115 +f 122/138/124 132/132/124 139/139/124 +f 132/132/117 123/126/117 139/139/117 +f 122/138/125 127/128/125 140/140/125 +f 127/128/115 125/125/115 140/140/115 +f 126/127/126 135/141/126 141/142/126 +f 135/141/127 128/131/127 141/142/127 +f 138/137/128 126/127/128 141/142/128 +f 128/131/118 124/124/118 142/143/118 +f 124/124/114 129/129/114 142/143/114 +f 142/143/129 129/129/129 143/144/129 +f 137/135/130 119/145/130 143/144/130 +f 129/129/120 137/135/120 143/144/120 +f 133/133/114 121/123/114 144/146/114 +f 130/136/121 133/133/121 144/146/121 +f 131/130/114 124/124/114 145/147/114 +f 125/125/131 131/130/131 145/147/131 +f 134/134/132 125/125/132 145/147/132 +f 124/124/133 134/134/133 145/147/133 +f 125/125/134 136/120/134 146/119/134 +f 122/138/135 140/140/135 146/119/135 +f 140/140/136 125/125/136 146/119/136 +f 141/142/137 130/136/137 147/148/137 +f 144/146/138 121/123/138 147/148/138 +f 130/136/139 144/146/139 147/148/139 +f 128/131/140 119/145/140 148/149/140 +f 119/145/141 137/135/141 148/149/141 +f 137/135/142 130/136/142 148/149/142 +f 141/142/143 128/131/143 148/149/143 +f 130/136/144 141/142/144 148/149/144 +f 119/145/145 128/131/145 149/150/145 +f 128/131/118 142/143/118 149/150/118 +f 142/143/129 143/144/129 149/150/129 +f 143/144/146 119/145/146 149/150/146 +f 126/127/115 123/126/115 150/151/115 +f 123/126/147 135/141/147 150/151/147 +f 135/141/148 126/127/148 150/151/148 +f 123/126/117 128/131/117 151/152/117 +f 135/141/147 123/126/147 151/152/147 +f 128/131/149 135/141/149 151/152/149 +f 121/123/122 138/137/122 152/153/122 +f 138/137/150 141/142/150 152/153/150 +f 147/148/151 121/123/151 152/153/151 +f 141/142/152 147/148/152 152/153/152 +f 132/132/153 122/138/153 153/121/153 +f 124/124/118 132/132/118 153/121/118 +f 134/134/154 124/124/154 153/121/154 +f 136/120/155 134/134/155 153/121/155 +f 122/138/156 146/119/156 153/121/156 +o cup_hull_8 +v -0.039367 0.009519 0.075211 +v -0.029677 0.021316 0.048666 +v -0.034312 0.021316 0.048666 +v -0.036418 -0.001013 0.048666 +v -0.032627 0.020472 0.075211 +v -0.040210 0.004464 0.048666 +v -0.038946 -0.001013 0.075211 +v -0.034313 0.021316 0.075211 +v -0.038103 0.013729 0.048666 +v -0.040210 -0.001013 0.048666 +v -0.040210 -0.001013 0.075211 +v -0.029677 0.020894 0.049931 +v -0.037261 0.015836 0.075211 +v -0.040210 0.004044 0.075211 +v -0.039367 0.009519 0.048666 +v -0.034734 0.020892 0.048666 +v -0.036418 -0.001013 0.049931 +v -0.032206 0.021316 0.072682 +v -0.037261 0.015836 0.048666 +v -0.034734 0.020892 0.075211 +v -0.038524 0.012466 0.075211 +v -0.038524 -0.001013 0.071417 +v -0.039788 0.007415 0.075211 +v -0.032206 0.020894 0.072682 +v -0.039788 0.007415 0.048666 +vt 0.000000 0.377447 +vt 1.000000 0.471711 +vt 1.000000 0.377447 vt 1.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.793951 -vt 0.919930 0.147220 -vt 0.032009 0.117756 -vt 0.919930 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.029464 -vt 0.000000 0.117756 +vt 1.000000 0.000000 +vt 1.000000 0.245301 +vt 0.000000 0.962216 +vt 0.000000 0.471711 vt 0.000000 0.000000 -vt 1.000000 0.500000 -vt 0.008027 0.117756 -vt 0.903974 0.000000 -vt 0.975920 0.793951 -vt 0.951938 0.088293 -vt 0.663861 0.029464 -vt 0.903974 0.058927 -vt 0.000000 0.264781 +vt 0.000000 1.000000 +vt 1.000000 0.660239 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.000000 0.147220 -vt 0.943911 0.117756 -vt 0.048062 0.029464 -vt 0.903974 0.117756 -vt 0.951938 0.088293 -vt 0.943911 0.206049 -vt 0.927956 0.029464 -vt 0.000000 0.117756 -vn 0.0000 0.9815 0.1916 +vt 0.952330 0.981108 +vt 0.000000 0.754601 +vt 0.000000 0.226507 +vt 1.000000 0.981010 +vt 0.952330 0.000000 +vt 0.095243 1.000000 +vt 1.000000 0.754601 +vt 0.000000 0.981010 +vt 0.000000 0.603661 +vt 0.142913 0.000000 +vt 0.095243 0.981108 +vn -0.9806 0.1960 0.0000 vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 -vn -1.0000 -0.0000 0.0000 vn 0.0000 0.0000 1.0000 vn 0.0000 1.0000 0.0000 -vn -0.9093 0.3035 0.2846 vn 0.0000 -1.0000 0.0000 -vn -0.2427 0.9701 0.0000 -vn -0.2377 0.9703 0.0446 -vn -0.4977 0.8532 0.1558 -vn -0.2432 0.9546 0.1719 -vn 0.0000 -0.4164 -0.9092 -vn 0.1524 -0.9883 -0.0071 -vn 0.1244 -0.9922 0.0000 -vn 0.4474 -0.8944 0.0000 -vn 0.0960 -0.5511 -0.8289 -vn 0.2249 -0.9738 0.0349 -vn 0.1964 -0.9805 0.0000 -vn 0.2416 -0.9704 0.0021 -vn 0.1417 -0.9897 0.0220 -vn 0.2697 -0.9439 -0.1905 -vn 0.2747 -0.9615 0.0000 -vn 0.0000 -0.8181 -0.5751 -vn 0.2466 -0.8217 -0.5138 -vn 0.1770 -0.5898 -0.7879 -vn 0.0645 -0.9680 -0.2426 -vn 0.0212 -0.8294 -0.5583 -vn 0.1503 -0.9749 -0.1644 -vn 0.2113 -0.9015 -0.3778 -vn 0.2112 -0.9013 -0.3782 -vn 0.0968 -0.7522 -0.6518 -vn -0.6860 0.3432 0.6416 -vn -0.1968 0.9630 0.1841 -vn -0.1855 0.9647 0.1869 +vn -1.0000 0.0000 0.0000 +vn 0.9529 -0.2877 -0.0959 +vn -0.7090 0.7052 -0.0000 +vn 0.9558 -0.2941 0.0000 +vn 0.4193 0.8378 0.3495 +vn 0.9488 0.2996 0.0999 +vn -0.9285 0.3712 0.0000 +vn -0.8945 0.4471 0.0000 +vn -0.7099 0.7043 0.0000 +vn -0.9364 0.3509 0.0019 +vn -0.9614 0.2752 0.0000 +vn -0.9578 0.2876 -0.0015 +vn 0.9516 -0.2928 0.0932 +vn -0.9923 0.1242 0.0020 +vn 0.9533 -0.2803 0.1122 +vn 0.9864 0.0000 0.1645 +vn 0.9939 0.0000 0.1104 +vn 0.9538 -0.2812 0.1060 +vn -0.9899 0.1415 0.0000 usemtl None s off -f 204/192/182 195/193/182 221/194/182 -f 194/195/183 193/196/183 197/197/183 -f 193/196/184 195/193/184 198/198/184 -f 196/199/185 197/197/185 199/200/185 -f 197/197/183 193/196/183 201/201/183 -f 193/196/184 198/198/184 201/201/184 -f 195/193/186 200/202/186 202/203/186 -f 196/199/185 199/200/185 203/204/185 -f 200/202/186 195/193/186 203/204/186 -f 193/196/187 194/195/187 204/192/187 -f 199/200/185 197/197/185 205/205/185 -f 197/197/183 201/201/183 205/205/183 -f 196/199/188 203/204/188 206/206/188 -f 203/204/189 199/200/189 207/207/189 -f 194/195/190 197/197/190 208/208/190 -f 197/197/185 196/199/185 208/208/185 -f 204/192/191 194/195/191 208/208/191 -f 196/199/192 206/206/192 208/208/192 -f 206/206/193 204/192/193 208/208/193 -f 205/205/194 201/201/194 209/209/194 -f 192/210/195 207/207/195 210/211/195 -f 203/204/186 195/193/186 211/212/186 -f 195/193/182 204/192/182 211/212/182 -f 200/202/186 203/204/186 212/213/186 -f 207/207/196 192/210/196 212/213/196 -f 203/204/189 207/207/189 212/213/189 -f 198/198/184 195/193/184 213/214/184 -f 202/203/197 198/198/197 213/214/197 -f 195/193/186 202/203/186 213/214/186 -f 209/209/198 201/201/198 214/215/198 -f 202/203/199 200/202/199 215/216/199 -f 192/210/200 210/211/200 215/216/200 -f 210/211/201 202/203/201 215/216/201 -f 212/213/196 192/210/196 215/216/196 -f 200/202/202 212/213/202 215/216/202 -f 198/198/197 202/203/197 216/217/197 -f 210/211/203 198/198/203 216/217/203 -f 202/203/204 210/211/204 216/217/204 -f 199/200/185 205/205/185 217/218/185 -f 209/209/205 199/200/205 217/218/205 -f 205/205/194 209/209/194 217/218/194 -f 201/201/184 198/198/184 218/219/184 -f 198/198/206 214/215/206 218/219/206 -f 214/215/207 201/201/207 218/219/207 -f 207/207/208 199/200/208 219/220/208 -f 199/200/209 209/209/209 219/220/209 -f 210/211/210 207/207/210 219/220/210 -f 198/198/211 210/211/211 219/220/211 -f 214/215/212 198/198/212 219/220/212 -f 209/209/213 214/215/213 219/220/213 -f 206/206/214 203/204/214 220/221/214 -f 204/192/215 206/206/215 220/221/215 -f 203/204/186 211/212/186 220/221/186 -f 211/212/216 204/192/216 220/221/216 -f 195/193/184 193/196/184 221/194/184 -f 193/196/187 204/192/187 221/194/187 -o Cup_hull_10 -v 0.021743 -0.013016 0.050164 -v 0.025167 -0.000378 0.032460 -v 0.025167 -0.002222 0.032460 -v 0.017793 -0.014070 0.032460 -v 0.024113 -0.000379 0.050164 -v 0.021743 -0.013016 0.032460 -v 0.022796 -0.000379 0.032460 -v 0.019637 -0.014335 0.050164 -v 0.024640 -0.005645 0.050164 -v 0.024113 -0.007750 0.032460 -v 0.025167 -0.000378 0.050164 -v 0.020691 -0.014335 0.032460 -v 0.023323 -0.009856 0.050164 -v 0.019637 -0.013806 0.050164 -v 0.017793 -0.014070 0.033306 -v 0.020691 -0.014335 0.050164 -v 0.022796 -0.000379 0.033586 -v 0.025167 -0.002222 0.050164 -v 0.024903 -0.004328 0.032460 -v 0.023323 -0.009856 0.032460 -v 0.017793 -0.014335 0.032460 -v 0.024113 -0.007750 0.050164 -v 0.021217 -0.013806 0.032460 -v 0.024903 -0.004328 0.050164 -v 0.024640 -0.005645 0.032460 -v 0.021217 -0.013806 0.050164 -vt 0.000000 0.000000 -vt 1.000000 0.037882 -vt 0.000000 0.037882 +f 176/154/157 168/155/157 178/156/157 +f 156/157/158 155/158/158 157/159/158 +f 156/157/158 157/159/158 159/160/158 +f 158/161/159 154/162/159 160/163/159 +f 155/158/160 156/157/160 161/164/160 +f 154/162/159 158/161/159 161/164/159 +f 156/157/158 159/160/158 162/165/158 +f 159/160/158 157/159/158 163/166/158 +f 157/159/161 160/163/161 163/166/161 +f 163/166/161 160/163/161 164/167/161 +f 160/163/159 154/162/159 164/167/159 +f 159/160/162 163/166/162 164/167/162 +f 157/159/163 155/158/163 165/168/163 +f 154/162/159 161/164/159 166/169/159 +f 164/167/159 154/162/159 167/170/159 +f 159/160/162 164/167/162 167/170/162 +f 162/165/158 159/160/158 168/155/158 +f 161/164/164 156/157/164 169/171/164 +f 156/157/158 162/165/158 169/171/158 +f 160/163/161 157/159/161 170/172/161 +f 157/159/165 165/168/165 170/172/165 +f 155/158/160 161/164/160 171/173/160 +f 161/164/166 158/161/166 171/173/166 +f 165/168/167 155/158/167 171/173/167 +f 162/165/168 166/169/168 172/174/168 +f 169/171/158 162/165/158 172/174/158 +f 166/169/169 169/171/169 172/174/169 +f 166/169/159 161/164/159 173/175/159 +f 161/164/170 169/171/170 173/175/170 +f 169/171/169 166/169/169 173/175/169 +f 154/162/159 166/169/159 174/176/159 +f 166/169/171 162/165/171 174/176/171 +f 168/155/172 154/162/172 174/176/172 +f 162/165/173 168/155/173 174/176/173 +f 160/163/161 170/172/161 175/177/161 +f 170/172/174 165/168/174 175/177/174 +f 167/170/159 154/162/159 176/154/159 +f 159/160/175 167/170/175 176/154/175 +f 154/162/157 168/155/157 176/154/157 +f 158/161/176 160/163/176 177/178/176 +f 171/173/177 158/161/177 177/178/177 +f 165/168/178 171/173/178 177/178/178 +f 160/163/179 175/177/179 177/178/179 +f 175/177/179 165/168/179 177/178/179 +f 168/155/158 159/160/158 178/156/158 +f 159/160/180 176/154/180 178/156/180 +o cup_hull_9 +v -0.040210 0.004464 0.048666 +v -0.019565 0.021316 0.022545 +v -0.032626 0.021316 0.022545 +v -0.033048 -0.001013 0.022545 +v -0.029257 0.020892 0.048241 +v -0.035996 -0.001013 0.047819 +v -0.040210 -0.001013 0.026758 +v -0.028834 -0.001013 0.023388 +v -0.034311 0.021316 0.048666 +v -0.038102 0.013729 0.027180 +v -0.040210 -0.001013 0.048666 +v -0.019565 0.020892 0.023388 +v -0.038102 0.013729 0.048666 +v -0.034733 0.020892 0.027180 +v -0.039787 0.007415 0.027602 +v -0.038945 0.002779 0.025073 +v -0.029677 -0.001013 0.027180 +v -0.029677 0.021316 0.048666 +v -0.028834 -0.001013 0.022545 +v -0.020409 0.020892 0.025917 +v -0.039367 0.009519 0.048666 +v -0.036417 -0.001013 0.048666 +v -0.038945 0.008678 0.025917 +v -0.037259 0.015836 0.048666 +v -0.040210 0.004044 0.027180 +v -0.037259 0.015836 0.027180 +v -0.038945 -0.001013 0.025073 +v -0.034733 0.020892 0.048666 +v -0.033048 0.014151 0.022545 +v -0.034311 0.021316 0.026758 +v -0.038524 0.012466 0.027602 +v -0.038524 0.011622 0.026337 +v -0.039367 0.004044 0.025495 +v -0.039367 0.009519 0.033920 +v -0.020409 0.021316 0.025917 +v -0.039787 0.007415 0.048666 +vt 0.000000 0.471711 +vt 0.806382 0.377447 +vt 0.000000 0.377447 vt 1.000000 1.000000 -vt 1.000000 0.867854 -vt 1.000000 0.018990 -vt 1.000000 0.094460 -vt 1.000000 0.999902 -vt 0.000000 0.094460 -vt 0.000000 0.999902 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.032400 0.000000 +vt 0.838684 0.000000 +vt 0.967698 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.245301 vt 0.000000 0.000000 -vt 0.000000 0.622651 -vt 1.000000 0.471809 +vt 0.000000 0.660239 +vt 0.822533 0.000000 +vt 0.967698 0.981010 vt 0.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 0.320869 -vt 0.000000 0.037882 -vt 0.952232 0.018990 -vt 0.936374 0.999902 -vt 0.000000 0.867854 -vt 1.000000 0.717012 -vt 1.000000 0.320869 -vt 1.000000 0.000000 -vt 0.000000 0.471809 -vt 0.000000 0.717012 -vt 1.000000 0.622651 -vn 0.7093 -0.7049 0.0000 +vt 0.016249 0.981010 +vt 0.870889 0.981010 +vt 0.000000 0.000000 +vt 0.000000 0.754601 +vt 0.822533 0.660239 +vt 0.822533 0.226507 +vt 0.870889 0.434025 +vt 0.822533 0.981010 +vt 0.822533 0.754601 +vt 0.903191 0.000000 +vt 0.903191 0.169832 +vt 0.000000 0.981010 +vt 1.000000 0.679131 +vt 0.838684 1.000000 +vt 0.806382 0.603661 +vt 0.854836 0.565877 +vt 0.887040 0.226507 +vt 0.564507 0.471711 +vt 0.870889 1.000000 +vn -0.9806 0.1958 0.0000 vn 0.0000 0.0000 -1.0000 -vn 0.0000 0.0000 1.0000 -vn 1.0000 0.0000 0.0000 -vn -0.0006 1.0000 0.0000 -vn 0.8944 -0.4472 0.0000 -vn -0.9941 0.0000 0.1087 -vn -0.9392 0.3433 0.0000 -vn -0.9441 0.3147 0.0984 vn 0.0000 -1.0000 0.0000 -vn -0.0013 1.0000 0.0001 -vn -0.9371 0.3410 0.0744 -vn 0.9923 -0.1242 0.0000 -vn 0.9363 -0.3513 0.0000 -vn -0.9444 -0.3139 0.0984 +vn 0.0000 1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn 0.9701 -0.2428 0.0000 -vn 0.8322 -0.5545 0.0000 -vn 0.9806 -0.1962 0.0000 +vn -0.0000 0.0000 1.0000 +vn 0.8906 -0.3639 0.2727 +vn 0.9022 -0.3818 0.2005 +vn 0.9069 -0.3765 -0.1892 +vn 0.9209 -0.3897 0.0000 +vn 0.8921 -0.2813 0.3536 +vn 0.8929 -0.3371 0.2983 +vn 0.8615 -0.2733 0.4279 +vn 0.6019 -0.1817 0.7776 +vn -0.9285 0.3713 0.0000 +vn -0.9922 0.1246 -0.0024 +vn -0.9255 0.1590 -0.3437 +vn -0.8401 0.4198 -0.3436 +vn -0.9285 0.3714 0.0000 +vn -0.8945 0.4470 0.0000 +vn -0.3941 0.0000 -0.9191 +vn -0.7085 0.7057 0.0000 +vn -0.4354 0.0257 -0.8999 +vn -0.8117 0.4855 -0.3247 +vn -0.9484 0.3171 0.0000 +vn -0.9577 0.2878 0.0019 +vn -0.7386 0.1973 -0.6447 +vn -0.9271 0.1793 -0.3293 +vn -0.8346 0.3377 -0.4352 +vn -0.8427 0.3370 -0.4198 +vn -0.9500 0.2598 -0.1732 +vn -0.9577 0.2395 -0.1596 +vn -0.5695 0.0826 -0.8178 +vn -0.6533 0.1275 -0.7463 +vn -0.8938 0.0373 -0.4470 +vn -0.8878 0.1213 -0.4440 +vn -0.7996 -0.0167 -0.6003 +vn -0.7067 0.0000 -0.7075 +vn -0.9700 0.2425 -0.0163 +vn -0.9614 0.2750 0.0000 +vn 0.8733 0.4353 0.2187 +vn 0.8147 0.4754 0.3319 +vn 0.9297 0.0000 0.3684 +vn 0.9485 0.0000 0.3168 +vn -0.9899 0.1417 0.0000 usemtl None s off -f 237/222/217 244/223/217 247/224/217 -f 223/225/218 224/226/218 225/227/218 -f 225/227/218 224/226/218 227/228/218 -f 223/225/218 225/227/218 228/229/218 -f 222/230/219 226/231/219 229/232/219 -f 226/231/219 222/230/219 230/233/219 -f 227/228/218 224/226/218 231/234/218 -f 224/226/220 223/225/220 232/235/220 -f 223/225/221 228/229/221 232/235/221 -f 226/231/219 230/233/219 232/235/219 -f 225/227/218 227/228/218 233/236/218 -f 222/230/222 227/228/222 234/237/222 -f 230/233/219 222/230/219 234/237/219 -f 229/232/219 226/231/219 235/238/219 -f 229/232/223 235/238/223 236/239/223 -f 228/229/224 225/227/224 236/239/224 -f 235/238/225 226/231/225 236/239/225 -f 222/230/219 229/232/219 237/222/219 -f 229/232/226 233/236/226 237/222/226 -f 232/235/221 228/229/221 238/240/221 -f 226/231/227 232/235/227 238/240/227 -f 228/229/224 236/239/224 238/240/224 -f 236/239/228 226/231/228 238/240/228 -f 224/226/220 232/235/220 239/241/220 -f 232/235/219 230/233/219 239/241/219 -f 231/234/218 224/226/218 240/242/218 -f 224/226/229 239/241/229 240/242/229 -f 227/228/218 231/234/218 241/243/218 -f 234/237/222 227/228/222 241/243/222 -f 231/234/230 234/237/230 241/243/230 -f 225/227/218 233/236/218 242/244/218 -f 233/236/226 229/232/226 242/244/226 -f 229/232/231 236/239/231 242/244/231 -f 236/239/232 225/227/232 242/244/232 -f 231/234/233 230/233/233 243/245/233 -f 230/233/219 234/237/219 243/245/219 -f 234/237/230 231/234/230 243/245/230 -f 227/228/234 222/230/234 244/223/234 -f 233/236/218 227/228/218 244/223/218 -f 237/222/217 233/236/217 244/223/217 -f 239/241/219 230/233/219 245/246/219 -f 230/233/235 240/242/235 245/246/235 -f 240/242/229 239/241/229 245/246/229 -f 230/233/233 231/234/233 246/247/233 -f 231/234/218 240/242/218 246/247/218 -f 240/242/235 230/233/235 246/247/235 -f 222/230/219 237/222/219 247/224/219 -f 244/223/234 222/230/234 247/224/234 -o Cup_hull_11 -v 0.024903 -0.004329 0.032460 -v 0.021479 -0.000377 0.016161 -v 0.020426 -0.000379 0.015036 -v 0.020426 -0.014335 0.015036 -v 0.011211 -0.014335 0.016161 -v 0.017530 -0.014071 0.032177 -v 0.022533 -0.000377 0.032177 -v 0.025166 -0.000377 0.017846 -v 0.020690 -0.014335 0.032458 -v 0.018056 -0.000379 0.015036 -v 0.023322 -0.009856 0.018411 -v 0.025166 -0.000377 0.032460 -v 0.011211 -0.014335 0.015036 -v 0.023322 -0.009856 0.032460 -v 0.024375 -0.006699 0.018128 -v 0.018318 -0.000379 0.017285 -v 0.011474 -0.014071 0.017004 -v 0.021743 -0.013016 0.018411 -v 0.024375 -0.000905 0.016724 -v 0.017794 -0.014335 0.032458 -v 0.025166 -0.002222 0.018411 -v 0.024112 -0.007750 0.032460 -v 0.021743 -0.013016 0.032460 -v 0.024375 -0.004329 0.017004 -v 0.011211 -0.014071 0.016161 -v 0.022796 -0.000377 0.032460 -v 0.021216 -0.013807 0.018130 -v 0.024903 -0.004329 0.018411 -v 0.025166 -0.002222 0.032460 -v 0.023586 -0.008277 0.017285 -v 0.018056 -0.000379 0.015880 -v 0.024639 -0.005646 0.032460 -v 0.020690 -0.014335 0.017285 -v 0.011211 -0.014071 0.015036 -v 0.021216 -0.013807 0.032458 -vt 0.822435 0.037784 -vt 0.000000 0.094460 -vt 0.000098 0.037784 -vt 1.000000 0.999902 -vt 0.935395 1.000000 -vt 0.838684 1.000000 -vt 0.016249 1.000000 -vt 0.935395 0.000000 +f 199/179/181 193/180/181 214/181/181 +f 181/182/182 180/183/182 182/184/182 +f 182/184/183 184/185/183 185/186/183 +f 184/185/183 182/184/183 186/187/183 +f 180/183/184 181/182/184 187/188/184 +f 179/189/185 185/186/185 189/190/185 +f 185/186/183 184/185/183 189/190/183 +f 187/188/186 179/189/186 189/190/186 +f 179/189/186 187/188/186 191/191/186 +f 184/185/183 186/187/183 195/192/183 +f 190/193/187 184/185/187 195/192/187 +f 186/187/188 190/193/188 195/192/188 +f 180/183/184 187/188/184 196/194/184 +f 187/188/186 189/190/186 196/194/186 +f 182/184/182 180/183/182 197/195/182 +f 186/187/183 182/184/183 197/195/183 +f 180/183/189 190/193/189 197/195/189 +f 190/193/190 186/187/190 197/195/190 +f 183/196/191 184/185/191 198/197/191 +f 184/185/192 190/193/192 198/197/192 +f 179/189/186 191/191/186 199/179/186 +f 184/185/193 183/196/193 200/198/193 +f 189/190/183 184/185/183 200/198/183 +f 183/196/194 196/194/194 200/198/194 +f 196/194/186 189/190/186 200/198/186 +f 191/191/186 187/188/186 202/199/186 +f 188/200/195 191/191/195 202/199/195 +f 185/186/185 179/189/185 203/201/185 +f 179/189/196 193/180/196 203/201/196 +f 193/180/197 201/202/197 203/201/197 +f 192/203/198 181/182/198 204/204/198 +f 188/200/199 202/199/199 204/204/199 +f 202/199/200 192/203/200 204/204/200 +f 182/184/183 185/186/183 205/205/183 +f 194/206/201 182/184/201 205/205/201 +f 187/188/202 192/203/202 206/207/202 +f 202/199/186 187/188/186 206/207/186 +f 192/203/200 202/199/200 206/207/200 +f 181/182/182 182/184/182 207/208/182 +f 194/206/203 181/182/203 207/208/203 +f 182/184/201 194/206/201 207/208/201 +f 187/188/184 181/182/184 208/209/184 +f 181/182/204 192/203/204 208/209/204 +f 192/203/202 187/188/202 208/209/202 +f 191/191/205 188/200/205 209/210/205 +f 199/179/206 191/191/206 209/210/206 +f 181/182/207 201/202/207 210/211/207 +f 201/202/208 193/180/208 210/211/208 +f 204/204/209 181/182/209 210/211/209 +f 188/200/210 204/204/210 210/211/210 +f 209/210/211 188/200/211 210/211/211 +f 193/180/212 209/210/212 210/211/212 +f 181/182/213 194/206/213 211/212/213 +f 201/202/214 181/182/214 211/212/214 +f 185/186/215 203/201/215 211/212/215 +f 203/201/216 201/202/216 211/212/216 +f 205/205/217 185/186/217 211/212/217 +f 194/206/218 205/205/218 211/212/218 +f 193/180/181 199/179/181 212/213/181 +f 209/210/219 193/180/219 212/213/219 +f 199/179/220 209/210/220 212/213/220 +f 190/193/221 180/183/221 213/214/221 +f 196/194/222 183/196/222 213/214/222 +f 180/183/184 196/194/184 213/214/184 +f 183/196/223 198/197/223 213/214/223 +f 198/197/224 190/193/224 213/214/224 +f 193/180/225 179/189/225 214/181/225 +f 179/189/186 199/179/186 214/181/186 +o cup_hull_10 +v -0.015351 0.037325 0.075200 +v -0.004397 0.039855 0.026341 +v -0.004817 0.039855 0.026341 +v -0.015351 0.024689 0.022542 +v -0.004397 0.038590 0.075200 +v -0.015351 0.037325 0.026764 +v -0.004397 0.028480 0.022542 +v -0.006925 0.039855 0.075200 +v -0.014507 0.035640 0.075200 +v -0.015351 0.032690 0.022542 +v -0.014929 0.024689 0.024233 +v -0.010716 0.039012 0.027187 +v -0.004397 0.032692 0.022542 +v -0.004397 0.039855 0.075200 +v -0.005239 0.038169 0.075200 +v -0.004397 0.028480 0.023815 +v -0.010716 0.039012 0.075200 +v -0.015351 0.035640 0.075200 +v -0.006925 0.039855 0.027187 +v -0.006082 0.038590 0.025078 +v -0.014507 0.037747 0.027187 +v -0.010716 0.038169 0.025501 +v -0.014507 0.037747 0.075200 +v -0.009032 0.039433 0.027187 +v -0.014507 0.036904 0.025501 +v -0.004397 0.037747 0.024656 +v -0.009032 0.039433 0.075200 +v -0.015351 0.024689 0.024233 +v -0.014507 0.024689 0.022542 +vt 1.000000 0.249926 +vt 0.975820 0.249926 vt 1.000000 0.000000 -vt 0.000098 0.000000 -vt 1.000000 0.999902 -vt 0.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 0.716915 -vt 0.000000 0.320869 -vt 0.016249 0.018892 -vt 0.887040 0.018892 -vt 0.806284 0.320869 -vt 0.806284 0.094460 -vt 0.903093 0.962216 -vt 0.000098 0.000000 -vt 0.806284 0.867854 -vt 0.000000 0.471809 -vt 0.822533 0.547083 -vt 0.887040 0.716915 -vt 0.935395 0.018892 -vt 0.870889 0.999902 +vt 0.000000 0.833186 +vt 0.919824 0.833186 +vt 0.927851 1.000000 +vt 0.000000 0.916593 +vt 0.927851 1.000000 vt 0.000000 1.000000 -vt 0.806284 0.716915 -vt 0.000000 0.867854 -vt 0.870889 0.434025 -vt 0.951547 0.999902 -vt 0.000000 0.622553 -vt 0.870889 0.000000 -vt 1.000000 0.018892 -vn 0.8321 -0.5547 0.0000 -vn 0.0010 1.0000 -0.0021 -vn 0.0000 1.0000 -0.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 1.0000 -0.0012 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 0.0000 1.0000 -vn -0.8998 -0.2478 0.3591 -vn -0.8795 0.3213 0.3510 -vn 0.8812 -0.4404 -0.1718 -vn 0.8945 -0.4470 0.0000 -vn 0.3931 0.0000 -0.9195 -vn 0.3488 0.7294 -0.5885 -vn -0.8201 -0.4665 0.3313 -vn 1.0000 0.0000 0.0000 -vn 0.9364 -0.3510 0.0000 -vn 0.9484 -0.3169 -0.0058 -vn 0.0000 -0.0013 1.0000 -vn 0.5751 -0.0666 -0.8153 -vn 0.8266 -0.0458 -0.5610 -vn 0.9275 -0.1094 -0.3575 +vt 0.000000 0.722075 +vt 1.000000 0.527557 +vt 1.000000 0.527655 +vt 0.000000 1.000000 +vt 0.000000 0.888791 +vt 0.967890 0.000000 +vt 0.000000 0.944395 +vt 0.000000 0.722075 +vt 0.911796 1.000000 +vt 0.951836 0.916593 +vt 0.911796 0.860989 +vt 0.911796 0.944395 +vt 0.943808 0.888791 +vt 0.000000 0.860989 +vt 0.911796 0.972198 +vt 0.943808 0.805384 +vt 0.959863 0.860989 +vt 0.000000 0.972198 +vt 0.967890 0.000000 +vn 0.3510 -0.9364 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.8684 0.4306 0.2457 -vn -0.9544 0.0000 0.2986 -vn -0.8736 0.4026 0.2734 -vn -0.7070 0.2583 0.6584 -vn -0.6033 0.2161 0.7677 -vn -0.0004 0.0000 1.0000 -vn 0.8456 -0.5183 -0.1275 -vn 0.9923 -0.1242 0.0000 -vn 0.9237 -0.1641 -0.3461 -vn 0.9300 -0.1164 -0.3485 -vn 0.8884 -0.3554 -0.2906 -vn 0.9131 -0.3265 -0.2442 -vn 0.7927 -0.1996 -0.5760 -vn 0.8765 -0.2063 -0.4350 -vn -0.0004 1.0000 0.0000 -vn -0.0010 1.0000 0.0002 -vn -0.8944 0.4472 0.0000 -vn -0.8809 0.4438 0.1644 -vn 0.9700 -0.2431 0.0000 -vn 0.9805 -0.1963 0.0000 -vn 0.9762 -0.2169 -0.0020 -vn 0.7740 -0.6267 -0.0907 -vn 0.7081 -0.7062 0.0000 -vn 0.0065 -0.0065 1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.2578 -0.9451 0.2009 +vn 0.3394 -0.9233 0.1797 +vn 0.4411 -0.8806 0.1733 +vn 0.0000 -0.9777 0.2101 +vn 0.0000 0.7066 -0.7076 +vn -0.4469 0.8946 0.0000 +vn -0.3020 0.9050 -0.2998 +vn -0.3165 0.9486 0.0000 +vn -0.2738 0.8602 -0.4303 +vn -0.1272 0.7616 -0.6354 +vn -0.1254 0.5515 -0.8247 +vn -0.2428 0.9701 0.0000 +vn -0.1763 0.8809 -0.4393 +vn -0.1962 0.9806 0.0000 +vn -0.2184 0.8727 -0.4366 +vn -0.1805 0.8648 -0.4685 +vn -0.6101 0.5336 -0.5858 +vn -0.2799 0.8388 -0.4670 +vn -0.1967 0.5896 -0.7834 +vn -0.0001 0.3857 -0.9226 +vn 0.1158 0.6203 -0.7758 +vn -0.0182 0.4188 -0.9079 +vn 0.0000 -1.0000 0.0000 +vn 0.3404 -0.9364 0.0848 usemtl None s off -f 274/248/236 270/249/236 282/250/236 -f 250/251/237 249/252/237 255/253/237 -f 249/252/238 254/254/238 255/253/238 -f 252/255/239 251/256/239 256/257/239 -f 249/252/240 250/251/240 257/258/240 -f 250/251/241 251/256/241 257/258/241 -f 255/253/238 254/254/238 259/259/238 -f 251/256/239 252/255/239 260/260/239 -f 257/258/241 251/256/241 260/260/241 -f 248/261/242 259/259/242 261/262/242 -f 252/255/243 253/263/243 264/264/243 -f 253/263/244 254/254/244 264/264/244 -f 251/256/245 258/265/245 265/266/245 -f 258/265/246 261/262/246 265/266/246 -f 251/256/247 250/251/247 266/267/247 -f 250/251/248 255/253/248 266/267/248 -f 253/263/249 252/255/249 267/268/249 -f 252/255/239 256/257/239 267/268/239 -f 255/253/250 259/259/250 268/269/250 -f 248/261/242 261/262/242 269/270/242 -f 261/262/251 258/265/251 269/270/251 -f 258/265/252 262/271/252 269/270/252 -f 261/262/242 259/259/242 270/249/242 -f 265/266/246 261/262/246 270/249/246 -f 267/268/253 256/257/253 270/249/253 -f 251/256/254 266/267/254 271/272/254 -f 266/267/255 255/253/255 271/272/255 -f 255/253/256 268/269/256 271/272/256 -f 260/260/257 252/255/257 272/273/257 -f 254/254/258 263/274/258 272/273/258 -f 252/255/259 264/264/259 272/273/259 -f 264/264/260 254/254/260 272/273/260 -f 254/254/261 253/263/261 273/275/261 -f 259/259/238 254/254/238 273/275/238 -f 253/263/262 267/268/262 273/275/262 -f 270/249/242 259/259/242 273/275/242 -f 267/268/263 270/249/263 273/275/263 -f 251/256/264 265/266/264 274/248/264 -f 265/266/236 270/249/236 274/248/236 -f 268/269/265 248/261/265 275/276/265 -f 262/271/266 271/272/266 275/276/266 -f 271/272/267 268/269/267 275/276/267 -f 259/259/242 248/261/242 276/277/242 -f 248/261/265 268/269/265 276/277/265 -f 268/269/250 259/259/250 276/277/250 -f 258/265/268 251/256/268 277/278/268 -f 262/271/269 258/265/269 277/278/269 -f 251/256/270 271/272/270 277/278/270 -f 271/272/271 262/271/271 277/278/271 -f 254/254/272 249/252/272 278/279/272 -f 249/252/272 257/258/272 278/279/272 -f 263/274/273 254/254/273 278/279/273 -f 257/258/274 272/273/274 278/279/274 -f 272/273/275 263/274/275 278/279/275 -f 248/261/242 269/270/242 279/280/242 -f 269/270/276 262/271/276 279/280/276 -f 275/276/277 248/261/277 279/280/277 -f 262/271/278 275/276/278 279/280/278 -f 256/257/239 251/256/239 280/281/239 -f 251/256/279 274/248/279 280/281/279 -f 274/248/280 256/257/280 280/281/280 -f 257/258/241 260/260/241 281/282/241 -f 260/260/257 272/273/257 281/282/257 -f 272/273/274 257/258/274 281/282/274 -f 270/249/281 256/257/281 282/250/281 -f 256/257/280 274/248/280 282/250/280 -o Cup_hull_12 -v 0.024903 0.004363 0.050164 -v 0.021217 0.013580 0.032460 -v 0.021481 0.013315 0.032460 -v 0.022796 -0.000377 0.032460 -v 0.020164 0.013052 0.050164 -v 0.018320 0.013315 0.032460 -v 0.025167 0.002257 0.032460 -v 0.024113 -0.000377 0.050164 -v 0.023322 0.009891 0.050164 -v 0.024376 0.006732 0.032460 -v 0.025167 -0.000377 0.032460 -v 0.021217 0.013580 0.050164 -v 0.025167 -0.000377 0.050164 -v 0.018320 0.013315 0.033306 -v 0.023060 0.010417 0.032460 -v 0.021743 0.013052 0.050164 -v 0.022796 -0.000377 0.033586 -v 0.018320 0.013580 0.033306 -v 0.024376 0.006732 0.050164 -v 0.025167 0.002257 0.050164 -v 0.020164 0.013580 0.050164 -v 0.024903 0.004363 0.032460 -v 0.022006 0.012525 0.032460 -v 0.023586 0.009103 0.032460 -v 0.024640 0.005682 0.045386 -vt 1.000000 0.339663 -vt 1.000000 0.509397 -vt 0.269871 0.434123 -vt 1.000000 1.000000 -vt 1.000000 0.981010 -vt 1.000000 0.000000 -vt 1.000000 0.981010 -vt 1.000000 0.188724 -vt 0.000000 0.339663 -vt 0.000000 0.962216 +f 221/215/226 230/216/226 243/217/226 +f 218/218/227 215/219/227 220/220/227 +f 216/221/228 219/222/228 221/215/228 +f 216/221/229 217/223/229 222/224/229 +f 215/219/230 219/222/230 222/224/230 +f 219/222/230 215/219/230 223/225/230 +f 218/218/227 220/220/227 224/226/227 +f 221/215/231 218/218/231 224/226/231 +f 216/221/228 221/215/228 227/227/228 +f 221/215/231 224/226/231 227/227/231 +f 219/222/228 216/221/228 228/228/228 +f 216/221/229 222/224/229 228/228/229 +f 222/224/230 219/222/230 228/228/230 +f 219/222/230 223/225/230 229/229/230 +f 223/225/232 225/230/232 229/229/232 +f 229/229/233 225/230/233 230/216/233 +f 221/215/228 219/222/228 230/216/228 +f 219/222/234 229/229/234 230/216/234 +f 215/219/230 222/224/230 231/231/230 +f 215/219/227 218/218/227 232/232/227 +f 223/225/230 215/219/230 232/232/230 +f 225/230/235 223/225/235 232/232/235 +f 222/224/229 217/223/229 233/233/229 +f 217/223/236 216/221/236 234/234/236 +f 220/220/237 215/219/237 235/235/237 +f 226/236/238 220/220/238 235/235/238 +f 231/231/239 226/236/239 235/235/239 +f 220/220/240 226/236/240 236/237/240 +f 217/223/241 234/234/241 236/237/241 +f 234/234/242 224/226/242 236/237/242 +f 215/219/230 231/231/230 237/238/230 +f 235/235/237 215/219/237 237/238/237 +f 231/231/239 235/235/239 237/238/239 +f 226/236/243 231/231/243 238/239/243 +f 233/233/244 217/223/244 238/239/244 +f 222/224/245 233/233/245 238/239/245 +f 236/237/246 226/236/246 238/239/246 +f 217/223/247 236/237/247 238/239/247 +f 224/226/248 220/220/248 239/240/248 +f 220/220/249 236/237/249 239/240/249 +f 236/237/250 224/226/250 239/240/250 +f 216/221/228 227/227/228 240/241/228 +f 227/227/251 224/226/251 240/241/251 +f 234/234/252 216/221/252 240/241/252 +f 224/226/253 234/234/253 240/241/253 +f 231/231/230 222/224/230 241/242/230 +f 222/224/245 238/239/245 241/242/245 +f 238/239/243 231/231/243 241/242/243 +f 218/218/254 225/230/254 242/243/254 +f 232/232/227 218/218/227 242/243/227 +f 225/230/235 232/232/235 242/243/235 +f 218/218/231 221/215/231 243/217/231 +f 225/230/254 218/218/254 243/217/254 +f 230/216/255 225/230/255 243/217/255 +o cup_hull_11 +v 0.016671 -0.036830 0.047404 +v -0.004396 -0.040201 0.075208 +v 0.004455 -0.040201 0.075208 +v 0.020883 -0.029246 0.048248 +v -0.004396 -0.040201 0.047404 +v 0.021306 -0.032617 0.075208 +v -0.004396 -0.035988 0.049092 +v -0.004396 -0.038514 0.075208 +v 0.020883 -0.034724 0.075208 +v 0.009506 -0.039357 0.047404 +v 0.021306 -0.034302 0.047404 +v 0.013718 -0.038094 0.075208 +v -0.004396 -0.035988 0.047404 +v 0.004455 -0.040201 0.047404 +v 0.021306 -0.029246 0.047404 +v 0.020463 -0.032617 0.075208 +v 0.009506 -0.039357 0.075208 +v 0.013718 -0.038094 0.047404 +v 0.015826 -0.037251 0.075208 +v 0.020883 -0.034724 0.047404 +v 0.021306 -0.034302 0.075208 +v 0.007403 -0.039779 0.047404 +v 0.007403 -0.039779 0.075208 +v 0.012455 -0.038514 0.047404 +vt 1.000000 0.704777 +vt 0.000000 0.704777 +vt 1.000000 0.655638 +vt 0.000000 0.344362 vt 0.000000 0.000000 -vt 0.000000 0.735709 vt 1.000000 0.000000 vt 0.000000 1.000000 +vt 0.939311 0.000000 vt 0.000000 0.000000 -vt 0.952232 0.981010 -vt 1.000000 0.773395 -vt 0.000000 0.962216 -vt 0.936374 0.000000 -vt 0.952232 1.000000 -vt 0.000000 0.509397 -vt 0.000000 0.188724 -vt 0.000000 1.000000 -vt 1.000000 0.924432 -vt 1.000000 0.679229 -vn 0.9762 0.2171 -0.0023 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.9505 -0.3107 0.0000 -vn -0.9546 -0.2807 0.1000 -vn 0.7093 0.7049 -0.0001 -vn 0.7079 0.7063 0.0000 -vn 0.8946 0.4468 -0.0000 -vn -0.9483 -0.3085 0.0753 -vn -0.0870 0.9506 -0.2979 -vn 0.0000 1.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.9941 0.0000 0.1087 -vn 0.9922 0.1244 0.0000 -vn 0.8325 0.5540 -0.0041 -vn 0.8945 0.4471 -0.0000 -vn 0.9282 0.3720 -0.0027 -vn 0.9486 0.3164 0.0001 -vn 0.9488 0.3160 0.0000 -vn 0.9761 0.2171 0.0062 -vn 0.9698 0.2438 0.0000 -vn 0.9807 0.1954 0.0000 -usemtl None -s off -f 304/283/282 292/284/282 307/285/282 -f 284/286/283 285/287/283 286/288/283 -f 284/286/283 286/288/283 288/289/283 -f 286/288/283 285/287/283 289/290/283 -f 283/291/284 287/292/284 290/293/284 -f 287/292/284 283/291/284 291/294/284 -f 289/290/283 285/287/283 292/284/283 -f 286/288/283 289/290/283 293/295/283 -f 290/293/285 286/288/285 293/295/285 -f 287/292/284 291/294/284 294/296/284 -f 283/291/284 290/293/284 295/297/284 -f 293/295/286 289/290/286 295/297/286 -f 290/293/285 293/295/285 295/297/285 -f 288/289/287 286/288/287 296/298/287 -f 290/293/288 287/292/288 296/298/288 -f 292/284/283 285/287/283 297/299/283 -f 285/287/289 284/286/289 298/300/289 -f 284/286/290 294/296/290 298/300/290 -f 294/296/284 291/294/284 298/300/284 -f 291/294/291 297/299/291 298/300/291 -f 286/288/285 290/293/285 299/301/285 -f 296/298/287 286/288/287 299/301/287 -f 290/293/292 296/298/292 299/301/292 -f 284/286/293 288/289/293 300/302/293 -f 294/296/294 284/286/294 300/302/294 -f 288/289/295 296/298/295 300/302/295 -f 296/298/296 287/292/296 300/302/296 -f 291/294/284 283/291/284 301/303/284 -f 289/290/297 283/291/297 302/304/297 -f 283/291/284 295/297/284 302/304/284 -f 295/297/286 289/290/286 302/304/286 -f 287/292/284 294/296/284 303/305/284 -f 294/296/294 300/302/294 303/305/294 -f 300/302/296 287/292/296 303/305/296 -f 283/291/297 289/290/297 304/283/297 -f 289/290/283 292/284/283 304/283/283 -f 297/299/283 285/287/283 305/306/283 -f 285/287/298 298/300/298 305/306/298 -f 298/300/299 297/299/299 305/306/299 -f 297/299/300 291/294/300 306/307/300 -f 292/284/283 297/299/283 306/307/283 -f 291/294/301 301/303/301 306/307/301 -f 301/303/302 292/284/302 306/307/302 -f 301/303/303 283/291/303 307/285/303 -f 292/284/304 301/303/304 307/285/304 -f 283/291/305 304/283/305 307/285/305 -o Cup_hull_13 -v 0.022533 0.001203 0.032460 -v 0.020425 0.013580 0.015036 -v 0.024113 0.006469 0.017285 -v 0.018057 -0.000377 0.015036 -v 0.012001 0.013580 0.015880 -v 0.021215 0.013580 0.032458 -v 0.025167 -0.000377 0.032460 -v 0.024903 -0.000377 0.017285 -v 0.018057 0.013315 0.032177 -v 0.022533 -0.000377 0.032177 -v 0.024640 0.005682 0.032460 -v 0.023060 0.010418 0.018409 -v 0.024903 0.004363 0.018409 -v 0.012001 0.013580 0.015036 -v 0.018319 -0.000377 0.017285 -v 0.020425 -0.000377 0.015036 -v 0.023060 0.010418 0.032460 -v 0.012001 0.013315 0.015880 -v 0.021478 0.013315 0.017846 -v 0.025167 0.002257 0.018409 -v 0.024375 0.006732 0.018409 -v 0.018319 0.013580 0.032458 -v 0.024375 0.000677 0.016724 -v 0.025167 0.002257 0.032460 -v 0.022007 0.012525 0.032460 -v 0.012265 0.013315 0.016724 -v 0.025167 -0.000377 0.017848 -v 0.023585 0.009101 0.032460 -v 0.023585 0.009101 0.018130 -v 0.024375 0.004101 0.017004 -v 0.022007 0.012525 0.018409 -v 0.021215 0.013580 0.017846 -v 0.018057 -0.000377 0.015880 -v 0.024903 0.004363 0.032460 -v 0.024375 0.006732 0.032460 -v 0.022797 -0.000377 0.032460 -v 0.024903 0.003048 0.017567 -vt 0.870889 0.000000 -vt 0.887040 0.320869 -vt 0.854738 0.245399 +vt 0.969656 0.983555 +vt 0.000000 0.983555 +vt 1.000000 0.819695 +vt 1.000000 0.540916 vt 1.000000 1.000000 -vt 0.951547 1.000000 -vt 0.000098 1.000000 -vt 0.000000 0.000000 vt 1.000000 0.000000 -vt 0.016249 0.000000 -vt 0.000000 0.113254 -vt 0.000000 0.434123 +vt 1.000000 0.344362 vt 1.000000 1.000000 -vt 0.870889 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.773493 -vt 0.951547 0.981010 -vt 0.806382 0.773493 -vt 0.838684 0.981010 -vt 0.806382 0.339663 -vt 0.806382 0.509397 -vt 0.870889 0.490505 -vt 0.000098 1.000000 -vt 0.016249 0.981010 -vt 0.903093 0.075568 -vt 0.000000 0.188724 -vt 0.806382 0.188724 -vt 0.000000 0.924432 -vt 0.903093 0.981010 -vt 0.838587 0.000000 -vt 0.000000 0.679131 -vt 0.822435 0.679131 -vt 0.806382 0.924432 -vt 0.838684 1.000000 -vt 0.951547 0.000000 -vt 0.000000 0.339663 -vt 0.000000 0.509397 -vt 0.000000 0.000000 -vn 0.7754 0.0517 -0.6294 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn -0.9103 -0.3950 -0.1240 -vn -1.0000 0.0000 0.0000 -vn -0.8884 -0.3842 0.2513 -vn 0.8637 0.4163 -0.2843 -vn 0.9761 0.2172 -0.0021 -vn 0.9402 0.2092 -0.2690 -vn -0.8192 0.4811 0.3122 -vn 0.3931 0.0000 -0.9195 -vn 0.4355 -0.2435 -0.8667 -vn 1.0000 0.0000 0.0000 -vn 0.9922 0.1244 0.0000 -vn 0.8945 0.4471 0.0000 -vn 0.7999 0.6001 0.0035 -vn 0.0000 0.0016 1.0000 -vn -0.0005 -0.0000 1.0000 -vn -0.9208 0.1815 0.3451 -vn -0.8954 -0.2927 0.3356 -vn -0.9544 0.0000 0.2987 -vn -0.8925 -0.3541 0.2793 -vn 0.9287 0.3708 0.0000 -vn 0.9486 0.3164 0.0000 -vn 0.8514 0.3069 -0.4254 -vn 0.8648 0.4076 -0.2933 -vn 0.9203 0.2739 -0.2795 -vn 0.7206 0.1602 -0.6746 -vn 0.5691 0.0670 -0.8196 -vn 0.7744 0.0515 -0.6306 -vn 0.8750 0.4373 -0.2079 -vn 0.8311 0.5561 0.0000 -vn 0.6962 0.6906 -0.1957 -vn 0.7100 0.7043 0.0000 -vn -0.9145 -0.4045 0.0000 -vn -0.9014 -0.3987 0.1686 -vn 0.9807 0.1956 0.0000 -vn 0.9698 0.2439 0.0000 -vn -0.7111 -0.2325 0.6636 -vn -0.6165 -0.1977 0.7621 -vn -0.0008 -0.0001 1.0000 -vn 0.9349 0.1913 -0.2988 -vn 0.9740 0.1222 -0.1907 -vn 0.9047 0.0349 -0.4247 -vn 0.9661 0.0538 -0.2524 -vn 0.8487 0.1544 -0.5059 -usemtl None -s off -f 315/308/306 337/309/306 344/310/306 -f 309/311/307 312/312/307 313/313/307 -f 314/314/308 311/315/308 315/308/308 -f 311/315/308 314/314/308 317/316/308 -f 308/317/309 314/314/309 318/318/309 -f 309/311/310 311/315/310 321/319/310 -f 312/312/307 309/311/307 321/319/307 -f 311/315/308 317/316/308 322/320/308 -f 311/315/310 309/311/310 323/321/310 -f 315/308/308 311/315/308 323/321/308 -f 308/317/309 318/318/309 324/322/309 -f 321/319/311 311/315/311 325/323/311 -f 312/312/312 321/319/312 325/323/312 -f 322/320/313 317/316/313 325/323/313 -f 319/324/314 309/311/314 326/325/314 -f 318/318/315 320/326/315 328/327/315 -f 320/326/316 310/328/316 328/327/316 -f 313/313/307 312/312/307 329/329/307 -f 312/312/317 316/330/317 329/329/317 -f 323/321/318 309/311/318 330/331/318 -f 315/308/319 323/321/319 330/331/319 -f 318/318/309 314/314/309 331/332/309 -f 314/314/320 327/333/320 331/332/320 -f 327/333/321 320/326/321 331/332/321 -f 308/317/309 324/322/309 332/334/309 -f 324/322/322 319/324/322 332/334/322 -f 326/325/323 313/313/323 332/334/323 -f 313/313/324 329/329/324 332/334/324 -f 329/329/325 308/317/325 332/334/325 -f 316/330/326 312/312/326 333/335/326 -f 317/316/327 316/330/327 333/335/327 -f 312/312/328 325/323/328 333/335/328 -f 325/323/329 317/316/329 333/335/329 -f 314/314/308 315/308/308 334/336/308 -f 327/333/320 314/314/320 334/336/320 -f 324/322/309 318/318/309 335/337/309 -f 319/324/330 324/322/330 335/337/330 -f 335/337/331 328/327/331 336/338/331 -f 310/328/332 309/311/332 336/338/332 -f 309/311/333 319/324/333 336/338/333 -f 328/327/334 310/328/334 336/338/334 -f 319/324/330 335/337/330 336/338/330 -f 309/311/335 310/328/335 337/309/335 -f 330/331/336 309/311/336 337/309/336 -f 315/308/337 330/331/337 337/309/337 -f 319/324/338 326/325/338 338/339/338 -f 332/334/322 319/324/322 338/339/322 -f 326/325/339 332/334/339 338/339/339 -f 309/311/307 313/313/307 339/340/307 -f 326/325/340 309/311/340 339/340/340 -f 313/313/341 326/325/341 339/340/341 -f 311/315/308 322/320/308 340/341/308 -f 325/323/342 311/315/342 340/341/342 -f 322/320/343 325/323/343 340/341/343 -f 320/326/344 318/318/344 341/342/344 -f 318/318/309 331/332/309 341/342/309 -f 331/332/321 320/326/321 341/342/321 -f 318/318/345 328/327/345 342/343/345 -f 335/337/309 318/318/309 342/343/309 -f 328/327/331 335/337/331 342/343/331 -f 314/314/309 308/317/309 343/344/309 -f 317/316/308 314/314/308 343/344/308 -f 316/330/346 317/316/346 343/344/346 -f 329/329/347 316/330/347 343/344/347 -f 308/317/348 329/329/348 343/344/348 -f 310/328/349 320/326/349 344/310/349 -f 320/326/350 327/333/350 344/310/350 -f 334/336/351 315/308/351 344/310/351 -f 327/333/352 334/336/352 344/310/352 -f 337/309/353 310/328/353 344/310/353 -o Cup_hull_14 -v 0.008313 0.022796 0.050166 -v 0.001204 0.025166 0.017848 -v 0.003047 0.024902 0.017567 -v 0.008049 0.015951 0.015036 -v 0.000413 0.024112 0.050166 -v 0.000413 0.018058 0.015036 -v 0.008313 0.023849 0.018130 -v 0.004363 0.024902 0.050166 -v 0.000413 0.024376 0.016724 -v 0.008313 0.020427 0.015036 -v 0.000413 0.025166 0.050166 -v 0.008313 0.023849 0.050166 -v 0.005679 0.024639 0.018409 -v 0.008313 0.015951 0.015318 -v 0.000413 0.018058 0.015882 -v 0.000413 0.020428 0.015036 -v 0.002257 0.025166 0.018409 -v 0.008049 0.015951 0.015318 -v 0.007785 0.022796 0.050166 -v 0.000413 0.025166 0.017848 -v 0.006733 0.023849 0.017006 -v 0.006733 0.024377 0.050166 -v 0.002257 0.025166 0.047913 -v 0.004363 0.024902 0.018409 -v 0.006733 0.024377 0.018409 -v 0.003836 0.024112 0.016724 -v 0.008313 0.023323 0.017006 -v 0.005679 0.024639 0.050166 -vt 0.000000 0.914342 -vt 0.903974 0.942829 -vt 0.000000 0.942829 -vt 0.000000 0.885659 -vt 0.000000 0.742830 -vt 0.000000 0.971415 -vt 0.919930 1.000000 -vt 0.927956 0.971415 -vt 0.951938 0.914244 -vt 1.000000 0.228684 -vt 1.000000 0.000000 -vt 1.000000 0.485756 -vt 0.911903 0.857073 +vt 0.000000 0.967208 +vt 0.000000 0.540916 +vt 0.000000 0.786805 +vt 1.000000 0.983555 vt 0.000000 1.000000 -vt 0.000000 0.857073 -vt 0.991973 0.000000 -vt 0.975920 0.228684 -vt 1.000000 0.485854 -vt 0.903974 1.000000 -vt 0.991973 0.000000 -vt 0.000000 0.742830 -vt 0.919930 1.000000 -vt 0.943911 0.857073 -vt 0.064115 1.000000 -vt 0.903974 0.971415 -vt 0.903974 0.914342 -vt 0.951938 0.885659 -vt 0.943911 0.800000 -vn 0.2417 0.9704 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.0259 0.8092 -0.5869 +vt 1.000000 0.459084 +vt 0.000000 0.459084 +vn 0.3158 -0.9488 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 +vn -0.2537 0.9628 0.0931 vn 0.0000 0.0000 -1.0000 +vn -0.2577 0.9662 0.0000 +vn 0.2336 0.9653 0.1170 vn 1.0000 0.0000 0.0000 -vn 0.7297 -0.0430 -0.6824 -vn -0.2660 -0.9640 0.0000 -vn 0.0000 0.3932 -0.9194 -vn 0.1080 0.9732 -0.2030 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -0.9812 0.1928 -vn 0.0000 -1.0000 0.0000 -vn -0.2506 -0.9533 0.1683 -vn -0.1726 -0.9668 0.1886 -vn 0.0000 0.8182 -0.5750 -vn 0.2058 0.9106 -0.3583 -vn 0.3168 0.9485 0.0000 -vn 0.0664 0.9963 0.0544 -vn 0.1241 0.9923 0.0000 -vn 0.1962 0.9806 0.0000 -vn 0.1876 0.9375 -0.2931 -vn 0.1219 0.9741 -0.1904 -vn 0.2431 0.9079 -0.3415 -vn 0.2270 0.9115 -0.3429 -vn 0.0581 0.7547 -0.6535 -vn 0.0347 0.4508 -0.8920 -vn 0.1305 0.7812 -0.6105 -vn 0.1300 0.5392 -0.8321 -vn 0.2887 0.8672 -0.4056 -vn 0.1841 0.5529 -0.8126 +vn -0.2517 0.9596 -0.1261 +vn 0.0000 0.9923 0.1241 +vn -0.2292 0.9663 0.1173 +vn 0.3712 -0.9285 0.0000 +vn 0.4471 -0.8945 0.0000 +vn 0.3935 -0.9193 -0.0020 +vn 0.4473 -0.8944 0.0000 +vn 0.7061 -0.7081 0.0000 +vn 0.1418 -0.9899 0.0000 +vn 0.1965 -0.9805 0.0000 +vn 0.2748 -0.9615 0.0000 +vn 0.2873 -0.9578 0.0014 usemtl None s off -f 366/345/354 357/346/354 372/347/354 -f 349/348/355 345/349/355 352/350/355 -f 346/351/356 347/352/356 353/353/356 -f 350/354/357 349/348/357 353/353/357 -f 348/355/358 350/354/358 354/356/358 -f 351/357/359 345/349/359 354/356/359 -f 349/348/355 352/350/355 355/358/355 -f 353/353/357 349/348/357 355/358/357 -f 345/349/359 351/357/359 356/359/359 -f 352/350/355 345/349/355 356/359/355 -f 354/356/359 345/349/359 358/360/359 -f 348/355/360 354/356/360 358/360/360 -f 349/348/357 350/354/357 359/361/357 -f 350/354/361 348/355/361 359/361/361 -f 350/354/357 353/353/357 360/362/357 -f 354/356/358 350/354/358 360/362/358 -f 353/353/362 354/356/362 360/362/362 -f 347/352/363 346/351/363 361/363/363 -f 346/351/364 355/358/364 361/363/364 -f 358/360/365 345/349/365 362/364/365 -f 348/355/366 358/360/366 362/364/366 -f 359/361/361 348/355/361 362/364/361 -f 349/348/367 359/361/367 362/364/367 -f 345/349/355 349/348/355 363/365/355 -f 362/364/365 345/349/365 363/365/365 -f 349/348/368 362/364/368 363/365/368 -f 346/351/369 353/353/369 364/366/369 -f 355/358/364 346/351/364 364/366/364 -f 353/353/357 355/358/357 364/366/357 -f 347/352/370 357/346/370 365/367/370 -f 356/359/371 351/357/371 366/345/371 -f 352/350/355 356/359/355 366/345/355 -f 355/358/372 352/350/372 367/368/372 -f 361/363/364 355/358/364 367/368/364 -f 352/350/373 361/363/373 367/368/373 -f 352/350/374 357/346/374 368/369/374 -f 357/346/375 347/352/375 368/369/375 -f 347/352/376 361/363/376 368/369/376 -f 361/363/373 352/350/373 368/369/373 -f 351/357/377 365/367/377 369/370/377 -f 365/367/378 357/346/378 369/370/378 -f 366/345/371 351/357/371 369/370/371 -f 357/346/354 366/345/354 369/370/354 -f 353/353/379 347/352/379 370/371/379 -f 354/356/380 353/353/380 370/371/380 -f 347/352/381 365/367/381 370/371/381 -f 365/367/382 354/356/382 370/371/382 -f 351/357/359 354/356/359 371/372/359 -f 365/367/383 351/357/383 371/372/383 -f 354/356/384 365/367/384 371/372/384 -f 357/346/374 352/350/374 372/347/374 -f 352/350/355 366/345/355 372/347/355 -o Cup_hull_15 -v -0.002221 -0.020392 -0.048198 -v -0.020392 -0.014862 0.015036 -v -0.020126 -0.015389 0.015036 -v -0.002221 -0.017758 0.015036 -v -0.013280 -0.011965 -0.048198 -v -0.014860 -0.020392 -0.048198 -v -0.014860 -0.020392 0.015036 -v -0.013280 -0.011965 0.015036 -v -0.020392 -0.011965 -0.048198 -v -0.002221 -0.020392 0.015036 -v -0.002221 -0.017758 -0.048198 -v -0.020392 -0.011965 0.015036 -v -0.020126 -0.015389 -0.048198 -v -0.016704 -0.019073 -0.027679 -v -0.019074 -0.016704 0.015036 -v -0.019074 -0.016704 -0.048198 -v -0.020392 -0.014862 -0.048198 -v -0.015386 -0.020128 0.015036 -v -0.015386 -0.020128 -0.048198 -v -0.016968 -0.018811 0.015036 -v -0.016704 -0.019073 -0.048198 -vt 0.000000 0.188430 -vt 1.000000 0.072533 -vt 1.000000 0.202917 +f 261/244/256 255/245/256 267/246/256 +f 246/247/257 245/248/257 248/249/257 +f 245/248/258 246/247/258 249/250/258 +f 248/249/259 245/248/259 250/251/259 +f 250/251/259 245/248/259 251/252/259 +f 245/248/258 249/250/258 251/252/258 +f 247/253/260 250/251/260 251/252/260 +f 249/250/258 246/247/258 252/254/258 +f 248/249/261 244/255/261 253/256/261 +f 244/255/261 248/249/261 254/257/261 +f 252/254/258 246/247/258 255/245/258 +f 250/251/262 247/253/262 256/258/262 +f 248/249/259 250/251/259 256/258/259 +f 254/257/261 248/249/261 256/258/261 +f 246/247/257 248/249/257 257/259/257 +f 248/249/261 253/256/261 257/259/261 +f 247/253/263 249/250/263 258/260/263 +f 249/250/264 254/257/264 258/260/264 +f 256/258/265 247/253/265 258/260/265 +f 254/257/261 256/258/261 258/260/261 +f 249/250/266 247/253/266 259/261/266 +f 251/252/258 249/250/258 259/261/258 +f 247/253/267 251/252/267 259/261/267 +f 255/245/258 246/247/258 260/262/258 +f 253/256/261 244/255/261 261/244/261 +f 255/245/268 261/244/268 262/263/268 +f 244/255/269 252/254/269 262/263/269 +f 252/254/258 255/245/258 262/263/258 +f 261/244/270 244/255/270 262/263/270 +f 252/254/271 244/255/271 263/264/271 +f 244/255/261 254/257/261 263/264/261 +f 254/257/272 252/254/272 263/264/272 +f 249/250/258 252/254/258 264/265/258 +f 254/257/264 249/250/264 264/265/264 +f 252/254/272 254/257/272 264/265/272 +f 246/247/273 257/259/273 265/266/273 +f 257/259/261 253/256/261 265/266/261 +f 253/256/274 260/262/274 265/266/274 +f 265/266/274 260/262/274 266/267/274 +f 260/262/258 246/247/258 266/267/258 +f 246/247/273 265/266/273 266/267/273 +f 260/262/275 253/256/275 267/246/275 +f 255/245/276 260/262/276 267/246/276 +f 253/256/261 261/244/261 267/246/261 +o cup_hull_12 +v 0.014562 0.037748 0.047823 +v -0.004394 0.038590 0.075211 +v 0.019619 0.033114 0.075211 +v 0.019619 0.030166 0.047823 +v -0.004394 0.036063 0.047823 +v 0.003612 0.040275 0.075211 +v -0.003552 0.040275 0.047823 +v 0.020040 0.035221 0.075211 +v 0.020463 0.034799 0.047823 +v 0.006980 0.039854 0.047823 +v 0.010771 0.039012 0.075211 +v -0.003552 0.040275 0.075211 +v 0.020040 0.030166 0.049509 +v 0.020463 0.033114 0.075211 +v -0.004394 0.039854 0.047823 +v -0.004394 0.036063 0.049509 +v 0.015827 0.037327 0.075211 +v 0.003612 0.040275 0.047823 +v 0.020463 0.030166 0.047823 +v 0.016669 0.036905 0.047823 +v 0.010771 0.039012 0.047823 +v 0.006980 0.039854 0.075211 +v -0.004394 0.039854 0.075211 +v 0.020463 0.034799 0.075211 +v 0.020040 0.035221 0.047823 +v 0.009085 0.039432 0.075211 +vt 0.000000 0.457562 +vt 0.000000 0.610083 +vt 0.000000 0.542242 +vt 1.000000 0.762604 +vt 1.000000 0.966030 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.000000 0.014585 -vt 0.000000 1.000000 -vt 1.000000 0.391347 +vt 0.000000 0.966030 +vt 0.000000 0.322075 +vt 1.000000 0.033872 +vt 0.000000 0.982966 vt 1.000000 1.000000 -vt 1.000000 0.304424 -vt 0.000000 0.304424 -vt 0.000000 0.391347 -vt 1.000000 0.000000 +vt 1.000000 0.457562 +vt 0.000000 0.033872 +vt 0.938430 0.982966 vt 0.000000 1.000000 +vt 1.000000 0.000000 +vt 0.938430 0.000000 +vt 0.000000 0.813510 +vt 1.000000 0.322075 vt 1.000000 1.000000 +vt 1.000000 0.847381 +vt 1.000000 0.610083 vt 0.000000 0.000000 -vt 1.000000 0.014585 -vt 0.000000 0.072533 -vt 1.000000 0.000000 -vt 0.000000 0.275450 -vt 1.000000 0.275450 -vt 0.675509 0.202917 -vn -0.7071 -0.7071 -0.0000 -vn -0.0000 0.0000 1.0000 +vt 0.000000 1.000000 +vt 1.000000 0.982966 +vn 0.0000 0.0000 1.0000 vn 0.0000 0.0000 -1.0000 +vn 0.0000 1.0000 0.0000 +vn -0.2210 -0.9693 0.1076 +vn 0.0000 -0.9935 0.1140 +vn -1.0000 0.0000 0.0000 +vn -0.4478 0.8941 0.0000 +vn -0.2385 -0.9711 0.0000 +vn -0.2336 -0.9677 0.0951 +vn -0.2342 -0.9704 0.0585 +vn 0.1242 0.9923 0.0000 vn 0.0000 -1.0000 0.0000 -vn 0.4640 0.8858 0.0000 -vn -0.0001 1.0000 0.0000 vn 1.0000 0.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.8934 -0.4492 0.0000 -vn -0.7807 -0.6248 0.0000 -vn -0.4482 -0.8939 0.0000 -vn -0.6246 -0.7809 0.0000 -vn -0.7072 -0.7070 0.0000 -vn -0.6398 -0.7685 0.0008 -vn -0.7059 -0.7083 0.0000 +vn 0.3922 -0.9146 0.0985 +vn 0.3712 0.9286 -0.0029 +vn 0.3163 0.9487 -0.0000 +vn 0.3161 0.9487 0.0000 +vn 0.7056 0.7086 0.0000 +vn 0.4472 0.8944 0.0000 +vn 0.4471 0.8945 -0.0000 +vn 0.2169 0.9762 -0.0016 +vn 0.2420 0.9703 0.0000 +vn 0.1964 0.9805 0.0000 usemtl None s off -f 392/373/385 388/374/385 393/375/385 -f 374/376/386 375/377/386 376/378/386 -f 377/379/387 373/380/387 378/381/387 -f 378/381/388 373/380/388 379/382/388 -f 376/378/386 375/377/386 379/382/386 -f 374/376/386 376/378/386 380/383/386 -f 376/378/389 377/379/389 380/383/389 -f 380/383/390 377/379/390 381/384/390 -f 377/379/387 378/381/387 381/384/387 -f 373/380/391 376/378/391 382/385/391 -f 379/382/388 373/380/388 382/385/388 -f 376/378/386 379/382/386 382/385/386 -f 376/378/391 373/380/391 383/386/391 -f 373/380/387 377/379/387 383/386/387 -f 377/379/389 376/378/389 383/386/389 -f 374/376/386 380/383/386 384/387/386 -f 380/383/390 381/384/390 384/387/390 -f 381/384/392 374/376/392 384/387/392 -f 375/377/393 374/376/393 385/388/393 -f 381/384/387 378/381/387 385/388/387 -f 379/382/386 375/377/386 387/389/386 -f 375/377/394 385/388/394 387/389/394 -f 385/388/387 378/381/387 388/374/387 -f 387/389/394 385/388/394 388/374/394 -f 374/376/392 381/384/392 389/390/392 -f 385/388/393 374/376/393 389/390/393 -f 381/384/387 385/388/387 389/390/387 -f 378/381/395 379/382/395 390/391/395 -f 379/382/386 387/389/386 390/391/386 -f 388/374/387 378/381/387 391/392/387 -f 378/381/395 390/391/395 391/392/395 -f 390/391/396 386/393/396 391/392/396 -f 387/389/397 388/374/397 392/373/397 -f 386/393/398 390/391/398 392/373/398 -f 390/391/386 387/389/386 392/373/386 -f 388/374/387 391/392/387 393/375/387 -f 391/392/396 386/393/396 393/375/396 -f 386/393/399 392/373/399 393/375/399 -o Cup_hull_16 -v -0.020127 -0.011963 0.015036 -v -0.018021 -0.000377 -0.048198 -v -0.013545 -0.011700 -0.048198 -v -0.020392 -0.011963 -0.048198 -v -0.020392 -0.000377 0.015029 -v -0.013545 -0.011963 0.015036 -v -0.018021 -0.000377 0.015036 -v -0.020392 -0.000377 -0.048198 -v -0.020392 -0.011963 0.015029 -v -0.013545 -0.011963 -0.048198 -v -0.013545 -0.011700 0.015036 -vt 1.000000 0.022712 -vt 0.000000 1.000000 -vt 0.000000 0.022712 -vt 1.000000 1.000000 -vt 1.000000 0.000000 +f 289/268/277 278/269/277 293/270/277 +f 268/271/278 271/272/278 272/273/278 +f 269/274/277 270/275/277 273/276/277 +f 268/271/278 272/273/278 274/277/278 +f 273/276/277 270/275/277 275/278/277 +f 271/272/278 268/271/278 276/279/278 +f 268/271/278 274/277/278 277/280/278 +f 273/276/277 275/278/277 278/269/277 +f 269/274/277 273/276/277 279/281/277 +f 273/276/279 274/277/279 279/281/279 +f 270/275/280 269/274/280 280/282/280 +f 275/278/277 270/275/277 281/283/277 +f 270/275/281 280/282/281 281/283/281 +f 272/273/282 269/274/282 282/284/282 +f 274/277/278 272/273/278 282/284/278 +f 279/281/283 274/277/283 282/284/283 +f 272/273/284 271/272/284 283/285/284 +f 269/274/282 272/273/282 283/285/282 +f 280/282/285 269/274/285 283/285/285 +f 271/272/286 280/282/286 283/285/286 +f 278/269/277 275/278/277 284/286/277 +f 274/277/279 273/276/279 285/287/279 +f 273/276/287 277/280/287 285/287/287 +f 277/280/278 274/277/278 285/287/278 +f 271/272/278 276/279/278 286/288/278 +f 280/282/288 271/272/288 286/288/288 +f 276/279/289 281/283/289 286/288/289 +f 281/283/290 280/282/290 286/288/290 +f 276/279/278 268/271/278 287/289/278 +f 268/271/291 284/286/291 287/289/291 +f 268/271/278 277/280/278 288/290/278 +f 284/286/292 268/271/292 288/290/292 +f 278/269/293 284/286/293 288/290/293 +f 277/280/287 273/276/287 289/268/287 +f 273/276/277 278/269/277 289/268/277 +f 269/274/277 279/281/277 290/291/277 +f 282/284/282 269/274/282 290/291/282 +f 279/281/283 282/284/283 290/291/283 +f 276/279/294 275/278/294 291/292/294 +f 281/283/289 276/279/289 291/292/289 +f 275/278/277 281/283/277 291/292/277 +f 275/278/294 276/279/294 292/293/294 +f 284/286/295 275/278/295 292/293/295 +f 276/279/278 287/289/278 292/293/278 +f 287/289/296 284/286/296 292/293/296 +f 288/290/297 277/280/297 293/270/297 +f 278/269/298 288/290/298 293/270/298 +f 277/280/299 289/268/299 293/270/299 +o cup_hull_13 +v 0.014563 0.037746 0.027179 +v -0.004396 0.036061 0.047823 +v -0.004396 0.039854 0.047823 +v 0.020461 0.034797 0.047823 +v 0.020040 0.020473 0.022545 +v -0.004396 0.028480 0.022545 +v -0.004396 0.039854 0.026338 +v 0.020461 0.032690 0.022545 +v 0.020461 0.029744 0.047823 +v 0.006980 0.039854 0.047823 +v 0.003191 0.040275 0.027179 +v 0.020040 0.020898 0.025073 +v -0.004396 0.032692 0.022545 +v -0.004396 0.035641 0.047397 +v 0.020040 0.035218 0.027179 +v -0.004396 0.028901 0.025494 +v 0.016670 0.036904 0.047823 +v 0.001926 0.039011 0.025073 +v -0.003552 0.040275 0.047823 +v 0.010771 0.039011 0.027179 +v 0.020461 0.020473 0.022545 +v 0.010771 0.039011 0.047823 +v 0.003612 0.040275 0.047823 +v 0.020040 0.029744 0.047823 +v -0.003552 0.040275 0.027602 +v 0.008664 0.039011 0.025917 +v 0.006980 0.039854 0.027602 +v -0.004396 0.038589 0.025073 +v 0.020461 0.034797 0.026759 +v 0.016670 0.036904 0.027179 +v 0.020040 0.020473 0.023388 +v 0.020040 0.035218 0.047823 +v 0.014986 0.037325 0.026338 +v 0.014563 0.037746 0.047823 +v 0.001926 0.039854 0.025917 +v 0.006138 0.038589 0.025073 +v -0.004396 0.028480 0.023388 +v -0.001865 0.039011 0.025073 +vt 0.866582 0.254332 +vt 0.899961 0.254332 +vt 0.899961 0.101811 vt 0.000000 0.000000 vt 0.000000 0.000000 -vt 0.000098 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.000000 +vt 0.849941 0.000000 +vt 1.000000 0.983064 vt 1.000000 1.000000 -vt 0.000098 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.457660 vt 1.000000 0.000000 -vn 0.9300 0.3677 0.0000 -vn -0.0000 0.0000 -1.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn -0.0026 0.0005 1.0000 -vn 0.0000 1.0000 0.0000 +vt 0.016836 0.000000 +vt 0.883320 0.000000 +vt 0.899961 0.983064 +vt 0.000000 0.847479 +vt 0.000000 0.033970 +vt 1.000000 1.000000 +vt 0.000000 0.610181 +vt 0.816660 0.762702 +vt 0.816660 0.610181 +vt 0.000000 0.322173 +vt 0.816660 0.305237 +vt 0.000000 0.983064 +vt 0.799922 0.033970 +vt 0.866582 0.525404 +vt 0.799922 0.457660 +vt 0.899961 0.000000 +vt 0.833301 1.000000 +vt 0.816660 0.983064 +vt 0.816660 0.847479 +vt 0.966621 0.983064 +vt 0.000000 0.983064 +vt 0.849941 0.779736 +vt 0.000000 0.762702 +vt 0.899961 0.423789 +vt 0.966621 0.000000 +vn 0.0000 0.7074 -0.7069 +vn -0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.0234 0.0000 0.9997 +vn 0.0000 0.0000 -1.0000 vn 1.0000 0.0000 0.0000 +vn -0.2943 -0.9134 0.2811 +vn 0.0000 0.3715 -0.9284 +vn -0.4459 0.8951 0.0000 +vn 0.7464 -0.6248 0.2291 +vn 0.3167 0.9485 0.0000 +vn 0.2171 0.9761 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -0.9320 0.3624 +vn -0.1808 -0.6995 0.6914 +vn -0.2253 -0.9081 0.3531 +vn 0.1761 0.9394 -0.2941 +vn 0.2171 0.9762 0.0000 +vn 0.1239 0.9923 0.0000 +vn 0.1106 0.9939 -0.0023 +vn 0.1403 0.9344 -0.3274 +vn 0.7068 0.7074 0.0000 +vn 0.4086 0.8166 -0.4076 +vn 0.3707 0.9287 0.0000 +vn 0.4475 0.8943 0.0000 +vn 0.4084 0.8164 -0.4082 +vn -0.3114 -0.9503 0.0000 +vn -0.2991 -0.9253 0.2331 +vn 0.0000 -1.0000 0.0000 +vn 0.4397 -0.8709 0.2194 +vn 0.3021 0.9047 -0.3003 +vn 0.2447 0.7707 -0.5884 +vn 0.2591 0.8635 -0.4327 +vn 0.3572 0.8949 -0.2676 +vn 0.4081 0.8164 -0.4085 +vn -0.0202 0.9526 -0.3034 +vn -0.0188 0.9540 -0.2992 +vn 0.1130 0.9031 -0.4143 +vn 0.0937 0.7491 -0.6558 +vn 0.0494 0.4925 -0.8689 +vn 0.1386 0.6550 -0.7428 +vn 0.0708 0.7056 -0.7051 +vn -0.3059 -0.9336 0.1865 +vn -0.1172 0.7019 -0.7026 +vn -0.0657 0.3933 -0.9171 +vn -0.0405 0.7919 -0.6092 usemtl None s off -f 396/394/400 400/395/400 404/396/400 -f 395/397/401 396/394/401 397/398/401 -f 394/399/402 397/398/402 399/400/402 -f 394/399/403 399/400/403 400/395/403 -f 396/394/400 395/397/400 400/395/400 -f 398/401/404 394/399/404 400/395/404 -f 395/397/405 398/401/405 400/395/405 -f 395/397/401 397/398/401 401/402/401 -f 397/398/406 398/401/406 401/402/406 -f 398/401/405 395/397/405 401/402/405 -f 397/398/402 394/399/402 402/403/402 -f 394/399/407 398/401/407 402/403/407 -f 398/401/406 397/398/406 402/403/406 -f 397/398/401 396/394/401 403/404/401 -f 396/394/408 399/400/408 403/404/408 -f 399/400/402 397/398/402 403/404/402 -f 399/400/408 396/394/408 404/396/408 -f 400/395/403 399/400/403 404/396/403 -o Cup_hull_17 -v 0.015424 -0.020127 0.015036 -v 0.020163 -0.000379 -0.048198 -v 0.018057 -0.000379 -0.048198 -v 0.012263 -0.020390 -0.048198 -v 0.020426 -0.014861 -0.048192 -v 0.018057 -0.000379 0.015036 -v 0.012263 -0.013017 0.015036 -v 0.020426 -0.014859 0.015036 -v 0.012263 -0.013017 -0.048198 -v 0.020426 -0.000379 0.015036 -v 0.012263 -0.020390 0.015036 -v 0.014897 -0.020390 -0.048198 -v 0.018846 -0.016967 -0.048198 -v 0.020426 -0.000379 -0.048192 -v 0.018583 -0.017230 0.015036 -v 0.017003 -0.018811 -0.048198 -v 0.014897 -0.020390 0.015036 -v 0.017003 -0.018811 0.015036 -v 0.019899 -0.015651 0.015036 -v 0.015424 -0.020127 -0.044540 -v 0.019899 -0.015651 -0.048198 -vt 0.000000 0.236832 -vt 1.000000 0.171040 -vt 1.000000 0.236832 -vt 1.000000 1.000000 +f 328/294/300 311/295/300 331/296/300 +f 296/297/301 295/298/301 297/299/301 +f 295/298/302 296/297/302 299/300/302 +f 299/300/302 296/297/302 300/301/302 +f 298/302/303 299/300/303 301/303/303 +f 297/299/301 295/298/301 302/304/301 +f 301/303/304 297/299/304 302/304/304 +f 296/297/301 297/299/301 303/305/301 +f 299/300/302 300/301/302 306/306/302 +f 301/303/303 299/300/303 306/306/303 +f 295/298/302 299/300/302 307/307/302 +f 307/307/302 299/300/302 309/308/302 +f 305/309/305 307/307/305 309/308/305 +f 303/305/301 297/299/301 310/310/301 +f 301/303/306 306/306/306 311/295/306 +f 300/301/307 296/297/307 312/311/307 +f 296/297/301 303/305/301 312/311/301 +f 298/302/303 301/303/303 314/312/303 +f 301/303/304 302/304/304 314/312/304 +f 302/304/308 305/309/308 314/312/308 +f 303/305/301 310/310/301 315/313/301 +f 294/314/309 313/315/309 315/313/309 +f 313/315/310 303/305/310 315/313/310 +f 312/311/301 303/305/301 316/316/301 +f 304/317/311 312/311/311 316/316/311 +f 302/304/301 295/298/301 317/318/301 +f 305/309/312 302/304/312 317/318/312 +f 295/298/313 307/307/313 317/318/313 +f 307/307/314 305/309/314 317/318/314 +f 300/301/307 312/311/307 318/319/307 +f 312/311/311 304/317/311 318/319/311 +f 313/315/315 319/320/315 320/321/315 +f 303/305/316 313/315/316 320/321/316 +f 316/316/317 303/305/317 320/321/317 +f 304/317/318 316/316/318 320/321/318 +f 319/320/319 304/317/319 320/321/319 +f 306/306/302 300/301/302 321/322/302 +f 297/299/304 301/303/304 322/323/304 +f 308/324/320 297/299/320 322/323/320 +f 308/324/321 322/323/321 323/325/321 +f 294/314/322 310/310/322 323/325/322 +f 310/310/323 308/324/323 323/325/323 +f 322/323/324 301/303/324 323/325/324 +f 299/300/325 298/302/325 324/326/325 +f 305/309/326 309/308/326 324/326/326 +f 298/302/327 314/312/327 324/326/327 +f 314/312/328 305/309/328 324/326/328 +f 297/299/320 308/324/320 325/327/320 +f 310/310/301 297/299/301 325/327/301 +f 308/324/323 310/310/323 325/327/323 +f 313/315/329 294/314/329 326/328/329 +f 301/303/330 319/320/330 326/328/330 +f 319/320/331 313/315/331 326/328/331 +f 294/314/332 323/325/332 326/328/332 +f 323/325/333 301/303/333 326/328/333 +f 310/310/322 294/314/322 327/329/322 +f 315/313/301 310/310/301 327/329/301 +f 294/314/309 315/313/309 327/329/309 +f 300/301/334 318/319/334 328/294/334 +f 318/319/335 304/317/335 328/294/335 +f 304/317/336 319/320/336 328/294/336 +f 328/294/337 319/320/337 329/330/337 +f 301/303/338 311/295/338 329/330/338 +f 319/320/339 301/303/339 329/330/339 +f 311/295/340 328/294/340 329/330/340 +f 309/308/302 299/300/302 330/331/302 +f 299/300/325 324/326/325 330/331/325 +f 324/326/341 309/308/341 330/331/341 +f 311/295/306 306/306/306 331/296/306 +f 321/322/342 300/301/342 331/296/342 +f 306/306/343 321/322/343 331/296/343 +f 300/301/344 328/294/344 331/296/344 +o cup_hull_14 +v -0.023777 -0.032617 -0.072261 +v -0.032623 -0.023769 0.022524 +v -0.032202 -0.024612 0.022524 +v -0.002711 -0.028403 0.020844 +v -0.021250 -0.019134 -0.072261 +v -0.002711 -0.032617 -0.072261 +v -0.023777 -0.032617 0.022524 +v -0.021250 -0.019134 0.022524 +v -0.032623 -0.019134 -0.072261 +v -0.002711 -0.032617 0.022524 +v -0.003132 -0.028403 -0.072261 +v -0.032623 -0.019134 0.022524 +v -0.032202 -0.024612 -0.072261 +v -0.026726 -0.030508 0.022524 +v -0.027148 -0.030088 -0.072261 +v -0.030518 -0.026717 0.022524 +v -0.032623 -0.023769 -0.072261 +v -0.002711 -0.028824 -0.072261 +v -0.030518 -0.026717 -0.072261 +v -0.002711 -0.028824 0.022524 +v -0.024620 -0.032194 -0.072261 +v -0.024620 -0.032194 0.022524 +v -0.026726 -0.030508 -0.072261 +vt 1.000000 0.183064 +vt 1.000000 0.267548 +vt 1.000000 0.197161 +vt 1.000000 0.295742 +vt 1.000000 0.380225 vt 1.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 0.014097 +vt 0.000000 0.295742 +vt 0.017719 1.000000 +vt 0.000000 0.380225 vt 1.000000 0.000000 vt 0.000000 1.000000 -vt 0.000000 0.013119 -vt 0.000000 0.368416 -vt 0.000000 0.276385 -vt 1.000000 0.368416 -vt 0.000000 1.000000 -vt 0.999902 0.276287 +vt 1.000000 0.985903 vt 0.000000 0.000000 +vt 1.000000 0.014097 +vt 0.000000 0.197161 +vt 0.000000 0.070387 vt 1.000000 0.000000 -vt 0.999902 1.000000 -vt 0.000000 0.157920 -vt 1.000000 0.078911 -vt 0.000000 0.000000 -vt 0.000000 0.078911 -vt 0.942150 0.013119 -vn 0.7809 -0.6247 0.0000 +vt 1.000000 1.000000 +vt 1.000000 0.070387 +vt 0.000000 1.000000 +vt 0.000000 0.267548 vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.4472 0.8944 0.0000 vn 0.0000 1.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn -0.9090 0.4167 0.0000 +vn 1.0000 -0.0000 0.0000 +vn 0.4555 0.8903 -0.0021 vn -1.0000 0.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -vn 0.0235 0.0000 -0.9997 -vn 0.4461 -0.8950 0.0000 -vn 0.7072 -0.7070 0.0000 -vn 0.7071 -0.7071 0.0000 -vn 0.6404 -0.7681 0.0000 -vn 0.8326 -0.5539 0.0000 -vn 0.7682 -0.6403 0.0005 -vn 0.5997 -0.7997 -0.0289 -vn 0.0121 -0.0002 -0.9999 -vn 0.8319 -0.5549 0.0000 +vn -0.8944 -0.4472 0.0000 +vn -0.7069 -0.7073 0.0000 +vn -0.7809 -0.6246 0.0000 +vn 0.7066 0.7077 -0.0032 +vn -0.7071 -0.7071 0.0000 +vn 0.4522 0.8652 0.2169 +vn -0.4478 -0.8941 0.0000 +vn -0.6252 -0.7804 0.0000 +vn -0.7054 -0.7088 0.0000 usemtl None s off -f 423/405/409 417/406/409 425/407/409 -f 407/408/410 406/409/410 408/410/410 -f 406/409/411 407/408/411 410/411/411 -f 405/412/412 410/411/412 411/413/412 -f 410/411/413 407/408/413 411/413/413 -f 410/411/412 405/412/412 412/414/412 -f 407/408/410 408/410/410 413/415/410 -f 411/413/413 407/408/413 413/415/413 -f 408/410/414 411/413/414 413/415/414 -f 406/409/411 410/411/411 414/416/411 -f 412/414/415 409/417/415 414/416/415 -f 410/411/412 412/414/412 414/416/412 -f 405/412/412 411/413/412 415/418/412 -f 411/413/414 408/410/414 415/418/414 -f 408/410/410 406/409/410 416/419/410 -f 415/418/416 408/410/416 416/419/416 -f 416/419/410 406/409/410 417/406/410 -f 409/417/417 406/409/417 418/420/417 -f 406/409/411 414/416/411 418/420/411 -f 414/416/415 409/417/415 418/420/415 -f 412/414/412 405/412/412 419/421/412 -f 416/419/410 417/406/410 420/422/410 -f 405/412/412 415/418/412 421/423/412 -f 416/419/418 405/412/418 421/423/418 -f 415/418/416 416/419/416 421/423/416 -f 419/421/412 405/412/412 422/424/412 -f 417/406/419 419/421/419 422/424/419 -f 420/422/420 417/406/420 422/424/420 -f 405/412/421 420/422/421 422/424/421 -f 409/417/422 412/414/422 423/405/422 -f 412/414/412 419/421/412 423/405/412 -f 419/421/423 417/406/423 423/405/423 -f 405/412/418 416/419/418 424/425/418 -f 420/422/421 405/412/421 424/425/421 -f 416/419/424 420/422/424 424/425/424 -f 406/409/425 409/417/425 425/407/425 -f 417/406/410 406/409/410 425/407/410 -f 409/417/426 423/405/426 425/407/426 -o Cup_hull_18 -v -0.015651 0.019899 -0.048198 -v -0.020392 0.013317 0.015036 -v -0.011965 0.013317 0.015036 -v 0.000413 0.020426 0.015036 -v -0.011965 0.013317 -0.048198 -v 0.000413 0.018056 -0.048198 -v -0.014861 0.020425 0.015036 -v -0.020392 0.014897 -0.048198 -v 0.000413 0.020426 -0.048198 -v 0.000413 0.018056 0.015036 -v -0.020392 0.013317 -0.048198 -v -0.018811 0.017002 0.015036 -v -0.014861 0.020425 -0.048198 -v -0.020392 0.014897 0.015036 -v -0.018811 0.017002 -0.048198 -v -0.017231 0.018583 0.015036 -v -0.020127 0.015424 0.015036 -v -0.016966 0.018846 -0.048198 -v -0.015651 0.019899 0.015036 -v -0.020127 0.015424 -0.045667 -vt 0.000000 0.012725 -vt 1.000000 0.075959 -vt 0.959965 0.012725 +f 346/332/345 352/333/345 354/334/345 +f 332/335/345 336/336/345 337/337/345 +f 333/338/346 334/339/346 338/340/346 +f 332/335/347 337/337/347 338/340/347 +f 335/341/348 336/336/348 339/342/348 +f 333/338/346 338/340/346 339/342/346 +f 336/336/345 332/335/345 340/343/345 +f 339/342/349 336/336/349 340/343/349 +f 337/337/350 335/341/350 341/344/350 +f 338/340/347 337/337/347 341/344/347 +f 339/342/346 338/340/346 341/344/346 +f 336/336/351 335/341/351 342/345/351 +f 337/337/345 336/336/345 342/345/345 +f 333/338/346 339/342/346 343/346/346 +f 340/343/352 333/338/352 343/346/352 +f 339/342/349 340/343/349 343/346/349 +f 334/339/353 333/338/353 344/347/353 +f 340/343/345 332/335/345 344/347/345 +f 338/340/346 334/339/346 345/348/346 +f 344/347/345 332/335/345 346/332/345 +f 346/332/354 345/348/354 347/349/354 +f 334/339/355 344/347/355 347/349/355 +f 345/348/346 334/339/346 347/349/346 +f 333/338/352 340/343/352 348/350/352 +f 344/347/353 333/338/353 348/350/353 +f 340/343/345 344/347/345 348/350/345 +f 335/341/350 337/337/350 349/351/350 +f 342/345/356 335/341/356 349/351/356 +f 337/337/345 342/345/345 349/351/345 +f 344/347/345 346/332/345 350/352/345 +f 346/332/357 347/349/357 350/352/357 +f 347/349/355 344/347/355 350/352/355 +f 335/341/358 339/342/358 351/353/358 +f 341/344/350 335/341/350 351/353/350 +f 339/342/346 341/344/346 351/353/346 +f 332/335/359 338/340/359 352/333/359 +f 346/332/345 332/335/345 352/333/345 +f 338/340/346 345/348/346 353/354/346 +f 352/333/359 338/340/359 353/354/359 +f 345/348/360 352/333/360 353/354/360 +f 345/348/361 346/332/361 354/334/361 +f 352/333/360 345/348/360 354/334/360 +o cup_hull_15 +v -0.025041 0.031848 -0.072261 +v -0.032626 0.021318 0.022524 +v -0.019144 0.021318 0.022524 +v 0.000660 0.032692 0.022524 +v -0.019144 0.021318 -0.072261 +v 0.000660 0.028900 -0.072261 +v -0.023777 0.032691 0.022524 +v -0.032626 0.023845 -0.072261 +v 0.000660 0.032692 -0.072261 +v 0.000660 0.028900 0.022524 +v -0.032626 0.021318 -0.072261 +v -0.030098 0.027214 0.022524 +v -0.023777 0.032691 -0.072261 +v -0.032626 0.023845 0.022524 +v -0.030098 0.027214 -0.072261 +v -0.027146 0.030162 0.022524 +v -0.032203 0.024687 0.022524 +v -0.027146 0.030162 -0.072261 +v -0.032203 0.024687 -0.072261 +v -0.025041 0.031848 0.022524 +vt 0.000000 0.164644 +vt 0.000000 0.265857 +vt 0.000000 0.227878 vt 0.000000 0.000000 vt 0.000000 0.405051 vt 0.000000 1.000000 vt 1.000000 0.405051 vt 1.000000 1.000000 vt 1.000000 0.227878 -vt 0.000000 0.265858 vt 1.000000 0.000000 vt 1.000000 1.000000 vt 0.000000 1.000000 vt 1.000000 0.000000 vt 0.000000 0.075959 -vt 1.000000 0.265858 +vt 1.000000 0.265857 vt 0.000000 0.000000 -vt 0.000000 0.151919 +vt 1.000000 0.075959 +vt 0.000000 0.012725 vt 1.000000 0.164644 -vt 0.000000 0.227878 -vn -0.7682 0.6402 0.0000 +vt 1.000000 0.012725 vn 0.0000 0.0000 1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.3576 -0.9339 0.0000 -vn -0.0000 0.0000 -1.0000 +vn 0.3575 -0.9339 0.0000 +vn 0.0000 0.0000 -1.0000 vn 1.0000 0.0000 0.0000 vn -0.0000 1.0000 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.5543 0.8323 0.0000 -vn -0.7072 0.7070 0.0000 -vn -0.8935 0.4490 0.0000 -vn -0.7069 0.7074 -0.0000 -vn -0.6400 0.7684 0.0005 -vn -0.6249 0.7807 0.0000 -vn -0.7991 0.5998 -0.0413 +vn -0.5548 0.8320 0.0000 +vn -0.7067 0.7075 0.0000 +vn -0.8933 0.4495 0.0000 +vn -0.7683 0.6401 0.0000 +vn -0.6251 0.7805 0.0000 usemtl None s off -f 442/426/427 440/427/427 445/428/427 -f 427/429/428 428/430/428 429/431/428 -f 428/430/429 427/429/429 430/432/429 -f 428/430/430 430/432/430 431/433/430 -f 430/432/431 426/434/431 431/433/431 -f 427/429/428 429/431/428 432/435/428 -f 426/434/431 430/432/431 433/436/431 -f 429/431/432 431/433/432 434/437/432 -f 431/433/431 426/434/431 434/437/431 -f 432/435/433 429/431/433 434/437/433 -f 429/431/428 428/430/428 435/438/428 -f 428/430/430 431/433/430 435/438/430 -f 431/433/432 429/431/432 435/438/432 -f 430/432/429 427/429/429 436/439/429 -f 433/436/431 430/432/431 436/439/431 -f 427/429/434 433/436/434 436/439/434 -f 427/429/428 432/435/428 437/440/428 -f 426/434/435 432/435/435 438/441/435 -f 434/437/431 426/434/431 438/441/431 -f 432/435/433 434/437/433 438/441/433 -f 433/436/434 427/429/434 439/442/434 -f 427/429/428 437/440/428 439/442/428 -f 426/434/431 433/436/431 440/427/431 -f 440/427/436 437/440/436 441/443/436 -f 437/440/428 432/435/428 441/443/428 -f 433/436/437 439/442/437 442/426/437 -f 439/442/428 437/440/428 442/426/428 -f 437/440/427 440/427/427 442/426/427 -f 426/434/431 440/427/431 443/444/431 -f 440/427/438 441/443/438 443/444/438 -f 443/444/439 441/443/439 444/445/439 -f 432/435/435 426/434/435 444/445/435 -f 441/443/428 432/435/428 444/445/428 -f 426/434/440 443/444/440 444/445/440 -f 440/427/441 433/436/441 445/428/441 -f 433/436/437 442/426/437 445/428/437 -o Cup_hull_19 -v 0.018056 0.017793 -0.048198 -v 0.000413 0.018056 0.015036 -v 0.012788 0.012527 0.015036 -v 0.014896 0.020427 0.015036 -v 0.000413 0.020426 -0.048198 -v 0.012788 0.012527 -0.048198 -v 0.020427 0.012527 0.015036 -v 0.020427 0.012527 -0.048192 -v 0.014896 0.020427 -0.048198 -v 0.000413 0.020426 0.015036 -v 0.000413 0.018056 -0.048198 -v 0.020427 0.014897 0.015036 -v 0.020427 0.014897 -0.048192 -v 0.018319 0.017529 0.015036 -v 0.015686 0.019898 0.015036 -v 0.019900 0.015686 -0.048198 -v 0.017265 0.018583 -0.048198 -v 0.019900 0.015686 0.015036 -v 0.018583 0.017266 -0.048198 -v 0.015686 0.019898 -0.048198 -v 0.017792 0.018056 0.015036 -vt 1.000000 0.842013 -vt 0.000000 0.763117 -vt 0.000000 0.868344 +f 370/355/362 361/356/362 374/357/362 +f 356/358/362 357/359/362 358/360/362 +f 357/359/363 356/358/363 359/361/363 +f 357/359/364 359/361/364 360/362/364 +f 359/361/365 355/363/365 360/362/365 +f 356/358/362 358/360/362 361/356/362 +f 355/363/365 359/361/365 362/364/365 +f 358/360/366 360/362/366 363/365/366 +f 360/362/365 355/363/365 363/365/365 +f 361/356/367 358/360/367 363/365/367 +f 358/360/362 357/359/362 364/366/362 +f 357/359/364 360/362/364 364/366/364 +f 360/362/366 358/360/366 364/366/366 +f 359/361/363 356/358/363 365/367/363 +f 362/364/365 359/361/365 365/367/365 +f 356/358/368 362/364/368 365/367/368 +f 356/358/362 361/356/362 366/368/362 +f 355/363/369 361/356/369 367/369/369 +f 363/365/365 355/363/365 367/369/365 +f 361/356/367 363/365/367 367/369/367 +f 362/364/368 356/358/368 368/370/368 +f 356/358/362 366/368/362 368/370/362 +f 355/363/365 362/364/365 369/371/365 +f 369/371/370 366/368/370 370/355/370 +f 366/368/362 361/356/362 370/355/362 +f 362/364/371 368/370/371 371/372/371 +f 368/370/362 366/368/362 371/372/362 +f 366/368/372 369/371/372 371/372/372 +f 355/363/365 369/371/365 372/373/365 +f 369/371/370 370/355/370 372/373/370 +f 370/355/373 355/363/373 372/373/373 +f 369/371/365 362/364/365 373/374/365 +f 362/364/371 371/372/371 373/374/371 +f 371/372/372 369/371/372 373/374/372 +f 361/356/369 355/363/369 374/357/369 +f 355/363/373 370/355/373 374/357/373 +o cup_hull_16 +v 0.029310 0.028057 -0.072261 +v 0.000664 0.028900 0.022524 +v 0.019621 0.020894 0.022524 +v 0.023831 0.032692 0.022524 +v 0.000664 0.032692 -0.072261 +v 0.019621 0.020894 -0.072261 +v 0.032679 0.020894 0.022524 +v 0.023831 0.032692 -0.072261 +v 0.032679 0.020894 -0.072261 +v 0.000664 0.032692 0.022524 +v 0.000664 0.028900 -0.072261 +v 0.032679 0.023845 0.022524 +v 0.032679 0.023845 -0.072261 +v 0.028047 0.029320 0.022524 +v 0.031839 0.025108 0.022524 +v 0.025097 0.031848 -0.072261 +v 0.031839 0.025108 -0.072261 +v 0.025097 0.031848 0.022524 +v 0.028047 0.029320 -0.072261 +v 0.029310 0.028057 0.022524 +vt 0.000000 0.973762 +vt 1.000000 0.894752 +vt 0.000000 0.894752 vt 0.000000 0.000000 -vt 0.000000 0.618344 -vt 0.000000 0.723669 -vt 1.000000 0.618344 +vt 0.000000 0.592129 +vt 0.000000 0.723615 +vt 1.000000 0.592129 vt 1.000000 0.000000 -vt 1.000000 0.881558 vt 0.000000 1.000000 -vt 0.999902 1.000000 -vt 1.000000 0.723669 +vt 1.000000 0.723615 +vt 1.000000 1.000000 vt 0.000000 0.000000 vt 1.000000 0.000000 vt 0.000000 1.000000 -vt 0.999902 1.000000 -vt 0.000000 0.894675 -vt 1.000000 0.973669 -vt 0.000000 0.973669 -vt 1.000000 0.907890 -vt 1.000000 0.763117 -vn 0.6585 0.7526 0.0008 +vt 1.000000 1.000000 +vt 0.000000 0.855297 +vt 1.000000 0.763168 +vt 1.000000 0.973762 +vt 0.000000 0.763168 +vt 1.000000 0.855297 +vn 0.7589 0.6512 0.0000 vn 0.0000 0.0000 1.0000 -vn -0.4079 -0.9130 0.0000 +vn -0.3890 -0.9212 0.0000 vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.0001 1.0000 0.0000 +vn 0.0000 1.0000 0.0000 vn -1.0000 0.0000 0.0000 vn 1.0000 0.0000 0.0000 -vn 0.5560 0.8312 0.0000 -vn 0.0008 -0.0018 -1.0000 -vn 0.0117 0.0000 -0.9999 -vn 0.8317 0.5552 -0.0000 -vn 0.8315 0.5555 0.0000 -vn 0.7682 0.6402 0.0000 -vn 0.7069 0.7073 0.0000 -vn -0.0001 0.0000 -1.0000 -vn 0.7590 0.6511 0.0005 -vn 0.6401 0.7683 0.0000 -vn 0.7066 0.7076 0.0000 +vn 0.8327 0.5537 0.0000 +vn 0.5547 0.8321 0.0000 +vn 0.6508 0.7593 0.0000 +vn 0.7072 0.7071 0.0000 +usemtl None +s off +f 389/375/374 375/376/374 394/377/374 +f 376/378/375 377/379/375 378/380/375 +f 377/379/376 376/378/376 380/381/376 +f 379/382/377 375/376/377 380/381/377 +f 377/379/378 380/381/378 381/383/378 +f 378/380/375 377/379/375 381/383/375 +f 375/376/377 379/382/377 382/384/377 +f 379/382/379 378/380/379 382/384/379 +f 380/381/377 375/376/377 383/385/377 +f 381/383/378 380/381/378 383/385/378 +f 376/378/375 378/380/375 384/386/375 +f 378/380/379 379/382/379 384/386/379 +f 379/382/380 376/378/380 384/386/380 +f 376/378/380 379/382/380 385/387/380 +f 380/381/376 376/378/376 385/387/376 +f 379/382/377 380/381/377 385/387/377 +f 378/380/375 381/383/375 386/388/375 +f 381/383/381 383/385/381 386/388/381 +f 386/388/381 383/385/381 387/389/381 +f 383/385/377 375/376/377 387/389/377 +f 378/380/375 386/388/375 388/390/375 +f 388/390/375 386/388/375 389/375/375 +f 386/388/382 387/389/382 389/375/382 +f 375/376/377 382/384/377 390/391/377 +f 382/384/383 378/380/383 390/391/383 +f 387/389/377 375/376/377 391/392/377 +f 389/375/382 387/389/382 391/392/382 +f 375/376/374 389/375/374 391/392/374 +f 378/380/375 388/390/375 392/393/375 +f 390/391/383 378/380/383 392/393/383 +f 388/390/384 390/391/384 392/393/384 +f 388/390/385 375/376/385 393/394/385 +f 375/376/377 390/391/377 393/394/377 +f 390/391/384 388/390/384 393/394/384 +f 375/376/385 388/390/385 394/377/385 +f 388/390/375 389/375/375 394/377/375 +o cup_hull_17 +v -0.017040 -0.036409 0.026339 +v -0.034312 -0.021664 0.067199 +v -0.034312 -0.021242 0.067199 +v -0.016615 -0.034722 0.075211 +v -0.019144 -0.021240 0.022545 +v -0.032623 -0.023770 0.022545 +v -0.024624 -0.032194 0.075211 +v -0.032204 -0.021242 0.075211 +v -0.026726 -0.030508 0.022545 +v -0.016617 -0.023347 0.023390 +v -0.033889 -0.021242 0.026339 +v -0.030518 -0.026719 0.075211 +v -0.018725 -0.035987 0.068462 +v -0.016617 -0.032614 0.022545 +v -0.021674 -0.034301 0.027607 +v -0.016615 -0.036409 0.075211 +v -0.030518 -0.026719 0.022545 +v -0.032623 -0.021242 0.022545 +v -0.033468 -0.022927 0.075211 +v -0.024624 -0.032194 0.022545 +v -0.033466 -0.022929 0.027607 +v -0.026725 -0.030508 0.075211 +v -0.022938 -0.033457 0.075211 +v -0.016617 -0.036409 0.026339 +v -0.017461 -0.036409 0.026762 +v -0.017459 -0.036409 0.075211 +v -0.033889 -0.021242 0.075211 +v -0.032204 -0.024612 0.022545 +v -0.016617 -0.023347 0.022545 +v -0.033889 -0.022085 0.026762 +v -0.021674 -0.034301 0.068462 +v -0.023782 -0.032614 0.022545 +v -0.019144 -0.021240 0.022973 +v -0.032204 -0.024612 0.075211 +v -0.018725 -0.035987 0.058776 +v -0.022938 -0.033457 0.027607 +vt 0.000000 0.642717 +vt 1.000000 0.547475 +vt 0.903876 0.642717 +vt 0.000000 0.547475 +vt 0.000000 1.000000 +vt 0.000000 0.119127 +vt 1.000000 0.095438 +vt 1.000000 0.857087 +vt 1.000000 0.428641 +vt 0.983947 0.999902 +vt 0.152114 0.000000 +vt 0.152114 0.000000 +vt 0.927956 0.023884 +vt 0.000000 0.214370 +vt 1.000000 0.999902 +vt 0.000000 1.000000 +vt 1.000000 0.214370 +vt 1.000000 0.095438 +vt 0.000000 0.047670 +vt 0.903876 0.047768 +vt 0.000000 0.428739 +vt 0.927956 0.976018 +vt 0.927956 0.999902 +vt 0.919930 0.952232 +vt 0.903876 0.714174 +vt 0.128132 0.880775 +vt 0.000000 0.952330 +vt 0.000000 0.023884 +vt 1.000000 0.119127 +vt 1.000000 0.999902 +vt 0.919930 0.023884 +vt 0.128132 0.714174 +vt 1.000000 0.595047 +vt 0.991875 0.857087 +vt 0.000000 0.119127 +vt 0.312059 0.880775 +vn -0.5998 -0.8001 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.6453 0.7462 0.1638 +vn -0.9999 0.0000 -0.0103 +vn -0.0001 1.0000 -0.0000 +vn 1.0000 0.0000 -0.0000 +vn -0.7069 -0.7074 0.0000 +vn -0.9486 0.0000 -0.3166 +vn -0.6254 -0.7803 0.0000 +vn -0.8316 -0.5553 -0.0000 +vn -0.6257 -0.7801 0.0000 +vn -0.7067 -0.7075 0.0000 +vn 0.0000 -0.7070 -0.7072 +vn 0.0000 -1.0000 0.0000 +vn -0.4611 -0.8819 -0.0983 +vn -0.4740 -0.8799 0.0340 +vn -0.3160 -0.9488 0.0000 +vn -0.9986 0.0000 0.0527 +vn -0.9682 -0.2418 0.0638 +vn -0.7809 -0.6247 0.0000 +vn -0.8000 -0.6000 -0.0000 +vn 1.0000 0.0001 0.0000 +vn 0.6403 0.7681 0.0000 +vn -0.9999 -0.0052 -0.0104 +vn -0.9630 -0.1208 -0.2409 +vn -0.8921 -0.4517 -0.0046 +vn -0.8915 -0.4439 -0.0903 +vn -0.8700 -0.4901 -0.0540 +vn -0.4966 -0.8680 0.0000 +vn -0.4965 -0.8679 0.0154 +vn -0.5549 -0.8319 0.0000 +vn -0.3215 -0.8912 -0.3201 +vn -0.4425 -0.8866 -0.1346 +vn 0.6175 0.7713 0.1544 +vn 0.0000 1.0000 0.0000 +vn -0.7999 -0.6002 0.0000 +vn -0.3163 -0.9486 0.0000 +vn -0.4485 -0.8938 -0.0059 +vn -0.5547 -0.8317 -0.0229 usemtl None s off -f 462/446/442 460/447/442 466/448/442 -f 447/449/443 448/450/443 449/451/443 -f 448/450/444 447/449/444 451/452/444 -f 450/453/445 446/454/445 451/452/445 -f 448/450/446 451/452/446 452/455/446 -f 449/451/443 448/450/443 452/455/443 -f 452/455/446 451/452/446 453/456/446 -f 446/454/445 450/453/445 454/457/445 -f 450/453/447 449/451/447 454/457/447 -f 447/449/443 449/451/443 455/458/443 -f 449/451/447 450/453/447 455/458/447 -f 450/453/448 447/449/448 455/458/448 -f 447/449/448 450/453/448 456/459/448 -f 451/452/444 447/449/444 456/459/444 -f 450/453/445 451/452/445 456/459/445 -f 449/451/443 452/455/443 457/460/443 -f 452/455/449 453/456/449 457/460/449 -f 457/460/449 453/456/449 458/461/449 -f 449/451/443 457/460/443 459/462/443 -f 454/457/450 449/451/450 460/447/450 -f 449/451/443 459/462/443 460/447/443 -f 451/452/445 446/454/445 461/463/445 -f 453/456/451 451/452/451 461/463/451 -f 458/461/452 453/456/452 461/463/452 -f 457/460/453 458/461/453 461/463/453 -f 446/454/445 454/457/445 462/446/445 -f 459/462/443 457/460/443 463/464/443 -f 457/460/454 461/463/454 463/464/454 -f 463/464/455 461/463/455 464/465/455 -f 446/454/456 459/462/456 464/465/456 -f 461/463/457 446/454/457 464/465/457 -f 459/462/458 463/464/458 464/465/458 -f 454/457/450 460/447/450 465/466/450 -f 462/446/445 454/457/445 465/466/445 -f 460/447/459 462/446/459 465/466/459 -f 459/462/456 446/454/456 466/448/456 -f 460/447/443 459/462/443 466/448/443 -f 446/454/460 462/446/460 466/448/460 -o Cup_hull_20 -v -0.019075 -0.016703 0.048477 -v -0.021180 -0.009068 0.034429 -v -0.023551 -0.009068 0.034429 -v -0.013281 -0.021182 0.034429 -v -0.013281 -0.020127 0.050166 -v -0.022498 -0.009068 0.050166 -v -0.019075 -0.016703 0.034429 -v -0.013281 -0.018811 0.034429 -v -0.021708 -0.013019 0.050166 -v -0.015389 -0.020127 0.050166 -v -0.020918 -0.014335 0.034429 -v -0.023287 -0.009859 0.050166 -v -0.016705 -0.019074 0.034429 -v -0.013808 -0.021182 0.050166 -v -0.022234 -0.009068 0.049039 -v -0.014335 -0.020917 0.034429 -v -0.021180 -0.009068 0.035553 -v -0.022498 -0.011439 0.034429 -v -0.016705 -0.019074 0.050166 -v -0.013281 -0.018811 0.035553 -v -0.020127 -0.015387 0.050166 -v -0.023551 -0.009068 0.046230 -v -0.013281 -0.021182 0.050166 -v -0.023551 -0.009332 0.034429 -v -0.021708 -0.013019 0.034429 -v -0.023287 -0.009068 0.050166 -v -0.013808 -0.021182 0.034429 +f 417/395/386 414/396/386 430/397/386 +f 401/398/387 398/399/387 402/400/387 +f 400/401/388 399/402/388 403/403/388 +f 402/400/389 398/399/389 404/404/389 +f 396/405/390 397/406/390 405/407/390 +f 397/406/391 399/402/391 405/407/391 +f 401/398/387 402/400/387 406/408/387 +f 403/403/388 399/402/388 408/409/388 +f 398/399/387 401/398/387 410/410/387 +f 408/409/392 398/399/392 410/410/392 +f 400/401/388 403/403/388 411/411/388 +f 403/403/393 406/408/393 411/411/393 +f 399/402/388 400/401/388 412/412/388 +f 405/407/391 399/402/391 412/412/391 +f 400/401/394 405/407/394 412/412/394 +f 406/408/387 402/400/387 413/413/387 +f 401/398/395 403/403/395 414/396/395 +f 403/403/388 408/409/388 414/396/388 +f 413/413/396 396/405/396 415/414/396 +f 403/403/397 401/398/397 416/415/397 +f 401/398/387 406/408/387 416/415/387 +f 406/408/398 403/403/398 416/415/398 +f 410/410/387 401/398/387 417/395/387 +f 401/398/386 414/396/386 417/395/386 +f 395/416/399 408/409/399 418/417/399 +f 410/410/400 395/416/400 418/417/400 +f 408/409/392 410/410/392 418/417/392 +f 395/416/400 410/410/400 419/418/400 +f 409/419/401 414/396/401 419/418/401 +f 417/395/402 407/420/402 420/421/402 +f 410/410/387 417/395/387 420/421/387 +f 407/420/403 419/418/403 420/421/403 +f 419/418/400 410/410/400 420/421/400 +f 397/406/404 396/405/404 421/422/404 +f 396/405/405 413/413/405 421/422/405 +f 413/413/387 402/400/387 421/422/387 +f 400/401/388 411/411/388 422/423/388 +f 411/411/406 406/408/406 422/423/406 +f 413/413/407 415/414/407 422/423/407 +f 404/404/408 398/399/408 423/424/408 +f 399/402/409 404/404/409 423/424/409 +f 398/399/392 408/409/392 423/424/392 +f 408/409/388 399/402/388 423/424/388 +f 396/405/410 405/407/410 424/425/410 +f 405/407/411 400/401/411 424/425/411 +f 415/414/412 396/405/412 424/425/412 +f 400/401/413 422/423/413 424/425/413 +f 422/423/414 415/414/414 424/425/414 +f 409/419/415 407/420/415 425/426/415 +f 407/420/416 417/395/416 425/426/416 +f 417/395/417 409/419/417 425/426/417 +f 408/409/399 395/416/399 426/427/399 +f 414/396/388 408/409/388 426/427/388 +f 395/416/418 419/418/418 426/427/418 +f 419/418/419 414/396/419 426/427/419 +f 399/402/391 397/406/391 427/428/391 +f 402/400/420 404/404/420 427/428/420 +f 404/404/409 399/402/409 427/428/409 +f 397/406/391 421/422/391 427/428/391 +f 421/422/421 402/400/421 427/428/421 +f 406/408/387 413/413/387 428/429/387 +f 422/423/406 406/408/406 428/429/406 +f 413/413/422 422/423/422 428/429/422 +f 407/420/415 409/419/415 429/430/415 +f 419/418/423 407/420/423 429/430/423 +f 409/419/424 419/418/424 429/430/424 +f 414/396/425 409/419/425 430/397/425 +f 409/419/417 417/395/417 430/397/417 +o cup_hull_18 +v -0.032626 0.000670 0.022526 +v -0.026306 0.021316 -0.072261 +v -0.026306 0.011203 -0.072261 +v -0.032626 0.021316 -0.072261 +v -0.026306 0.021316 0.022526 +v -0.032626 0.000670 -0.072261 +v -0.032626 0.021316 0.022526 +v -0.028835 0.000670 0.022526 +v -0.028835 0.000670 -0.072261 +v -0.026306 0.011203 0.022526 vt 0.000000 0.000000 -vt 1.000000 0.021829 -vt 1.000000 0.000000 +vt 1.000000 0.510180 +vt 0.000000 0.510180 vt 1.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.000000 vt 0.000000 1.000000 -vt 1.000000 0.369714 -vt 1.000000 0.195673 -vt 0.000000 0.087020 -vt 0.000000 0.673845 -vt 0.000000 0.087020 -vt 1.000000 0.565192 -vt 0.000000 0.934710 -vt 0.107283 0.369714 -vt 1.000000 0.173943 -vt 0.071554 1.000000 -vt 0.928543 1.000000 -vt 1.000000 0.804229 -vt 0.000000 0.173943 -vt 0.928543 0.195673 -vt 0.000000 0.478367 -vt 0.250098 1.000000 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 1.000000 0.978172 -vt 1.000000 0.673845 vt 0.000000 1.000000 -vn -0.4486 -0.8937 0.0000 +vt 1.000000 0.000000 +vn 0.9724 -0.2334 0.0000 vn 0.0000 0.0000 -1.0000 -vn 0.0000 1.0000 -0.0000 vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 -vn -0.7074 -0.7068 0.0000 -vn 0.7560 0.6300 0.1775 -vn -0.6137 -0.7895 -0.0015 -vn -0.5547 -0.8321 0.0046 -vn 0.7768 0.6297 0.0000 -vn 0.7728 0.6317 0.0604 -vn -0.8945 -0.4471 0.0000 -vn -0.6248 -0.7808 0.0000 -vn 0.7756 0.6287 0.0566 -vn -0.7810 -0.6246 0.0000 -vn -0.7892 -0.6141 -0.0014 -vn -0.8318 -0.5551 0.0047 -vn -0.7311 -0.6784 0.0731 vn 0.0000 -1.0000 0.0000 -vn -0.0001 0.0000 -1.0000 -vn -0.8946 -0.4469 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.9579 -0.2870 0.0064 -vn -0.8574 -0.5147 0.0000 -vn -0.8943 -0.4474 0.0000 -vn -0.9978 0.0000 0.0668 usemtl None s off -f 480/467/461 482/468/461 493/469/461 -f 469/470/462 468/471/462 470/472/462 -f 468/471/463 469/470/463 472/473/463 -f 469/470/462 470/472/462 473/474/462 -f 470/472/462 468/471/462 474/475/462 -f 471/476/464 470/472/464 474/475/464 -f 471/476/465 472/473/465 475/477/465 -f 471/476/465 475/477/465 476/478/465 -f 469/470/462 473/474/462 477/479/462 -f 475/477/465 472/473/465 478/480/465 -f 467/481/466 473/474/466 479/482/466 -f 473/474/462 470/472/462 479/482/462 -f 471/476/465 476/478/465 480/467/465 -f 468/471/463 472/473/463 481/483/463 -f 472/473/467 471/476/467 481/483/467 -f 479/482/462 470/472/462 482/468/462 -f 476/478/468 479/482/468 482/468/468 -f 480/467/469 476/478/469 482/468/469 -f 474/475/470 468/471/470 483/484/470 -f 468/471/463 481/483/463 483/484/463 -f 481/483/471 471/476/471 483/484/471 -f 469/470/462 477/479/462 484/485/462 -f 475/477/472 478/480/472 484/485/472 -f 476/478/465 475/477/465 485/486/465 -f 467/481/466 479/482/466 485/486/466 -f 479/482/473 476/478/473 485/486/473 -f 471/476/464 474/475/464 486/487/464 -f 474/475/470 483/484/470 486/487/470 -f 483/484/474 471/476/474 486/487/474 -f 473/474/475 467/481/475 487/488/475 -f 477/479/476 473/474/476 487/488/476 -f 475/477/477 477/479/477 487/488/477 -f 467/481/478 485/486/478 487/488/478 -f 485/486/465 475/477/465 487/488/465 -f 472/473/463 469/470/463 488/489/463 -f 470/472/464 471/476/464 489/490/464 -f 480/467/479 470/472/479 489/490/479 -f 471/476/465 480/467/465 489/490/465 -f 469/470/480 484/485/480 490/491/480 -f 484/485/481 478/480/481 490/491/481 -f 488/489/482 469/470/482 490/491/482 -f 478/480/483 488/489/483 490/491/483 -f 477/479/484 475/477/484 491/492/484 -f 484/485/462 477/479/462 491/492/462 -f 475/477/485 484/485/485 491/492/485 -f 478/480/465 472/473/465 492/493/465 -f 472/473/463 488/489/463 492/493/463 -f 488/489/486 478/480/486 492/493/486 -f 470/472/479 480/467/479 493/469/479 -f 482/468/462 470/472/462 493/469/462 -o Cup_hull_21 -v -0.016705 -0.019073 0.034427 -v -0.015388 -0.009068 0.015038 -v -0.020391 -0.009068 0.015038 -v -0.013281 -0.020391 0.015038 -v -0.023552 -0.009332 0.034427 -v -0.013281 -0.018548 0.034143 -v -0.020127 -0.015387 0.015038 -v -0.020918 -0.009068 0.034143 -v -0.013281 -0.011966 0.015038 -v -0.023552 -0.009068 0.018410 -v -0.013808 -0.021182 0.018129 -v -0.013281 -0.021182 0.034427 -v -0.020918 -0.014335 0.034427 -v -0.016969 -0.018811 0.015038 -v -0.021708 -0.013019 0.018129 -v -0.015915 -0.009068 0.017568 -v -0.019075 -0.016704 0.034427 -v -0.014335 -0.020917 0.034427 -v -0.015388 -0.020126 0.015038 -v -0.021181 -0.009068 0.034427 -v -0.013281 -0.012492 0.017287 -v -0.022760 -0.009859 0.017006 -v -0.019075 -0.016704 0.015038 -v -0.023552 -0.009068 0.034427 -v -0.023552 -0.009332 0.018410 -v -0.021708 -0.013019 0.034427 -v -0.013281 -0.021182 0.017568 -v -0.013281 -0.018811 0.034427 -v -0.020391 -0.014861 0.015038 -v -0.020918 -0.014335 0.018410 -v -0.013808 -0.021182 0.034427 -v -0.022497 -0.009068 0.016725 -v -0.014335 -0.020917 0.018410 -vt 0.000000 0.021829 -vt 1.000000 0.087118 -vt 0.826057 0.021829 -vt 1.000000 1.000000 +f 438/431/426 433/432/426 440/433/426 +f 432/434/427 433/432/427 434/435/427 +f 433/432/428 432/434/428 435/436/428 +f 432/434/429 434/435/429 435/436/429 +f 434/435/427 433/432/427 436/437/427 +f 431/438/430 434/435/430 436/437/430 +f 434/435/430 431/438/430 437/439/430 +f 431/438/431 435/436/431 437/439/431 +f 435/436/429 434/435/429 437/439/429 +f 435/436/431 431/438/431 438/431/431 +f 431/438/432 436/437/432 438/431/432 +f 438/431/432 436/437/432 439/440/432 +f 436/437/427 433/432/427 439/440/427 +f 433/432/426 438/431/426 439/440/426 +f 433/432/428 435/436/428 440/433/428 +f 435/436/431 438/431/431 440/433/431 +o cup_hull_19 +v -0.015774 0.036902 0.026342 +v -0.033890 0.021316 0.052032 +v -0.033887 0.021316 0.075211 +v -0.015774 0.023847 0.022542 +v -0.015353 0.035639 0.075211 +v -0.030096 0.027217 0.022542 +v -0.023361 0.033111 0.075211 +v -0.032626 0.021316 0.022542 +v -0.019146 0.021316 0.023388 +v -0.032205 0.021316 0.075211 +v -0.023779 0.032689 0.022542 +v -0.030096 0.027217 0.075211 +v -0.015776 0.037325 0.075211 +v -0.015351 0.032688 0.022542 +v -0.033890 0.022161 0.027182 +v -0.015351 0.024267 0.023810 +v -0.020832 0.034794 0.027605 +v -0.027149 0.030161 0.022542 +v -0.015351 0.037327 0.027605 +v -0.032205 0.024689 0.075211 +v -0.027147 0.030161 0.075211 +v -0.020832 0.034796 0.075211 +v -0.032203 0.024687 0.022542 +v -0.033887 0.022159 0.075211 +v -0.015774 0.037327 0.027605 +v -0.015776 0.035217 0.075211 +v -0.025042 0.031846 0.022542 +v -0.015353 0.037325 0.075211 +v -0.033890 0.021316 0.026342 +v -0.019146 0.021316 0.022542 +v -0.023358 0.033109 0.026764 +v -0.025042 0.031848 0.075211 +vt 1.000000 0.477291 +vt 1.000000 0.363645 +vt 0.000000 0.477291 +vt 0.000000 0.000196 +vt 0.000000 0.999902 +vt 0.000000 0.567933 +vt 0.440094 0.000000 +vt 1.000000 0.068226 +vt 1.000000 0.204679 +vt 1.000000 0.977193 +vt 0.983947 0.795321 +vt 0.000000 0.090936 +vt 1.000000 0.545419 +vt 0.000000 0.204679 +vt 0.000000 0.977095 +vt 0.927858 0.977193 vt 1.000000 1.000000 -vt 1.000000 0.065290 -vt 1.000000 0.478367 -vt 0.014683 1.000000 -vt 1.000000 0.760768 -vt 0.014683 0.217404 -vt 0.826057 1.000000 -vt 0.000000 0.978172 -vt 0.000000 0.174041 -vt 0.000000 0.000000 -vt 0.000000 0.565192 -vt 1.000000 0.195673 -vt 0.869518 1.000000 -vt 0.000000 0.369616 -vt 0.000000 1.000000 -vt 0.884005 0.717306 -vt 1.000000 0.369616 -vt 0.000000 1.000000 -vt 0.826057 0.978172 -vt 0.840544 0.673845 -vt 0.898493 0.934710 -vt 0.000000 0.673845 -vt 0.869518 0.000000 -vt 0.840544 0.000000 -vt 0.000000 0.195673 -vt 1.000000 0.521731 -vt 0.826057 0.565192 -vt 0.000000 0.000000 -vt 0.912980 1.000000 -vn -0.6004 -0.7997 0.0000 +vt 0.975920 1.000000 +vt 0.903876 1.000000 +vt 0.000000 0.090936 +vt 0.000000 0.363743 +vt 0.000000 0.704385 +vt 0.903876 0.704385 +vt 1.000000 0.091034 +vt 0.911903 0.000000 +vt 0.000000 0.000196 +vt 0.903876 0.977193 +vt 0.000000 0.977095 +vt 0.000000 0.999902 +vt 0.927858 0.000000 +vt 1.000000 0.795321 +vt 0.919832 0.568128 +vn -0.6245 0.7810 -0.0000 +vn -0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 vn 0.0000 0.0000 -1.0000 +vn 0.0001 0.6696 -0.7427 +vn 0.6087 -0.7912 0.0591 +vn 0.5965 -0.7884 0.1503 +vn 0.9521 -0.0455 -0.3024 +vn -0.7068 0.7074 0.0000 +vn 0.7875 0.4544 -0.4164 +vn 1.0000 -0.0000 0.0000 +vn -0.7679 0.6406 0.0000 +vn -0.7066 0.7076 0.0000 +vn -0.5543 0.8323 -0.0000 +vn -0.7684 0.6400 -0.0000 +vn -0.8316 0.5554 -0.0000 +vn -1.0000 0.0000 0.0002 +vn -1.0000 0.0022 0.0001 +vn -0.8327 0.5538 0.0001 +vn -0.3283 0.8953 -0.3011 +vn -0.4450 0.8887 -0.1104 +vn 0.0000 0.9478 -0.3187 vn 0.0000 1.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.7581 0.6107 0.2288 -vn -0.7893 -0.6140 0.0011 -vn -0.7070 -0.7072 0.0000 -vn -0.6396 -0.7687 -0.0017 -vn -0.6140 -0.7893 0.0012 -vn 0.8012 0.5826 0.1364 -vn 0.7884 0.5929 0.1641 -vn 0.7832 0.5852 0.2102 -vn -0.7813 -0.6242 0.0000 -vn -0.7073 -0.7069 0.0000 -vn -1.0000 0.0000 0.0000 -vn -0.8944 -0.4473 0.0000 -vn -0.8713 0.0000 -0.4908 +vn -0.4474 0.8943 0.0000 +vn -0.4478 0.8942 -0.0000 +vn 0.0002 0.0000 1.0000 +vn 0.6976 -0.6996 0.1548 +vn 0.6370 -0.7528 0.1656 +vn -1.0000 -0.0000 0.0000 +vn -0.9422 0.1182 -0.3136 +vn -0.9488 0.2227 -0.2239 +vn 0.6004 -0.7997 0.0000 +vn -0.5481 0.8360 -0.0285 +vn -0.5549 0.8319 -0.0001 +vn -0.5550 0.8314 -0.0274 +vn -0.5999 0.8000 -0.0001 vn 0.0001 0.0000 1.0000 -vn -0.8574 -0.5147 0.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.1189 -0.9477 -0.2963 -vn -0.2242 -0.9516 -0.2102 -vn 0.6737 0.5426 0.5017 -vn 0.6308 0.5114 0.5836 -vn -0.8882 -0.4454 -0.1129 -vn -0.8916 -0.4368 -0.1194 -vn -0.8797 -0.2601 -0.3981 -vn -0.7995 -0.6007 0.0000 -vn -0.8532 -0.5202 -0.0377 -vn -0.4486 -0.8937 0.0000 -vn -0.8440 0.0935 -0.5281 -vn -0.6252 0.0000 -0.7804 -vn -0.6798 -0.0338 -0.7326 -vn -0.4726 -0.8793 -0.0586 +vn -0.6252 0.7805 0.0000 +vn -0.6009 0.7993 -0.0000 usemtl None s off -f 511/494/487 512/495/487 526/496/487 -f 496/497/488 495/498/488 497/499/488 -f 496/497/488 497/499/488 500/500/488 -f 495/498/489 496/497/489 501/501/489 -f 497/499/488 495/498/488 502/502/488 -f 499/503/490 497/499/490 502/502/490 -f 501/501/489 496/497/489 503/504/489 -f 498/505/491 494/506/491 505/507/491 -f 497/499/490 499/503/490 505/507/490 -f 494/506/491 498/505/491 506/508/491 -f 500/500/488 497/499/488 507/509/488 -f 495/498/489 501/501/489 509/510/489 -f 501/501/492 499/503/492 509/510/492 -f 494/506/491 506/508/491 510/511/491 -f 506/508/493 500/500/493 510/511/493 -f 507/509/494 494/506/494 510/511/494 -f 505/507/491 494/506/491 511/494/491 -f 507/509/488 497/499/488 512/495/488 -f 494/506/495 507/509/495 512/495/495 -f 511/494/496 494/506/496 512/495/496 -f 501/501/489 503/504/489 513/512/489 -f 498/505/491 505/507/491 513/512/491 -f 502/502/497 495/498/497 514/513/497 -f 499/503/490 502/502/490 514/513/490 -f 495/498/498 509/510/498 514/513/498 -f 509/510/499 499/503/499 514/513/499 -f 500/500/488 507/509/488 516/514/488 -f 510/511/500 500/500/500 516/514/500 -f 507/509/501 510/511/501 516/514/501 -f 503/504/502 498/505/502 517/515/502 -f 498/505/491 513/512/491 517/515/491 -f 513/512/489 503/504/489 517/515/489 -f 498/505/502 503/504/502 518/516/502 -f 508/517/503 498/505/503 518/516/503 -f 503/504/504 515/518/504 518/516/504 -f 506/508/505 498/505/505 519/519/505 -f 498/505/503 508/517/503 519/519/503 -f 508/517/506 506/508/506 519/519/506 -f 497/499/490 505/507/490 520/520/490 -f 505/507/507 504/521/507 520/520/507 -f 512/495/508 497/499/508 520/520/508 -f 504/521/509 512/495/509 520/520/509 -f 499/503/510 501/501/510 521/522/510 -f 505/507/490 499/503/490 521/522/490 -f 501/501/511 513/512/511 521/522/511 -f 513/512/491 505/507/491 521/522/491 -f 496/497/488 500/500/488 522/523/488 -f 500/500/512 508/517/512 522/523/512 -f 508/517/513 518/516/513 522/523/513 -f 518/516/514 515/518/514 522/523/514 -f 500/500/515 506/508/515 523/524/515 -f 508/517/516 500/500/516 523/524/516 -f 506/508/506 508/517/506 523/524/506 -f 504/521/507 505/507/507 524/525/507 -f 505/507/491 511/494/491 524/525/491 -f 511/494/517 504/521/517 524/525/517 -f 503/504/489 496/497/489 525/526/489 -f 515/518/518 503/504/518 525/526/518 -f 496/497/519 522/523/519 525/526/519 -f 522/523/520 515/518/520 525/526/520 -f 504/521/517 511/494/517 526/496/517 -f 512/495/521 504/521/521 526/496/521 -o Cup_hull_22 -v -0.024078 -0.007750 0.050164 -v -0.023025 -0.000378 0.033584 -v -0.025132 -0.000378 0.033584 -v -0.021182 -0.009067 0.033584 -v -0.024078 -0.000642 0.050164 -v -0.023814 -0.008540 0.033584 -v -0.022499 -0.009067 0.050164 -v -0.025132 -0.002485 0.050164 -v -0.024868 -0.004592 0.033584 -v -0.025132 -0.000378 0.050164 -v -0.021182 -0.008803 0.034991 -v -0.023551 -0.009067 0.050164 -v -0.023551 -0.009067 0.033584 -v -0.024604 -0.005907 0.050164 -v -0.023025 -0.000378 0.034991 -v -0.022499 -0.008540 0.050164 -v -0.025132 -0.002485 0.033584 -v -0.024604 -0.005907 0.033584 -v -0.024868 -0.004592 0.050164 -v -0.024078 -0.000378 0.048758 -v -0.021182 -0.008540 0.033584 -vt 0.915133 1.000000 -vt 0.915133 0.030345 -vt 1.000000 0.060689 +f 467/441/433 458/442/433 472/443/433 +f 443/444/434 445/445/434 447/446/434 +f 443/444/435 442/447/435 448/448/435 +f 446/449/436 444/450/436 448/448/436 +f 443/444/435 448/448/435 449/451/435 +f 445/445/434 443/444/434 450/452/434 +f 443/444/435 449/451/435 450/452/435 +f 444/450/436 446/449/436 451/453/436 +f 443/444/434 447/446/434 452/454/434 +f 447/446/434 445/445/434 453/455/434 +f 451/453/437 441/456/437 454/457/437 +f 444/450/436 451/453/436 454/457/436 +f 449/451/438 444/450/438 456/458/438 +f 450/452/439 449/451/439 456/458/439 +f 444/450/440 454/457/440 456/458/440 +f 451/453/436 446/449/436 458/442/436 +f 446/449/441 452/454/441 458/442/441 +f 454/457/442 441/456/442 459/459/442 +f 445/445/443 456/458/443 459/459/443 +f 456/458/443 454/457/443 459/459/443 +f 443/444/434 452/454/434 460/460/434 +f 452/454/444 446/449/444 460/460/444 +f 452/454/434 447/446/434 461/461/434 +f 458/442/445 452/454/445 461/461/445 +f 447/446/434 453/455/434 462/462/434 +f 457/463/446 447/446/446 462/462/446 +f 446/449/436 448/448/436 463/464/436 +f 460/460/447 446/449/447 463/464/447 +f 455/465/448 460/460/448 463/464/448 +f 442/447/449 443/444/449 464/466/449 +f 455/465/450 442/447/450 464/466/450 +f 443/444/434 460/460/434 464/466/434 +f 460/460/451 455/465/451 464/466/451 +f 441/456/452 451/453/452 465/467/452 +f 451/453/453 457/463/453 465/467/453 +f 459/459/454 441/456/454 465/467/454 +f 453/455/455 459/459/455 465/467/455 +f 462/462/456 453/455/456 465/467/456 +f 457/463/457 462/462/457 465/467/457 +f 445/445/458 450/452/458 466/468/458 +f 456/458/459 445/445/459 466/468/459 +f 450/452/460 456/458/460 466/468/460 +f 451/453/436 458/442/436 467/441/436 +f 453/455/434 445/445/434 468/469/434 +f 445/445/443 459/459/443 468/469/443 +f 459/459/455 453/455/455 468/469/455 +f 448/448/435 442/447/435 469/470/435 +f 442/447/461 455/465/461 469/470/461 +f 463/464/462 448/448/462 469/470/462 +f 455/465/463 463/464/463 469/470/463 +f 448/448/436 444/450/436 470/471/436 +f 444/450/464 449/451/464 470/471/464 +f 449/451/435 448/448/435 470/471/435 +f 457/463/465 451/453/465 471/472/465 +f 447/446/466 457/463/466 471/472/466 +f 451/453/467 467/441/467 471/472/467 +f 467/441/468 447/446/468 471/472/468 +f 461/461/469 447/446/469 472/443/469 +f 458/442/470 461/461/470 472/443/470 +f 447/446/471 467/441/471 472/443/471 +o cup_hull_20 +v 0.026362 -0.011126 0.022524 +v 0.032683 0.000667 -0.072261 +v 0.032683 -0.011971 -0.072261 +v 0.032683 0.000667 0.022524 +v 0.028891 0.000667 -0.072261 +v 0.026362 -0.011971 -0.072261 +v 0.032683 -0.011971 0.022524 +v 0.028891 0.000667 0.022524 +v 0.026362 -0.011971 0.022524 +v 0.026362 -0.010705 -0.072261 +v 0.026362 -0.010705 0.020844 +vt 1.000000 0.100147 +vt 0.000000 0.066862 +vt 0.017719 0.100147 +vt 1.000000 0.000000 vt 1.000000 1.000000 +vt 0.000000 1.000000 vt 1.000000 1.000000 vt 1.000000 0.000000 -vt 1.000000 0.060689 -vt 0.000000 0.969655 -vt 0.000000 0.151527 vt 0.000000 0.000000 -vt 0.000000 0.757537 -vt 1.000000 0.515074 vt 0.000000 1.000000 vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 0.000000 0.363645 -vt 0.000000 0.060689 -vt 1.000000 0.757537 -vt 1.000000 0.363645 -vt 0.000000 0.515074 -vt 0.084769 1.000000 -vn 0.9761 0.2136 0.0400 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 0.0000 vn 0.0000 0.0000 -1.0000 -vn -0.0000 0.0000 1.0000 vn 0.0000 1.0000 0.0000 -vn -1.0000 0.0000 0.0000 -vn 0.9183 -0.3892 0.0729 -vn -0.9285 -0.3714 0.0029 +vn 0.0000 0.0000 1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.8947 -0.4467 0.0000 -vn 0.9744 0.2132 0.0713 -vn 0.9773 0.1954 0.0814 -vn 0.9963 0.0000 0.0865 -vn -0.9922 -0.1244 0.0000 -vn -0.9578 -0.2874 -0.0015 -vn -0.9615 -0.2747 0.0000 -vn -0.9806 -0.1962 0.0000 -vn 0.2388 0.9544 0.1790 -vn 0.9238 0.3764 0.0706 -vn 1.0000 0.0000 0.0000 -vn 0.9754 0.2203 0.0000 +vn -0.9762 0.2170 0.0000 +vn -0.9764 0.2094 0.0524 usemtl None s off -f 541/527/522 537/528/522 547/529/522 -f 529/530/523 528/531/523 530/532/523 -f 529/530/523 530/532/523 532/533/523 -f 531/534/524 527/535/524 533/536/524 -f 527/535/524 531/534/524 534/537/524 -f 529/530/523 532/533/523 535/538/523 -f 528/531/525 529/530/525 536/539/525 -f 534/537/524 531/534/524 536/539/524 -f 529/530/526 534/537/526 536/539/526 -f 533/536/527 530/532/527 537/528/527 -f 527/535/528 532/533/528 538/540/528 -f 530/532/529 533/536/529 538/540/529 -f 533/536/524 527/535/524 538/540/524 -f 532/533/523 530/532/523 539/541/523 -f 538/540/530 532/533/530 539/541/530 -f 530/532/529 538/540/529 539/541/529 -f 527/535/524 534/537/524 540/542/524 -f 528/531/525 536/539/525 541/527/525 -f 531/534/531 537/528/531 541/527/531 -f 531/534/524 533/536/524 542/543/524 -f 537/528/532 531/534/532 542/543/532 -f 533/536/533 537/528/533 542/543/533 -f 534/537/526 529/530/526 543/544/526 -f 529/530/523 535/538/523 543/544/523 -f 535/538/534 534/537/534 543/544/534 -f 532/533/535 527/535/535 544/545/535 -f 535/538/523 532/533/523 544/545/523 -f 527/535/536 540/542/536 544/545/536 -f 540/542/537 535/538/537 544/545/537 -f 534/537/534 535/538/534 545/546/534 -f 540/542/524 534/537/524 545/546/524 -f 535/538/537 540/542/537 545/546/537 -f 536/539/538 531/534/538 546/547/538 -f 541/527/525 536/539/525 546/547/525 -f 531/534/539 541/527/539 546/547/539 -f 530/532/523 528/531/523 547/529/523 -f 537/528/540 530/532/540 547/529/540 -f 528/531/541 541/527/541 547/529/541 -o Cup_hull_23 -v -0.015652 -0.009067 0.015036 -v -0.025131 -0.002485 0.033582 -v -0.024868 -0.004592 0.033582 -v -0.024868 -0.003275 0.017567 -v -0.018022 -0.000378 0.015037 -v -0.020918 -0.009066 0.033301 -v -0.023550 -0.009066 0.017846 -v -0.022761 -0.000378 0.033301 -v -0.025131 -0.000378 0.017846 -v -0.020655 -0.008803 0.015037 -v -0.023550 -0.009066 0.033582 -v -0.015915 -0.008804 0.017004 -v -0.025131 -0.000378 0.033582 -v -0.020655 -0.000378 0.015037 -v -0.018549 -0.000378 0.018128 -v -0.024605 -0.005907 0.018409 -v -0.024341 -0.000378 0.016722 -v -0.025131 -0.002485 0.018409 -v -0.024078 -0.007750 0.033582 -v -0.024341 -0.004592 0.017004 -v -0.021181 -0.008277 0.033582 -v -0.020918 -0.008803 0.033301 -v -0.023024 -0.009066 0.017004 -v -0.023814 -0.008540 0.018409 -v -0.018022 -0.000378 0.015880 -v -0.022761 -0.000906 0.033582 -v -0.024868 -0.004592 0.018409 -v -0.024605 -0.005907 0.033582 -v -0.015652 -0.008804 0.015880 -v -0.020392 -0.009066 0.015037 -vt 0.893882 0.222222 -vt 0.999902 0.472149 -vt 0.999902 0.499951 -vt 0.015174 0.250024 -vt 0.999902 0.749976 -vt 0.848458 0.000000 +f 482/473/472 473/474/472 483/475/472 +f 475/476/473 474/477/473 476/478/473 +f 474/477/474 475/476/474 477/479/474 +f 476/478/475 474/477/475 477/479/475 +f 477/479/474 475/476/474 478/480/474 +f 475/476/473 476/478/473 479/481/473 +f 476/478/476 473/474/476 479/481/476 +f 478/480/477 475/476/477 479/481/477 +f 473/474/476 476/478/476 480/482/476 +f 476/478/475 477/479/475 480/482/475 +f 473/474/472 478/480/472 481/483/472 +f 479/481/476 473/474/476 481/483/476 +f 478/480/477 479/481/477 481/483/477 +f 478/480/472 473/474/472 482/473/472 +f 477/479/474 478/480/474 482/473/474 +f 480/482/478 477/479/478 482/473/478 +f 480/482/478 482/473/478 483/475/478 +f 473/474/479 480/482/479 483/475/479 +o cup_hull_21 +v 0.008666 -0.038093 0.025073 +v -0.004396 -0.040201 0.047402 +v -0.004396 -0.035986 0.047402 +v -0.004396 -0.033039 0.022545 +v 0.008666 -0.027561 0.023810 +v 0.008666 -0.035143 0.047402 +v -0.004396 -0.040201 0.027601 +v 0.007401 -0.039779 0.047402 +v -0.004396 -0.028404 0.022968 +v 0.004450 -0.040201 0.027601 +v 0.008666 -0.033039 0.022545 +v -0.003132 -0.038935 0.025073 +v -0.004396 -0.035565 0.046976 +v 0.008666 -0.039356 0.026759 +v 0.008666 -0.027561 0.022545 +v 0.008666 -0.039356 0.047402 +v -0.004396 -0.029248 0.026759 +v 0.008243 -0.027984 0.025496 +v 0.004450 -0.040201 0.047402 +v 0.008243 -0.034722 0.046555 +v 0.003186 -0.039779 0.025917 +v -0.004396 -0.028404 0.022545 +v 0.003186 -0.038935 0.025073 +v 0.007401 -0.039779 0.027601 +v -0.004396 -0.039779 0.026338 +vt 0.898297 0.096809 +vt 0.864330 0.580462 +vt 0.847396 0.000000 vt 0.000000 0.000000 -vt 0.000000 0.027704 -vt 0.000000 0.166716 -vt 1.000000 1.000000 -vt 0.015174 0.444445 -vt 0.848458 0.166716 -vt 0.893882 0.972198 vt 0.000000 0.000000 -vt 0.999902 0.472149 -vt 0.833284 0.694371 -vt 0.863534 0.027704 -vt 0.909055 0.083309 -vt 0.818111 0.000000 -vt 0.000000 0.111111 -vt 0.818111 0.055507 -vt 0.893882 0.083309 -vt 0.000000 0.416642 -vt 0.015174 0.444445 -vt 0.818111 0.138913 -vt 0.954479 0.749976 -vt 0.000000 0.250024 -vt 0.818111 0.027704 -vt 0.000000 0.055507 -vt 0.954479 1.000000 -vn -0.5131 -0.5145 -0.6870 -vn 0.0000 1.0000 0.0000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.898297 1.000000 +vt 0.949099 1.000000 +vt 0.796593 0.000000 +vt 0.000000 0.903191 +vt 0.982968 0.000000 +vt 0.796593 0.677271 +vt 1.000000 1.000000 +vt 0.017130 0.000000 +vt 0.830462 1.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.830462 0.000000 +vt 0.881265 0.967600 +vt 0.000000 0.677271 +vt 0.034064 0.967600 +vt 1.000000 0.000000 +vt 0.898297 0.580462 +vt 0.796593 0.903191 +vn -0.0320 -0.8165 -0.5765 +vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn 1.0000 0.0000 0.0000 vn 0.0000 -1.0000 0.0000 -vn -0.0001 -1.0000 0.0000 -vn 0.6427 -0.7434 0.1853 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0002 -1.0000 -vn -0.0004 0.0000 -1.0000 -vn 0.9313 0.2566 0.2585 -vn -0.8181 -0.0187 -0.5748 -vn -0.4157 0.0000 -0.9095 -vn -0.9923 -0.1237 0.0000 -vn -0.9683 -0.0645 -0.2414 -vn -0.9078 -0.2076 -0.3645 -vn -0.8945 -0.2302 -0.3832 -vn -0.7764 -0.0420 -0.6288 -vn -0.5198 -0.0569 -0.8524 -vn 0.1013 -0.3039 0.9473 -vn 0.9560 0.0000 0.2935 -vn 0.9357 0.2047 0.2872 -vn 0.7299 0.0000 0.6835 -vn -0.0001 -1.0000 -0.0001 -vn -0.8229 -0.2422 -0.5140 -vn -0.6161 -0.1813 -0.7665 -vn -0.8942 -0.4476 0.0000 -vn -0.9427 -0.2831 -0.1766 -vn -0.9283 -0.3718 0.0032 -vn -0.9577 -0.2876 -0.0017 -vn 0.9390 0.2641 0.2202 -vn 0.1042 0.4682 0.8774 -vn 0.9069 0.1984 0.3717 -vn 0.8662 0.1856 0.4639 -vn -0.9805 -0.1965 0.0000 -vn -0.9373 -0.1878 -0.2936 -vn -0.9743 -0.1214 -0.1898 -vn -0.9615 -0.2749 0.0000 -vn 0.9615 0.2623 -0.0817 -vn 0.7851 -0.5914 0.1841 -vn 0.9626 0.2708 0.0000 -vn -0.0004 -0.0004 -1.0000 -vn -0.0002 -1.0000 -0.0002 +vn 0.0000 -0.3941 -0.9191 +vn -0.0458 0.7106 0.7021 +vn -0.0645 0.9979 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.3174 -0.9483 0.0000 +vn -0.0768 0.9732 0.2166 +vn -0.0656 0.9524 0.2976 +vn -0.0747 0.9715 0.2251 +vn 0.1415 -0.9899 0.0000 +vn 0.3170 0.9029 0.2902 +vn -0.0437 0.8858 0.4619 +vn -0.0533 0.9511 0.3043 +vn 0.2534 0.9214 0.2948 +vn 0.0000 -0.9700 -0.2431 +vn 0.1521 -0.7910 -0.5926 +vn 0.1226 -0.9371 -0.3269 +vn 0.0686 -0.4464 -0.8922 +vn 0.0000 -0.7073 -0.7069 +vn 0.1081 -0.7031 -0.7028 +vn 0.1361 -0.9520 -0.2741 +vn -0.4783 -0.4307 -0.7653 +vn -0.0176 -0.9483 -0.3169 usemtl None s off -f 570/548/542 557/549/542 577/550/542 -f 555/551/543 552/552/543 556/553/543 -f 549/554/544 550/555/544 558/556/544 -f 548/557/545 553/558/545 558/556/545 -f 554/559/546 548/557/546 558/556/546 -f 553/558/547 548/557/547 559/560/547 -f 556/553/548 549/554/548 560/561/548 -f 555/551/543 556/553/543 560/561/543 -f 549/554/544 558/556/544 560/561/544 -f 552/552/549 548/557/549 561/562/549 -f 556/553/543 552/552/543 561/562/543 -f 548/557/550 557/549/550 561/562/550 -f 552/552/543 555/551/543 562/563/543 -f 555/551/551 559/560/551 562/563/551 -f 551/564/552 556/553/552 564/565/552 -f 556/553/543 561/562/543 564/565/543 -f 561/562/553 557/549/553 564/565/553 -f 550/555/554 549/554/554 565/566/554 -f 549/554/548 556/553/548 565/566/548 -f 556/553/555 551/564/555 565/566/555 -f 558/556/544 550/555/544 566/567/544 -f 563/568/556 551/564/556 567/569/556 -f 554/559/557 563/568/557 567/569/557 -f 551/564/558 564/565/558 567/569/558 -f 564/565/559 557/549/559 567/569/559 -f 558/556/560 553/558/560 568/570/560 -f 560/561/544 558/556/544 568/570/544 -f 553/558/561 559/560/561 569/571/561 -f 559/560/562 555/551/562 569/571/562 -f 568/570/563 553/558/563 569/571/563 -f 548/557/564 554/559/564 570/548/564 -f 554/559/565 567/569/565 570/548/565 -f 567/569/566 557/549/566 570/548/566 -f 554/559/567 558/556/567 571/572/567 -f 563/568/568 554/559/568 571/572/568 -f 558/556/569 566/567/569 571/572/569 -f 566/567/570 563/568/570 571/572/570 -f 552/552/543 562/563/543 572/573/543 -f 562/563/571 559/560/571 572/573/571 -f 555/551/572 560/561/572 573/574/572 -f 560/561/544 568/570/544 573/574/544 -f 569/571/573 555/551/573 573/574/573 -f 568/570/574 569/571/574 573/574/574 -f 563/568/575 550/555/575 574/575/575 -f 551/564/576 563/568/576 574/575/576 -f 550/555/554 565/566/554 574/575/554 -f 565/566/577 551/564/577 574/575/577 -f 550/555/575 563/568/575 575/576/575 -f 566/567/544 550/555/544 575/576/544 -f 563/568/578 566/567/578 575/576/578 -f 548/557/579 552/552/579 576/577/579 -f 559/560/580 548/557/580 576/577/580 -f 552/552/581 572/573/581 576/577/581 -f 572/573/571 559/560/571 576/577/571 -f 557/549/582 548/557/582 577/550/582 -f 548/557/583 570/548/583 577/550/583 -o Cup_hull_24 -v -0.025132 0.002520 0.050166 -v -0.021182 0.008313 0.032181 -v -0.023814 0.008313 0.032181 -v -0.022762 -0.000376 0.032181 -v -0.022762 0.008313 0.050166 -v -0.025132 -0.000376 0.032181 -v -0.024341 -0.000376 0.050166 -v -0.024078 0.007785 0.050166 -v -0.024604 0.005941 0.032181 -v -0.021182 0.007785 0.032744 -v -0.025132 -0.000376 0.050166 -v -0.025132 0.002520 0.032181 -v -0.024078 0.000677 0.050166 -v -0.022762 -0.000376 0.033306 -v -0.024604 0.005941 0.050166 -v -0.022762 0.007785 0.050166 -v -0.023814 0.008313 0.050166 -v -0.024078 0.007785 0.032181 -v -0.024868 0.004362 0.050166 -vt 0.000000 0.727068 -vt 1.000000 0.727068 -vt 0.000000 0.545276 +f 495/484/480 504/485/480 508/486/480 +f 485/487/481 486/488/481 487/489/481 +f 486/488/482 485/487/482 489/490/482 +f 484/491/483 488/492/483 489/490/483 +f 485/487/481 487/489/481 490/493/481 +f 489/490/482 485/487/482 491/494/482 +f 487/489/481 486/488/481 492/495/481 +f 485/487/484 490/493/484 493/496/484 +f 488/492/483 484/491/483 494/497/483 +f 487/489/485 494/497/485 495/484/485 +f 486/488/486 489/490/486 496/498/486 +f 492/495/481 486/488/481 496/498/481 +f 484/491/483 489/490/483 497/499/483 +f 492/495/487 488/492/487 498/500/487 +f 494/497/488 487/489/488 498/500/488 +f 488/492/483 494/497/483 498/500/483 +f 489/490/482 491/494/482 499/501/482 +f 497/499/483 489/490/483 499/501/483 +f 491/494/489 497/499/489 499/501/489 +f 488/492/490 492/495/490 500/502/490 +f 492/495/481 496/498/481 500/502/481 +f 500/502/491 496/498/491 501/503/491 +f 488/492/492 500/502/492 501/503/492 +f 491/494/482 485/487/482 502/504/482 +f 485/487/484 493/496/484 502/504/484 +f 493/496/493 491/494/493 502/504/493 +f 489/490/494 488/492/494 503/505/494 +f 496/498/495 489/490/495 503/505/495 +f 501/503/496 496/498/496 503/505/496 +f 488/492/497 501/503/497 503/505/497 +f 493/496/498 490/493/498 504/485/498 +f 484/491/499 497/499/499 504/485/499 +f 497/499/500 493/496/500 504/485/500 +f 487/489/481 492/495/481 505/506/481 +f 498/500/488 487/489/488 505/506/488 +f 492/495/487 498/500/487 505/506/487 +f 494/497/501 484/491/501 506/507/501 +f 495/484/485 494/497/485 506/507/485 +f 504/485/502 495/484/502 506/507/502 +f 484/491/503 504/485/503 506/507/503 +f 491/494/493 493/496/493 507/508/493 +f 497/499/489 491/494/489 507/508/489 +f 493/496/504 497/499/504 507/508/504 +f 490/493/481 487/489/481 508/486/481 +f 487/489/505 495/484/505 508/486/505 +f 504/485/506 490/493/506 508/486/506 +o cup_hull_22 +v 0.020884 -0.029247 0.047399 +v 0.021306 -0.019555 0.022543 +v 0.021306 -0.032614 0.022543 +v 0.008666 -0.027563 0.022545 +v 0.008666 -0.039358 0.047399 +v 0.008666 -0.038934 0.025915 +v 0.021305 -0.034299 0.047399 +v 0.008666 -0.034722 0.046976 +v 0.015829 -0.037249 0.027178 +v 0.020884 -0.020398 0.025915 +v 0.008666 -0.033035 0.022545 +v 0.020884 -0.034722 0.027178 +v 0.015829 -0.037249 0.047399 +v 0.008666 -0.027983 0.025915 +v 0.009510 -0.039358 0.027599 +v 0.021305 -0.029247 0.047399 +v 0.012458 -0.038513 0.047399 +v 0.020884 -0.019555 0.023387 +v 0.013723 -0.038093 0.027178 +v 0.009088 -0.034722 0.047399 +v 0.020884 -0.034722 0.047399 +v 0.020884 -0.028827 0.046555 +v 0.021306 -0.034301 0.026755 +v 0.009510 -0.039358 0.047399 +v 0.009088 -0.038513 0.025495 +v 0.011616 -0.038513 0.026336 +v 0.008666 -0.027563 0.024229 +v 0.016248 -0.036829 0.026336 +vt 0.813510 0.063919 +vt 0.847381 0.042678 +vt 0.847381 0.127741 vt 1.000000 1.000000 +vt 1.000000 0.340544 +vt 0.999902 0.595634 +vt 0.000000 0.000000 +vt 0.864317 0.021437 +vt 0.000000 0.510572 +vt 0.000000 0.255481 +vt 0.017034 0.234142 +vt 0.999902 0.319303 +vt 0.813510 0.106500 +vt 0.813510 0.234142 +vt 0.000000 0.106500 +vt 0.864317 0.574393 +vt 0.796574 0.000000 +vt 0.000000 0.510572 +vt 0.864317 0.957420 +vt 0.000000 0.042678 +vt 0.966030 1.000000 +vt 0.000000 0.234142 +vt 0.000000 0.234142 +vt 0.033970 0.531813 +vt 0.830543 0.255384 +vt 0.000000 0.000000 +vt 0.881253 0.042678 +vt 0.932159 0.595634 +vn 0.3188 -0.8768 -0.3599 +vn -0.0002 0.0000 -1.0000 +vn -1.0000 -0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.4472 -0.8944 0.0000 +vn -0.4206 -0.9071 -0.0179 +vn 0.7216 0.6450 0.2515 +vn -0.5170 0.8161 -0.2584 +vn 0.5350 0.8015 0.2673 +vn -0.4930 0.8253 0.2753 +vn -0.5107 0.8189 0.2620 +vn 0.3717 -0.9283 0.0000 +vn 0.3511 -0.9363 0.0025 +vn 0.2876 -0.9578 -0.0019 +vn -0.7069 0.0643 0.7044 +vn -0.3978 0.8494 0.3469 +vn 0.0000 0.8951 0.4459 +vn 0.1646 0.9132 0.3729 +vn -0.3836 0.8266 0.4118 +vn -0.3896 0.8352 0.3882 +vn 1.0000 0.0000 0.0000 +vn 0.4836 -0.8126 -0.3253 +vn 1.0000 0.0000 0.0001 +vn 0.7087 -0.7055 0.0001 +vn 0.7060 -0.7082 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.2755 -0.9613 0.0000 +vn 0.0156 -0.4730 -0.8809 +vn -0.3484 -0.4650 -0.8139 +vn 0.1787 -0.9291 -0.3238 +vn 0.2649 -0.9452 -0.1908 +vn 0.2095 -0.7487 -0.6290 +vn 0.1958 -0.7848 -0.5880 +vn -0.5481 0.8364 0.0000 +vn -0.5265 0.8249 0.2058 +vn 0.4396 -0.8321 -0.3382 +vn 0.4364 -0.8728 -0.2187 +vn 0.3581 -0.8943 -0.2684 +vn 0.2945 -0.8100 -0.5071 +usemtl None +s off +f 527/509/507 534/510/507 536/511/507 +f 510/512/508 511/513/508 512/514/508 +f 513/515/509 512/514/509 514/516/509 +f 509/517/510 513/515/510 515/518/510 +f 512/514/509 513/515/509 516/519/509 +f 512/514/508 511/513/508 519/520/508 +f 514/516/509 512/514/509 519/520/509 +f 517/521/511 520/522/511 521/523/511 +f 515/518/510 513/515/510 521/523/510 +f 512/514/509 516/519/509 522/524/509 +f 513/515/512 514/516/512 523/525/512 +f 509/517/510 515/518/510 524/526/510 +f 510/512/513 518/527/513 524/526/513 +f 521/523/510 513/515/510 525/528/510 +f 510/512/514 512/514/514 526/529/514 +f 518/527/515 510/512/515 526/529/515 +f 516/519/516 518/527/516 526/529/516 +f 522/524/517 516/519/517 526/529/517 +f 517/521/518 521/523/518 527/509/518 +f 521/523/519 525/528/519 527/509/519 +f 525/528/520 523/525/520 527/509/520 +f 513/515/510 509/517/510 528/530/510 +f 516/519/521 513/515/521 528/530/521 +f 521/523/511 520/522/511 529/531/511 +f 515/518/510 521/523/510 529/531/510 +f 518/527/522 516/519/522 530/532/522 +f 509/517/523 524/526/523 530/532/523 +f 524/526/524 518/527/524 530/532/524 +f 528/530/525 509/517/525 530/532/525 +f 516/519/526 528/530/526 530/532/526 +f 511/513/527 510/512/527 531/533/527 +f 520/522/528 511/513/528 531/533/528 +f 510/512/529 524/526/529 531/533/529 +f 524/526/529 515/518/529 531/533/529 +f 515/518/530 529/531/530 531/533/530 +f 529/531/531 520/522/531 531/533/531 +f 513/515/532 523/525/532 532/534/532 +f 525/528/510 513/515/510 532/534/510 +f 523/525/533 525/528/533 532/534/533 +f 519/520/534 511/513/534 533/535/534 +f 514/516/535 519/520/535 533/535/535 +f 523/525/536 514/516/536 534/510/536 +f 527/509/537 523/525/537 534/510/537 +f 533/535/538 511/513/538 534/510/538 +f 514/516/539 533/535/539 534/510/539 +f 512/514/509 522/524/509 535/536/509 +f 526/529/540 512/514/540 535/536/540 +f 522/524/541 526/529/541 535/536/541 +f 511/513/542 520/522/542 536/511/542 +f 520/522/543 517/521/543 536/511/543 +f 517/521/544 527/509/544 536/511/544 +f 534/510/545 511/513/545 536/511/545 +o cup_hull_23 +v 0.027628 -0.029667 0.075211 +v 0.038160 -0.013235 0.051615 +v 0.038160 -0.013657 0.051615 +v 0.021306 -0.030088 0.051615 +v 0.036474 -0.013235 0.075211 +v 0.027207 -0.030088 0.051615 +v 0.021306 -0.032195 0.075211 +v 0.034366 -0.013235 0.052881 +v 0.034788 -0.020819 0.075211 +v 0.022151 -0.033881 0.051615 +v 0.032261 -0.024611 0.051615 +v 0.022151 -0.033881 0.075211 +v 0.037738 -0.014500 0.075211 +v 0.034788 -0.020819 0.051615 +v 0.030154 -0.027139 0.075211 +v 0.021306 -0.033881 0.051615 +v 0.034367 -0.013235 0.051615 +v 0.024678 -0.032195 0.075211 +v 0.037317 -0.015763 0.075211 +v 0.021306 -0.030088 0.053304 +v 0.038160 -0.013235 0.071418 +v 0.032261 -0.024611 0.075211 +v 0.036053 -0.013657 0.075211 +v 0.021306 -0.033881 0.075211 +v 0.030154 -0.027139 0.051615 +v 0.024678 -0.032195 0.051615 +v 0.037317 -0.015763 0.051615 +vt 0.000000 0.877545 +vt 1.000000 0.632635 +vt 1.000000 0.877545 vt 1.000000 1.000000 -vt 1.000000 0.000000 +vt 1.000000 0.979542 +vt 1.000000 0.183731 +vt 1.000000 0.183731 +vt 0.000000 0.204092 vt 0.000000 1.000000 +vt 0.000000 0.081637 +vt 0.946359 1.000000 +vt 0.000000 0.632635 vt 1.000000 0.000000 +vt 1.000000 0.449002 vt 0.000000 0.000000 -vt 0.000000 0.333333 -vt 0.000000 0.939207 -vt 0.968677 0.939207 +vt 0.000000 0.938724 +vt 0.000000 0.326547 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 0.081637 +vt 0.928446 0.183731 +vt 0.160728 1.000000 +vt 0.000000 0.449002 +vt 0.000000 0.979542 vt 0.000000 0.000000 -vt 1.000000 0.333333 -vt 0.000000 0.121194 -vt 0.937451 0.000000 -vt 0.000000 0.939207 -vt 0.000000 1.000000 -vt 1.000000 0.939207 -vn -0.9864 0.1644 0.0000 +vt 1.000000 0.326547 +vt 1.000000 0.081637 +vn 0.8944 -0.4473 0.0000 vn 0.0000 0.0000 -1.0000 -vn 0.0000 1.0000 0.0000 -vn 0.0000 -1.0000 -0.0000 vn 0.0000 0.0000 1.0000 -vn 0.9703 -0.1765 -0.1655 -vn 0.9919 0.0929 0.0871 +vn 0.0000 1.0000 0.0000 +vn 0.8321 -0.5547 0.0000 vn -1.0000 0.0000 0.0000 -vn 0.9791 -0.1835 0.0879 -vn 0.9818 -0.1901 0.0000 -vn 0.9662 -0.2416 0.0905 -vn -0.9615 0.2747 0.0000 -vn 0.9959 0.0000 0.0903 -vn 0.9794 -0.1813 0.0888 -vn -0.8950 0.4461 0.0000 -vn -0.9899 0.1419 0.0000 -vn -0.9883 0.1524 -0.0011 +vn 0.0000 -1.0000 0.0000 +vn -0.7904 0.6126 -0.0010 +vn 0.6508 -0.7593 0.0019 +vn 0.5548 -0.8320 0.0000 +vn 0.9487 -0.3160 0.0057 +vn -0.7884 0.6124 0.0589 +vn -0.7904 0.6125 0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.9541 -0.2994 0.0064 +vn 0.6749 0.6742 0.3000 +vn 0.7682 -0.6402 0.0000 +vn -0.0001 0.0000 1.0000 +vn -0.7070 0.7041 0.0668 +vn -0.7806 0.6210 0.0707 +vn 0.7074 -0.7069 -0.0000 +vn 0.7074 -0.7068 0.0000 +vn 0.6402 -0.7682 0.0000 +vn 0.9284 -0.3717 0.0000 usemtl None s off -f 592/578/584 586/579/584 596/580/584 -f 580/581/585 579/582/585 581/583/585 -f 579/582/586 580/581/586 582/584/586 -f 580/581/585 581/583/585 583/585/585 -f 583/585/587 581/583/587 584/586/587 -f 582/584/588 578/587/588 584/586/588 -f 578/587/588 582/584/588 585/588/588 -f 580/581/585 583/585/585 586/579/585 -f 581/583/589 579/582/589 587/589/589 -f 579/582/590 582/584/590 587/589/590 -f 578/587/591 583/585/591 588/590/591 -f 583/585/587 584/586/587 588/590/587 -f 584/586/588 578/587/588 588/590/588 -f 583/585/591 578/587/591 589/591/591 -f 586/579/585 583/585/585 589/591/585 -f 582/584/588 584/586/588 590/592/588 -f 587/589/592 590/592/592 591/593/592 -f 584/586/587 581/583/587 591/593/587 -f 581/583/593 587/589/593 591/593/593 -f 590/592/594 584/586/594 591/593/594 -f 578/587/588 585/588/588 592/578/588 -f 585/588/595 586/579/595 592/578/595 -f 587/589/596 582/584/596 593/594/596 -f 582/584/588 590/592/588 593/594/588 -f 590/592/597 587/589/597 593/594/597 -f 582/584/586 580/581/586 594/595/586 -f 580/581/598 585/588/598 594/595/598 -f 585/588/588 582/584/588 594/595/588 -f 585/588/598 580/581/598 595/596/598 -f 580/581/585 586/579/585 595/596/585 -f 586/579/595 585/588/595 595/596/595 -f 589/591/599 578/587/599 596/580/599 -f 586/579/600 589/591/600 596/580/600 -f 578/587/588 592/578/588 596/580/588 -o Cup_hull_25 -v -0.023551 0.007522 0.017006 -v -0.025132 -0.000376 0.032177 -v -0.022760 -0.000376 0.032177 -v -0.020655 -0.000376 0.015037 -v -0.016179 0.008313 0.016444 -v -0.023814 0.008313 0.032177 -v -0.025132 -0.000376 0.017848 -v -0.018023 -0.000376 0.015881 -v -0.020917 0.008313 0.031895 -v -0.020655 0.008313 0.015037 -v -0.024604 0.005941 0.018410 -v -0.016179 0.007785 0.015037 -v -0.025132 0.002520 0.032177 -v -0.023814 0.008313 0.017848 -v -0.022497 -0.000376 0.031895 -v -0.024340 0.001730 0.016724 -v -0.025132 0.002520 0.018410 -v -0.024604 0.005941 0.032177 -v -0.018023 -0.000376 0.015037 -v -0.016179 0.008048 0.016444 -v -0.018549 -0.000376 0.018130 -v -0.020917 0.008048 0.031895 -v -0.021180 0.008313 0.032177 -v -0.024340 0.004362 0.017006 -v -0.024340 -0.000376 0.016724 -v -0.024077 0.007785 0.032177 -v -0.016179 0.008313 0.015037 -v -0.024077 0.007785 0.018410 -v -0.024867 0.004362 0.018130 -v -0.024867 0.001730 0.017286 -vt 0.803211 0.000000 -vt 0.819561 0.029561 -vt 0.868807 0.029561 -vt 0.000000 0.264879 -vt 0.000000 0.000000 -vt 1.000000 0.500000 -vt 0.000000 0.147220 -vt 0.836009 0.000000 -vt 0.950754 0.794048 -vt 0.917956 1.000000 -vt 0.016448 0.470732 -vt 1.000000 0.500000 +f 555/537/546 550/538/546 563/539/546 +f 538/540/547 539/541/547 540/542/547 +f 540/542/547 539/541/547 542/543/547 +f 537/544/548 541/545/548 543/546/548 +f 541/545/549 538/540/549 544/547/549 +f 541/545/548 537/544/548 545/548/548 +f 540/542/547 542/543/547 546/549/547 +f 542/543/547 539/541/547 547/550/547 +f 537/544/548 543/546/548 548/551/548 +f 541/545/548 545/548/548 549/552/548 +f 547/550/547 539/541/547 550/538/547 +f 545/548/550 547/550/550 550/538/550 +f 545/548/548 537/544/548 551/553/548 +f 543/546/551 540/542/551 552/554/551 +f 540/542/547 546/549/547 552/554/547 +f 546/549/552 548/551/552 552/554/552 +f 538/540/547 540/542/547 553/555/547 +f 544/547/549 538/540/549 553/555/549 +f 540/542/553 544/547/553 553/555/553 +f 542/543/554 537/544/554 554/556/554 +f 537/544/548 548/551/548 554/556/548 +f 548/551/555 546/549/555 554/556/555 +f 539/541/556 549/552/556 555/537/556 +f 549/552/548 545/548/548 555/537/548 +f 545/548/546 550/538/546 555/537/546 +f 540/542/551 543/546/551 556/557/551 +f 543/546/557 544/547/557 556/557/557 +f 544/547/558 540/542/558 556/557/558 +f 539/541/559 538/540/559 557/558/559 +f 538/540/549 541/545/549 557/558/549 +f 549/552/560 539/541/560 557/558/560 +f 541/545/561 549/552/561 557/558/561 +f 547/550/550 545/548/550 558/559/550 +f 545/548/548 551/553/548 558/559/548 +f 551/553/562 547/550/562 558/559/562 +f 543/546/563 541/545/563 559/560/563 +f 541/545/564 544/547/564 559/560/564 +f 544/547/565 543/546/565 559/560/565 +f 548/551/548 543/546/548 560/561/548 +f 543/546/551 552/554/551 560/561/551 +f 552/554/552 548/551/552 560/561/552 +f 537/544/566 542/543/566 561/562/566 +f 542/543/547 547/550/547 561/562/547 +f 551/553/567 537/544/567 561/562/567 +f 547/550/562 551/553/562 561/562/562 +f 546/549/547 542/543/547 562/563/547 +f 542/543/568 554/556/568 562/563/568 +f 554/556/555 546/549/555 562/563/555 +f 550/538/547 539/541/547 563/539/547 +f 539/541/569 555/537/569 563/539/569 +o cup_hull_24 +v 0.022150 -0.033881 0.051615 +v 0.029733 -0.013235 0.022542 +v 0.037737 -0.013237 0.026336 +v 0.023836 -0.032616 0.022542 +v 0.038159 -0.013657 0.051615 +v 0.021307 -0.019136 0.023390 +v 0.033946 -0.013237 0.050770 +v 0.032260 -0.024609 0.022542 +v 0.021307 -0.029667 0.051191 +v 0.030154 -0.027139 0.051615 +v 0.021307 -0.032616 0.022542 +v 0.025942 -0.013235 0.025493 +v 0.034788 -0.020819 0.051615 +v 0.037316 -0.015765 0.027181 +v 0.027206 -0.030088 0.022542 +v 0.025099 -0.013657 0.022542 +v 0.032683 -0.013237 0.022542 +v 0.024677 -0.032195 0.051615 +v 0.021307 -0.033881 0.026336 +v 0.034367 -0.013237 0.051615 +v 0.021307 -0.033881 0.051615 +v 0.034788 -0.020819 0.027599 +v 0.032260 -0.024609 0.051615 +v 0.021307 -0.019136 0.022542 +v 0.038159 -0.013237 0.051615 +v 0.027206 -0.030088 0.051615 +v 0.030154 -0.027137 0.022542 +v 0.022150 -0.033881 0.027181 +v 0.038159 -0.013657 0.027599 +v 0.024677 -0.032195 0.022542 +v 0.037316 -0.015765 0.051615 +v 0.021307 -0.030088 0.051615 +v 0.032683 -0.023766 0.022542 +v 0.036473 -0.013237 0.025072 +v 0.021307 -0.019977 0.025917 +vt 0.014585 0.204092 +vt 0.898493 1.000000 +vt 0.883908 0.673453 +vt 1.000000 0.061276 vt 1.000000 1.000000 +vt 1.000000 0.449099 +vt 0.000000 0.979542 vt 0.000000 0.000000 -vt 0.836009 0.147220 -vt 0.885158 0.176586 -vt 0.016448 0.294244 -vt 0.901606 0.088391 -vt 0.000000 0.058927 -vt 1.000000 0.794048 -vt 0.917956 1.000000 -vt 0.819561 0.735219 -vt 0.016448 0.470732 -vt 0.000000 0.441366 -vt 0.885158 0.088391 -vt 0.901606 0.088391 -vt 0.000000 0.117756 -vt 0.803211 0.058927 -vt 1.000000 1.000000 -vt 0.803211 0.117756 -vn -0.9527 0.0929 -0.2895 -vn 0.0000 -1.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 1.0000 -0.0000 +vt 0.000000 0.326547 +vt 1.000000 0.061276 +vt 0.970830 0.714174 +vt 0.029072 0.999902 +vt 0.000000 0.632635 +vt 1.000000 0.183731 +vt 1.000000 0.979542 +vt 1.000000 0.999902 +vt 0.000000 0.081637 +vt 0.869518 0.000000 +vt 0.000000 0.999902 +vt 0.000000 0.000000 +vt 0.826057 0.632635 +vt 0.840446 0.877447 +vt 0.000000 0.449099 +vt 1.000000 0.714174 +vt 0.869518 0.999902 +vt 0.000000 0.999902 +vt 0.000000 0.183731 +vt 1.000000 0.326645 +vt 0.840446 0.000000 +vt 0.826057 0.979542 +vt 1.000000 0.081637 +vt 0.000000 0.877447 +vt 0.000000 0.183731 +vt 1.000000 0.489918 +vt 0.912980 0.999902 +vn -0.7983 0.5624 0.2156 vn -0.0000 0.0000 -1.0000 +vn -0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.5764 0.4982 -0.6477 -vn -0.4161 0.0000 -0.9093 -vn 0.9754 -0.2204 0.0000 -vn 0.9561 0.0000 0.2932 -vn 0.9755 -0.2162 0.0405 +vn -0.7659 0.5954 0.2426 +vn -0.0902 0.9892 -0.1158 +vn -0.8026 0.5782 0.1465 +vn 0.0000 -0.9486 -0.3164 +vn -0.7334 0.5735 0.3650 +vn -0.0004 1.0000 0.0002 +vn 0.0000 -1.0000 0.0000 +vn 0.8320 -0.5548 0.0000 +vn 0.8860 -0.4519 -0.1041 +vn 0.8943 -0.4474 0.0000 +vn 0.7685 -0.6398 0.0000 +vn -0.8222 0.5691 0.0000 +vn 0.0003 1.0000 -0.0000 +vn 0.0000 1.0000 0.0001 +vn 0.7072 -0.7070 0.0000 +vn 0.6403 -0.7681 0.0000 +vn 0.7683 -0.6401 -0.0000 +vn 0.7074 -0.7068 -0.0000 +vn 0.5549 -0.8319 0.0000 +vn 0.1929 -0.9622 -0.1923 +vn 0.8804 -0.2755 -0.3859 +vn 0.9285 -0.3713 0.0000 +vn 0.7234 0.6904 -0.0121 vn 1.0000 0.0000 0.0000 -vn 0.9397 -0.2105 0.2695 -vn 0.9492 -0.2226 0.2223 -vn 0.7245 -0.1359 0.6757 -vn 0.9410 -0.1765 0.2886 -vn 0.6667 -0.1212 0.7354 -vn 0.7313 0.0000 0.6820 -vn -0.5831 0.1457 -0.7992 -vn -0.8571 0.2142 -0.4686 -vn -0.5422 0.0895 -0.8355 -vn -0.8946 0.4468 0.0000 -vn -0.9615 0.2747 0.0000 -vn -0.9441 0.2698 -0.1895 -vn -0.9058 0.2155 -0.3647 -vn -0.9898 0.1423 0.0000 -vn -0.9864 0.1642 0.0000 -vn -0.9883 0.1524 0.0014 -vn -0.8860 0.2066 -0.4151 -vn -0.8973 0.1348 -0.4203 -vn -0.9635 0.0510 -0.2626 -vn -0.7278 0.0730 -0.6819 -vn -0.8167 -0.0508 -0.5748 -vn -0.7298 0.0000 -0.6837 +vn 0.4455 -0.8916 -0.0813 +vn -0.6756 0.5236 0.5191 +vn 0.8755 -0.2778 -0.3953 +vn 0.8876 -0.4448 -0.1195 +vn 0.5551 0.0000 -0.8318 +vn 0.0005 1.0000 -0.0005 +vn 0.0007 1.0000 -0.0010 +vn 0.7046 -0.0844 -0.7046 +vn -0.8038 0.5645 0.1878 usemtl None s off -f 613/597/601 625/598/601 626/599/601 -f 599/600/602 598/601/602 600/602/602 -f 598/601/603 599/600/603 602/603/603 -f 600/602/602 598/601/602 603/604/602 -f 599/600/602 600/602/602 604/605/602 -f 601/606/604 602/603/604 605/607/604 -f 602/603/604 601/606/604 606/608/604 -f 600/602/605 606/608/605 608/609/605 -f 598/601/603 602/603/603 609/610/603 -f 603/604/606 598/601/606 609/610/606 -f 602/603/604 606/608/604 610/611/604 -f 606/608/607 597/612/607 610/611/607 -f 599/600/602 604/605/602 611/613/602 -f 606/608/608 600/602/608 612/614/608 -f 603/604/606 609/610/606 613/597/606 -f 609/610/603 602/603/603 614/615/603 -f 604/605/602 600/602/602 615/616/602 -f 600/602/605 608/609/605 615/616/605 -f 608/609/609 604/605/609 615/616/609 -f 601/606/610 605/607/610 616/617/610 -f 604/605/611 608/609/611 616/617/611 -f 608/609/612 601/606/612 616/617/612 -f 616/617/613 611/613/613 617/618/613 -f 611/613/602 604/605/602 617/618/602 -f 604/605/614 616/617/614 617/618/614 -f 599/600/615 611/613/615 618/619/615 -f 616/617/610 605/607/610 618/619/610 -f 611/613/616 616/617/616 618/619/616 -f 602/603/603 599/600/603 619/620/603 -f 605/607/604 602/603/604 619/620/604 -f 599/600/617 618/619/617 619/620/617 -f 618/619/618 605/607/618 619/620/618 -f 597/612/619 606/608/619 620/621/619 -f 610/611/620 597/612/620 620/621/620 -f 606/608/621 612/614/621 620/621/621 -f 600/602/602 603/604/602 621/622/602 -f 612/614/608 600/602/608 621/622/608 -f 602/603/622 610/611/622 622/623/622 -f 614/615/603 602/603/603 622/623/603 -f 607/624/623 614/615/623 622/623/623 -f 606/608/604 601/606/604 623/625/604 -f 601/606/612 608/609/612 623/625/612 -f 608/609/605 606/608/605 623/625/605 -f 610/611/624 607/624/624 624/626/624 -f 622/623/622 610/611/622 624/626/622 -f 607/624/623 622/623/623 624/626/623 -f 607/624/625 610/611/625 625/598/625 -f 613/597/626 609/610/626 625/598/626 -f 614/615/627 607/624/627 625/598/627 -f 609/610/628 614/615/628 625/598/628 -f 610/611/629 620/621/629 625/598/629 -f 625/598/630 620/621/630 626/599/630 -f 603/604/631 613/597/631 626/599/631 -f 620/621/632 612/614/632 626/599/632 -f 621/622/633 603/604/633 626/599/633 -f 612/614/634 621/622/634 626/599/634 -o Cup_hull_26 -v -0.020654 0.014632 0.050164 -v -0.014335 0.020690 0.033584 -v -0.014335 0.017793 0.033584 -v -0.023815 0.008313 0.033584 -v -0.022761 0.008313 0.050164 -v -0.014335 0.019373 0.050164 -v -0.021180 0.008578 0.034149 -v -0.020127 0.015422 0.033584 -v -0.015388 0.020163 0.050164 -v -0.023288 0.009895 0.050164 -v -0.021708 0.013055 0.033584 -v -0.016968 0.018846 0.033584 -v -0.018549 0.017265 0.050164 -v -0.023815 0.008313 0.050164 -v -0.021444 0.008313 0.033584 -v -0.014335 0.020690 0.050164 -v -0.021708 0.013055 0.050164 -v -0.023288 0.009895 0.033584 -v -0.022497 0.008578 0.050164 -v -0.014598 0.020690 0.033584 -v -0.014335 0.017793 0.034430 -v -0.021444 0.008313 0.035272 -v -0.018812 0.017002 0.033584 -v -0.016968 0.018846 0.050164 -v -0.023815 0.008578 0.050164 -v -0.015388 0.020163 0.033584 -v -0.023815 0.008578 0.033584 -v -0.019865 0.015685 0.050164 -v -0.014598 0.020690 0.050164 -vt 0.000000 1.000000 +f 572/564/570 575/565/570 598/566/570 +f 567/567/571 565/568/571 571/569/571 +f 568/570/572 564/571/572 573/572/572 +f 565/568/571 567/567/571 574/573/571 +f 572/564/573 569/574/573 574/573/573 +f 572/564/574 570/575/574 575/565/574 +f 568/570/572 573/572/572 576/576/572 +f 567/567/571 571/569/571 578/577/571 +f 565/568/571 574/573/571 579/578/571 +f 575/565/575 565/568/575 579/578/575 +f 569/574/576 575/565/576 579/578/576 +f 571/569/571 565/568/571 580/579/571 +f 573/572/572 564/571/572 581/580/572 +f 574/573/577 567/567/577 582/581/577 +f 572/564/573 574/573/573 582/581/573 +f 564/571/572 568/570/572 583/582/572 +f 570/575/578 572/564/578 583/582/578 +f 575/565/579 570/575/579 583/582/579 +f 582/581/580 564/571/580 584/583/580 +f 572/564/573 582/581/573 584/583/573 +f 564/571/572 583/582/572 584/583/572 +f 576/576/581 571/569/581 585/584/581 +f 571/569/582 577/585/582 585/584/582 +f 577/585/583 576/576/583 585/584/583 +f 573/572/584 571/569/584 586/586/584 +f 571/569/581 576/576/581 586/586/581 +f 576/576/572 573/572/572 586/586/572 +f 574/573/573 569/574/573 587/587/573 +f 579/578/571 574/573/571 587/587/571 +f 569/574/585 579/578/585 587/587/585 +f 566/588/586 565/568/586 588/589/586 +f 565/568/587 575/565/587 588/589/587 +f 583/582/572 568/570/572 588/589/572 +f 575/565/587 583/582/587 588/589/587 +f 578/577/588 573/572/588 589/590/588 +f 573/572/572 581/580/572 589/590/572 +f 581/580/589 578/577/589 589/590/589 +f 571/569/590 573/572/590 590/591/590 +f 578/577/571 571/569/571 590/591/571 +f 573/572/591 578/577/591 590/591/591 +f 581/580/592 564/571/592 591/592/592 +f 564/571/580 582/581/580 591/592/580 +f 582/581/593 567/567/593 591/592/593 +f 577/585/594 566/588/594 592/593/594 +f 568/570/595 577/585/595 592/593/595 +f 566/588/596 588/589/596 592/593/596 +f 588/589/597 568/570/597 592/593/597 +f 567/567/571 578/577/571 593/594/571 +f 578/577/589 581/580/589 593/594/589 +f 581/580/592 591/592/592 593/594/592 +f 591/592/598 567/567/598 593/594/598 +f 568/570/572 576/576/572 594/595/572 +f 577/585/595 568/570/595 594/595/595 +f 576/576/583 577/585/583 594/595/583 +f 583/582/599 572/564/599 595/596/599 +f 572/564/573 584/583/573 595/596/573 +f 584/583/572 583/582/572 595/596/572 +f 566/588/600 577/585/600 596/597/600 +f 577/585/601 571/569/601 596/597/601 +f 571/569/571 580/579/571 596/597/571 +f 596/597/602 580/579/602 597/598/602 +f 565/568/603 566/588/603 597/598/603 +f 580/579/604 565/568/604 597/598/604 +f 566/588/605 596/597/605 597/598/605 +f 569/574/573 572/564/573 598/566/573 +f 575/565/606 569/574/606 598/566/606 +o cup_hull_25 +v 0.038581 -0.011969 0.075211 +v 0.040266 0.000668 0.050772 +v 0.040266 -0.003545 0.050772 +v 0.034368 -0.012390 0.050772 +v 0.038581 0.000668 0.075211 +v 0.036897 0.000668 0.050772 +v 0.038159 -0.013233 0.050772 +v 0.036475 -0.013233 0.075211 +v 0.040266 0.000668 0.075211 +v 0.039845 -0.006914 0.075211 +v 0.039423 -0.009020 0.050772 +v 0.034368 -0.013233 0.050772 +v 0.038159 -0.013233 0.075211 +v 0.036475 -0.012390 0.075211 +v 0.040266 -0.003545 0.075211 +v 0.036897 0.000668 0.052459 +v 0.038581 -0.012390 0.070996 +v 0.034368 -0.012390 0.051196 +v 0.038581 -0.012390 0.050772 +v 0.039845 -0.006914 0.050772 +v 0.039423 -0.009020 0.075211 +vt 0.172475 0.060689 +vt 1.000000 0.303054 +vt 0.000000 0.303054 vt 1.000000 1.000000 +vt 1.000000 0.696946 +vt 1.000000 0.060689 vt 0.000000 1.000000 vt 1.000000 1.000000 -vt 1.000000 0.765955 vt 1.000000 0.000000 -vt 0.000000 0.893598 -vt 0.000000 0.510572 -vt 0.000000 0.000000 -vt 1.000000 0.574393 -vt 0.000000 0.957420 -vt 0.000000 0.127839 -vt 1.000000 0.383124 -vt 1.000000 0.851018 -vt 0.000000 0.723277 +vt 0.000000 0.090936 vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.454581 vt 1.000000 0.000000 -vt 0.965936 0.021437 -vt 0.000000 0.383124 -vt 1.000000 0.127839 -vt 0.000000 0.021437 -vt 0.949002 0.765955 -vt 0.898199 0.000000 -vt 1.000000 0.702036 -vt 0.000000 0.851018 -vt 0.000000 0.021437 -vt 1.000000 0.957420 -vt 1.000000 0.021437 -vt 0.000000 0.595634 +vt 0.000000 0.000000 +vt 0.000000 0.060689 +vt 0.000000 0.696946 +vt 0.930991 1.000000 +vt 0.982674 0.060689 +vt 1.000000 0.060689 +vt 1.000000 0.454581 +vn 0.9701 -0.2425 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 1.0000 0.0000 -vn -0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn 1.0000 0.0000 0.0000 vn 0.0000 -1.0000 0.0000 -vn 0.7967 -0.5975 -0.0911 -vn -0.8316 0.5553 0.0000 -vn -0.8317 0.5552 0.0000 -vn -0.8944 0.4473 0.0000 -vn 0.8027 -0.5963 0.0000 -vn 0.8012 -0.5966 0.0471 -vn 0.7095 -0.7047 0.0000 -vn 0.7081 -0.7034 0.0626 -vn 0.7958 -0.6018 0.0670 -vn 0.8011 -0.5955 0.0598 -vn -0.7073 0.7070 0.0000 -vn -0.6402 0.7682 0.0000 -vn -0.7071 0.7071 0.0000 +vn 0.9923 -0.1241 0.0000 +vn -0.9818 0.1901 0.0000 +vn 0.9482 -0.3161 0.0315 +vn 0.8946 -0.4469 0.0000 vn -1.0000 0.0000 0.0000 -vn -0.9284 0.3716 0.0000 -vn -0.5551 0.8318 0.0000 -vn -0.8000 0.6001 0.0032 -vn 0.0001 0.0000 1.0000 -vn -0.7686 0.6397 0.0020 -vn -0.7684 0.6400 0.0021 +vn -0.9954 -0.0431 0.0858 +vn -0.9836 0.1586 0.0863 +vn -0.9962 0.0000 0.0874 +vn -0.9805 0.1829 0.0726 +vn 0.0001 0.0000 -1.0000 +vn 0.9806 -0.1962 0.0000 +vn -0.0001 0.0000 1.0000 +vn 0.9612 -0.2746 0.0274 usemtl None s off -f 642/627/635 646/628/635 655/629/635 -f 628/630/636 629/631/636 630/632/636 -f 629/631/637 628/630/637 632/633/637 -f 627/634/638 631/635/638 632/633/638 -f 628/630/636 630/632/636 634/636/636 -f 627/634/638 632/633/638 635/637/638 -f 631/635/638 627/634/638 636/638/638 -f 634/636/636 630/632/636 637/639/636 -f 628/630/636 634/636/636 638/640/636 -f 627/634/638 635/637/638 639/641/638 -f 630/632/639 631/635/639 640/642/639 -f 631/635/638 636/638/638 640/642/638 -f 630/632/636 629/631/636 641/643/636 -f 631/635/639 630/632/639 641/643/639 -f 629/631/640 633/644/640 641/643/640 -f 632/633/637 628/630/637 642/627/637 -f 635/637/638 632/633/638 642/627/638 -f 627/634/641 634/636/641 643/645/641 -f 636/638/638 627/634/638 643/645/638 -f 634/636/642 637/639/642 643/645/642 -f 637/639/643 636/638/643 643/645/643 -f 637/639/636 630/632/636 644/646/636 -f 636/638/643 637/639/643 644/646/643 -f 632/633/638 631/635/638 645/647/638 -f 628/630/636 638/640/636 646/628/636 -f 642/627/635 628/630/635 646/628/635 -f 629/631/637 632/633/637 647/648/637 -f 633/644/644 629/631/644 647/648/644 -f 633/644/645 647/648/645 648/649/645 -f 631/635/639 641/643/639 648/649/639 -f 641/643/646 633/644/646 648/649/646 -f 645/647/647 631/635/647 648/649/647 -f 632/633/648 645/647/648 648/649/648 -f 647/648/649 632/633/649 648/649/649 -f 638/640/636 634/636/636 649/650/636 -f 649/650/650 639/641/650 650/651/650 -f 635/637/651 638/640/651 650/651/651 -f 639/641/638 635/637/638 650/651/638 -f 638/640/652 649/650/652 650/651/652 -f 630/632/653 640/642/653 651/652/653 -f 640/642/638 636/638/638 651/652/638 -f 636/638/654 644/646/654 651/652/654 -f 638/640/651 635/637/651 652/653/651 -f 646/628/636 638/640/636 652/653/636 -f 635/637/655 646/628/655 652/653/655 -f 644/646/636 630/632/636 653/654/636 -f 630/632/653 651/652/653 653/654/653 -f 651/652/654 644/646/654 653/654/654 -f 634/636/656 627/634/656 654/655/656 -f 627/634/657 639/641/657 654/655/657 -f 649/650/658 634/636/658 654/655/658 -f 639/641/659 649/650/659 654/655/659 -f 635/637/638 642/627/638 655/629/638 -f 646/628/655 635/637/655 655/629/655 -o Cup_hull_27 -v -0.023550 0.008578 0.017568 -v -0.014335 0.020690 0.017848 -v -0.014335 0.020426 0.015039 -v -0.015915 0.008313 0.015882 -v -0.021180 0.008313 0.033582 -v -0.014335 0.020690 0.033582 -v -0.021708 0.013055 0.033582 -v -0.020127 0.015422 0.015039 -v -0.014335 0.017529 0.033301 -v -0.014335 0.010684 0.015039 -v -0.023815 0.008313 0.033582 -v -0.016968 0.018845 0.033582 -v -0.020654 0.008313 0.015039 -v -0.023288 0.009895 0.018411 -v -0.017233 0.018582 0.015039 -v -0.018812 0.017002 0.033582 -v -0.015388 0.020163 0.016724 -v -0.021708 0.013055 0.018411 -v -0.023815 0.008313 0.018411 -v -0.023288 0.009895 0.033582 -v -0.016179 0.008313 0.017005 -v -0.020127 0.015422 0.033582 -v -0.014598 0.020690 0.033582 -v -0.015915 0.008313 0.015039 -v -0.014335 0.010947 0.016443 -v -0.018812 0.017002 0.015039 -v -0.014335 0.017793 0.033582 -v -0.020391 0.014895 0.015039 -v -0.023815 0.008578 0.018411 -v -0.015388 0.020163 0.033582 -v -0.022761 0.008313 0.016724 -v -0.014862 0.020426 0.015039 -v -0.014598 0.020690 0.017848 -v -0.023815 0.008578 0.033582 -vt 0.000000 0.127839 -vt 0.818191 0.021437 -vt 0.000000 0.021437 -vt 1.000000 0.978661 -vt 0.848541 1.000000 +f 615/599/607 609/600/607 619/601/607 +f 600/602/608 601/603/608 602/604/608 +f 603/605/609 600/602/609 604/606/609 +f 600/602/608 602/604/608 604/606/608 +f 602/604/608 601/603/608 605/607/608 +f 599/608/610 603/605/610 606/609/610 +f 601/603/611 600/602/611 607/610/611 +f 603/605/610 599/608/610 607/610/610 +f 600/602/609 603/605/609 607/610/609 +f 607/610/610 599/608/610 608/611/610 +f 605/607/608 601/603/608 609/600/608 +f 602/604/608 605/607/608 610/612/608 +f 605/607/612 606/609/612 610/612/612 +f 606/609/612 605/607/612 611/613/612 +f 599/608/610 606/609/610 611/613/610 +f 606/609/610 603/605/610 612/614/610 +f 601/603/611 607/610/611 613/615/611 +f 608/611/613 601/603/613 613/615/613 +f 607/610/610 608/611/610 613/615/610 +f 603/605/609 604/606/609 614/616/609 +f 604/606/614 602/604/614 614/616/614 +f 599/608/615 611/613/615 615/599/615 +f 611/613/616 605/607/616 615/599/616 +f 602/604/617 610/612/617 616/617/617 +f 610/612/618 606/609/618 616/617/618 +f 612/614/619 603/605/619 616/617/619 +f 606/609/620 612/614/620 616/617/620 +f 614/616/614 602/604/614 616/617/614 +f 603/605/621 614/616/621 616/617/621 +f 605/607/608 609/600/608 617/618/608 +f 615/599/616 605/607/616 617/618/616 +f 609/600/607 615/599/607 617/618/607 +f 601/603/613 608/611/613 618/619/613 +f 609/600/622 601/603/622 618/619/622 +f 608/611/623 609/600/623 618/619/623 +f 608/611/624 599/608/624 619/601/624 +f 609/600/623 608/611/623 619/601/623 +f 599/608/625 615/599/625 619/601/625 +o cup_hull_26 +v 0.039843 -0.006913 0.027179 +v 0.025941 -0.013233 0.024651 +v 0.025941 -0.012812 0.024651 +v 0.034366 -0.013233 0.050772 +v 0.036472 0.000668 0.050350 +v 0.028891 0.000668 0.022542 +v 0.037316 -0.013233 0.025493 +v 0.039843 0.000668 0.025913 +v 0.039843 -0.006913 0.050772 +v 0.040267 0.000668 0.050772 +v 0.038159 -0.013233 0.050772 +v 0.032683 -0.013233 0.022542 +v 0.025941 -0.013233 0.022542 +v 0.032683 0.000668 0.022542 +v 0.029734 0.000668 0.027179 +v 0.038581 -0.012390 0.032236 +v 0.040267 -0.003545 0.027599 +v 0.039002 -0.001860 0.025071 +v 0.033945 -0.012812 0.049930 +v 0.026363 -0.012812 0.026339 +v 0.038159 -0.013233 0.026759 +v 0.040267 0.000668 0.026759 +v 0.040267 -0.003545 0.050772 +v 0.039002 -0.006913 0.025493 +v 0.039424 -0.009020 0.050772 +v 0.036896 0.000668 0.050772 +v 0.028891 0.000668 0.023811 +v 0.039424 -0.009020 0.027179 +v 0.038581 -0.012390 0.050772 +v 0.038159 -0.008598 0.025071 +v 0.039002 0.000668 0.025071 +vt 0.910435 0.911707 +vt 1.000000 0.470634 +vt 0.910435 0.911707 +vt 0.000000 0.588097 +vt 0.925313 0.000000 +vt 0.895458 0.794049 +vt 1.000000 0.205951 +vt 0.014977 0.735121 +vt 0.880580 0.970439 vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 0.000000 0.383125 -vt 0.015175 0.744616 -vt 1.000000 0.574393 -vt 1.000000 0.191562 -vt 0.954572 0.000000 -vt 0.000000 0.000000 -vt 0.000000 0.850920 +vt 0.000000 0.970439 +vt 0.000000 0.852878 +vt 1.000000 0.470634 +vt 0.925313 0.000000 vt 1.000000 0.000000 -vt 1.000000 0.829679 -vt 0.000000 0.702036 -vt 0.909144 0.957420 -vt 0.818191 0.383125 -vt 0.818191 0.127839 -vt 0.818191 0.000000 -vt 0.893969 0.000000 -vt 0.000000 0.574393 +vt 0.835748 0.264781 +vt 0.835748 0.970439 +vt 0.820869 1.000000 +vt 0.029855 0.558731 +vt 0.865505 0.029464 +vt 0.850626 0.852878 +vt 0.656617 0.882341 +vt 0.850626 1.000000 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 0.924320 0.212803 -vt 1.000000 0.702036 -vt 0.000000 0.765955 -vt 1.000000 0.531813 -vt 0.863619 0.021437 -vt 0.000000 0.957420 -vt 0.909144 0.000000 -vt 1.000000 0.978661 -vt 0.848541 1.000000 -vn -0.9284 0.3716 0.0000 -vn 1.0000 0.0000 0.0000 -vn -0.0000 0.0000 1.0000 -vn 0.0000 0.0000 -1.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.7069 0.7073 0.0001 -vn -0.6500 0.7600 -0.0015 -vn -0.8317 0.5552 0.0000 -vn -0.8895 0.4449 -0.1046 -vn -0.8944 0.4473 0.0000 -vn 0.7835 -0.5747 0.2364 -vn -0.7686 0.6397 0.0000 +vt 0.895458 0.911707 +vt 0.000000 0.941171 +vt 0.000000 0.764683 +vt 0.955070 0.205951 +vt 0.835748 0.941171 +vt 0.000000 0.882341 +vt 0.910435 0.852878 +vn 0.3715 0.0000 -0.9284 +vn 0.0000 -1.0000 -0.0000 vn 0.0000 1.0000 0.0000 -vn 0.8321 -0.5546 0.0000 -vn 0.8439 -0.5274 0.0988 -vn 0.8227 -0.5347 0.1929 -vn 0.8217 -0.5309 0.2073 -vn -0.7072 0.7070 0.0000 -vn 0.7105 -0.5131 0.4816 -vn -0.8895 0.4448 -0.1047 -vn -0.9014 0.3608 -0.2395 -vn -0.9541 0.0000 -0.2995 +vn 0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.8985 0.3365 -0.2821 -vn -0.6405 0.7679 0.0000 -vn -0.5551 0.8318 0.0000 -vn -0.6501 -0.6421 -0.4063 -vn -0.7153 0.0799 -0.6942 -vn -0.6244 0.0250 -0.7807 -vn 0.0000 0.9956 -0.0936 -vn -0.6125 0.7875 -0.0684 -vn -0.5241 0.8511 -0.0309 +vn -0.9774 0.2074 -0.0415 +vn 0.0000 0.0000 -1.0000 +vn 0.9922 -0.1247 0.0000 +vn -0.9022 -0.3183 0.2910 +vn -0.8545 0.1446 0.4989 +vn -0.9387 0.1666 0.3017 +vn -0.9701 0.0000 0.2425 +vn -0.9373 0.2174 0.2726 +vn -0.9186 -0.2626 0.2953 +vn 0.8943 -0.4474 0.0000 +vn 0.9299 -0.0719 -0.3608 +vn 1.0000 0.0000 0.0000 +vn 0.7806 -0.0521 -0.6229 +vn 0.8126 -0.2167 -0.5411 +vn 0.8922 -0.0745 -0.4454 +vn 0.8917 -0.0742 -0.4466 +vn 0.9808 -0.1952 0.0000 +vn -0.7008 0.1275 0.7019 +vn -0.9769 0.2138 0.0000 +vn -0.9460 0.2218 0.2365 +vn -0.9459 0.2218 0.2367 +vn 0.9582 -0.2847 -0.0300 +vn 0.8809 -0.1753 -0.4397 +vn 0.8546 -0.2092 -0.4754 +vn 0.9701 -0.2426 0.0000 +vn 0.5292 -0.1720 -0.8309 +vn 0.4581 -0.0573 -0.8871 +vn 0.7185 -0.1916 -0.6686 +vn 0.5547 -0.0694 -0.8292 +vn 0.7077 0.0000 -0.7065 usemtl None s off -f 675/656/660 684/657/660 689/658/660 -f 658/659/661 657/660/661 661/661/661 -f 660/662/662 661/661/662 662/663/662 -f 658/659/661 661/661/661 664/664/661 -f 663/665/663 658/659/663 665/666/663 -f 658/659/661 664/664/661 665/666/661 -f 659/667/664 660/662/664 666/668/664 -f 660/662/662 662/663/662 666/668/662 -f 662/663/662 661/661/662 667/669/662 -f 663/665/663 665/666/663 668/670/663 -f 659/667/664 666/668/664 668/670/664 -f 658/659/663 663/665/663 670/671/663 -f 667/669/665 670/671/665 671/672/665 -f 662/663/662 667/669/662 671/672/662 -f 670/671/666 667/669/666 672/673/666 -f 662/663/667 663/665/667 673/674/667 -f 663/665/668 669/675/668 673/674/668 -f 669/675/669 662/663/669 673/674/669 -f 668/670/664 666/668/664 674/676/664 -f 666/668/662 662/663/662 675/656/662 -f 662/663/669 669/675/669 675/656/669 -f 660/662/664 659/667/664 676/677/664 -f 664/664/670 660/662/670 676/677/670 -f 663/665/667 662/663/667 677/678/667 -f 662/663/662 671/672/662 677/678/662 -f 671/672/671 663/665/671 677/678/671 -f 661/661/672 657/660/672 678/679/672 -f 667/669/662 661/661/662 678/679/662 -f 665/666/673 659/667/673 679/680/673 -f 668/670/663 665/666/663 679/680/663 -f 659/667/664 668/670/664 679/680/664 -f 659/667/674 665/666/674 680/681/674 -f 665/666/661 664/664/661 680/681/661 -f 676/677/675 659/667/675 680/681/675 -f 664/664/676 676/677/676 680/681/676 -f 670/671/663 663/665/663 681/682/663 -f 671/672/677 670/671/677 681/682/677 -f 663/665/671 671/672/671 681/682/671 -f 661/661/662 660/662/662 682/683/662 -f 660/662/678 664/664/678 682/683/678 -f 664/664/661 661/661/661 682/683/661 -f 663/665/663 668/670/663 683/684/663 -f 669/675/679 663/665/679 683/684/679 -f 669/675/680 683/684/680 684/657/680 -f 656/685/681 674/676/681 684/657/681 -f 674/676/682 666/668/682 684/657/682 -f 675/656/660 669/675/660 684/657/660 -f 683/684/683 656/685/683 684/657/683 -f 672/673/684 667/669/684 685/686/684 -f 667/669/662 678/679/662 685/686/662 -f 678/679/685 672/673/685 685/686/685 -f 674/676/686 656/685/686 686/687/686 -f 668/670/664 674/676/664 686/687/664 -f 656/685/687 683/684/687 686/687/687 -f 683/684/688 668/670/688 686/687/688 -f 657/660/689 658/659/689 687/688/689 -f 658/659/663 670/671/663 687/688/663 -f 670/671/690 672/673/690 687/688/690 -f 678/679/672 657/660/672 688/689/672 -f 672/673/685 678/679/685 688/689/685 -f 657/660/689 687/688/689 688/689/689 -f 687/688/691 672/673/691 688/689/691 -f 666/668/662 675/656/662 689/658/662 -f 684/657/682 666/668/682 689/658/682 -o Cup_hull_28 -v 0.018582 -0.017233 0.015041 -v 0.008313 -0.023815 0.050164 -v 0.008579 -0.023815 0.050164 -v 0.019372 -0.014335 0.050164 -v 0.008313 -0.015916 0.015041 -v 0.008313 -0.023815 0.018414 -v 0.020425 -0.014335 0.015041 -v 0.015421 -0.020128 0.050164 -v 0.010685 -0.014335 0.015041 -v 0.015421 -0.020128 0.015041 -v 0.020689 -0.014598 0.050164 -v 0.008579 -0.022497 0.050164 -v 0.013054 -0.021707 0.018414 -v 0.008313 -0.020653 0.015041 -v 0.018055 -0.017759 0.050164 -v 0.008313 -0.015916 0.015883 -v 0.013056 -0.021707 0.050164 -v 0.009895 -0.023288 0.018132 -v 0.020688 -0.014599 0.017850 -v 0.017002 -0.018812 0.015041 -v 0.009105 -0.023023 0.017008 -v 0.020689 -0.014335 0.050164 -v 0.019898 -0.015651 0.050164 -v 0.009896 -0.023288 0.050164 -v 0.017001 -0.018812 0.050164 -v 0.008313 -0.022760 0.050164 -v 0.019899 -0.015652 0.015041 -v 0.018581 -0.017233 0.050164 -v 0.010948 -0.014335 0.016444 -v 0.008578 -0.023815 0.018414 -v 0.014896 -0.020391 0.015041 -v 0.020688 -0.014335 0.017850 -v 0.008578 -0.023550 0.017568 -vt 1.000000 0.531911 -vt 0.911992 0.127839 -vt 0.928047 0.021437 -vt 0.000000 0.000000 -vt 0.000000 0.021535 -vt 0.000000 0.893598 +f 637/620/626 633/621/626 650/622/626 +f 623/623/627 621/624/627 626/625/627 +f 625/626/628 624/627/628 627/628/628 +f 627/628/628 624/627/628 629/629/628 +f 623/623/629 628/630/629 629/629/629 +f 623/623/627 626/625/627 630/631/627 +f 628/630/629 623/623/629 630/631/629 +f 626/625/627 621/624/627 631/632/627 +f 621/624/630 622/633/630 632/634/630 +f 622/633/631 625/626/631 632/634/631 +f 631/632/627 621/624/627 632/634/627 +f 625/626/632 631/632/632 632/634/632 +f 625/626/628 627/628/628 633/621/628 +f 631/632/632 625/626/632 633/621/632 +f 624/627/628 625/626/628 634/635/628 +f 628/630/633 620/636/633 636/637/633 +f 631/632/626 633/621/626 637/620/626 +f 621/624/634 623/623/634 638/638/634 +f 623/623/635 624/627/635 638/638/635 +f 638/638/636 624/627/636 639/639/636 +f 622/633/637 621/624/637 639/639/637 +f 624/627/638 634/635/638 639/639/638 +f 621/624/639 638/638/639 639/639/639 +f 630/631/627 626/625/627 640/640/627 +f 635/641/640 630/631/640 640/640/640 +f 627/628/628 629/629/628 641/642/628 +f 636/637/641 620/636/641 641/642/641 +f 629/629/642 636/637/642 641/642/642 +f 629/629/629 628/630/629 642/643/629 +f 628/630/633 636/637/633 642/643/633 +f 636/637/642 629/629/642 642/643/642 +f 637/620/643 627/628/643 643/644/643 +f 640/640/644 626/625/644 643/644/644 +f 641/642/645 620/636/645 643/644/645 +f 627/628/646 641/642/646 643/644/646 +f 620/636/647 628/630/647 644/645/647 +f 628/630/629 630/631/629 644/645/629 +f 624/627/648 623/623/648 645/646/648 +f 623/623/629 629/629/629 645/646/629 +f 629/629/628 624/627/628 645/646/628 +f 625/626/649 622/633/649 646/647/649 +f 634/635/628 625/626/628 646/647/628 +f 622/633/650 639/639/650 646/647/650 +f 639/639/651 634/635/651 646/647/651 +f 635/641/652 640/640/652 647/648/652 +f 643/644/653 620/636/653 647/648/653 +f 640/640/654 643/644/654 647/648/654 +f 620/636/647 644/645/647 647/648/647 +f 644/645/655 635/641/655 647/648/655 +f 630/631/640 635/641/640 648/649/640 +f 644/645/629 630/631/629 648/649/629 +f 635/641/655 644/645/655 648/649/655 +f 626/625/656 631/632/656 649/650/656 +f 631/632/657 637/620/657 649/650/657 +f 643/644/658 626/625/658 649/650/658 +f 637/620/659 643/644/659 649/650/659 +f 633/621/628 627/628/628 650/622/628 +f 627/628/660 637/620/660 650/622/660 +o cup_hull_27 +v 0.040266 0.003620 0.075211 +v 0.037317 0.015417 0.048666 +v 0.037738 0.014574 0.048666 +v 0.036475 0.000670 0.048666 +v 0.035633 0.015417 0.075211 +v 0.033105 0.015417 0.048666 +v 0.040266 0.000670 0.048666 +v 0.038581 0.000670 0.075211 +v 0.037738 0.014574 0.075211 +v 0.039423 0.009094 0.048666 +v 0.033105 0.014995 0.050355 +v 0.040266 0.000670 0.075211 +v 0.039002 0.010782 0.075211 +v 0.040266 0.003620 0.048666 +v 0.035633 0.014574 0.075211 +v 0.036475 0.000670 0.050355 +v 0.039845 0.006992 0.075211 +v 0.037317 0.015417 0.075211 +v 0.039002 0.010782 0.048666 +v 0.039845 0.006992 0.048666 +vt 0.000000 0.428739 +vt 1.000000 0.200078 +vt 1.000000 0.428739 +vt 1.000000 1.000000 +vt 1.000000 0.942835 vt 1.000000 0.000000 -vt 0.903965 0.000000 -vt 1.000000 0.829777 -vt 1.000000 0.978661 -vt 0.000000 0.574393 -vt 1.000000 0.191660 -vt 1.000000 0.574393 vt 0.000000 1.000000 -vt 0.000000 0.021535 +vt 1.000000 1.000000 vt 1.000000 0.000000 -vt 0.000000 0.787197 -vt 0.976016 0.000000 -vt 0.000000 0.383222 -vt 0.903965 0.383124 -vt 1.000000 0.702134 -vt 0.000000 1.000000 -vt 0.920020 0.999902 -vt 0.000000 0.936081 -vt 0.000000 0.127937 -vt 0.000000 0.702036 vt 0.000000 0.000000 -vt 1.000000 0.936179 -vt 0.000000 0.829679 -vt 0.960059 0.212901 -vt 0.903965 0.021437 -vt 0.944004 0.064017 -vt 0.920020 0.999902 -vn 0.3165 -0.8917 -0.3237 -vn 0.0000 0.0000 1.0000 -vn -1.0000 -0.0000 0.0000 -vn 0.0000 -1.0000 0.0000 +vt 0.000000 0.200078 +vt 0.000000 0.942835 +vt 1.000000 0.571261 +vt 0.936374 0.971417 +vt 0.000000 0.000000 +vt 0.000000 0.685689 +vt 0.000000 0.942835 +vt 0.936374 0.000000 +vt 0.000000 1.000000 +vt 1.000000 0.685689 +vn 0.9923 0.1240 0.0000 vn 0.0000 0.0000 -1.0000 vn 0.0000 1.0000 0.0000 -vn -0.5547 0.8321 0.0000 -vn -0.5958 0.7878 0.1559 -vn 0.5550 -0.8318 0.0000 -vn 0.5548 -0.8320 -0.0000 -vn 0.4476 -0.8942 -0.0000 -vn 0.4524 -0.8865 -0.0974 -vn 0.6397 -0.7686 0.0000 -vn 0.7070 -0.7072 0.0000 -vn 1.0000 0.0000 -0.0000 -vn 0.3716 -0.9284 -0.0000 -vn 0.6400 -0.7683 0.0000 -vn 0.7069 -0.7073 0.0000 -vn -0.6949 0.7052 0.1408 -vn 0.9220 -0.3679 -0.1209 -vn 0.8005 -0.5993 -0.0000 -vn 0.7996 -0.6005 0.0000 -vn 0.7684 -0.6399 0.0000 -vn 0.7074 -0.7068 0.0000 -vn 0.7683 -0.6401 0.0000 -vn -0.5306 0.8372 0.1326 -vn -0.5274 0.8438 0.0988 -vn 0.4439 -0.8887 -0.1148 -vn 0.0253 -0.6334 -0.7734 -vn 0.9957 0.0000 -0.0932 -vn -0.8238 -0.4136 -0.3877 -vn -0.1297 -0.6585 -0.7413 -vn 0.0000 -0.9544 -0.2984 -vn 0.3032 -0.9095 -0.2844 -vn 0.1567 -0.7887 -0.5944 +vn 0.0000 -1.0000 -0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.8945 0.4471 0.0000 +vn -0.9306 0.3551 0.0886 +vn -0.9734 -0.2225 -0.0555 +vn 1.0000 0.0000 0.0000 +vn 0.9487 0.3162 0.0000 +vn -0.9949 0.0000 0.1012 +vn -0.9738 -0.2065 0.0955 +vn -0.9734 -0.2290 0.0000 +vn -0.9701 -0.2283 0.0822 +vn 0.9762 0.2171 0.0017 +vn 0.9702 0.2422 0.0000 +vn 0.9805 0.1966 0.0000 usemtl None s off -f 720/690/692 707/691/692 722/692/692 -f 691/693/693 692/694/693 693/695/693 -f 691/693/694 694/696/694 695/697/694 -f 692/694/695 691/693/695 695/697/695 -f 690/698/696 694/696/696 696/699/696 -f 693/695/693 692/694/693 697/700/693 -f 693/695/697 696/699/697 698/701/697 -f 696/699/696 694/696/696 698/701/696 -f 694/696/696 690/698/696 699/702/696 -f 693/695/693 697/700/693 700/703/693 -f 691/693/693 693/695/693 701/704/693 -f 695/697/694 694/696/694 703/705/694 -f 694/696/696 699/702/696 703/705/696 -f 700/703/693 697/700/693 704/706/693 -f 694/696/694 691/693/694 705/707/694 -f 698/701/698 694/696/698 705/707/698 -f 701/704/699 693/695/699 705/707/699 -f 697/700/693 692/694/693 706/708/693 -f 699/702/700 697/700/700 706/708/700 -f 702/709/701 699/702/701 706/708/701 -f 702/709/702 706/708/702 707/691/702 -f 699/702/703 702/709/703 707/691/703 -f 699/702/696 690/698/696 709/710/696 -f 697/700/704 699/702/704 709/710/704 -f 690/698/705 704/706/705 709/710/705 -f 696/699/697 693/695/697 711/711/697 -f 693/695/693 700/703/693 711/711/693 -f 700/703/706 708/712/706 711/711/706 -f 700/703/693 704/706/693 712/713/693 -f 706/708/693 692/694/693 713/714/693 -f 707/691/702 706/708/702 713/714/702 -f 692/694/707 707/691/707 713/714/707 -f 704/706/693 697/700/693 714/715/693 -f 697/700/708 709/710/708 714/715/708 -f 709/710/709 704/706/709 714/715/709 -f 691/693/693 701/704/693 715/716/693 -f 705/707/694 691/693/694 715/716/694 -f 701/704/710 705/707/710 715/716/710 -f 690/698/696 696/699/696 716/717/696 -f 696/699/711 708/712/711 716/717/711 -f 708/712/712 700/703/712 716/717/712 -f 700/703/713 712/713/713 716/717/713 -f 716/717/714 712/713/714 717/718/714 -f 704/706/715 690/698/715 717/718/715 -f 712/713/693 704/706/693 717/718/693 -f 690/698/716 716/717/716 717/718/716 -f 693/695/697 698/701/697 718/719/697 -f 705/707/717 693/695/717 718/719/717 -f 698/701/718 705/707/718 718/719/718 -f 692/694/695 695/697/695 719/720/695 -f 707/691/707 692/694/707 719/720/707 -f 703/705/696 699/702/696 720/690/696 -f 699/702/719 707/691/719 720/690/719 -f 710/721/720 703/705/720 720/690/720 -f 708/712/721 696/699/721 721/722/721 -f 696/699/697 711/711/697 721/722/697 -f 711/711/706 708/712/706 721/722/706 -f 695/697/722 703/705/722 722/692/722 -f 703/705/723 710/721/723 722/692/723 -f 719/720/724 695/697/724 722/692/724 -f 707/691/725 719/720/725 722/692/725 -f 710/721/726 720/690/726 722/692/726 -o Cup_hull_29 -v -0.020392 -0.000377 0.015036 -v -0.016441 0.007259 -0.048198 -v -0.016441 0.006732 -0.048198 -v -0.020392 0.007259 -0.048198 -v -0.016441 0.007259 0.015036 -v -0.018022 -0.000377 -0.048198 -v -0.020392 0.007259 0.015036 -v -0.018022 -0.000377 0.015036 -v -0.020392 -0.000377 -0.048198 -v -0.016441 0.006732 0.013624 -vt 0.000000 0.000000 -vt 1.000000 0.930991 -vt 0.022318 0.930991 -vt 1.000000 1.000000 -vt 1.000000 1.000000 +f 667/651/661 664/652/661 670/653/661 +f 652/654/662 653/655/662 654/656/662 +f 655/657/663 652/654/663 656/658/663 +f 652/654/662 654/656/662 656/658/662 +f 654/656/662 653/655/662 657/659/662 +f 654/656/664 657/659/664 658/660/664 +f 651/661/665 655/657/665 658/660/665 +f 653/655/666 652/654/666 659/662/666 +f 655/657/665 651/661/665 659/662/665 +f 657/659/662 653/655/662 660/663/662 +f 655/657/667 656/658/667 661/664/667 +f 656/658/668 654/656/668 661/664/668 +f 657/659/669 651/661/669 662/665/669 +f 658/660/664 657/659/664 662/665/664 +f 651/661/665 658/660/665 662/665/665 +f 659/662/665 651/661/665 663/666/665 +f 653/655/670 659/662/670 663/666/670 +f 651/661/669 657/659/669 664/652/669 +f 657/659/662 660/663/662 664/652/662 +f 658/660/665 655/657/665 665/667/665 +f 655/657/671 661/664/671 665/667/671 +f 661/664/672 658/660/672 665/667/672 +f 654/656/664 658/660/664 666/668/664 +f 661/664/673 654/656/673 666/668/673 +f 658/660/674 661/664/674 666/668/674 +f 663/666/665 651/661/665 667/651/665 +f 660/663/675 663/666/675 667/651/675 +f 651/661/661 664/652/661 667/651/661 +f 652/654/663 655/657/663 668/669/663 +f 659/662/666 652/654/666 668/669/666 +f 655/657/665 659/662/665 668/669/665 +f 660/663/662 653/655/662 669/670/662 +f 653/655/670 663/666/670 669/670/670 +f 663/666/676 660/663/676 669/670/676 +f 664/652/662 660/663/662 670/653/662 +f 660/663/677 667/651/677 670/653/677 +o cup_hull_28 +v 0.039844 0.006991 0.027600 +v 0.024678 0.014995 0.024652 +v 0.024678 0.015417 0.024652 +v 0.033103 0.015417 0.048666 +v 0.036052 0.000670 0.048241 +v 0.028891 0.000670 0.022545 +v 0.036895 0.015417 0.025917 +v 0.039002 0.010782 0.048666 +v 0.040265 0.000671 0.026758 +v 0.040265 0.000671 0.048666 +v 0.032680 0.015417 0.022545 +v 0.037316 0.015417 0.048666 +v 0.024678 0.015417 0.022545 +v 0.039002 0.000670 0.025073 +v 0.029313 0.000670 0.025917 +v 0.037738 0.014574 0.027180 +v 0.032680 0.000670 0.022545 +v 0.032680 0.014995 0.048241 +v 0.040265 0.003620 0.048666 +v 0.039002 0.006992 0.025495 +v 0.039002 0.010782 0.027180 +v 0.040265 0.003620 0.027600 +v 0.039844 0.006992 0.048666 +v 0.036474 0.000670 0.048666 +v 0.037738 0.014574 0.048666 +v 0.037738 0.012043 0.025495 +v 0.039423 0.009094 0.027180 +v 0.037316 0.015417 0.026758 +v 0.028891 0.000670 0.023810 +v 0.024678 0.014574 0.022545 +v 0.025943 0.014995 0.028443 +vt 0.016249 0.729711 +vt 0.016249 0.513363 +vt 0.774178 0.081155 +vt 0.919342 0.000000 +vt 0.000000 0.540480 +vt 0.870889 0.783749 +vt 0.000000 0.918943 vt 0.000000 1.000000 +vt 1.000000 0.513363 +vt 0.000000 0.810769 +vt 0.919342 0.000000 vt 1.000000 0.000000 -vt 0.000000 0.000000 +vt 1.000000 0.270289 +vt 0.903191 0.918943 +vt 0.838684 1.000000 +vt 0.870889 0.297308 +vt 1.000000 0.513363 vt 0.000000 1.000000 +vt 0.887040 0.918943 +vt 0.822533 0.837885 +vt 0.822533 0.918943 +vt 0.806480 1.000000 +vt 0.000000 0.972981 +vt 0.806480 0.972981 +vt 0.000000 0.756730 +vt 0.000000 0.837885 +vt 0.887040 0.837885 +vt 0.822533 0.945962 +vt 0.838684 0.810769 +vt 0.951547 0.270289 vt 1.000000 0.000000 -vn 0.9762 -0.2170 0.0000 -vn 0.0000 0.0000 -1.0000 -vn 1.0000 0.0000 0.0000 +vn -0.9240 -0.2175 0.3144 vn 0.0000 1.0000 0.0000 -vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn 0.9765 -0.2021 0.0755 +vn 0.0011 -1.0000 0.0000 +vn -0.9209 -0.2733 0.2780 +vn 0.3714 0.0000 -0.9285 +vn -0.8045 0.5225 0.2822 +vn 1.0000 0.0000 0.0000 +vn 0.7994 0.0400 -0.5994 +vn 0.4849 0.0582 -0.8726 +vn 0.9487 0.3161 0.0000 +vn 0.9192 0.1080 -0.3787 +vn 0.9923 0.1240 -0.0000 +vn 0.9923 0.1239 0.0000 +vn 0.0004 -1.0000 0.0000 +vn -0.6265 -0.1432 0.7661 +vn -0.7001 -0.1648 0.6947 +vn 0.8939 0.4482 0.0000 +vn 0.6056 0.2461 -0.7568 +vn 0.5677 0.1420 -0.8109 +vn 0.8564 0.2693 -0.4405 +vn 0.8516 0.2130 -0.4790 +vn 0.9702 0.2421 0.0000 +vn 0.8521 0.2127 -0.4782 +vn 0.9292 0.1161 -0.3509 +vn 0.9214 0.1133 -0.3716 +vn 0.9762 0.2170 0.0021 +vn 0.9805 0.1963 -0.0000 +vn 0.8601 0.2737 -0.4306 +vn 0.9039 0.3011 -0.3038 +vn -0.9393 -0.2873 0.1878 +vn -0.9569 -0.2848 0.0570 +vn -0.9570 -0.2900 0.0000 +vn -0.9486 0.0000 0.3165 +vn -0.9241 -0.2260 0.3083 +vn -0.9452 0.0568 0.3216 usemtl None s off -f 730/723/727 725/724/727 732/725/727 -f 724/726/728 725/724/728 726/727/728 -f 725/724/729 724/726/729 727/728/729 -f 724/726/730 726/727/730 727/728/730 -f 726/727/728 725/724/728 728/729/728 -f 726/727/731 723/730/731 729/731/731 -f 723/730/732 727/728/732 729/731/732 -f 727/728/730 726/727/730 729/731/730 -f 727/728/732 723/730/732 730/723/732 -f 728/729/727 725/724/727 730/723/727 -f 723/730/733 728/729/733 730/723/733 -f 723/730/731 726/727/731 731/732/731 -f 726/727/728 728/729/728 731/732/728 -f 728/729/733 723/730/733 731/732/733 -f 725/724/729 727/728/729 732/725/729 -f 727/728/734 730/723/734 732/725/734 -o Cup_hull_30 -v 0.017529 0.018321 0.034429 -v 0.008314 0.022795 0.050166 -v 0.008314 0.023587 0.050166 -v 0.021217 0.013580 0.050166 -v 0.018582 0.013580 0.034429 -v 0.008314 0.021480 0.034429 -v 0.015686 0.019899 0.050166 -v 0.009894 0.023322 0.034429 -v 0.019899 0.013580 0.050166 -v 0.021217 0.013844 0.034429 -v 0.019899 0.015687 0.050166 -v 0.012527 0.022006 0.050166 -v 0.013843 0.021216 0.034429 -v 0.008314 0.023587 0.034429 -v 0.008314 0.021480 0.035553 -v 0.009105 0.023587 0.050166 -v 0.008314 0.022533 0.048477 -v 0.017793 0.018057 0.050166 -v 0.019899 0.015687 0.034429 -v 0.018582 0.013580 0.035553 -v 0.021217 0.013580 0.034429 -v 0.015686 0.019899 0.034429 -v 0.021217 0.013844 0.050166 -v 0.018319 0.017530 0.034429 -v 0.012527 0.022006 0.034429 -v 0.014633 0.020688 0.050166 -v 0.010421 0.023059 0.050166 -v 0.009105 0.023587 0.034429 -v 0.018319 0.017530 0.050166 -v 0.020689 0.014634 0.050166 -vt 0.000000 0.897905 -vt 0.000000 1.000000 -vt 0.000000 0.959084 -vt 0.000000 0.000000 +f 675/671/678 688/672/678 701/673/678 +f 673/674/679 674/675/679 677/676/679 +f 678/677/680 674/675/680 680/678/680 +f 673/674/679 677/676/679 681/679/679 +f 677/676/679 674/675/679 682/680/679 +f 674/675/680 678/677/680 682/680/680 +f 672/681/681 673/674/681 683/682/681 +f 673/674/679 681/679/679 683/682/679 +f 681/679/682 676/683/682 683/682/682 +f 675/671/683 676/683/683 684/684/683 +f 679/685/684 680/678/684 684/684/684 +f 675/671/685 672/681/685 685/686/685 +f 676/683/683 675/671/683 685/686/683 +f 676/683/682 681/679/682 687/687/682 +f 684/684/683 676/683/683 687/687/683 +f 681/679/686 684/684/686 687/687/686 +f 674/675/687 673/674/687 688/672/687 +f 678/677/680 680/678/680 689/688/680 +f 680/678/688 679/685/688 689/688/688 +f 679/685/689 684/684/689 690/689/689 +f 684/684/690 681/679/690 690/689/690 +f 686/690/691 678/677/691 691/691/691 +f 689/688/688 679/685/688 692/692/688 +f 679/685/692 690/689/692 692/692/692 +f 678/677/680 689/688/680 693/693/680 +f 692/692/693 671/694/693 693/693/693 +f 689/688/694 692/692/694 693/693/694 +f 680/678/680 674/675/680 694/695/680 +f 675/671/683 684/684/683 694/695/683 +f 684/684/695 680/678/695 694/695/695 +f 674/675/696 688/672/696 694/695/696 +f 688/672/697 675/671/697 694/695/697 +f 682/680/680 678/677/680 695/696/680 +f 678/677/691 686/690/691 695/696/691 +f 686/690/698 682/680/698 695/696/698 +f 681/679/699 677/676/699 696/697/699 +f 690/689/700 681/679/700 696/697/700 +f 677/676/701 691/691/701 696/697/701 +f 691/691/702 690/689/702 696/697/702 +f 691/691/703 678/677/703 697/698/703 +f 690/689/704 691/691/704 697/698/704 +f 671/694/705 692/692/705 697/698/705 +f 692/692/706 690/689/706 697/698/706 +f 678/677/707 693/693/707 697/698/707 +f 693/693/708 671/694/708 697/698/708 +f 677/676/679 682/680/679 698/699/679 +f 682/680/698 686/690/698 698/699/698 +f 691/691/709 677/676/709 698/699/709 +f 686/690/710 691/691/710 698/699/710 +f 685/686/711 672/681/711 699/700/711 +f 676/683/683 685/686/683 699/700/683 +f 672/681/681 683/682/681 700/701/681 +f 683/682/682 676/683/682 700/701/682 +f 699/700/712 672/681/712 700/701/712 +f 676/683/713 699/700/713 700/701/713 +f 673/674/714 672/681/714 701/673/714 +f 672/681/715 675/671/715 701/673/715 +f 688/672/716 673/674/716 701/673/716 +o cup_hull_29 +v 0.033945 0.022160 0.075211 +v 0.021308 0.034378 0.051615 +v 0.022151 0.033953 0.051615 +v 0.033523 0.015417 0.051615 +v 0.020465 0.032690 0.075211 +v 0.033945 0.022160 0.051615 +v 0.035631 0.015417 0.075211 +v 0.020465 0.030584 0.051615 +v 0.028048 0.029320 0.075211 +v 0.037317 0.015840 0.051615 +v 0.021308 0.034378 0.075211 +v 0.029312 0.028054 0.051615 +v 0.037317 0.015840 0.075211 +v 0.035211 0.015417 0.073945 +v 0.020465 0.034378 0.051615 +v 0.033523 0.015417 0.053304 +v 0.031839 0.025107 0.075211 +v 0.025100 0.031848 0.051615 +v 0.023414 0.033112 0.075211 +v 0.037317 0.015417 0.051615 +v 0.035211 0.020051 0.051615 +v 0.020465 0.030584 0.052881 +v 0.020465 0.034378 0.075211 +v 0.031839 0.025107 0.051615 +v 0.035211 0.020051 0.075211 +v 0.037317 0.015417 0.075211 +v 0.027626 0.029741 0.051615 +v 0.025100 0.031848 0.075211 +v 0.029312 0.028054 0.075211 +v 0.033102 0.023425 0.051615 +vt 1.000000 0.511061 +vt 0.000000 0.511061 +vt 1.000000 0.422377 +vt 1.000000 1.000000 +vt 1.000000 0.977584 +vt 1.000000 0.000000 +vt 1.000000 0.355619 +vt 0.000000 0.355619 +vt 0.000000 0.911022 vt 0.000000 0.000000 +vt 1.000000 0.799922 +vt 0.000000 0.733262 +vt 1.000000 0.022318 vt 0.000000 1.000000 -vt 1.000000 0.000000 -vt 1.000000 0.714174 -vt 1.000000 0.795810 -vt 0.000000 0.571359 -vt 1.000000 0.122455 -vt 0.000000 0.897905 +vt 1.000000 0.666503 +vt 0.000000 0.022318 +vt 0.053641 0.000000 vt 1.000000 1.000000 -vt 0.000000 0.326547 -vt 1.000000 0.428543 +vt 0.928446 0.000000 +vt 1.000000 0.866582 +vt 0.000000 0.933242 vt 1.000000 0.000000 -vt 0.928543 0.000000 -vt 0.000000 0.061276 -vt 0.107283 0.000000 -vt 0.000000 0.734632 -vt 1.000000 0.897905 -vt 0.928543 0.795810 -vt 1.000000 1.000000 -vt 1.000000 0.571359 -vt 1.000000 0.775450 -vt 1.000000 0.326547 -vt 0.000000 0.489722 -vt 0.000000 0.163273 -vt 1.000000 0.061276 -vt 0.000000 0.775450 -vn 0.0001 0.0000 1.0000 +vt 1.000000 0.244421 +vt 0.946359 0.799922 +vt 0.000000 1.000000 +vt 0.000000 0.244421 +vt 0.000000 0.000000 +vt 1.000000 0.755482 +vt 0.000000 0.866582 +vt 0.000000 0.666503 +vn 0.7994 0.6007 0.0000 +vn 0.0000 0.0000 -1.0000 vn 0.0000 0.0000 1.0000 +vn 0.4502 0.8929 0.0000 +vn 0.0000 -1.0000 -0.0000 +vn -0.7291 -0.6401 0.2423 vn -1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn -0.7578 -0.6525 0.0000 +vn -0.7569 -0.6506 0.0619 +vn 0.5150 0.8572 0.0030 +vn 0.5809 0.8140 -0.0021 +vn 1.0000 0.0000 0.0000 +vn 0.8575 0.5146 0.0000 +vn 0.8943 0.4474 0.0000 +vn -0.7572 -0.6502 0.0613 +vn 0.7591 0.6509 0.0000 +vn 0.7074 0.7069 -0.0000 +vn 0.6405 0.7679 0.0000 +vn 0.5998 0.8001 0.0000 +vn 0.6510 0.7591 0.0019 +vn 0.7077 0.7065 0.0000 +vn -0.0001 0.0000 1.0000 +vn 0.8323 0.5543 0.0000 +vn 0.8136 0.5815 0.0021 +usemtl None +s off +f 725/702/717 718/703/717 731/704/717 +f 703/705/718 704/706/718 705/707/718 +f 705/707/718 704/706/718 707/708/718 +f 702/709/719 706/710/719 708/711/719 +f 703/705/718 705/707/718 709/712/718 +f 706/710/719 702/709/719 710/713/719 +f 705/707/718 707/708/718 711/714/718 +f 704/706/720 703/705/720 712/715/720 +f 706/710/719 710/713/719 712/715/719 +f 707/708/718 704/706/718 713/716/718 +f 702/709/719 708/711/719 714/717/719 +f 705/707/721 708/711/721 715/718/721 +f 708/711/722 706/710/722 715/718/722 +f 703/705/718 709/712/718 716/719/718 +f 709/712/723 706/710/723 716/719/723 +f 712/715/724 703/705/724 716/719/724 +f 709/712/725 705/707/725 717/720/725 +f 705/707/721 715/718/721 717/720/721 +f 715/718/726 706/710/726 717/720/726 +f 710/713/719 702/709/719 718/703/719 +f 713/716/718 704/706/718 719/721/718 +f 704/706/727 712/715/727 720/722/727 +f 712/715/719 710/713/719 720/722/719 +f 719/721/728 704/706/728 720/722/728 +f 708/711/721 705/707/721 721/723/721 +f 705/707/718 711/714/718 721/723/718 +f 711/714/729 714/717/729 721/723/729 +f 707/708/730 702/709/730 722/724/730 +f 711/714/718 707/708/718 722/724/718 +f 714/717/731 711/714/731 722/724/731 +f 706/710/723 709/712/723 723/725/723 +f 709/712/725 717/720/725 723/725/725 +f 717/720/732 706/710/732 723/725/732 +f 706/710/719 712/715/719 724/726/719 +f 716/719/723 706/710/723 724/726/723 +f 712/715/724 716/719/724 724/726/724 +f 707/708/718 713/716/718 725/702/718 +f 713/716/733 718/703/733 725/702/733 +f 702/709/719 714/717/719 726/727/719 +f 722/724/730 702/709/730 726/727/730 +f 714/717/731 722/724/731 726/727/731 +f 714/717/719 708/711/719 727/728/719 +f 708/711/721 721/723/721 727/728/721 +f 721/723/729 714/717/729 727/728/729 +f 710/713/734 713/716/734 728/729/734 +f 713/716/718 719/721/718 728/729/718 +f 728/729/735 719/721/735 729/730/735 +f 720/722/719 710/713/719 729/730/719 +f 719/721/736 720/722/736 729/730/736 +f 710/713/737 728/729/737 729/730/737 +f 713/716/738 710/713/738 730/731/738 +f 710/713/739 718/703/739 730/731/739 +f 718/703/733 713/716/733 730/731/733 +f 702/709/740 707/708/740 731/704/740 +f 718/703/741 702/709/741 731/704/741 +f 707/708/718 725/702/718 731/704/718 +o cup_hull_30 +v 0.035210 0.020053 0.051615 +v 0.020887 0.034378 0.026336 +v 0.020464 0.034378 0.026336 +v 0.024257 0.015417 0.022542 +v 0.020464 0.030584 0.051615 +v 0.036894 0.015840 0.026336 +v 0.033104 0.015417 0.051191 +v 0.029311 0.028054 0.022542 +v 0.023414 0.033112 0.051615 +v 0.020464 0.020053 0.022542 +v 0.037315 0.015417 0.051615 +v 0.032683 0.015417 0.022542 +v 0.029311 0.028054 0.051615 +v 0.023835 0.032690 0.022542 +v 0.032683 0.023845 0.022542 +v 0.020464 0.034378 0.051615 +v 0.024677 0.015417 0.025493 +v 0.020464 0.032690 0.022542 +v 0.037315 0.015840 0.027599 +v 0.031840 0.025107 0.051615 +v 0.027627 0.029741 0.036450 +v 0.033945 0.022158 0.027181 +v 0.020464 0.020474 0.025072 +v 0.037315 0.015417 0.027599 +v 0.020464 0.030161 0.050770 +v 0.025100 0.031848 0.022542 +v 0.022150 0.033953 0.027181 +v 0.021307 0.034378 0.051615 +v 0.027627 0.029741 0.051615 +v 0.035210 0.020053 0.027181 +v 0.031840 0.025107 0.022542 +v 0.033524 0.015417 0.051615 +v 0.033104 0.023424 0.051615 +v 0.037315 0.015840 0.051615 +v 0.025100 0.031848 0.051615 +v 0.028048 0.029320 0.022542 +vt 0.521633 0.755482 +vt 0.000000 0.755482 +vt 1.000000 0.733262 +vt 0.000000 0.799922 +vt 0.000000 0.244518 +vt 0.000000 0.933242 +vt 0.869518 1.000000 +vt 1.000000 0.244518 +vt 1.000000 0.666503 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 0.014585 0.000000 +vt 1.000000 0.000000 +vt 0.000000 0.666503 +vt 0.869518 1.000000 +vt 1.000000 0.911022 +vt 1.000000 0.444499 +vt 0.869518 0.022318 +vt 0.000000 1.000000 +vt 0.898493 0.000000 +vt 1.000000 0.911022 +vt 0.826057 0.022318 +vt 0.000000 0.511061 +vt 0.912980 0.266738 +vt 0.826057 0.000000 +vt 0.029072 0.777604 +vt 1.000000 0.866582 +vt 0.840446 0.977584 +vt 0.000000 1.000000 +vt 0.840446 0.244518 +vt 0.840446 0.355521 +vt 1.000000 0.511061 +vt 0.000000 0.000000 +vt 0.000000 0.422279 +vt 0.000000 0.022318 +vt 0.000000 0.866582 +vn 0.7077 0.7065 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 -0.0000 0.0000 vn 0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.6098 -0.7926 0.0000 +vn 0.0000 0.9137 -0.4064 +vn 0.6693 0.0000 -0.7430 vn 0.0000 1.0000 0.0000 -vn -0.6179 -0.7769 0.1208 -vn -0.6160 -0.7851 0.0640 -vn 0.6581 0.7529 0.0016 -vn -0.6089 -0.7914 0.0549 +vn 0.8957 0.3299 -0.2982 +vn 0.7589 0.6512 0.0000 +vn -0.7698 -0.6297 0.1049 +vn -0.7682 -0.6308 0.1095 +vn 0.4531 -0.7889 -0.4151 vn 1.0000 0.0000 0.0000 -vn 0.6504 0.7596 0.0000 -vn 0.7070 0.7072 -0.0000 -vn 0.7593 0.6508 0.0000 -vn 0.4472 0.8945 0.0000 -vn 0.5144 0.8575 0.0000 -vn 0.5305 0.8477 0.0018 -vn 0.5997 0.8002 0.0000 -vn 0.5816 0.8135 -0.0019 -vn 0.4471 0.8945 0.0000 -vn 0.3723 0.9281 0.0031 -vn 0.3177 0.9482 0.0000 -vn 0.7073 0.7069 0.0000 -vn 0.8001 0.5998 0.0000 -vn 0.8136 0.5814 -0.0019 -vn 0.8316 0.5554 0.0000 +vn 0.9488 0.0000 -0.3159 +vn -0.7268 -0.6142 0.3075 +vn -0.7399 -0.6274 0.2426 +vn -0.7570 -0.6114 0.2305 +vn 0.3826 0.9173 -0.1107 +vn 0.5789 0.8154 -0.0019 +vn 0.5541 0.8321 -0.0252 +vn 0.3220 0.9467 -0.0054 +vn 0.5150 0.8572 0.0029 +vn 0.6403 0.7681 0.0000 +vn 0.8946 0.4469 0.0000 +vn 0.8919 0.4324 -0.1324 +vn 0.8571 0.5152 0.0000 +vn 0.8562 0.5147 -0.0457 +vn 0.8313 0.5553 -0.0242 +vn -0.6057 -0.5216 0.6009 +vn 0.8480 0.5300 0.0017 +vn 0.7998 0.6003 0.0000 +vn 0.8154 0.5789 -0.0019 +vn 0.5998 0.8001 0.0000 +vn 0.6510 0.7591 -0.0033 usemtl None s off -f 743/733/735 755/734/735 762/735/735 -f 735/736/736 734/737/736 736/738/736 -f 734/737/737 735/736/737 738/739/737 -f 733/740/738 737/741/738 738/739/738 -f 735/736/736 736/738/736 739/742/736 -f 733/740/738 738/739/738 740/743/738 -f 736/738/736 734/737/736 741/744/736 -f 737/741/739 736/738/739 741/744/739 -f 737/741/738 733/740/738 742/745/738 -f 739/742/736 736/738/736 743/733/736 -f 735/736/736 739/742/736 744/746/736 -f 733/740/738 740/743/738 745/747/738 -f 738/739/737 735/736/737 746/748/737 -f 740/743/738 738/739/738 746/748/738 -f 734/737/737 738/739/737 747/749/737 -f 738/739/740 737/741/740 747/749/740 -f 735/736/736 744/746/736 748/750/736 -f 746/748/741 735/736/741 748/750/741 -f 741/744/742 734/737/742 749/751/742 -f 734/737/737 747/749/737 749/751/737 -f 747/749/743 741/744/743 749/751/743 -f 733/740/744 739/742/744 750/752/744 -f 739/742/736 743/733/736 750/752/736 -f 742/745/738 733/740/738 751/753/738 -f 737/741/739 741/744/739 752/754/739 -f 747/749/740 737/741/740 752/754/740 -f 741/744/745 747/749/745 752/754/745 -f 736/738/739 737/741/739 753/755/739 -f 742/745/746 736/738/746 753/755/746 -f 737/741/738 742/745/738 753/755/738 -f 739/742/747 733/740/747 754/756/747 -f 733/740/738 745/747/738 754/756/738 -f 736/738/746 742/745/746 755/734/746 -f 743/733/736 736/738/736 755/734/736 -f 733/740/748 750/752/748 756/757/748 -f 743/733/749 751/753/749 756/757/749 -f 751/753/738 733/740/738 756/757/738 -f 740/743/750 744/746/750 757/758/750 -f 745/747/738 740/743/738 757/758/738 -f 744/746/751 745/747/751 757/758/751 -f 744/746/736 739/742/736 758/759/736 -f 745/747/752 744/746/752 758/759/752 -f 739/742/753 754/756/753 758/759/753 -f 754/756/754 745/747/754 758/759/754 -f 744/746/755 740/743/755 759/760/755 -f 748/750/736 744/746/736 759/760/736 -f 740/743/756 748/750/756 759/760/756 -f 740/743/738 746/748/738 760/761/738 -f 748/750/757 740/743/757 760/761/757 -f 746/748/741 748/750/741 760/761/741 -f 750/752/736 743/733/736 761/762/736 -f 756/757/758 750/752/758 761/762/758 -f 743/733/749 756/757/749 761/762/749 -f 751/753/759 743/733/759 762/735/759 -f 742/745/760 751/753/760 762/735/760 -f 755/734/761 742/745/761 762/735/761 -o Cup_hull_31 -v 0.019899 0.015687 0.015038 -v 0.008313 0.021479 0.034427 -v 0.008313 0.023586 0.034427 -v 0.021215 0.013581 0.034427 -v 0.008577 0.015687 0.015038 -v 0.008313 0.023586 0.017568 -v 0.014633 0.020689 0.034427 -v 0.012262 0.013581 0.017568 -v 0.014896 0.020425 0.015038 -v 0.020425 0.013581 0.015038 -v 0.018319 0.013581 0.034143 -v 0.018319 0.017531 0.034427 -v 0.010421 0.023059 0.018129 -v 0.008313 0.020425 0.015038 -v 0.008313 0.016214 0.017006 -v 0.009894 0.023322 0.034427 -v 0.011737 0.013581 0.015038 -v 0.017793 0.018057 0.015038 -v 0.021215 0.013844 0.018410 -v 0.020689 0.014634 0.034427 -v 0.012526 0.022005 0.018129 -v 0.008313 0.021215 0.033862 -v 0.015685 0.019899 0.034427 -v 0.012526 0.022005 0.034427 -v 0.009104 0.023586 0.018129 -v 0.015686 0.019899 0.015038 -v 0.018583 0.013581 0.034427 -v 0.013844 0.021215 0.018410 -v 0.017529 0.018320 0.034427 -v 0.008841 0.022795 0.016725 -v 0.019899 0.015687 0.034427 -v 0.009104 0.023586 0.034427 -v 0.021215 0.013581 0.018410 -v 0.018319 0.017531 0.015038 -v 0.020425 0.014897 0.015038 -v 0.008313 0.015951 0.015038 -v 0.021215 0.013844 0.034427 -vt 0.826057 1.000000 -vt 0.000000 0.959275 +f 752/732/742 760/733/742 767/734/742 +f 736/735/743 732/736/743 740/737/743 +f 736/735/744 734/738/744 741/739/744 +f 739/740/745 735/741/745 741/739/745 +f 732/736/743 736/735/743 742/742/743 +f 738/743/746 735/741/746 742/742/746 +f 735/741/745 739/740/745 743/744/745 +f 742/742/746 735/741/746 743/744/746 +f 740/737/743 732/736/743 744/745/743 +f 734/738/747 733/746/747 745/747/747 +f 739/740/745 741/739/745 745/747/745 +f 743/744/745 739/740/745 746/748/745 +f 737/749/748 743/744/748 746/748/748 +f 733/746/749 734/738/749 747/750/749 +f 734/738/744 736/735/744 747/750/744 +f 736/735/743 740/737/743 747/750/743 +f 735/741/746 738/743/746 748/751/746 +f 741/739/744 734/738/744 749/752/744 +f 734/738/747 745/747/747 749/752/747 +f 745/747/745 741/739/745 749/752/745 +f 737/749/750 746/748/750 750/753/750 +f 744/745/743 732/736/743 751/754/743 +f 739/740/751 744/745/751 751/754/751 +f 741/739/752 735/741/752 754/755/752 +f 736/735/744 741/739/744 754/755/744 +f 735/741/753 748/751/753 754/755/753 +f 743/744/754 737/749/754 755/756/754 +f 742/742/746 743/744/746 755/756/746 +f 750/753/755 742/742/755 755/756/755 +f 737/749/756 750/753/756 755/756/756 +f 738/743/757 736/735/757 756/757/757 +f 748/751/758 738/743/758 756/757/758 +f 736/735/744 754/755/744 756/757/744 +f 754/755/759 748/751/759 756/757/759 +f 739/740/745 745/747/745 757/758/745 +f 745/747/760 733/746/760 758/759/760 +f 740/737/761 757/758/761 758/759/761 +f 757/758/762 745/747/762 758/759/762 +f 733/746/749 747/750/749 759/760/749 +f 747/750/743 740/737/743 759/760/743 +f 758/759/763 733/746/763 759/760/763 +f 740/737/764 758/759/764 759/760/764 +f 740/737/743 744/745/743 760/733/743 +f 752/732/765 757/758/765 760/733/765 +f 732/736/766 750/753/766 761/761/766 +f 750/753/767 746/748/767 761/761/767 +f 753/762/768 732/736/768 761/761/768 +f 746/748/769 753/762/769 761/761/769 +f 746/748/745 739/740/745 762/763/745 +f 739/740/751 751/754/751 762/763/751 +f 753/762/770 746/748/770 762/763/770 +f 736/735/771 738/743/771 763/764/771 +f 742/742/743 736/735/743 763/764/743 +f 738/743/746 742/742/746 763/764/746 +f 751/754/743 732/736/743 764/765/743 +f 732/736/772 753/762/772 764/765/772 +f 762/763/773 751/754/773 764/765/773 +f 753/762/774 762/763/774 764/765/774 +f 732/736/743 742/742/743 765/766/743 +f 750/753/766 732/736/766 765/766/766 +f 742/742/755 750/753/755 765/766/755 +f 757/758/775 740/737/775 766/767/775 +f 740/737/743 760/733/743 766/767/743 +f 760/733/765 757/758/765 766/767/765 +f 744/745/742 739/740/742 767/734/742 +f 739/740/745 757/758/745 767/734/745 +f 757/758/776 752/732/776 767/734/776 +f 760/733/742 744/745/742 767/734/742 +o cup_hull_31 +v -0.022093 -0.017869 -0.072261 +v -0.032625 -0.019134 0.022524 +v -0.023779 -0.019134 0.022524 +v -0.032625 -0.010707 0.022524 +v -0.032625 -0.019134 -0.072261 +v -0.026727 -0.010707 -0.072261 +v -0.026307 -0.011128 0.022524 +v -0.032625 -0.010707 -0.072261 +v -0.021671 -0.019133 0.022524 +v -0.021671 -0.019133 -0.072261 +v -0.026727 -0.010707 0.022524 +v -0.022093 -0.017869 0.020844 +v -0.026307 -0.011128 -0.072261 +v -0.021671 -0.018712 0.022524 +v -0.021671 -0.018712 -0.072261 vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 1.000000 vt 0.000000 0.000000 +vt 0.000000 0.807636 vt 0.000000 0.000000 -vt 0.000000 1.000000 -vt 0.869518 0.000000 -vt 0.000000 0.489868 -vt 1.000000 0.897993 -vt 1.000000 0.020460 -vt 1.000000 0.510230 -vt 1.000000 0.938815 -vt 0.869518 0.306118 -vt 0.014683 0.775526 -vt 0.000000 0.775526 vt 1.000000 0.000000 -vt 0.898493 0.000000 -vt 0.000000 0.122565 -vt 1.000000 0.265394 -vt 1.000000 0.734802 -vt 0.840544 0.163387 -vt 0.840544 0.326579 -vt 0.029170 0.000000 -vt 0.000000 0.571415 -vt 0.000000 0.326579 -vt 0.840544 0.061282 -vt 1.000000 0.571512 -vt 0.000000 0.795986 -vt 0.826057 0.428683 -vt 0.000000 0.714342 -vt 0.912980 0.040920 -vt 0.000000 0.897993 -vt 0.000000 0.061282 -vt 0.826057 1.000000 -vt 1.000000 0.775526 -vt 1.000000 0.938815 +vt 1.000000 0.961527 +vt 1.000000 0.538424 +vt 0.000000 0.576799 vt 1.000000 0.000000 -vn 0.8325 0.5541 0.0000 +vt 0.000000 1.000000 +vt 0.000000 0.538424 +vt 0.017719 0.961527 +vt 1.000000 0.576799 +vn 1.0000 0.0000 0.0000 vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 vn -1.0000 0.0000 0.0000 vn 0.0000 0.0000 -1.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0001 -1.0000 -0.0000 +vn 0.0004 -1.0000 0.0000 +vn 0.7081 0.7061 0.0000 +vn 0.8479 0.5301 0.0000 +vn 0.8945 0.4471 0.0000 +vn 0.8523 0.5209 0.0476 +vn 0.0001 0.0000 -1.0000 +usemtl None +s off +f 781/768/777 777/769/777 782/770/777 +f 769/771/778 770/772/778 771/773/778 +f 770/772/779 769/771/779 772/774/779 +f 769/771/780 771/773/780 772/774/780 +f 768/775/781 772/774/781 773/776/781 +f 771/773/778 770/772/778 774/777/778 +f 772/774/780 771/773/780 775/778/780 +f 771/773/782 773/776/782 775/778/782 +f 773/776/781 772/774/781 775/778/781 +f 774/777/778 770/772/778 776/779/778 +f 772/774/781 768/775/781 777/769/781 +f 770/772/783 772/774/783 777/769/783 +f 776/779/784 770/772/784 777/769/784 +f 773/776/782 771/773/782 778/780/782 +f 771/773/778 774/777/778 778/780/778 +f 774/777/785 773/776/785 778/780/785 +f 768/775/786 774/777/786 779/781/786 +f 768/775/781 773/776/781 780/782/781 +f 774/777/786 768/775/786 780/782/786 +f 773/776/785 774/777/785 780/782/785 +f 774/777/778 776/779/778 781/768/778 +f 776/779/777 777/769/777 781/768/777 +f 768/775/787 779/781/787 781/768/787 +f 779/781/788 774/777/788 781/768/788 +f 777/769/789 768/775/789 782/770/789 +f 768/775/787 781/768/787 782/770/787 +o cup_hull_32 +v -0.027571 -0.010707 0.022524 +v -0.028835 0.000670 -0.072261 +v -0.026728 -0.009863 -0.072261 +v -0.032626 -0.010707 -0.072261 +v -0.032626 0.000670 0.022524 +v -0.032626 -0.010707 0.022524 +v -0.028835 0.000670 0.022524 +v -0.032626 0.000670 -0.072261 +v -0.026728 -0.009863 0.021688 +v -0.026728 -0.010706 -0.072261 +v -0.026728 -0.010706 0.022524 +vt 0.000000 0.000000 +vt 1.000000 0.000098 +vt 0.000000 0.000098 +vt 1.000000 1.000000 +vt 1.000000 0.074197 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 0.008811 0.074197 +vn 0.0013 -1.0000 0.0000 +vn -0.0000 0.0000 -1.0000 vn 0.0000 -1.0000 0.0000 -vn -0.5631 -0.8140 0.1424 -vn -0.5630 -0.8004 0.2057 -vn -0.5511 -0.8266 0.1144 -vn 0.8154 0.5789 -0.0018 -vn 0.4447 0.8885 -0.1132 -vn -0.5754 -0.7414 0.3454 -vn -0.5946 -0.7708 0.2287 -vn 0.4476 0.8943 0.0000 -vn 0.4476 0.8942 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.9806 0.1962 0.0000 vn 0.0000 1.0000 0.0000 -vn 0.2744 0.8807 -0.3862 -vn 0.3600 0.9000 -0.2456 -vn 0.3714 0.9285 -0.0030 -vn 0.6002 0.7999 0.0000 -vn -0.5307 -0.6901 0.4921 -vn 0.5196 0.8536 -0.0379 -vn 0.5299 0.8481 0.0018 -vn 0.5140 0.8578 0.0000 -vn 0.5792 0.8152 -0.0017 -vn 0.5537 0.8324 -0.0223 -vn 0.7071 0.7071 0.0000 -vn 0.6583 0.7528 -0.0013 -vn 0.6504 0.7596 0.0000 -vn 0.1198 0.7605 -0.6382 -vn -0.2966 0.5968 -0.7456 -vn 0.0000 0.5799 -0.8147 -vn 0.7592 0.6508 0.0000 -vn 0.7999 0.6001 0.0000 -vn 0.0001 0.0000 1.0000 -vn 0.3161 0.9487 0.0000 -vn 0.9737 0.0000 -0.2279 +vn 0.0002 -1.0000 -0.0000 vn 1.0000 0.0000 0.0000 -vn 0.7075 0.7067 0.0000 -vn 0.8320 0.5544 -0.0217 -vn -0.7033 -0.7046 0.0943 +vn 0.9671 0.1791 0.1808 usemtl None s off -f 781/763/762 782/764/762 799/765/762 -f 765/766/763 764/767/763 766/768/763 -f 764/767/764 765/766/764 768/769/764 -f 765/766/763 766/768/763 769/770/763 -f 763/771/765 767/772/765 771/773/765 -f 767/772/765 763/771/765 772/774/765 -f 766/768/766 770/775/766 772/774/766 -f 770/775/766 766/768/766 773/776/766 -f 769/770/763 766/768/763 774/777/763 -f 764/767/764 768/769/764 776/778/764 -f 771/773/765 767/772/765 776/778/765 -f 767/772/767 770/775/767 777/779/767 -f 770/775/768 773/776/768 777/779/768 -f 764/767/764 776/778/764 777/779/764 -f 765/766/763 769/770/763 778/780/763 -f 770/775/769 767/772/769 779/781/769 -f 767/772/765 772/774/765 779/781/765 -f 772/774/766 770/775/766 779/781/766 -f 763/771/765 771/773/765 780/782/765 -f 774/777/763 766/768/763 782/764/763 -f 781/763/770 763/771/770 782/764/770 -f 771/773/771 775/783/771 783/784/771 -f 773/776/772 764/767/772 784/785/772 -f 764/767/764 777/779/764 784/785/764 -f 777/779/773 773/776/773 784/785/773 -f 769/770/763 774/777/763 785/786/763 -f 778/780/763 769/770/763 786/787/763 -f 775/783/774 778/780/774 786/787/774 -f 783/784/775 775/783/775 786/787/775 -f 768/769/776 765/766/776 787/788/776 -f 771/773/777 768/769/777 787/788/777 -f 775/783/778 771/773/778 787/788/778 -f 778/780/779 775/783/779 787/788/779 -f 780/782/765 771/773/765 788/789/765 -f 769/770/780 785/786/780 788/789/780 -f 766/768/763 764/767/763 789/790/763 -f 764/767/781 773/776/781 789/790/781 -f 773/776/766 766/768/766 789/790/766 -f 771/773/782 783/784/782 790/791/782 -f 786/787/783 769/770/783 790/791/783 -f 783/784/784 786/787/784 790/791/784 -f 769/770/785 788/789/785 790/791/785 -f 788/789/786 771/773/786 790/791/786 -f 774/777/787 780/782/787 791/792/787 -f 785/786/763 774/777/763 791/792/763 -f 780/782/788 788/789/788 791/792/788 -f 788/789/789 785/786/789 791/792/789 -f 768/769/790 771/773/790 792/793/790 -f 776/778/791 768/769/791 792/793/791 -f 771/773/792 776/778/792 792/793/792 -f 763/771/793 774/777/793 793/794/793 -f 782/764/794 763/771/794 793/794/794 -f 774/777/795 782/764/795 793/794/795 -f 765/766/763 778/780/763 794/795/763 -f 787/788/776 765/766/776 794/795/776 -f 778/780/796 787/788/796 794/795/796 -f 766/768/766 772/774/766 795/796/766 -f 772/774/797 781/763/797 795/796/797 -f 781/763/798 766/768/798 795/796/798 -f 774/777/793 763/771/793 796/797/793 -f 763/771/765 780/782/765 796/797/765 -f 780/782/799 774/777/799 796/797/799 -f 772/774/765 763/771/765 797/798/765 -f 763/771/800 781/763/800 797/798/800 -f 781/763/797 772/774/797 797/798/797 -f 776/778/765 767/772/765 798/799/765 -f 767/772/801 777/779/801 798/799/801 -f 777/779/764 776/778/764 798/799/764 -f 766/768/798 781/763/798 799/765/798 -f 782/764/763 766/768/763 799/765/763 -o Cup_hull_32 -v 0.004626 -0.019601 -0.043977 -v -0.002221 -0.020391 0.015036 -v 0.001203 -0.020392 -0.005762 -v 0.004626 -0.017495 0.015036 -v -0.002221 -0.017758 -0.048198 -v -0.002221 -0.020391 -0.048198 -v -0.002221 -0.017758 0.014751 -v 0.004626 -0.020392 0.015036 -v 0.004625 -0.017495 -0.048198 -v 0.004625 -0.020392 -0.048198 -v 0.003308 -0.017495 0.013624 -v 0.003308 -0.017495 -0.048198 -v -0.002221 -0.018022 0.015036 -vt 0.000000 1.000000 -vt 0.004503 0.000000 +f 783/783/790 792/784/790 793/785/790 +f 784/786/791 785/787/791 786/788/791 +f 786/788/792 783/783/792 788/789/792 +f 783/783/793 787/790/793 788/789/793 +f 787/790/794 786/788/794 788/789/794 +f 785/787/795 784/786/795 789/791/795 +f 787/790/793 783/783/793 789/791/793 +f 784/786/796 787/790/796 789/791/796 +f 784/786/791 786/788/791 790/792/791 +f 786/788/794 787/790/794 790/792/794 +f 787/790/796 784/786/796 790/792/796 +f 785/787/795 789/791/795 791/793/795 +f 786/788/791 785/787/791 792/784/791 +f 783/783/797 786/788/797 792/784/797 +f 785/787/798 791/793/798 792/784/798 +f 792/784/798 791/793/798 793/785/798 +f 789/791/793 783/783/793 793/785/793 +f 791/793/799 789/791/799 793/785/799 +o cup_hull_33 +v 0.008666 -0.027561 -0.072261 +v -0.002711 -0.032617 0.022524 +v 0.008665 -0.032617 0.022524 +v -0.002711 -0.032617 -0.072261 +v -0.002711 -0.028825 0.022524 +v 0.008666 -0.032617 -0.072261 +v 0.008665 -0.027561 0.022524 +v -0.002711 -0.028825 -0.072261 +v 0.007401 -0.027561 -0.072261 +v 0.007401 -0.027561 0.021688 +vt 1.000000 0.888802 vt 0.000000 0.000000 +vt 0.008811 0.888802 +vt 0.000000 0.999902 vt 0.000000 0.000000 vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 1.000000 +vt 0.000000 0.999902 vt 1.000000 0.000000 -vt 0.328896 0.500000 -vt 0.000000 1.000000 -vt 0.933242 1.000000 -vt 1.000000 0.999902 -vt 1.000000 0.999902 -vt 0.022318 0.807557 -vt 1.000000 0.807557 -vn -0.0564 0.7329 0.6780 +vn -0.1241 0.9923 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.0001 -1.0000 0.0000 -vn -0.0000 -1.0000 0.0000 -vn -0.0000 0.0000 1.0000 vn 1.0000 0.0000 0.0000 -vn 1.0000 0.0003 -0.0000 vn 0.0000 0.0000 -1.0000 -vn 1.0000 -0.0008 -0.0000 -vn 1.0000 0.0000 -0.0002 -vn -0.0399 0.9985 0.0373 -vn -0.0475 0.9989 0.0000 -vn 0.0000 1.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn -0.1090 0.9803 0.1649 usemtl None s off -f 803/800/802 806/801/802 812/802/802 -f 801/803/803 804/804/803 805/805/803 -f 802/806/804 801/803/804 805/805/804 -f 804/804/803 801/803/803 806/801/803 -f 801/803/805 802/806/805 807/807/805 -f 803/800/806 801/803/806 807/807/806 -f 800/808/807 803/800/807 807/807/807 -f 803/800/808 800/808/808 808/809/808 -f 805/805/809 804/804/809 808/809/809 -f 802/806/805 805/805/805 809/810/805 -f 807/807/805 802/806/805 809/810/805 -f 800/808/810 807/807/810 809/810/810 -f 808/809/811 800/808/811 809/810/811 -f 805/805/809 808/809/809 809/810/809 -f 806/801/812 803/800/812 810/811/812 -f 804/804/813 806/801/813 810/811/813 -f 803/800/814 808/809/814 810/811/814 -f 810/811/814 808/809/814 811/812/814 -f 808/809/809 804/804/809 811/812/809 -f 804/804/813 810/811/813 811/812/813 -f 801/803/806 803/800/806 812/802/806 -f 806/801/803 801/803/803 812/802/803 -o Cup_hull_33 -v 0.011736 -0.013546 -0.048198 -v 0.004626 -0.020391 0.015036 -v 0.007524 -0.020392 0.007726 -v 0.012262 -0.013282 0.015036 -v 0.012263 -0.020392 -0.048192 -v 0.004626 -0.017231 -0.048198 -v 0.012262 -0.020392 0.015036 -v 0.004626 -0.020391 -0.048198 -v 0.004626 -0.017231 0.014751 -v 0.011999 -0.013282 -0.048192 -v 0.012263 -0.013282 -0.048192 -v 0.011473 -0.013546 0.008289 -v 0.011999 -0.013282 0.015036 -v 0.011473 -0.013546 -0.043420 -v 0.004890 -0.017231 0.015036 -vt 0.000000 0.965446 -vt 0.004503 0.000000 -vt 0.000000 0.034554 +f 802/794/800 798/795/800 803/796/800 +f 796/797/801 795/798/801 797/799/801 +f 795/798/802 796/797/802 798/795/802 +f 797/799/803 795/798/803 798/795/803 +f 794/800/804 796/797/804 799/801/804 +f 796/797/801 797/799/801 799/801/801 +f 797/799/805 794/800/805 799/801/805 +f 796/797/804 794/800/804 800/802/804 +f 798/795/802 796/797/802 800/802/802 +f 794/800/805 797/799/805 801/803/805 +f 797/799/803 798/795/803 801/803/803 +f 800/802/806 794/800/806 802/794/806 +f 801/803/800 798/795/800 802/794/800 +f 794/800/805 801/803/805 802/794/805 +f 798/795/807 800/802/807 803/796/807 +f 800/802/806 802/794/806 803/796/806 +o cup_hull_34 +v 0.008666 -0.027561 0.022524 +v 0.019199 -0.021662 -0.072261 +v 0.019199 -0.032616 -0.072261 +v 0.019199 -0.021662 0.022524 +v 0.008666 -0.027139 -0.072261 +v 0.019199 -0.032616 0.022524 +v 0.008666 -0.032617 -0.072261 +v 0.008666 -0.032617 0.022524 +v 0.017934 -0.022083 0.021688 +v 0.008666 -0.027139 0.021262 +v 0.017934 -0.022083 -0.072261 +v 0.018778 -0.021662 0.022524 +v 0.018778 -0.021662 -0.072261 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000098 +vt 0.000000 1.000000 +vt 1.000000 0.500000 +vt 0.000000 0.000098 +vt 0.000000 0.461531 +vt 1.000000 0.000000 vt 0.000000 0.000000 -vt 0.115603 0.379405 -vt 0.000000 0.999902 +vt 0.008811 0.961531 +vt 0.013314 0.500000 +vt 1.000000 0.961531 +vn 0.0000 1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn -0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0001 -1.0000 0.0000 +vn -0.4789 0.8779 0.0000 +vn -0.4470 0.8946 0.0000 +vn -0.4800 0.8763 0.0426 +vn -0.4841 0.8299 0.2772 +vn -0.4470 0.8945 0.0000 +usemtl None +s off +f 815/804/808 805/805/808 816/806/808 +f 806/807/809 805/805/809 807/808/809 +f 805/805/810 806/807/810 808/809/810 +f 806/807/809 807/808/809 809/810/809 +f 807/808/811 804/811/811 809/810/811 +f 804/811/812 808/809/812 810/812/812 +f 808/809/810 806/807/810 810/812/810 +f 806/807/813 809/810/813 810/812/813 +f 810/812/813 809/810/813 811/813/813 +f 809/810/811 804/811/811 811/813/811 +f 804/811/812 810/812/812 811/813/812 +f 812/814/814 808/809/814 813/815/814 +f 808/809/812 804/811/812 813/815/812 +f 805/805/810 808/809/810 814/816/810 +f 808/809/814 812/814/814 814/816/814 +f 814/816/815 812/814/815 815/804/815 +f 807/808/808 805/805/808 815/804/808 +f 804/811/811 807/808/811 815/804/811 +f 812/814/816 813/815/816 815/804/816 +f 813/815/817 804/811/817 815/804/817 +f 805/805/810 814/816/810 816/806/810 +f 814/816/818 815/804/818 816/806/818 +o cup_hull_35 +v 0.024678 -0.032194 0.022524 +v 0.032683 -0.011971 -0.072261 +v 0.032683 -0.023767 -0.072261 +v 0.019199 -0.021243 -0.072261 +v 0.032683 -0.011971 0.022524 +v 0.025941 -0.011973 0.022524 +v 0.019199 -0.032615 -0.072261 +v 0.019199 -0.021243 0.022524 +v 0.032683 -0.023767 0.022524 +v 0.025941 -0.011973 -0.072261 +v 0.019199 -0.032615 0.022524 +v 0.023835 -0.032615 -0.072261 +v 0.030154 -0.027138 -0.072261 +v 0.030154 -0.027138 0.022524 +v 0.027204 -0.030087 -0.072261 +v 0.023835 -0.032615 0.022524 +v 0.032260 -0.024610 0.022524 +v 0.027204 -0.030087 0.022524 +v 0.024678 -0.032194 -0.072261 +v 0.032260 -0.024610 -0.072261 +vt 0.000000 0.387763 +vt 1.000000 0.265296 +vt 1.000000 0.387763 +vt 1.000000 1.000000 +vt 1.000000 0.428585 +vt 1.000000 0.550857 +vt 0.000000 1.000000 vt 0.000000 0.999902 -vt 0.999902 1.000000 +vt 0.000000 0.020362 vt 1.000000 0.000000 -vt 1.000000 0.930991 +vt 0.000000 0.550857 +vt 0.000000 0.428585 +vt 1.000000 0.999902 +vt 0.000000 0.000000 vt 1.000000 0.000000 -vt 0.999902 0.965446 -vt 0.999902 1.000000 -vt 0.106695 0.896535 -vt 0.924432 0.896535 -vn -0.4428 0.7971 0.4104 -vn -0.0001 -1.0000 0.0001 -vn 0.0000 0.0000 1.0000 +vt 0.000000 0.265296 +vt 1.000000 0.122467 +vt 0.000000 0.000000 +vt 0.000000 0.122467 +vt 1.000000 0.020362 +vn 0.7683 -0.6401 0.0000 +vn 0.0000 0.0000 -1.0000 vn 1.0000 0.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -vn -0.0002 -1.0000 0.0000 -vn 0.0008 -0.0008 -1.0000 -vn -0.0001 -1.0000 -0.0000 +vn -0.0003 1.0000 0.0000 +vn -0.0000 0.0000 1.0000 vn -1.0000 0.0000 0.0000 -vn -0.0000 0.0000 -1.0000 -vn -0.0252 0.0485 -0.9985 -vn 0.0000 1.0000 -0.0000 -vn 0.0118 0.0000 -0.9999 -vn 0.0000 0.0235 -0.9997 -vn -0.4740 0.8805 0.0000 -vn -0.4481 0.8940 0.0000 -vn -0.4722 0.8815 0.0024 -vn -0.4722 0.8815 -0.0034 -vn -0.7321 0.0611 0.6785 +vn -0.8087 0.5882 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.7070 -0.7073 0.0000 +vn 0.4461 -0.8950 0.0000 +vn 0.8940 -0.4480 0.0000 +vn 0.6407 -0.7678 0.0000 usemtl None s off -f 825/813/815 821/814/815 827/815/815 -f 814/816/816 815/817/816 819/818/816 -f 816/819/817 814/816/817 819/818/817 -f 817/820/818 816/819/818 819/818/818 -f 815/817/819 817/820/819 819/818/819 -f 815/817/820 814/816/820 820/821/820 -f 813/822/821 817/820/821 820/821/821 -f 817/820/822 815/817/822 820/821/822 -f 814/816/823 818/823/823 820/821/823 -f 818/823/824 813/822/824 820/821/824 -f 818/823/823 814/816/823 821/814/823 -f 813/822/825 818/823/825 822/824/825 -f 822/824/826 816/819/826 823/825/826 -f 817/820/827 813/822/827 823/825/827 -f 816/819/818 817/820/818 823/825/818 -f 813/822/828 822/824/828 823/825/828 -f 818/823/829 821/814/829 824/826/829 -f 822/824/830 824/826/830 825/813/830 -f 814/816/817 816/819/817 825/813/817 -f 816/819/826 822/824/826 825/813/826 -f 824/826/831 821/814/831 825/813/831 -f 822/824/832 818/823/832 826/827/832 -f 818/823/829 824/826/829 826/827/829 -f 824/826/830 822/824/830 826/827/830 -f 821/814/833 814/816/833 827/815/833 -f 814/816/817 825/813/817 827/815/817 +f 833/817/819 829/818/819 836/819/819 +f 818/820/820 819/821/820 820/822/820 +f 819/821/821 818/820/821 821/823/821 +f 821/823/822 818/820/822 822/824/822 +f 817/825/823 821/823/823 822/824/823 +f 820/822/820 819/821/820 823/826/820 +f 820/822/824 823/826/824 824/827/824 +f 822/824/825 820/822/825 824/827/825 +f 817/825/823 822/824/823 824/827/823 +f 821/823/823 817/825/823 825/828/823 +f 819/821/821 821/823/821 825/828/821 +f 818/820/820 820/822/820 826/829/820 +f 822/824/822 818/820/822 826/829/822 +f 820/822/825 822/824/825 826/829/825 +f 824/827/824 823/826/824 827/830/824 +f 817/825/823 824/827/823 827/830/823 +f 823/826/820 819/821/820 828/831/820 +f 827/830/826 823/826/826 828/831/826 +f 828/831/820 819/821/820 829/818/820 +f 825/828/823 817/825/823 830/832/823 +f 829/818/827 830/832/827 831/833/827 +f 828/831/820 829/818/820 831/833/820 +f 817/825/823 827/830/823 832/834/823 +f 828/831/828 817/825/828 832/834/828 +f 827/830/826 828/831/826 832/834/826 +f 819/821/829 825/828/829 833/817/829 +f 825/828/823 830/832/823 833/817/823 +f 830/832/819 829/818/819 833/817/819 +f 830/832/823 817/825/823 834/835/823 +f 831/833/827 830/832/827 834/835/827 +f 817/825/830 831/833/830 834/835/830 +f 817/825/828 828/831/828 835/836/828 +f 831/833/830 817/825/830 835/836/830 +f 828/831/820 831/833/820 835/836/820 +f 829/818/820 819/821/820 836/819/820 +f 819/821/829 833/817/829 836/819/829 diff --git a/cram_demos/cram_projection_demos/resource/household/ikea_big_plate.stl b/cram_demos/cram_projection_demos/resource/household/ikea_big_plate.stl new file mode 100644 index 0000000000..28262849bd Binary files /dev/null and b/cram_demos/cram_projection_demos/resource/household/ikea_big_plate.stl differ diff --git a/cram_demos/cram_projection_demos/resource/household/ikea_small_plate.stl b/cram_demos/cram_projection_demos/resource/household/ikea_small_plate.stl new file mode 100644 index 0000000000..f8f45a1352 Binary files /dev/null and b/cram_demos/cram_projection_demos/resource/household/ikea_small_plate.stl differ diff --git a/cram_demos/cram_projection_demos/resource/retail/full_store.urdf.xacro b/cram_demos/cram_projection_demos/resource/retail/full_store.urdf.xacro new file mode 100644 index 0000000000..c3f331cd8b --- /dev/null +++ b/cram_demos/cram_projection_demos/resource/retail/full_store.urdf.xacro @@ -0,0 +1,2275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/resource/retail/full_store_empty.urdf b/cram_demos/cram_projection_demos/resource/retail/full_store_empty.urdf new file mode 100644 index 0000000000..56451b7412 --- /dev/null +++ b/cram_demos/cram_projection_demos/resource/retail/full_store_empty.urdf @@ -0,0 +1,2264 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cram_demos/cram_projection_demos/resource/retail/full_store_empty_random.urdf b/cram_demos/cram_projection_demos/resource/retail/full_store_empty_random.urdf new file mode 100644 index 0000000000..aeb5610516 --- /dev/null +++ b/cram_demos/cram_projection_demos/resource/retail/full_store_empty_random.urdf @@ -0,0 +1,11864 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cram_demos/cram_projection_demos/resource/retail/shelf.urdf b/cram_demos/cram_projection_demos/resource/retail/shelf.urdf deleted file mode 100644 index 742ea91195..0000000000 --- a/cram_demos/cram_projection_demos/resource/retail/shelf.urdf +++ /dev/null @@ -1,348 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/cram_demos/cram_projection_demos/resource/retail/storage.urdf.xacro b/cram_demos/cram_projection_demos/resource/retail/storage.urdf.xacro new file mode 100644 index 0000000000..90b6a04d07 --- /dev/null +++ b/cram_demos/cram_projection_demos/resource/retail/storage.urdf.xacro @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/resource/retail/store_walls.urdf.xacro b/cram_demos/cram_projection_demos/resource/retail/store_walls.urdf.xacro new file mode 100644 index 0000000000..ed263e2dce --- /dev/null +++ b/cram_demos/cram_projection_demos/resource/retail/store_walls.urdf.xacro @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/resource/robots/iai_donbot.urdf.xacro b/cram_demos/cram_projection_demos/resource/robots/iai_donbot.urdf.xacro new file mode 100644 index 0000000000..6feabb5549 --- /dev/null +++ b/cram_demos/cram_projection_demos/resource/robots/iai_donbot.urdf.xacro @@ -0,0 +1,5 @@ + + + + + diff --git a/cram_demos/cram_projection_demos/resource/robots/iai_donbot.xacro b/cram_demos/cram_projection_demos/resource/robots/iai_donbot.xacro new file mode 100644 index 0000000000..0ccb84f796 --- /dev/null +++ b/cram_demos/cram_projection_demos/resource/robots/iai_donbot.xacro @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cram_demos/cram_projection_demos/src/assembly-demo.lisp b/cram_demos/cram_projection_demos/src/assembly-demo.lisp index c90b1d69a3..d7fa5e6f82 100644 --- a/cram_demos/cram_projection_demos/src/assembly-demo.lisp +++ b/cram_demos/cram_projection_demos/src/assembly-demo.lisp @@ -32,6 +32,7 @@ (defparameter *plate-x* -1.1115) (defparameter *plate-y* 1.6) (defparameter *plate-z* 0.8626) +(defparameter *original-plate-z* 0.8626) (defparameter *plate-rad-x* 0.36) (defparameter *plate-rad-y* 0.60) @@ -103,8 +104,8 @@ (:holder-plane-horizontal :holder-plane-horizontal ,*yellow-plastic* - ((,(+ 0.05 *holder-plane-horizontal-rad-x*) 0.6 ,*holder-plane-horizontal-rad-z*) - (0 0 0 1))) + ((,(+ 0.02 *holder-plane-horizontal-rad-x*) 0.6 ,*holder-plane-horizontal-rad-z*) + (0 0 0.7071d0 0.7071d0))) (:holder-window :holder-window ,*gray-plastic* @@ -116,7 +117,7 @@ ((,*holder-plane-vertical-rad-x* ,(- 1.0 *holder-plane-vertical-rad-y*) ,*holder-plane-vertical-rad-z*) - (0 0 0 1))) + (0 0 1 0))) (:holder-top-wing :holder-top-wing ,*yellow-plastic* @@ -129,8 +130,7 @@ (:rear-wing :rear-wing ,*yellow-plane* - ((0.079 0.599 0.056) - ,man-int:*rotation-around-z+90-list*)) + ((0.121 0.528 0.055) ,man-int:*rotation-around-z+180-list*)) ;; bolts are used intermediately (:bolt-1 @@ -158,7 +158,7 @@ (:chassis :chassis ,*yellow-plane* - ((0.2 0.9 ,*chassis-rad-z*) ,man-int:*rotation-around-z-90-list*)) + ((0.2 0.95 ,*chassis-rad-z*) ,man-int:*rotation-around-z-90-list*)) (:bottom-wing :bottom-wing ,*cyan-plane* @@ -188,33 +188,27 @@ (:propeller :propeller ,*yellow-plane* - ((0.075 1.10 0) (0 0 0 1))) + ((0.075 1.13 0) ,man-int:*rotation-around-z-90-list*)) (:front-wheel-1 :front-wheel ,*black-plane* - ((0.15 0.775 ,*front-wheel-rad-z*) (0 0 0 1))) + ((0.15 0.825 ,*front-wheel-rad-z*) (0 0 0 1))) (:front-wheel-2 :front-wheel ,*black-plane* - ((0.215 0.775 ,*front-wheel-rad-z*) (0 0 0 1))) + ((0.215 0.825 ,*front-wheel-rad-z*) (0 0 0 1))) (:nut-1 :nut ,*gray-plane* - ((0.15 0.725 ,*nut-rad-z*) (0 0 0 1))) + ((0.15 0.775 ,*nut-rad-z*) (0 0 0 1))) (:nut-2 :nut ,*gray-plane* - ((0.215 0.725 ,*nut-rad-z*) (0 0 0 1))))) + ((0.215 0.775 ,*nut-rad-z*) (0 0 0 1))))) (defun spawn-assembly-objects (&optional (spawning-data *object-spawning-data*)) - (btr-utils:kill-all-objects) - (btr:detach-all-objects (btr:get-robot-object)) - (btr:detach-all-objects (btr:get-environment-object)) - ;; detach all items from each other - (mapcar #'btr:detach-all-objects - (remove-if-not (lambda (obj) (typep obj 'btr:item)) - (btr:objects btr:*current-bullet-world*))) + (kill-and-detach-all) ;; spawn objects at default poses (let ((objects (mapcar (lambda (object-name-type-pose-list) @@ -224,6 +218,7 @@ (let ((object-relative-pose (cram-tf:list->pose object-pose-list))) (unless (btr:object btr:*current-bullet-world* object-name) + (roslisp:ros-info (assembly) "Spawning ~a" object-name) (btr:add-object btr:*current-bullet-world* :mesh @@ -247,10 +242,53 @@ object-relative-pose)))))) spawning-data))) - (btr:attach-object :motor-grill :underbody) + (btr:attach-object :underbody :motor-grill) objects)) + +(defun transport (?object-type ?object-location-property + ?other-object-type ?other-object-location-property + ?attachment-type + ?wooden-plate) + (let* ((?env-name + (rob-int:get-environment-name)) + (?object-location + (if (eq ?object-location-property :bolt) + (desig:a location + (on (desig:an object + (type counter-top) + (urdf-name kitchen-island-surface) + (part-of ?env-name))) + (range-invert 0.9) + (side right) + (side front)) + (desig:a location + (on ?wooden-plate) + (side front) + ?object-location-property))) + (?other-object-location + (desig:a location + (on ?wooden-plate) + (side front) + ?other-object-location-property)) + (?object + (desig:an object + (type ?object-type) + (location ?object-location))) + (?other-object + (desig:an object + (type ?other-object-type) + (location ?other-object-location)))) + (exe:perform + (desig:an action + (type transporting) + (object ?object) + (target (desig:a location + (on ?other-object) + (for ?object) + (attachments (?attachment-type)))))))) + ;;; ASSEMBLY STEPS: ;;; (1) put chassis on holder (bump inwards) ;;; (2) put bottom wing on chassis @@ -271,11 +309,22 @@ ;;; * screw nut onto wheel ;;; * screw bottom body (defun assembly-demo () + (when (eq (rob-int:get-robot-name) :tiago-dual) + (let ((kitchen-island-offset -0.2)) + (setf *plate-z* (+ *plate-z* kitchen-island-offset)) + (btr-belief:vary-kitchen-urdf `(("kitchen_island_footprint_joint" + ((-1.365d0 0.59d0 ,kitchen-island-offset) (0 0 0 1))))) + (setf btr:*current-bullet-world* (make-instance 'btr:bt-reasoning-world)) + (btr-belief:spawn-world))) + (urdf-proj:with-projected-robot ;;(setf cram-robosherlock::*no-robosherlock-mode* t) (spawn-assembly-objects) (let ((old-visibility btr:*visibility-threshold*)) - (setf btr:*visibility-threshold* 0.4) + (setf btr:*visibility-threshold* + (case (rob-int:get-robot-name) + (:iai-donbot 0.1) ; perceiving with an object in hand is hard + (t 0.4))) (unwind-protect (let* ((?env-name (rob-int:get-environment-name)) @@ -292,114 +341,69 @@ (side front) (range 0.3)))))) ;; 1 - (go-transport :chassis '(:side :left) :holder-plane-horizontal '(:range 0.3) - :horizontal-attachment - wooden-plate) + (transport :chassis '(:side :left) :holder-plane-horizontal '(:range 0.3) + :horizontal-attachment + wooden-plate) ;; 2 - (go-transport :bottom-wing '(:side :right) :chassis '(:range 0.3) - :wing-attachment - wooden-plate) + (transport :bottom-wing '(:side :right) :chassis '(:range 0.3) + :wing-attachment + wooden-plate) ;; 3 - (go-transport :underbody '(:side :right) :bottom-wing '(:range 0.3) - :body-attachment - wooden-plate) + (transport :underbody '(:side :right) :bottom-wing '(:range 0.3) + :body-attachment + wooden-plate) ;; we put the underbody on the bottom-wing but by doing that ;; we also put it on the rear-wing. - ;; as there is no explicit placing action, the two will not be - ;; attached automatically. + ;; as there is no explicit placing action, + ;; the attachment that we get is loose, ;; so we have to attach them manually unfortunately. ;; this is required for later moving the whole plane onto another holder - (btr:attach-object 'underbody 'rear-wing) + (btr:attach-object :underbody :rear-wing) ;; 4 - (go-transport :upper-body '(:side :right) :underbody '(:range 0.3) - :body-on-body - wooden-plate) + (transport :upper-body '(:side :right) :underbody '(:range 0.3) + :body-on-body + wooden-plate) ;; 5 - (go-transport :bolt '(:side :right) :upper-body '(:range 0.3) - :rear-thread - wooden-plate) + (transport :bolt '(:side :right) :upper-body '(:range 0.3) + :rear-thread + wooden-plate) ;; 6 - (go-transport :top-wing '(:side :left) :upper-body '(:range 0.3) - :wing-attachment - wooden-plate) + (transport :top-wing '(:side :left) :upper-body '(:range 0.3) + :wing-attachment + wooden-plate) ;; 7 - (go-transport :bolt :bolt :top-wing '(:range 0.3) - :middle-thread - wooden-plate) + (transport :bolt :bolt :top-wing '(:range 0.3) + :middle-thread + wooden-plate) ;; 8 - (go-transport :window '(:side :left) :top-wing '(:range 0.3) - :window-attachment - wooden-plate) + (transport :window '(:side :left) :top-wing '(:range 0.3) + :window-attachment + wooden-plate) ;; 9 - (go-transport :bolt :bolt :window '(:range 0.3) - :window-thread - wooden-plate) + (transport :bolt :bolt :window '(:range 0.3) + :window-thread + wooden-plate) ;; 10 - (go-transport :top-wing '(:range 0.3) :holder-plane-vertical '(:side :left) - ;; or `((,(- *base-x* 0.00) 1.45 0) (0 0 0 1)) - :vertical-attachment - wooden-plate) + (transport :top-wing '(:range 0.3) :holder-plane-vertical '(:side :left) + :vertical-attachment + wooden-plate) ;; 11 - (go-transport :propeller '(:side :left) :motor-grill '(:side :left) - ;; or `((,(- *base-x* 0.15) 1.8 0) (0 0 0 1)) - :propeller-attachment - wooden-plate) + (transport :propeller '(:side :left) :motor-grill '(:side :left) + :propeller-attachment + wooden-plate) ;; 12 - (go-transport :bolt :bolt :propeller '(:side :left) - ;; or `((,*base-x* 1.85 0) (0 0 0 1)) - :propeller-thread - wooden-plate)) + (transport :bolt :bolt :propeller '(:side :left) + :propeller-thread + wooden-plate)) + (setf *plate-z* *original-plate-z*) (setf btr:*visibility-threshold* old-visibility))))) -(defun go-transport (?object-type ?object-location-property - ?other-object-type ?other-object-location-property - ?attachment-type - ?wooden-plate) - (let* ((?env-name - (rob-int:get-environment-name)) - (?object-location - (if (eq ?object-location-property :bolt) - (desig:a location - (on (desig:an object - (type counter-top) - (urdf-name kitchen-island-surface) - (part-of ?env-name))) - (range-invert 0.9) - (side right) - (side front)) - (desig:a location - (on ?wooden-plate) - ?object-location-property - (side front)))) - (?other-object-location - (desig:a location - (on ?wooden-plate) - ?other-object-location-property - (side front))) - (?object - (desig:an object - (type ?object-type) - (location ?object-location))) - (?other-object - (desig:an object - (type ?other-object-type) - (location ?other-object-location)))) - (exe:perform - (desig:an action - (type transporting) - (object ?object) - (target (desig:a location - (on ?other-object) - (for ?object) - (attachments (?attachment-type)))))))) - - #+boxy-action-examples ( (urdf-proj:with-projected-robot diff --git a/cram_demos/cram_projection_demos/src/costmaps.lisp b/cram_demos/cram_projection_demos/src/costmaps.lisp index 886cfd406e..b3c084a3da 100644 --- a/cram_demos/cram_projection_demos/src/costmaps.lisp +++ b/cram_demos/cram_projection_demos/src/costmaps.lisp @@ -31,27 +31,15 @@ (defun make-dm-room-restricted-area-cost-function () (lambda (x y) - (if (> x 4.0) - 0.0 - (if (< x 0.0) - 0.0 - (if (> y 1.0) - 0.0 - (if (< y -1.0) - 0.0 - 1.0)))))) + (if (and (< 0.0 x 4.0) (< -1.0 y 1.0)) + 1.0 + 0.0))) (defun make-small-retail-restricted-area-cost-function () (lambda (x y) - (if (> x 2.0) - 0.0 - (if (< x -5.0) - 0.0 - (if (> y 1.0) - 0.0 - (if (< y -1.0) - 0.0 - 1.0)))))) + (if (and (< -5.0 x 2.0) (< -1.0 y 1.0)) + 1.0 + 0.0))) (defun make-iai-kitchen-assembly-restricted-area-cost-function () (lambda (x y) @@ -64,26 +52,51 @@ (lambda (x y) (if (> x 1.2) 0.0 - (if (and (> x 0.5) (> y -1.5) (< y 2.0)) + (if (and (> x 0.5) (< -1.5 y 2.0)) 1.0 - (if (and (> x 0.0) (> y -1.5) (< y 1.0)) + (if (and (> x 0.0) (< -1.5 y 1.0)) 1.0 - (if (and (> x -1.5) (> y -1.5) (< y 2.5)) + (if (and (> x -1.5) (< -1.5 y 2.5)) 1.0 - (if (and (> x -4.0) (> y -1.0) (< y 1.0)) + (if (and (> x -4.0) (< -1.0 y 1.0)) 1.0 0.0))))))) +(defun make-iai-kitchen-offset-household-restricted-area-cost-function () + (lambda (x y) + (if (< x 1.6) + (if (and (> x -1.0) (< -1.0 y 2.9)) + 1.0 + (if (and (> x -3.0) (< -0.5 y 2.9)) + 1.0 + 0.0)) + 0.0))) + +(defun make-storage-restricted-area-cost-function () + (lambda (x y) + (if (and (< -2.6 x 2.6) (< -1.6 y 1.6)) + 1.0 + 0.0))) + (defun make-restricted-area-cost-function () (ecase (rob-int:get-environment-name) (:iai-kitchen (if (btr:object btr:*current-bullet-world* :big-wooden-plate) (make-iai-kitchen-assembly-restricted-area-cost-function) - (make-iai-kitchen-household-restricted-area-cost-function))) - (:dm-room + (if (> (cl-transforms:x + (cl-transforms:origin + (btr:pose + (btr:rigid-body (btr:get-environment-object) + :|IAI-KITCHEN.fridge_area|)))) + 0) + (make-iai-kitchen-household-restricted-area-cost-function) + (make-iai-kitchen-offset-household-restricted-area-cost-function)))) + ((or :dm-room :store) (make-dm-room-restricted-area-cost-function)) (:dm-shelves - (make-small-retail-restricted-area-cost-function)))) + (make-small-retail-restricted-area-cost-function)) + (:storage + (make-storage-restricted-area-cost-function)))) (defmethod costmap:costmap-generator-name->score ((name (eql 'restricted-area))) 5) diff --git a/cram_demos/cram_projection_demos/src/household-demo.lisp b/cram_demos/cram_projection_demos/src/household-demo.lisp index 8b2b6c6129..dfc2eb6990 100644 --- a/cram_demos/cram_projection_demos/src/household-demo.lisp +++ b/cram_demos/cram_projection_demos/src/household-demo.lisp @@ -29,30 +29,15 @@ (in-package :demos) -(defparameter *object-spawning-poses* - '("sink_area_surface" - (:breakfast-cereal . ((0.2 -0.15 0.1) (0 0 0 1))) - (:cup . ((0.2 -0.35 0.1) (0 0 0 1))) - (:bowl . ((0.18 -0.55 0.1) (0 0 0 1))) - (:spoon . ((0.15 -0.4 -0.05) (0 0 0 1))) - (:milk . ((0.07 -0.35 0.1) (0 0 0 1)))) - "Relative poses on sink area") - -(defparameter *object-placing-poses* - '((:breakfast-cereal . ((-0.78 0.9 0.95) (0 0 1 0))) - (:cup . ((-0.79 1.35 0.9) (0 0 0.7071 0.7071))) - (:bowl . ((-0.76 1.19 0.88) (0 0 0.7071 0.7071))) - (:spoon . ((-0.78 1.5 0.86) (0 0 0 1))) - (:milk . ((-0.75 1.7 0.95) (0 0 0.7071 0.7071)))) - "Absolute poses on kitchen_island.") - (defparameter *demo-object-spawning-poses* '((:bowl "sink_area_left_middle_drawer_main" - ((0.10 -0.1505 -0.062256) (0 0 -1 0))) + ((0.10 -0.0505 -0.062256) (0 0 -1 0))) (:cup - "sink_area_left_bottom_drawer_main" - ((0.11 0.12 -0.0547167) (0 0 -1 0))) + ;; "sink_area_left_bottom_drawer_main" + ;; ((0.11 0.12 -0.0547167) (0 0 -1 0)) + "kitchen_island_left_upper_drawer_main" + ((0.11 0.08 -0.026367) (0 0 -1 0))) (:spoon ;; "oven_area_area_middle_upper_drawer_main" "sink_area_left_upper_drawer_main" @@ -60,7 +45,7 @@ ;; So far only this orientation works (:breakfast-cereal "oven_area_area_right_drawer_board_3_link" - ((0.123 -0.03 0.11) (0.0087786 0.005395 -0.838767 -0.544393))) + ((0.10 -0.03 0.11) (0.0087786 0.005395 -0.838767 -0.544393))) ;; ((:breakfast-cereal . ((1.398 1.490 1.2558) (0 0 0.7071 0.7071))) ;; (:breakfast-cereal . ((1.1 1.49 1.25) (0 0 0.7071 0.7071))) (:milk @@ -69,6 +54,233 @@ "iai_fridge_door_shelf1_bottom" ((-0.01 -0.05 0.094) (0 0 0 1))))) +(defparameter *object-grasps* + '((:cup . (:left-side :right-side :back :front)) + ;; PR2 cannot grasp the cereal from the top on the oven shelf + ;; (Boxy can though.) + (:breakfast-cereal . (:front :back :front-flipped :back-flipped)))) + +(defparameter *furniture-offsets-original-kitchen* + '(("sink_area_footprint_joint" + ((1.855d0 1.3d0 0.0d0) (0 0 1 0))) + ("oven_area_footprint_joint" + ((1.845d0 2.5d0 0.0d0) (0 0 1 0))) + ("kitchen_island_footprint_joint" + ((-1.363d0 0.59d0 0.0d0) (0 0 0 1))) + ("fridge_area_footprint_joint" + ((1.845d0 -0.73d0 0.0d0) (0 0 1 0))) + ("table_area_main_joint" + ((-2.4d0 -1.5d0 0.0d0) (0 0 1 0))) + ("dining_area_footprint_joint" + ((-3.38d0 0.28d0 0.0d0) (0.0d0 0.0d0 0.7071067811848163d0 0.7071067811882787d0))))) + +(defparameter *furniture-offsets-offset-kitchen* + '(("sink_area_footprint_joint" + ((1.855d0 2.9d0 0.0d0) (0 0 1 0))) + ("oven_area_footprint_joint" + ((1.65d0 0.35d0 0.0d0) (0 0 0.7 0.3))) + ("kitchen_island_footprint_joint" + ((-3.6d0 0.7d0 0.0d0) (0 0 0 1))) + ("fridge_area_footprint_joint" + ((-1.4d0 3.05d0 0.0d0) (0 0 -0.7 0.7))) + ("table_area_main_joint" + ((0.95d0 -0.95d0 0.0d0) (0 0 0.3 0.7))) + ("dining_area_footprint_joint" + ((-2.5d0 -0.55d0 0.0d0) (0 0 1 0))))) + + +(defun spawn-objects-on-fixed-spots (&key + (spawning-poses-relative + *demo-object-spawning-poses*) + (object-types + '(:breakfast-cereal :cup :bowl :spoon :milk))) + ;; clean up + (kill-and-detach-all) + + ;; spawn objects at default poses + (let* ((spawning-poses-absolute + (make-poses-list-relative spawning-poses-relative)) + (objects (mapcar (lambda (object-type) + (btr-utils:spawn-object + (intern (format nil "~a-1" object-type) :keyword) + object-type + :pose (cdr (assoc object-type + spawning-poses-absolute)))) + object-types))) + ;; stabilize world + ;; (btr:simulate btr:*current-bullet-world* 100) + objects) + + ;; attach objects to world + (mapcar (lambda (object-type) + (btr:attach-object (btr:get-environment-object) + (btr:object btr:*current-bullet-world* + (intern (format nil "~a-1" object-type) :keyword)) + :link (second (find object-type + spawning-poses-relative + :key #'car)))) + object-types)) + + +(defun park-robot () + (cpl:with-failure-handling + ((cpl:plan-failure (e) + (declare (ignore e)) + (return))) + (cpl:par + (exe:perform + (desig:an action + (type positioning-arm) + (left-configuration park) + (right-configuration park))) + (exe:perform + (desig:an action + (type moving-torso) + (joint-angle upper-limit))) + (let ((?pose (cl-transforms-stamped:make-pose-stamped + cram-tf:*fixed-frame* + 0.0 + (cl-transforms:make-identity-vector) + (cl-transforms:make-identity-rotation)))) + (exe:perform + (desig:an action + (type going) + (target (desig:a location + (pose ?pose)))))) + (exe:perform (desig:an action (type opening-gripper) (gripper (left right)))) + (exe:perform (desig:an action (type looking) (direction forward)))))) + +(defun initialize () + (sb-ext:gc :full t) + + ;;(when ccl::*is-logging-enabled* + ;; (setf ccl::*is-client-connected* nil) + ;; (ccl::connect-to-cloud-logger) + ;; (ccl::reset-logged-owl)) + + ;; (setf proj-reasoning::*projection-checks-enabled* t) + + (kill-and-detach-all) + (setf (btr:joint-state (btr:get-environment-object) + "sink_area_left_upper_drawer_main_joint") + 0.0 + (btr:joint-state (btr:get-environment-object) + "sink_area_left_middle_drawer_main_joint") + 0.0 + (btr:joint-state (btr:get-environment-object) + "sink_area_left_bottom_drawer_main_joint") + 0.0 + (btr:joint-state (btr:get-environment-object) + "iai_fridge_door_joint") + 0.0 + (btr:joint-state (btr:get-environment-object) + "sink_area_dish_washer_door_joint") + 0.0 + (btr:joint-state (btr:get-environment-object) + "sink_area_dish_washer_tray_main") + 0.0 + (btr:joint-state (btr:get-environment-object) + "oven_area_area_right_drawer_main_joint") + 0.0 + (btr:joint-state (btr:get-environment-object) + "sink_area_trash_drawer_main_joint") + 0.0 + (btr:joint-state (btr:get-environment-object) + "kitchen_island_left_upper_drawer_main_joint") + 0.0) + (btr-belief::publish-environment-joint-state + (btr:joint-states (btr:get-environment-object))) + + (setf desig::*designators* (tg:make-weak-hash-table :weakness :key)) + + ;; (coe:clear-belief) + + (btr:clear-costmap-vis-object)) + +(defun finalize () + ;; (setf proj-reasoning::*projection-reasoning-enabled* nil) + + ;;(when ccl::*is-logging-enabled* + ;; (ccl::export-log-to-owl "ease_milestone_2018.owl") + ;; (ccl::export-belief-state-to-owl "ease_milestone_2018_belief.owl")) + (sb-ext:gc :full t)) + + +(defun household-demo (&key (object-list '(:bowl :breakfast-cereal :milk :cup :spoon)) + varied-kitchen) + (urdf-proj:with-simulated-robot + + (if varied-kitchen + (btr-belief:vary-kitchen-urdf *furniture-offsets-offset-kitchen*) + (btr-belief:vary-kitchen-urdf *furniture-offsets-original-kitchen*)) + (if (> (cl-transforms:x + (cl-transforms:origin + (btr:pose + (btr:rigid-body (btr:get-environment-object) + :|IAI-KITCHEN.fridge_area|)))) + 0) + ;; if the fridge is in front of robot, current kitchen is original + (when varied-kitchen + (setf btr:*current-bullet-world* (make-instance 'btr:bt-reasoning-world)) + (btr-belief:spawn-world)) + ;; if the fridge is behind the robot, current kitchen is varied + (unless varied-kitchen + (setf btr:*current-bullet-world* (make-instance 'btr:bt-reasoning-world)) + (btr-belief:spawn-world))) + (initialize) + (setf btr:*visibility-threshold* 0.7) + (when cram-projection:*projection-environment* + (spawn-objects-on-fixed-spots + :object-types object-list + :spawning-poses-relative *demo-object-spawning-poses*)) + (park-robot) + + ;; set the table + (dolist (?object-type object-list) + (exe:perform + (desig:an action + (type transporting) + (object (desig:an object (type ?object-type))) + (context table-setting)))) + + ;; clean up + ;; (when cram-projection:*projection-environment* + ;; (spawn-objects-on-fixed-spots + ;; :object-types object-list + ;; :spawning-poses-relative *delivery-poses-relative*)) + + (dolist (?object-type (reverse object-list)) + (let ((?grasps (cdr (assoc ?object-type *object-grasps*)))) + (exe:perform + (desig:an action + (type transporting) + (object (desig:an object (type ?object-type))) + (context table-cleaning) + (grasps ?grasps))))))) + + + + + +;;;;;; THE STUFF BELOW IS FOR HOUSEHOLD-DEMO-RANDOM + +(defparameter *object-spawning-poses* + '("sink_area_surface" + (:breakfast-cereal . ((0.2 -0.15 0.1) (0 0 0 1))) + (:cup . ((0.2 -0.35 0.1) (0 0 0 1))) + (:bowl . ((0.18 -0.55 0.1) (0 0 0 1))) + (:spoon . ((0.15 -0.4 -0.05) (0 0 0 1))) + (:milk . ((0.07 -0.35 0.1) (0 0 0 1)))) + "Relative poses on sink area") + +(defparameter *object-placing-poses* + '((:breakfast-cereal . ((-0.78 0.9 0.95) (0 0 1 0))) + (:cup . ((-0.79 1.35 0.9) (0 0 0.7071 0.7071))) + (:bowl . ((-0.76 1.19 0.88) (0 0 0.7071 0.7071))) + (:spoon . ((-0.78 1.5 0.86) (0 0 0 1))) + (:milk . ((-0.75 1.7 0.95) (0 0 0.7071 0.7071)))) + "Absolute poses on kitchen_island.") + (defparameter *delivery-poses-relative* `((:bowl "kitchen_island_surface" @@ -101,26 +313,6 @@ (0.0 0.0 -0.9 0.7))) (:breakfast-cereal . ((-0.78 0.8 0.95) (0 0 0.6 0.4))))) -(defparameter *cleaning-deliver-poses* - `((:bowl . ((1.45 -0.4 1.0) (0 0 0 1))) - (:cup . ((1.45 -0.4 1.0) (0 0 0 1))) - (:spoon . ((1.45 -0.4 1.0) (0 0 0 1))) - (:milk . ((1.2 -0.5 0.8) (0 0 1 0))) - (:breakfast-cereal . ((1.15 -0.5 0.8) (0 0 1 0))))) - -(defparameter *object-grasping-arms* - '(;; (:breakfast-cereal . :right) - ;; (:cup . :left) - ;; (:bowl . :right) - ;; (:spoon . :right) - ;; (:milk . :right) - )) - -(defparameter *object-cad-models* - '(;; (:cup . "cup_eco_orange") - ;; (:bowl . "edeka_red_bowl") - )) - (defparameter *object-colors* '((:spoon . "black") (:breakfast-cereal . "yellow") @@ -128,15 +320,24 @@ (:bowl . "red") (:cup . "red"))) -(defparameter *object-grasps* - '((:spoon . :top) - (:breakfast-cereal . :front) - (:milk . :front) - (:cup . :top) - (:bowl . :top))) - +(defparameter *object-cad-models* + '(;; (:cup . "cup_eco_orange") + ;; (:bowl . "edeka_red_bowl") + )) +;; (defparameter *cleaning-deliver-poses* +;; `((:bowl . ((1.45 -0.4 1.0) (0 0 0 1))) +;; (:cup . ((1.45 -0.4 1.0) (0 0 0 1))) +;; (:spoon . ((1.45 -0.4 1.0) (0 0 0 1))) +;; (:milk . ((1.2 -0.5 0.8) (0 0 1 0))) +;; (:breakfast-cereal . ((1.15 -0.5 0.8) (0 0 1 0))))) +;; (defparameter *object-grasping-arms* +;; '((:breakfast-cereal . :right) +;; (:cup . :left) +;; (:bowl . :right) +;; (:spoon . :right) +;; (:milk . :right))) (defun spawn-objects-on-sink-counter (&key (object-types @@ -150,10 +351,7 @@ (random NIL)) ;; make sure mesh paths are known, kill old objects and destroy all attachments - (btr:add-objects-to-mesh-list "cram_pr2_pick_place_demo") - (btr-utils:kill-all-objects) - (btr:detach-all-objects (btr:get-robot-object)) - (btr:detach-all-objects (btr:get-environment-object)) + (kill-and-detach-all) ;; spawn objects (let* ((spawning-poses-absolute @@ -224,128 +422,6 @@ ;; return list of BTR objects objects)) -(defun attach-object-to-the-world (object-type) - (when *demo-object-spawning-poses* - (btr:attach-object (btr:get-environment-object) - (btr:object btr:*current-bullet-world* - (intern (format nil "~a-1" object-type) :keyword)) - :link (second (find object-type - *demo-object-spawning-poses* - :key #'car))))) - - - -(defun spawn-objects-on-fixed-spots (&key - (spawning-poses-relative - *demo-object-spawning-poses*) - (object-types - '(:breakfast-cereal :cup :bowl :spoon :milk))) - (btr-utils:kill-all-objects) - (btr:add-objects-to-mesh-list "cram_pr2_pick_place_demo") - (btr:detach-all-objects (btr:get-robot-object)) - ;; spawn objects at default poses - (let* ((spawning-poses-absolute - (make-poses-list-relative spawning-poses-relative)) - (objects (mapcar (lambda (object-type) - (btr-utils:spawn-object - (intern (format nil "~a-1" object-type) :keyword) - object-type - :pose (cdr (assoc object-type - ;; *demo-object-spawning-poses* - spawning-poses-absolute - )))) - object-types))) - ;; stabilize world - ;; (btr:simulate btr:*current-bullet-world* 100) - objects) - - (mapcar #'attach-object-to-the-world object-types)) - - - -(defun park-robot () - (cpl:with-failure-handling - ((cpl:plan-failure (e) - (declare (ignore e)) - (return))) - (cpl:par - (exe:perform - (desig:an action - (type positioning-arm) - (left-configuration park) - (right-configuration park))) - (exe:perform - (desig:an action - (type moving-torso) - (joint-angle upper-limit))) - (let ((?pose (cl-transforms-stamped:make-pose-stamped - cram-tf:*fixed-frame* - 0.0 - (cl-transforms:make-identity-vector) - (cl-transforms:make-identity-rotation)))) - (exe:perform - (desig:an action - (type going) - (target (desig:a location - (pose ?pose)))))) - (exe:perform (desig:an action (type opening-gripper) (gripper (left right)))) - (exe:perform (desig:an action (type looking) (direction forward)))))) - -(defun initialize () - (sb-ext:gc :full t) - - ;;(when ccl::*is-logging-enabled* - ;; (setf ccl::*is-client-connected* nil) - ;; (ccl::connect-to-cloud-logger) - ;; (ccl::reset-logged-owl)) - - ;; (setf proj-reasoning::*projection-checks-enabled* t) - - (btr:detach-all-objects (btr:get-robot-object)) - (btr:detach-all-objects (btr:get-environment-object)) - (btr-utils:kill-all-objects) - (setf (btr:joint-state (btr:get-environment-object) - "sink_area_left_upper_drawer_main_joint") - 0.0 - (btr:joint-state (btr:get-environment-object) - "sink_area_left_middle_drawer_main_joint") - 0.0 - (btr:joint-state (btr:get-environment-object) - "sink_area_left_bottom_drawer_main_joint") - 0.0 - (btr:joint-state (btr:get-environment-object) - "iai_fridge_door_joint") - 0.0 - (btr:joint-state (btr:get-environment-object) - "sink_area_dish_washer_door_joint") - 0.0 - (btr:joint-state (btr:get-environment-object) - "sink_area_dish_washer_tray_main") - 0.0 - (btr:joint-state (btr:get-environment-object) - "oven_area_area_right_drawer_main_joint") - 0.0 - (btr:joint-state (btr:get-environment-object) - "sink_area_trash_drawer_main_joint") - 0) - (btr-belief::publish-environment-joint-state - (btr:joint-states (btr:get-environment-object))) - - (setf desig::*designators* (tg:make-weak-hash-table :weakness :key)) - - ;; (coe:clear-belief) - - (btr:clear-costmap-vis-object)) - -(defun finalize () - ;; (setf proj-reasoning::*projection-reasoning-enabled* nil) - - ;;(when ccl::*is-logging-enabled* - ;; (ccl::export-log-to-owl "ease_milestone_2018.owl") - ;; (ccl::export-belief-state-to-owl "ease_milestone_2018_belief.owl")) - (sb-ext:gc :full t)) - - (defun household-demo-random (&optional (random nil) @@ -406,49 +482,27 @@ -(defun household-demo (&optional (object-list '(:bowl :spoon :cup - :breakfast-cereal :milk))) - (urdf-proj:with-simulated-robot - - (initialize) - (setf btr:*visibility-threshold* 0.7) - (when cram-projection:*projection-environment* - (spawn-objects-on-fixed-spots - :object-types object-list - :spawning-poses-relative *demo-object-spawning-poses*)) - (park-robot) - - ;; set the table - (dolist (?object-type object-list) - (exe:perform - (desig:an action - (type transporting) - (object (desig:an object (type ?object-type))) - (context table-setting)))) - - ;; clean up - ;; (when cram-projection:*projection-environment* - ;; (spawn-objects-on-fixed-spots - ;; :object-types object-list - ;; :spawning-poses-relative *delivery-poses-relative*)) - - (dolist (?object-type object-list) - (exe:perform - (desig:an action - (type transporting) - (object (desig:an object (type ?object-type))) - (context table-cleaning)))))) - - - - - - - - - - +;;;;;;;; THE STUFF BELOW IS FOR THE POURING EXPERIMENT +(defun pour-demo () + (spawn-objects-on-fixed-spots + :spawning-poses-relative *delivery-poses-relative*) + (urdf-proj:with-simulated-robot + (pp-plans::add + (desig:an object + (type milk) + (location (desig:a location + (on (desig:an object + (type counter-top) + (urdf-name kitchen-island-surface) + (part-of iai-kitchen)))))) + (desig:an object + (type bowl) + (location (desig:a location + (on (desig:an object + (type counter-top) + (urdf-name kitchen-island-surface) + (part-of iai-kitchen))))))))) diff --git a/cram_demos/cram_projection_demos/src/package.lisp b/cram_demos/cram_projection_demos/src/package.lisp index 460beda5a0..849ed8b14f 100644 --- a/cram_demos/cram_projection_demos/src/package.lisp +++ b/cram_demos/cram_projection_demos/src/package.lisp @@ -31,7 +31,7 @@ (defpackage cram-projection-demos (:nicknames #:demos) - (:use #:common-lisp #:cram-prolog) + (:use #:common-lisp #:cram-prolog #:urdf-proj #:cram-designators #:cram-executive) (:export ;; household-demo #:household-demo diff --git a/cram_demos/cram_projection_demos/src/retail-demo.lisp b/cram_demos/cram_projection_demos/src/retail-demo.lisp index 33bf005414..d413258076 100644 --- a/cram_demos/cram_projection_demos/src/retail-demo.lisp +++ b/cram_demos/cram_projection_demos/src/retail-demo.lisp @@ -1,5 +1,6 @@ ;;; ;;; Copyright (c) 2018, Gayane Kazhoyan +;;; Jonas Dech ;;; All rights reserved. ;;; ;;; Redistribution and use in source and binary forms, with or without @@ -82,8 +83,26 @@ (defparameter *small-shelf-poses* '("shelf_2_shelf_2_level_3_link" - (:balea-bottle . ((-0.15 -0.1 0.1) (0 0 0.5 0.5))) - (:dish-washer-tabs . ((0 -0.13 0.11) (0 0 0.5 0.5))))) + (:balea-bottle . ((-0.15 -0.14 0.1) (0 0 0.5 0.5))) + (:dish-washer-tabs . ((0 -0.13 0.11) (0 0 0.5 0.5))) + ;; (:box-item . ((-0.075 -0.135 0.1) (0 0 0 1))) + )) + +(defparameter *real-random-small-shelf-poses* + '("DMFloorT4W100_NLBMVEGQ" + (:balea-bottle . ((-0.15 -0.14 0.16) (0 0 0.5 0.5))) + (:dish-washer-tabs . ((0.1 -0.13 0.16) (0 0 0.5 0.5))) + (:breakfast-cereal . ((-0.35 -0.135 0.2) (0 0 0.5 0.5))) + (:breakfast-cereal . ((-0.35 0.135 0.2) (0 0 0.5 0.5))) + (:breakfast-cereal . ((-0.35 0 0.2) (0 0 0.5 0.5))))) + +(defparameter *real-small-shelf-poses* + '("DMFloorT4W100_ZMIYURLQ" + (:balea-bottle . ((-0.01 -0.14 0.16) (0 0 0.5 0.5))) + (:dish-washer-tabs . ((0.12 -0.13 0.16) (0 0 0.5 0.5))) + (:breakfast-cereal . ((-0.37 -0.135 0.19) (0 0 0.5 0.5))) + (:breakfast-cereal . ((-0.37 0.135 0.19) (0 0 0.5 0.5))) + (:breakfast-cereal . ((-0.37 0 0.19) (0 0 0.5 0.5))))) (defparameter *basket-in-pr2-wrist* (cl-transforms:make-transform @@ -96,22 +115,39 @@ (cl-transforms:make-3d-vector 0 -0.15 0.48) (cl-transforms:make-quaternion 0.5 0.5 0 0))) -(defun spawn-object-n-times (type pose times color &optional offset-axis offset) - "`offset-axis' can be one of :x, :y or :z." - (loop for i from 0 to (1- times) - for name = (intern (string-upcase (format nil "~a-~a" type i)) :keyword) - do (when offset-axis - (setf pose (cram-tf:translate-pose pose offset-axis offset))) - ;; if object with name NAME already exists, create a new unique name - (when (btr:object btr:*current-bullet-world* name) - (setf i (+ i times) - name (intern (string-upcase (format nil "~a-~a" type i)) - :keyword))) - (btr:add-object btr:*current-bullet-world* :mesh name pose :mesh type - :mass 0.0 - :color color))) - -(defun spawn-objects-on-big-shelf () +;; Calculated based on the basket grasp pose +#+first-set-the-basket-correctly-in-hand-then-take-the-relative-pose +(let* ((obj-T-std-gripper + (man-int:get-object-type-to-gripper-transform + :basket :b :left :top)) + (map-T-std-gripper + (cl-transforms:transform* + (cl-transforms:reference-transform + (btr:link-pose (btr:get-robot-object) "gripper_left_grasping_frame")) + (cl-transforms:make-transform + (cl-transforms:make-3d-vector (- 0.24 0.150575d0) 0 0 ) + (cl-transforms:make-identity-rotation)) + (cl-transforms:transform-inv + (cl-transforms:make-transform + (cl-transforms:make-identity-vector) + (cl-transforms:matrix->quaternion + #2A((0 1 0) + (0 0 1) + (1 0 0))))))) + (map-T-obj + (cl-transforms:transform* + map-T-std-gripper + (cl-transforms:transform-inv + obj-T-std-gripper)))) + (setf (btr:pose (btr:object btr:*current-bullet-world* :b)) + (cl-transforms:transform->pose map-T-obj))) +(defparameter *basket-in-tiago-wrist* + (cl-transforms:make-transform + (cl-transforms:make-3d-vector 0.42 0.15 0) + (cl-transforms:make-quaternion -0.5 0.5 0.5 -0.5)) + "In end-effector frame.") + +(defun spawn-objects-on-big-shelf (&optional (minimal-color 0.0)) (let ((type-and-pose-list (make-poses-relative-multiple *big-shelf-poses* "shelf_1_"))) (mapcar (lambda (type-and-pose) @@ -119,30 +155,174 @@ (spawn-object-n-times type pose - (+ (random 3) 1) ; times - `(,(float (/ (random 10) 10)) ; color - ,(float (/ (random 10) 10)) - ,(float (/ (random 10) 10))) + (+ (random 3) 1) + (list (cut:random-with-minimum 1.0 minimal-color) + (cut:random-with-minimum 1.0 minimal-color) + (cut:random-with-minimum 1.0 minimal-color)) :x 0.13))) type-and-pose-list))) -(defun spawn-objects-on-small-shelf () +(defun spawn-random-box-objects-on-shelf (base-link-name + &key + list-of-level-link-names + (maximal-box-size-in-level-frame + '(0.15 0.1 0.2)) + (minimal-box-size-one-dimension + 0.03) + (weight + 0.2) + (space-between-objects + 0.05) + (start-x-offset + 0.0) + (minimal-color + 0.0)) + (setf list-of-level-link-names + (or list-of-level-link-names + (mapcar #'cl-urdf:name + (btr:find-levels-under-link + (gethash base-link-name + (cl-urdf:links + (btr:urdf + (btr:get-environment-object)))))))) + + ;; for each shelf level + (loop for link-name in list-of-level-link-names + for level-transform = (cram-tf:pose->transform-stamped + cram-tf:*fixed-frame* + link-name + 0.0 + (btr:link-pose + (btr:get-environment-object) + link-name)) + for level-bb = (btr:calculate-bb-dims + (gethash link-name + (btr:links (btr:get-environment-object)))) + for end-x-in-link-frame = (- (/ (cl-transforms:x level-bb) 2.0) + space-between-objects) + for start-x-in-link-frame = (+ (- end-x-in-link-frame) + start-x-offset) + for start-z-in-link-frame = (/ (cl-transforms:z level-bb) 2.0) + ;; we assume that the face of the level is the -Y axis + for end-y-in-link-frame = (- (/ (cl-transforms:y level-bb) 2.0) + space-between-objects) + for start-y-in-link-frame = (- end-y-in-link-frame) + ;; for each row of items + do (loop for color = (list (cut:random-with-minimum 1.0 minimal-color) + (cut:random-with-minimum 1.0 minimal-color) + (cut:random-with-minimum 1.0 minimal-color)) + for box-size = (mapcar (lambda (dimension) + (cut:random-with-minimum + dimension + minimal-box-size-one-dimension)) + maximal-box-size-in-level-frame) + for box-size/2 = (mapcar (alexandria:rcurry #'/ 2.0) box-size) + for z-in-link-frame = (+ start-z-in-link-frame + (third box-size/2)) + for x-in-link-frame = (+ start-x-in-link-frame + (first box-size/2)) + then (+ next-start-x-in-link-frame + (first box-size/2)) + for next-start-x-in-link-frame = (+ x-in-link-frame + (first box-size/2) + space-between-objects) + while (< next-start-x-in-link-frame end-x-in-link-frame) + ;; go into the depth of the shelf + do (loop for next-start-y-in-link-frame = start-y-in-link-frame + then (+ y-in-link-frame + (second box-size/2) + space-between-objects) + for y-in-link-frame = (+ next-start-y-in-link-frame + (second box-size/2)) + while (< next-start-y-in-link-frame end-y-in-link-frame) + do (let* ((name + (intern (format nil "BOX-~a-~a-~a" + link-name + x-in-link-frame + y-in-link-frame))) + (link-frame-t-box + (cl-transforms-stamped:make-transform-stamped + link-name "box" 0.0 + (cl-transforms:make-3d-vector + x-in-link-frame + y-in-link-frame + z-in-link-frame) + (cl-transforms:make-identity-rotation))) + (pose-in-fixed-frame + (cram-tf:apply-transform + level-transform + link-frame-t-box + :result-as-pose-or-transform :pose)) + (btr-object + (btr:add-object + btr:*current-bullet-world* + :box-item + name + pose-in-fixed-frame + :mass weight + :size box-size/2 + :color color + :item-type :retail-item))) + (when (some (alexandria:rcurry #'typep 'btr:item) + (btr:find-objects-in-contact + btr:*current-bullet-world* btr-object)) + (btr:remove-object + btr:*current-bullet-world* name))))))) + +(defun spawn-objects-on-small-shelf (&optional (minimal-color 0.0)) (sb-ext:gc :full t) (setf desig::*designators* (tg:make-weak-hash-table :weakness :key)) - (btr:clear-costmap-vis-object) ;; (btr-utils:kill-all-objects) (btr:detach-all-objects (btr:get-robot-object)) (btr:detach-all-objects (btr:get-environment-object)) - (mapcar (lambda (type-and-pose) - (destructuring-bind (type . pose) type-and-pose - (spawn-object-n-times type pose 1 - (case type - (:dish-washer-tabs '(0 1 0)) - (t '(1.0 1.0 0.9)))))) - (make-poses-relative *small-shelf-poses*)) + (btr-utils:move-robot '((1.0 0 0) (0 0 0 1))) + + (let ((poses (make-poses-relative *small-shelf-poses*))) + (mapcar (lambda (type-and-pose) + (destructuring-bind (type . pose) type-and-pose + (spawn-object-n-times type pose 1 + (case type + (:dish-washer-tabs '(0 1 0)) + (:balea-bottle '(1 1 0)) + (t '(1.0 1.0 0.9)))))) + poses) + (btr:add-object btr:*current-bullet-world* + :box-item + :small-shelf-dish-washer-tabs-collision-box + (cdr (find :dish-washer-tabs poses :key #'car)) + :mass 0.0 + :size '(0.15 0.1 0.1) + :color '(0 0 0) + :item-type :collision-thingy) + (btr:add-object btr:*current-bullet-world* + :box-item + :small-shelf-balea-bottle-collision-box + (cdr (find :balea-bottle poses :key #'car)) + :mass 0.0 + :size '(0.15 0.1 0.1) + :color '(0 0 0) + :item-type :collision-thingy)) + + (spawn-random-box-objects-on-shelf "shelf_2_base" + :start-x-offset 0.05 + :minimal-color minimal-color) + + (btr:remove-object btr:*current-bullet-world* :small-shelf-dish-washer-tabs-collision-box) + (btr:remove-object btr:*current-bullet-world* :small-shelf-balea-bottle-collision-box) ;; (btr:simulate btr:*current-bullet-world* 50) - (btr-utils:move-robot '((1.0 0 0) (0 0 0 1)))) + ) + +(defun spawn-objects-on-real-small-shelf () + (let ((poses (make-poses-relative *real-small-shelf-poses*))) + (mapcar (lambda (type-and-pose) + (destructuring-bind (type . pose) type-and-pose + (spawn-object-n-times type pose 1 + (case type + (:dish-washer-tabs '(0 1 0)) + (:balea-bottle '(1 0.5 0)) + (t '(1.0 1.0 0.9)))))) + poses))) (defun spawn-basket () (let* ((left-ee-frame @@ -157,6 +337,8 @@ (wrist-T-basket (case (rob-int:get-robot-name) (:pr2 *basket-in-pr2-wrist*) + (:boxy *basket-in-boxy-wrist*) + (:tiago-dual *basket-in-tiago-wrist*) (t *basket-in-boxy-wrist*))) (map-T-basket (cl-transforms:transform* @@ -183,16 +365,54 @@ (defun retail-demo () + ;; (setf cram-tf:*tf-broadcasting-enabled* t) + ;; (roslisp-utilities:startup-ros) (urdf-proj:with-simulated-robot - - (setf btr:*visibility-threshold* 0.5) - (btr-utils:kill-all-objects) - (spawn-objects-on-small-shelf) - (spawn-objects-on-big-shelf) - (unless (eql (rob-int:get-robot-name) :iai-donbot) + (if (eql (rob-int:get-robot-name) :kmr-iiwa) + (setf btr:*visibility-threshold* 0.7) + (setf btr:*visibility-threshold* 0.5)) + (kill-and-detach-all) + (let ((?pose (cl-transforms-stamped:make-pose-stamped + "map" 0.0 + (cl-transforms-stamped:make-3d-vector 2 0 0.0d0) + (cl-transforms:make-quaternion 0 0 1 0)))) + (exe:perform + (desig:a motion + (type going) + (pose ?pose)))) + (if (eql (rob-int:get-environment-name) :store) + (spawn-objects-on-real-small-shelf) + (progn + (spawn-objects-on-small-shelf 0.6) + (spawn-objects-on-big-shelf 0.6))) + (unless (member (rob-int:get-robot-name) '(:iai-donbot :kmr-iiwa)) (spawn-basket)) - (let* ((?environment-name + (let* ((?source-shelf-base-urdf-name + (if (eql (rob-int:get-environment-name) :store) + :|DMShelfW100_EVZDYXFU| + :shelf-2-base)) + (?source-shelf-base-level + (if (eql (rob-int:get-environment-name) :store) + 4 ;3 + 4)) + (?target-shelf-level-urdf-name + (if (eql (rob-int:get-environment-name) :store) + :|DMFloorT6W100_YVLKGJSB| ; :|DMFloorT6W100_KYINFGDM| + :shelf-1-level-2-link)) + (?target-shelf-dishwasher-attachments + (if (eql (rob-int:get-environment-name) :store) + '(;; :dish-washer-tabs-real-shelf-1-front + :dish-washer-tabs-real-shelf-1-back) + '(:dish-washer-tabs-shelf-1-front + :dish-washer-tabs-shelf-1-back))) + (?target-shelf-balea-attachments + (if (eql (rob-int:get-environment-name) :store) + '(;; :balea-bottle-real-shelf-1-front + :balea-bottle-real-shelf-1-back) + '(:balea-bottle-shelf-1-front + :balea-bottle-shelf-1-back))) + (?environment-name (rob-int:get-environment-name)) (?robot-name (rob-int:get-robot-name)) @@ -200,10 +420,9 @@ (desig:a location (on (desig:an object (type shelf) - (urdf-name shelf-2-base) - (owl-name "shelf_system_verhuetung") + (urdf-name ?source-shelf-base-urdf-name) (part-of ?environment-name) - (level 4))) + (level ?source-shelf-base-level))) (side left) (range 0.2))) @@ -221,58 +440,90 @@ (type environment) (name ?environment-name) (part-of ?environment-name) - (urdf-name shelf-1-level-2-link))) + (urdf-name ?target-shelf-level-urdf-name))) (for ?dish-washer-tabs-desig) - (attachments (dish-washer-tabs-shelf-1-front - dish-washer-tabs-shelf-1-back)))) + (attachments ?target-shelf-dishwasher-attachments))) (?target-location-shelf-balea-bottle (desig:a location (on (desig:an object (type environment) (name ?environment-name) (part-of ?environment-name) - (urdf-name shelf-1-level-2-link))) + (urdf-name ?target-shelf-level-urdf-name))) (for ?balea-bottle-desig) - (attachments (balea-bottle-shelf-1-front - balea-bottle-shelf-1-back)))) - (?target-location-tray-dish-washer-tabs + (attachments ?target-shelf-balea-attachments))) + (?target-location-donbot-tray-dish-washer-tabs (desig:a location (on (desig:an object (type robot) (name ?robot-name) - (part-of ?environment-name) + (part-of ?robot-name) (owl-name "donbot_tray") (urdf-name plate))) (for ?dish-washer-tabs-desig) - (attachments (donbot-tray-front donbot-tray-back)))) + (attachments (donbot-tray-back donbot-tray-front)))) + (?target-location-kukabot-tray-dish-washer-tabs + (desig:a location + (on (desig:an object + (type robot) + (name ?robot-name) + (part-of ?robot-name) + (owl-name "kukabot_tray") + (urdf-name base-link))) + (for ?dish-washer-tabs-desig) + (attachments (kukabot-tray-back kukabot-tray-front)))) (?target-location-basket-dish-washer-tabs (desig:a location (on (desig:an object (type basket) (name b))) (for ?dish-washer-tabs-desig) - (attachments (; in-basket-front - in-basket-back)))) + (attachments (in-basket-back + in-basket-front + in-basket-other-back + in-basket-other-front)))) (?target-location-robot-dish-washer-tabs (case ?robot-name - (:iai-donbot ?target-location-tray-dish-washer-tabs) - (t ?target-location-basket-dish-washer-tabs)))) - - (exe:perform - (desig:an action - (type transporting) - (object ?dish-washer-tabs-desig) - (target ?target-location-robot-dish-washer-tabs))) - (exe:perform - (desig:an action - (type transporting) - (object ?balea-bottle-desig) - (target ?target-location-shelf-balea-bottle))) - (exe:perform - (desig:an action - (type transporting) - (object ?dish-washer-tabs-desig) - (target ?target-location-shelf-dish-washer-tabs))) + (:iai-donbot + ?target-location-donbot-tray-dish-washer-tabs) + (:kmr-iiwa + ?target-location-kukabot-tray-dish-washer-tabs) + (t + ?target-location-basket-dish-washer-tabs)))) + + (cpl:with-failure-handling + ((cpl:simple-plan-failure (e) + (declare (ignore e)) + (return))) + (exe:perform + (desig:an action + (type transporting) + (object ?dish-washer-tabs-desig) + (target ?target-location-robot-dish-washer-tabs) + ;; (grasps (back)) + ))) + (cpl:with-failure-handling + ((cpl:simple-plan-failure (e) + (declare (ignore e)) + (return))) + (exe:perform + (desig:an action + (type transporting) + (object ?balea-bottle-desig) + (target ?target-location-shelf-balea-bottle) + ;; (grasps (back)) + ))) + (cpl:with-failure-handling + ((cpl:simple-plan-failure (e) + (declare (ignore e)) + (return))) + (exe:perform + (desig:an action + (type transporting) + (object ?dish-washer-tabs-desig) + (target ?target-location-shelf-dish-washer-tabs) + ;; vvv donbot tries to grasp through itself otherwise + (grasps (back))))) ;; look at separators ;; (exe:perform @@ -283,7 +534,32 @@ ))) - +(defmethod cram-occasions-events:on-event + publish-object 3 ((event cram-plan-occasions-events:robot-state-changed)) + + (let ((items (remove-if-not (lambda (object) + (typep object 'btr:item)) + (btr:objects btr:*current-bullet-world*)))) + (dolist (item items) + (let* ((name + (btr:name item)) + (ros-name + (roslisp-utilities:rosify-underscores-lisp-name name)) + (pose + (btr:pose item)) + (mesh-path + (second (assoc (car (btr:item-types item)) btr::*mesh-files*))) + (color + (cl-bullet-vis:collision-shape-color + (cl-bullet:collision-shape + (btr:rigid-body item name))))) + (cram-tf:visualize-marker pose + ;; :topic "cram_items" + :namespace ros-name + :marker-type :mesh_resource + :scale-list '(1 1 1) + :r-g-b-list color + :mesh-path mesh-path))))) diff --git a/cram_demos/cram_projection_demos/src/setup.lisp b/cram_demos/cram_projection_demos/src/setup.lisp index 7f71b7dd79..917735f345 100644 --- a/cram_demos/cram_projection_demos/src/setup.lisp +++ b/cram_demos/cram_projection_demos/src/setup.lisp @@ -49,73 +49,10 @@ (btr:add-objects-to-mesh-list "assembly_models" :directory "battat/convention" :extension "stl") + (btr:add-objects-to-mesh-list "cram_bullet_reasoning") (btr:add-objects-to-mesh-list "cram_projection_demos" :directory "resource/household") (btr:add-objects-to-mesh-list "cram_projection_demos" :directory "resource/retail")) (roslisp-utilities:register-ros-init-function init-projection) - - - -(defun make-poses-relative (spawning-poses &optional frame-prefix) - "Gets an associative list in a form of - (FRAME (TYPE . COORDINATES-LIST) - (TYPE2 . COORDS2) - ...), -where coordinates-list is defined in the FRAME coordinate frame. -If `frame-prefix' is given, instead of FRAME 'frame-prefixFRAME' is used. -Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame -and returns a list in form - ((TYPE . POSE) (TYPE2 . POSE2) ...)." - (when spawning-poses - (destructuring-bind (frame . type-and-pose-list) - spawning-poses - (let* ((map-T-surface - (cl-transforms:pose->transform - (btr:link-pose (btr:get-environment-object) - (concatenate 'string frame-prefix frame))))) - (mapcar (lambda (type-and-pose) - (destructuring-bind (type . pose-list) - type-and-pose - (let* ((surface-T-object - (cl-transforms:pose->transform - (cram-tf:list->pose pose-list))) - (map-T-object - (cl-transforms:transform* - map-T-surface surface-T-object)) - (map-P-object - (cl-transforms:transform->pose map-T-object))) - `(,type . ,map-P-object)))) - type-and-pose-list))))) - -(defun make-poses-relative-multiple (poses &optional frame-prefix) - "Gets a list of ((FRAME1 ((TYPE1 . COORDS1) (TYPE2 . COORDS2) ...)) - (FRAME2 ((TYPEN . COORDSN) ...))). -Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame -and returns a list in form - ((TYPE . POSE) ...)." - (mapcan (lambda (frame-and-list-of-type-and-coords) - (make-poses-relative frame-and-list-of-type-and-coords frame-prefix)) - poses)) - -(defun make-poses-list-relative (spawning-poses-list) - "Gets a list of ((:type \"frame\" cords-list) ...) -Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame and returns a list in form - ((TYPE . POSE) ...)." - (when spawning-poses-list - (mapcar (lambda (type-and-frame-and-pose-list) - (destructuring-bind (type frame pose-list) - type-and-frame-and-pose-list - (let* ((map-T-surface - (cl-transforms:pose->transform - (btr:link-pose (btr:get-environment-object) frame))) - (surface-T-object - (cl-transforms:pose->transform - (cram-tf:list->pose pose-list))) - (map-T-object - (cl-transforms:transform* map-T-surface surface-T-object)) - (map-P-object - (cl-transforms:transform->pose map-T-object))) - `(,type . ,map-P-object)))) - spawning-poses-list))) diff --git a/cram_demos/cram_projection_demos/src/storage-demo.lisp b/cram_demos/cram_projection_demos/src/storage-demo.lisp new file mode 100644 index 0000000000..1a6f791d9f --- /dev/null +++ b/cram_demos/cram_projection_demos/src/storage-demo.lisp @@ -0,0 +1,203 @@ +;;; +;;; Copyright (c) 2022, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :demos) + +(defparameter *storage-poses* + `(("board0" + (:dish-washer-tabs . ((0 0.4 0.0858) (-0.5 0.5 0.5 0.5))) + (:balea-bottle . ((-0.35 0.45 0.1061) (0 0 0.5 0.5))) + (:chassis . ((-0.7 0.45 0.078) (0 0 0 1))) + (:front-wheel . ((0.4 0.43 0.0386) (0 0 0 1))) + (:propeller . ((0.8 0.41 0.02635) (0 0 0 1))) + + (:mug . ((0.8 0.4 0.07434) (0 0 0.8 0.2))) + (:spatula . ((0.5 0.41 0.03343) (-0.001785 0.01511 0.112743 0.99351))) + (:bowl-round . ((0.2 0.4 0.05541) (0 0 0 1))) + (:pot . ((-0.35 0.35 0.106334) (0 0 0 1))) + (:fork . ((-0.7 0.41 0.03) (0 0 0.93 0.37)))) + + ("board2" + (:bowl . ((-0.8 0.4 0.07655) (0 0 0 1))) + (:cup . ((-0.5 0.4 0.10155) (0 0 0 1))) + (:spoon . ((-0.1 0.4 0.03274) (0 0 0.3 0.7))) + (:breakfast-cereal . ((0.2 0.4 0.1279) (0 0 0 1))) + (:milk . ((0.6 0.4 0.11369) (0 0 0 1))) + + (:denkmit-entkalker . ((-0.8 0.43 0.11383) (0 0 0 1))) + (:heitmann-citronensaeure . ((-0.3 0.42 0.121446) (0 0 0 1))) + (:kuehne-essig-essenz . ((-0.1 0.4 0.112) (0 0 0.3 0.7))) + (:domestos-allzweckreiniger . ((0.2 0.4 0.17265) (0 0 0 1))) + (:shoe . ((0.6 0.4 0.11755) (0 0 0.1 0.9)))))) + +(defun spawn-storage-objects (&key (attach t) (spawning-poses-relative *storage-poses*) + objects-list (weight 0.0)) + (kill-and-detach-all) + (let ((poses (make-poses-relative-multiple spawning-poses-relative))) + (mapcar (lambda (type-and-pose) + (destructuring-bind (type . pose) type-and-pose + (when (or (null objects-list) (member type objects-list)) + (spawn-object-n-times type pose 1 + ;; color + (case type + (:dish-washer-tabs '(0 1 0)) + (:balea-bottle '(1 0.5 0)) + ((:chassis :propeller) *yellow-plane*) + (:front-wheel *black-plane*) + (t nil)) + nil nil + (case type + ;; dishwasher tabs are unstable, so mass=0 + ;; (:dish-washer-tabs 0.0) + (t weight))) + ;; attach object to environment + (when attach + (btr:attach-object (btr:get-environment-object) + (btr:object btr:*current-bullet-world* + (intern (format nil "~a-0" type) :keyword)) + :link (car (find type spawning-poses-relative + :key (lambda (urdf-name-and-list) + (car (find type + (cdr urdf-name-and-list) + :key #'car)))))))))) + poses))) + + + + +(defun storage-demo (&optional (objects-list '(:dish-washer-tabs :balea-bottle + :chassis :front-wheel :propeller + :bowl :cup :spoon :milk :breakfast-cereal))) + ;; (setf cram-tf:*tf-broadcasting-enabled* t) + (urdf-proj:with-simulated-robot + (spawn-storage-objects :objects-list objects-list) + (let ((old-visibility btr:*visibility-threshold*)) + (setf btr:*visibility-threshold* + (case (rob-int:get-robot-name) + ;; perceiving with an object in hand is hard, and perceiving the pot + ;; even without objects in hand is also too hard + ((:iai-donbot :kmr-iiwa) 0.4) + (t 0.7))) + (unwind-protect + + (let ((?environment-name + (rob-int:get-environment-name))) + + ;; bring objects to table + (dolist (object-type-and-urdf-name + (apply + (alexandria:curry #'concatenate 'list) + (mapcar (lambda (urdf-name-and-stuff) + (mapcar (lambda (type-and-pose) + (cons (car type-and-pose) + (car urdf-name-and-stuff))) + (cdr urdf-name-and-stuff))) + *storage-poses*))) + + (let ((?object-type (car object-type-and-urdf-name)) + (?urdf-name (cdr object-type-and-urdf-name))) + (when (member ?object-type objects-list) + (cpl:with-failure-handling + ((cpl:simple-plan-failure (e) + (declare (ignore e)) + (return))) + (exe:perform + (desig:an action + (type transporting) + (object (desig:an object + (type ?object-type) + (location (desig:a location + (on (desig:an object + (type shelf) + (urdf-name ?urdf-name) + (part-of ?environment-name))) + (side left))))) + (target (desig:a location + (on (desig:an object + (type table) + (urdf-name top) + (part-of ?environment-name))) + (for (desig:an object + (type ?object-type))))))))))) + + ;; put objects back + (dolist (object-type-and-urdf-name + (reverse + (apply + (alexandria:curry #'concatenate 'list) + (mapcar (lambda (urdf-name-and-stuff) + (mapcar (lambda (type-and-pose) + (cons (car type-and-pose) + (if (string= (car urdf-name-and-stuff) + "board0") + "board2" + "board0"))) + (cdr urdf-name-and-stuff))) + *storage-poses*)))) + + (let* ((?object-type (car object-type-and-urdf-name)) + (?urdf-name (cdr object-type-and-urdf-name)) + (?grasps (case ?object-type + (:bowl '(:top-left-tilted :top-right-tilted)) + (:dish-washer-tabs '(:back :front)) + (:balea-bottle '(:back :front)) + ((:shoe :mug) '(:back :front :left-side :right-side)) + ;; (:pot '(:left-side :right-side)) + (t (cdr (assoc ?object-type *object-grasps*)))))) + (when (member ?object-type objects-list) + (cpl:with-failure-handling + ((cpl:simple-plan-failure (e) + (declare (ignore e)) + (return))) + (exe:perform + (desig:an action + (type transporting) + (object (desig:an object + (type ?object-type) + (location (desig:a location + (on (desig:an object + (type table) + (urdf-name top) + (part-of ?environment-name))))))) + (target (desig:a location + (on (desig:an object + (type shelf) + (urdf-name ?urdf-name) + (part-of ?environment-name))) + (side left) + (for (desig:an object + (type ?object-type))))) + (grasps ?grasps)))))))) + + (setf btr:*visibility-threshold* old-visibility))))) + +(defun storage-demo-new-objects () + (storage-demo '(:mug :pot :bowl-round :fork :spatula + :denkmit-entkalker :heitmann-citronensaeure :kuehne-essig-essenz + :domestos-allzweckreiniger :shoe))) diff --git a/cram_demos/cram_projection_demos/src/utils.lisp b/cram_demos/cram_projection_demos/src/utils.lisp new file mode 100644 index 0000000000..3820be022b --- /dev/null +++ b/cram_demos/cram_projection_demos/src/utils.lisp @@ -0,0 +1,116 @@ +;;; +;;; Copyright (c) 2022, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :demos) + +(defun make-poses-relative (spawning-poses &optional frame-prefix) + "Gets an associative list in a form of + (FRAME (TYPE . COORDINATES-LIST) + (TYPE2 . COORDS2) + ...), +where coordinates-list is defined in the FRAME coordinate frame. +If `frame-prefix' is given, instead of FRAME 'frame-prefixFRAME' is used. +Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame +and returns a list in form + ((TYPE . POSE) (TYPE2 . POSE2) ...)." + (when spawning-poses + (destructuring-bind (frame . type-and-pose-list) + spawning-poses + (let* ((map-T-surface + (cl-transforms:pose->transform + (btr:link-pose (btr:get-environment-object) + (concatenate 'string frame-prefix frame))))) + (mapcar (lambda (type-and-pose) + (destructuring-bind (type . pose-list) + type-and-pose + (let* ((surface-T-object + (cl-transforms:pose->transform + (cram-tf:list->pose pose-list))) + (map-T-object + (cl-transforms:transform* + map-T-surface surface-T-object)) + (map-P-object + (cl-transforms:transform->pose map-T-object))) + `(,type . ,map-P-object)))) + type-and-pose-list))))) + +(defun make-poses-relative-multiple (poses &optional frame-prefix) + "Gets a list of ((FRAME1 ((TYPE1 . COORDS1) (TYPE2 . COORDS2) ...)) + (FRAME2 ((TYPEN . COORDSN) ...))). +Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame +and returns a list in form + ((TYPE . POSE) ...)." + (mapcan (lambda (frame-and-list-of-type-and-coords) + (make-poses-relative frame-and-list-of-type-and-coords frame-prefix)) + poses)) + +(defun make-poses-list-relative (spawning-poses-list) + "Gets a list of ((:type \"frame\" cords-list) ...) +Converts these coordinates into CRAM-TF:*FIXED-FRAME* frame and returns a list in form + ((TYPE . POSE) ...)." + (when spawning-poses-list + (mapcar (lambda (type-and-frame-and-pose-list) + (destructuring-bind (type frame pose-list) + type-and-frame-and-pose-list + (let* ((map-T-surface + (cl-transforms:pose->transform + (btr:link-pose (btr:get-environment-object) frame))) + (surface-T-object + (cl-transforms:pose->transform + (cram-tf:list->pose pose-list))) + (map-T-object + (cl-transforms:transform* map-T-surface surface-T-object)) + (map-P-object + (cl-transforms:transform->pose map-T-object))) + `(,type . ,map-P-object)))) + spawning-poses-list))) + +(defun spawn-object-n-times (type pose times color &optional offset-axis offset mass) + "`offset-axis' can be one of :x, :y or :z." + (loop for i from 0 to (1- times) + for name = (intern (string-upcase (format nil "~a-~a" type i)) :keyword) + do (when offset-axis + (setf pose (cram-tf:translate-pose pose offset-axis offset))) + ;; if object with name NAME already exists, create a new unique name + (when (btr:object btr:*current-bullet-world* name) + (setf i (+ i times) + name (intern (string-upcase (format nil "~a-~a" type i)) + :keyword))) + (btr-utils:spawn-object name type + :pose pose :mass (or mass 0.0) :color color))) + +(defun kill-and-detach-all () + (btr-utils:kill-all-objects) + (btr:detach-all-objects (btr:get-robot-object)) + (btr:detach-all-objects (btr:get-environment-object)) + ;; detach all items from each other + (mapcar #'btr:detach-all-objects + (remove-if-not (lambda (obj) (typep obj 'btr:item)) + (btr:objects btr:*current-bullet-world*))) + (btr:clear-costmap-vis-object)) diff --git a/cram_donbot/cram_donbot_process_modules/cram-donbot-process-modules.asd b/cram_donbot/cram_donbot_process_modules/cram-donbot-process-modules.asd index 323f019fb6..1f70c9790f 100644 --- a/cram_donbot/cram_donbot_process_modules/cram-donbot-process-modules.asd +++ b/cram_donbot/cram_donbot_process_modules/cram-donbot-process-modules.asd @@ -43,7 +43,8 @@ cram-bullet-reasoning-belief-state ; for WORLD-STATE-DETECTING cram-robosherlock ; for WITH-REAL-ROBOT - cram-giskard) + cram-giskard + cram-joint-states) :components ((:module "src" :components diff --git a/cram_donbot/cram_donbot_process_modules/package.xml b/cram_donbot/cram_donbot_process_modules/package.xml index 597f51d4ea..751dd5fa76 100644 --- a/cram_donbot/cram_donbot_process_modules/package.xml +++ b/cram_donbot/cram_donbot_process_modules/package.xml @@ -18,4 +18,5 @@ cram_donbot_low_level cram_robosherlock cram_giskard + cram_joint_states diff --git a/cram_donbot/cram_donbot_process_modules/src/definitions.lisp b/cram_donbot/cram_donbot_process_modules/src/definitions.lisp index 72c8616f70..0a4c8f5bf6 100644 --- a/cram_donbot/cram_donbot_process_modules/src/definitions.lisp +++ b/cram_donbot/cram_donbot_process_modules/src/definitions.lisp @@ -41,55 +41,3 @@ :action-type-or-position action-type-or-position :left-or-right which-gripper :effort-but-actually-slippage-parameter effort-but-actually-slippage-param))))) - -;;;;;;;;;;;;;;;;;;;; GISKARD ;;;;;;;;;;;;;;;;;;;;;;;; - -(cpm:def-process-module giskard-pm (motion-designator) - (destructuring-bind (command argument-1 &rest rest-args) - (desig:reference motion-designator) - (ecase command - (cram-common-designators:move-tcp - (giskard:call-arm-cartesian-action - :goal-pose-left argument-1 - :goal-pose-right (first rest-args) - :collision-mode (second rest-args) - :collision-object-b (third rest-args) - :collision-object-b-link (fourth rest-args) - :collision-object-a (fifth rest-args) - :move-base (sixth rest-args) - :prefer-base (seventh rest-args) - :align-planes-left (eighth rest-args) - :align-planes-right (ninth rest-args))) - (cram-common-designators:move-joints - (giskard:call-arm-joint-action - :goal-configuration-left argument-1 - :goal-configuration-right (first rest-args) - :align-planes-left (second rest-args) - :align-planes-right (third rest-args))) - (cram-common-designators:move-arm-pull - (giskard:call-environment-manipulation-action - :open-or-close :open - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-arm-push - (giskard:call-environment-manipulation-action - :open-or-close :close - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-head - (when argument-1 - (giskard:call-neck-action - :goal-pose argument-1)) - (when (car rest-args) - (giskard:call-neck-joint-action - :goal-configuration (car rest-args)))) - (cram-common-designators:move-base - (giskard:call-base-action - :goal-pose argument-1)) - (cram-common-designators:move-torso - (giskard:call-torso-action - :goal-joint-state argument-1))))) diff --git a/cram_donbot/cram_donbot_process_modules/src/interface.lisp b/cram_donbot/cram_donbot_process_modules/src/interface.lisp index e4450dc80e..170e21895e 100644 --- a/cram_donbot/cram_donbot_process_modules/src/interface.lisp +++ b/cram_donbot/cram_donbot_process_modules/src/interface.lisp @@ -37,7 +37,7 @@ (desig:desig-prop ?motion-designator (:type :closing-gripper)) (desig:desig-prop ?motion-designator (:type :moving-gripper-joint)))) - (<- (cpm:matching-process-module ?motion-designator giskard-pm) + (<- (cpm:matching-process-module ?motion-designator giskard:giskard-pm) (or (desig:desig-prop ?motion-designator (:type :moving-tcp)) (desig:desig-prop ?motion-designator (:type :moving-arm-joints)) (desig:desig-prop ?motion-designator (:type :pulling)) @@ -47,16 +47,14 @@ (desig:desig-prop ?motion-designator (:type :looking)))) (<- (cpm:available-process-module ?pm) - (member ?pm (grippers-pm giskard-pm)) - (not (cpm:projection-running ?_))) - - (<- (cpm:available-process-module btr-belief:world-state-detecting-pm))) + (member ?pm (grippers-pm giskard:giskard-pm)) + (not (cpm:projection-running ?_)))) (defmacro with-real-robot (&body body) `(cram-process-modules:with-process-modules-running (donbot-pm:grippers-pm - rs:robosherlock-perception-pm giskard:giskard-pm - btr-belief:world-state-detecting-pm) + rs:robosherlock-perception-pm giskard:giskard-pm joints:joint-state-pm + btr-belief:world-state-detecting-pm common-desig:wait) (cpl-impl::named-top-level (:name :top-level) ,@body))) diff --git a/cram_external_interfaces/cram_giskard/cram-giskard.asd b/cram_external_interfaces/cram_giskard/cram-giskard.asd index 5900386308..02e11fa095 100644 --- a/cram_external_interfaces/cram_giskard/cram-giskard.asd +++ b/cram_external_interfaces/cram_giskard/cram-giskard.asd @@ -60,15 +60,18 @@ ((:module "src" :components ((:file "package") - (:file "action-client" :depends-on ("package")) + (:file "collision-scene" :depends-on ("package")) + (:file "action-client" :depends-on ("package" "collision-scene")) (:file "hash-table-conversions" :depends-on ("package")) (:file "making-goal-messages" :depends-on ("package" "hash-table-conversions")) - (:file "arm-goals" :depends-on ("package" - "action-client" - "making-goal-messages")) (:file "base-goals" :depends-on ("package" "action-client" "making-goal-messages")) + (:file "arm-goals" :depends-on ("package" + "action-client" + "making-goal-messages" + ;; because we constrain base velocity + "base-goals")) (:file "torso-goals" :depends-on ("package" "making-goal-messages" "action-client")) @@ -80,8 +83,18 @@ "action-client")) (:file "environment-manipulation-goals" :depends-on ("package" "making-goal-messages" - "action-client")) + "action-client" + ;; because we + ;; constrain + ;; base velocity + "base-goals")) (:file "misc-goals" :depends-on ("package" "making-goal-messages" "action-client")) - (:file "collision-scene" :depends-on ("package")))))) + (:file "process-module" :depends-on ("package" + "arm-goals" + "base-goals" + "torso-goals" + "gripper-goals" + "neck-goals" + "environment-manipulation-goals")))))) diff --git a/cram_external_interfaces/cram_giskard/src/action-client.lisp b/cram_external_interfaces/cram_giskard/src/action-client.lisp index 2961a8f57b..26208d37bb 100644 --- a/cram_external_interfaces/cram_giskard/src/action-client.lisp +++ b/cram_external_interfaces/cram_giskard/src/action-client.lisp @@ -37,7 +37,6 @@ (roslisp-utilities:register-ros-init-function make-giskard-action-client) - (defun call-action (&key action-goal action-timeout check-goal-function) (declare (type giskard_msgs-msg:movegoal action-goal) (type (or number null) action-timeout) @@ -45,8 +44,9 @@ ;; check if the goal has already been reached (when (and check-goal-function - (not (funcall check-goal-function))) - (roslisp:ros-warn (giskard action-client) "Giskard action already reached.") + (not (funcall check-goal-function nil nil))) + (roslisp:ros-warn (giskard action-client) + "Giskard action goal already reached.") (return-from call-action)) ;; call the actionlib action @@ -68,10 +68,22 @@ (roslisp:ros-warn (giskard cartesian) "Giskard action aborted.~%Result: ~a" result))) + (when (and result + (member (roslisp:symbol-code + 'giskard_msgs-msg:moveresult + :unknown_object) + (map 'list #'identity + (roslisp:msg-slot-value + result + :error_codes)))) + (full-update-collision-scene)) + ;; check if the goal was reached, if not, throw a failure (when check-goal-function - (let ((failure (funcall check-goal-function))) + (let ((failure (funcall check-goal-function result status))) (when failure + (roslisp:ros-warn (giskard action-client) + "Giskard action goal was not reached.") (cpl:fail failure)))) ;; this is only used by HPN: diff --git a/cram_external_interfaces/cram_giskard/src/arm-goals.lisp b/cram_external_interfaces/cram_giskard/src/arm-goals.lisp index 22e7c25b0f..81774b3e34 100644 --- a/cram_external_interfaces/cram_giskard/src/arm-goals.lisp +++ b/cram_external_interfaces/cram_giskard/src/arm-goals.lisp @@ -29,12 +29,16 @@ (in-package :giskard) -(defparameter *arm-convergence-delta-xy* 0.1 ;; 0.005 +(defparameter *arm-convergence-delta-xy* 0.025 ;; 0.005 "in meters") (defparameter *arm-convergence-delta-theta* 0.5 ;; 0.1 "in radiants, about 30 degrees") (defparameter *arm-convergence-delta-joint* 0.17 "in radiants, about 10 degrees") +(defparameter *arm-max-velocity-slow-xy* 0.1 + "in m/s") +(defparameter *arm-max-velocity-slow-theta* 0.5 + "in rad/s") (defun make-arm-cartesian-action-goal (left-pose right-pose pose-base-frame collision-mode @@ -54,7 +58,8 @@ (make-giskard-goal :constraints (list (make-avoid-joint-limits-constraint) - (when prefer-base (make-prefer-base-constraint)) + (when prefer-base + (make-prefer-base-constraint)) ;; (when align-planes-left ;; (make-align-planes-constraint ;; pose-base-frame @@ -75,8 +80,14 @@ ;; (cl-transforms-stamped:make-vector-stamped ;; cram-tf:*robot-base-frame* 0.0 ;; (cl-transforms:make-3d-vector 0 0 1)))) - (when unmovable-joints (make-unmovable-joints-constraint - unmovable-joints))) + (when unmovable-joints + (make-unmovable-joints-constraint unmovable-joints)) + (make-base-velocity-constraint + *base-max-velocity-slow-xy* *base-max-velocity-slow-theta*) + (make-head-pointing-at-hand-constraint + (if left-pose + :left + :right))) :cartesian-constraints (list (when left-pose (make-simple-cartesian-constraint pose-base-frame @@ -88,56 +99,88 @@ cram-tf:*robot-right-tool-frame* right-pose))) :collisions (ecase collision-mode - (:avoid-all (make-avoid-all-collision 0.1)) + (:avoid-all nil;; (make-avoid-all-collision) + ) (:allow-all (make-allow-all-collision)) - (:allow-hand (list (make-avoid-all-collision 0.05) + (:allow-hand (list ;; (make-avoid-all-collision) (make-allow-hand-collision arms collision-object-b collision-object-b-link) (make-allow-hand-collision arms (rob-int:get-environment-name)))) - (:allow-arm (list (make-avoid-all-collision 0.05) + (:allow-fingers (list ;; (make-avoid-all-collision) + (make-allow-fingers-collision + arms collision-object-b + collision-object-b-link) + (make-allow-fingers-collision + arms (rob-int:get-environment-name)))) + (:allow-arm (list ;; (make-avoid-all-collision) (make-allow-arm-collision arms collision-object-b collision-object-b-link) (make-allow-arm-collision arms (rob-int:get-environment-name)))) - (:allow-attached (list (make-avoid-all-collision 0.02) + (:allow-attached (list ;; (make-avoid-all-collision) (make-allow-attached-collision collision-object-a collision-object-b-link))))))) (defun make-arm-joint-action-goal (joint-state-left joint-state-right - align-planes-left align-planes-right) + align-planes-left align-planes-right + &key try-harder) (declare (type list joint-state-left joint-state-right) (type boolean align-planes-left align-planes-right)) (make-giskard-goal :constraints (list - (make-avoid-joint-limits-constraint) - ;; (when align-planes-left - ;; (make-align-planes-constraint - ;; cram-tf:*odom-frame* - ;; "refills_finger" - ;; (cl-transforms-stamped:make-vector-stamped - ;; cram-tf:*robot-base-frame* 0.0 - ;; (cl-transforms:make-3d-vector 0 0 1)) - ;; (cl-transforms-stamped:make-vector-stamped - ;; cram-tf:*robot-base-frame* 0.0 - ;; (cl-transforms:make-3d-vector 0 0 1)))) - ;; (when align-planes-right - ;; (make-align-planes-constraint - ;; cram-tf:*odom-frame* - ;; "refills_finger" - ;; (cl-transforms-stamped:make-vector-stamped - ;; cram-tf:*robot-base-frame* 0.0 - ;; (cl-transforms:make-3d-vector 0 0 1)) - ;; (cl-transforms-stamped:make-vector-stamped - ;; cram-tf:*robot-base-frame* 0.0 - ;; (cl-transforms:make-3d-vector 0 0 1)))) - ) + (make-ee-velocity-constraint + :left + (if try-harder + (/ *arm-max-velocity-slow-xy* 3.0) + *arm-max-velocity-slow-xy*) + (if try-harder + (/ *arm-max-velocity-slow-theta* 3.0) + *arm-max-velocity-slow-theta*)) + (make-ee-velocity-constraint + :right + (if try-harder + (/ *arm-max-velocity-slow-xy* 3.0) + *arm-max-velocity-slow-xy*) + (if try-harder + (/ *arm-max-velocity-slow-theta* 3.0) + *arm-max-velocity-slow-theta*)) + (make-cartesian-constraint + cram-tf:*odom-frame* cram-tf:*robot-base-frame* + (cl-transforms-stamped:pose->pose-stamped + cram-tf:*robot-base-frame* 0.0 + (cl-transforms:make-identity-pose)) + :max-velocity *base-max-velocity-slow-xy* + :avoid-collisions-much t) + ;; (make-base-velocity-constraint + ;; *base-max-velocity-slow-xy* + ;; *base-max-velocity-slow-theta*) + ;; (make-avoid-joint-limits-constraint) + (when align-planes-left + (make-align-planes-tool-frame-constraint + :left + (cl-transforms-stamped:make-vector-stamped + cram-tf:*robot-base-frame* 0.0 + (cl-transforms:make-3d-vector 0 0 1)) + (cl-transforms-stamped:make-vector-stamped + cram-tf:*robot-base-frame* 0.0 + (cl-transforms:make-3d-vector 0 0 1)))) + (when align-planes-right + (make-align-planes-tool-frame-constraint + :right + (cl-transforms-stamped:make-vector-stamped + cram-tf:*robot-base-frame* 0.0 + (cl-transforms:make-3d-vector 0 0 1)) + (cl-transforms-stamped:make-vector-stamped + cram-tf:*robot-base-frame* 0.0 + (cl-transforms:make-3d-vector 0 0 1))))) :joint-constraints (list (make-simple-joint-constraint joint-state-left) (make-simple-joint-constraint joint-state-right)) - :collisions (make-avoid-all-collision))) + :collisions (list ;; (make-avoid-all-collision) + ))) @@ -155,20 +198,19 @@ goal-configuration) (get-arm-joint-names-and-positions-list arm)))) - - (defun ensure-arm-cartesian-goal-reached (goal-pose goal-frame) (when goal-pose - (unless (cram-tf:tf-frame-converged - goal-frame goal-pose - *arm-convergence-delta-xy* *arm-convergence-delta-theta*) - (make-instance 'common-fail:manipulation-goal-not-reached - :description (format nil "Giskard did not converge to goal:~%~ - ~a should have been at ~a ~ - with delta-xy of ~a and delta-angle of ~a." - goal-frame goal-pose - *arm-convergence-delta-xy* - *arm-convergence-delta-theta*))))) + (multiple-value-bind (converged delta-xy delta-theta) + (cram-tf:tf-frame-converged + goal-frame goal-pose + *arm-convergence-delta-xy* *arm-convergence-delta-theta*) + (unless converged + (make-instance 'common-fail:manipulation-goal-not-reached + :description (format nil "Giskard did not converge to goal:~%~ + ~a should have been at ~a.~% + Delta-xy: ~a, delta-theta: ~a." + goal-frame goal-pose + delta-xy delta-theta)))))) (defun ensure-arm-joint-goal-reached (goal-configuration arm) (when goal-configuration @@ -238,7 +280,8 @@ :align-planes-right align-planes-right :unmovable-joints unmovable-joints) :action-timeout action-timeout - :check-goal-function (lambda () + :check-goal-function (lambda (result status) + (declare (ignore result status)) (or (ensure-arm-cartesian-goal-reached goal-pose-left cram-tf:*robot-left-tool-frame*) (ensure-arm-cartesian-goal-reached @@ -249,9 +292,11 @@ (defun call-arm-joint-action (&key action-timeout goal-configuration-left goal-configuration-right - align-planes-left align-planes-right) + align-planes-left align-planes-right + avoid-collisions-not-much) (declare (type (or list null) goal-configuration-left goal-configuration-right) - (type (or number null) action-timeout)) + (type (or number null) action-timeout) + (type boolean avoid-collisions-not-much)) (let ((joint-state-left (ensure-arm-joint-goal-input goal-configuration-left :left)) @@ -261,9 +306,11 @@ (call-action :action-goal (make-arm-joint-action-goal joint-state-left joint-state-right - align-planes-left align-planes-right) + align-planes-left align-planes-right + :try-harder avoid-collisions-not-much) :action-timeout action-timeout - :check-goal-function (lambda () + :check-goal-function (lambda (result status) + (declare (ignore result status)) (or (ensure-arm-joint-goal-reached goal-configuration-left :left) (ensure-arm-joint-goal-reached diff --git a/cram_external_interfaces/cram_giskard/src/base-goals.lisp b/cram_external_interfaces/cram_giskard/src/base-goals.lisp index 1b0197c175..9d208c47d2 100644 --- a/cram_external_interfaces/cram_giskard/src/base-goals.lisp +++ b/cram_external_interfaces/cram_giskard/src/base-goals.lisp @@ -29,16 +29,52 @@ (in-package :giskard) -(defparameter *base-convergence-delta-xy* 0.05 "in meters") -(defparameter *base-convergence-delta-theta* 0.1 "in radiants, about 6 degrees.") +(defparameter *base-convergence-delta-xy* + 0.05 "in meters.") +(defparameter *base-convergence-delta-theta* + 0.1 "in radiants, about 6 degrees.") +(defparameter *base-collision-avoidance-distance* + 0.2 "In meters.") +(defparameter *base-collision-avoidance-hint-vector* + (cl-transforms:make-3d-vector 0 -1 0)) +(defparameter *base-collision-avoidance-hint-link* + "kitchen_island" "A link name from the environment URDF.") +(defparameter *base-max-velocity-fast-xy* + ;; 0.5 + 0.25 "In meters/s") +(defparameter *base-max-velocity-fast-theta* + 0.4 "In rad/s, about 23 deg/s.") +(defparameter *base-max-velocity-slow-xy* + 0.04 "In meters/s") +(defparameter *base-max-velocity-slow-theta* + 0.07 "In rad/s, about 11.5 deg.") -(defun make-giskard-base-action-goal (pose) - (declare (type cl-transforms-stamped:pose-stamped pose)) +(defun make-giskard-base-action-goal (pose base-velocity) + (declare (type cl-transforms-stamped:pose-stamped pose) + (type (or keyword number null) base-velocity)) (make-giskard-goal - :cartesian-constraints (make-simple-cartesian-constraint - cram-tf:*odom-frame* cram-tf:*robot-base-frame* pose) + :constraints (list + (make-cartesian-constraint + cram-tf:*odom-frame* cram-tf:*robot-base-frame* pose + :avoid-collisions-much t + :max-velocity *base-max-velocity-fast-xy*) + (make-base-collision-avoidance-hint-constraint + *base-collision-avoidance-hint-link* + (cl-transforms-stamped:make-vector-stamped + cram-tf:*fixed-frame* 0.0 + *base-collision-avoidance-hint-vector*)) + (if (eq base-velocity :slow) + (make-base-velocity-constraint + *base-max-velocity-slow-xy* *base-max-velocity-slow-theta*) + (make-base-velocity-constraint + *base-max-velocity-fast-xy* *base-max-velocity-fast-theta*)) + (make-head-pointing-constraint + (cl-transforms-stamped:make-pose-stamped + cram-tf:*robot-base-frame* 0.0 + (cl-transforms:make-3d-vector 1 0 0) + (cl-transforms:make-identity-rotation)))) :joint-constraints (make-current-joint-state-constraint '(:left :right)) - :collisions (make-avoid-all-collision))) + :collisions (make-avoid-all-collision *base-collision-avoidance-distance*))) (defun ensure-base-goal-input (pose) (cram-tf:ensure-pose-in-frame pose cram-tf:*fixed-frame*)) @@ -55,8 +91,9 @@ *base-convergence-delta-xy* *base-convergence-delta-theta*)))) -(defun call-base-action (&key action-timeout goal-pose) +(defun call-base-action (&key action-timeout goal-pose base-velocity) (declare (type cl-transforms-stamped:pose-stamped goal-pose) + (type (or keyword number null) base-velocity) (type (or null number) action-timeout)) (setf goal-pose (ensure-base-goal-input goal-pose)) @@ -64,6 +101,8 @@ (cram-tf:visualize-marker goal-pose :r-g-b-list '(0 1 0)) (call-action - :action-goal (make-giskard-base-action-goal goal-pose) + :action-goal (make-giskard-base-action-goal goal-pose base-velocity) :action-timeout action-timeout - :check-goal-function (lambda () (ensure-base-goal-reached goal-pose)))) + :check-goal-function (lambda (result status) + (declare (ignore result status)) + (ensure-base-goal-reached goal-pose)))) diff --git a/cram_external_interfaces/cram_giskard/src/collision-scene.lisp b/cram_external_interfaces/cram_giskard/src/collision-scene.lisp index a699a95de6..f32e62f3a7 100644 --- a/cram_external_interfaces/cram_giskard/src/collision-scene.lisp +++ b/cram_external_interfaces/cram_giskard/src/collision-scene.lisp @@ -73,6 +73,7 @@ &key name pose + mesh-path dimensions joint-state-topic) (declare (type keyword add-or-remove-or-attach-or-detach) @@ -86,79 +87,87 @@ (cl-transforms:make-identity-rotation)))) (unless dimensions (setf dimensions '(1.0 1.0 1.0))) - (ecase add-or-remove-or-attach-or-detach - (:add - (roslisp:make-request - 'giskard_msgs-srv:updateworld - :operation (roslisp:symbol-code - 'giskard_msgs-srv:updateworld-request - :add) - :rigidly_attached nil - :body (roslisp:make-msg - 'giskard_msgs-msg:worldbody - :type (roslisp:symbol-code - 'giskard_msgs-msg:worldbody - :primitive_body) - :name name - :shape (roslisp:make-msg - 'shape_msgs-msg:solidprimitive - :type (roslisp:symbol-code 'shape_msgs-msg:solidprimitive :box) - :dimensions (map 'vector #'identity dimensions))) - :pose (cl-transforms-stamped:to-msg pose))) - (:add-environment - (roslisp:make-request - 'giskard_msgs-srv:updateworld - :operation (roslisp:symbol-code - 'giskard_msgs-srv:updateworld-request - :add) - :rigidly_attached nil - :body (roslisp:make-msg - 'giskard_msgs-msg:worldbody - :type (roslisp:symbol-code - 'giskard_msgs-msg:worldbody - :urdf_body) - :name name - :urdf (roslisp:get-param rob-int:*environment-description-parameter* nil) - :joint_state_topic joint-state-topic) - :pose (cl-transforms-stamped:to-msg pose))) - (:remove - (roslisp:make-request - 'giskard_msgs-srv:updateworld - :operation (roslisp:symbol-code - 'giskard_msgs-srv:updateworld-request - :remove) - :body (roslisp:make-msg 'giskard_msgs-msg:worldbody :name name))) - (:remove-all - (roslisp:make-request - 'giskard_msgs-srv:updateworld - :operation (roslisp:symbol-code - 'giskard_msgs-srv:updateworld-request - :remove_all))) - (:attach - (roslisp:make-request - 'giskard_msgs-srv:updateworld - :operation (roslisp:symbol-code - 'giskard_msgs-srv:updateworld-request - :add) - :rigidly_attached t - :body (roslisp:make-msg - 'giskard_msgs-msg:worldbody - :type (roslisp:symbol-code - 'giskard_msgs-msg:worldbody - :primitive_body) - :name name - :shape (roslisp:make-msg - 'shape_msgs-msg:solidprimitive - :type (roslisp:symbol-code 'shape_msgs-msg:solidprimitive :box) - :dimensions (map 'vector #'identity dimensions))) - :pose (cl-transforms-stamped:to-msg pose))) - (:detach - (roslisp:make-request - 'giskard_msgs-srv:updateworld - :operation (roslisp:symbol-code - 'giskard_msgs-srv:updateworld-request - :detach) - :body (roslisp:make-msg 'giskard_msgs-msg:worldbody :name name))))) + (let ((body (if mesh-path + (roslisp:make-msg + 'giskard_msgs-msg:worldbody + :type (roslisp:symbol-code + 'giskard_msgs-msg:worldbody + :mesh_body) + :name name + :mesh mesh-path) + (roslisp:make-msg + 'giskard_msgs-msg:worldbody + :type (roslisp:symbol-code + 'giskard_msgs-msg:worldbody + :primitive_body) + :name name + :shape (roslisp:make-msg + 'shape_msgs-msg:solidprimitive + :type (roslisp:symbol-code 'shape_msgs-msg:solidprimitive :box) + :dimensions (map 'vector #'identity dimensions))) ))) + (ecase add-or-remove-or-attach-or-detach + (:add + (roslisp:make-request + 'giskard_msgs-srv:updateworld + :operation (roslisp:symbol-code + 'giskard_msgs-srv:updateworld-request + :add) + :rigidly_attached nil + :body body + :pose (cl-transforms-stamped:to-msg pose))) + (:alter + (roslisp:make-request + 'giskard_msgs-srv:updateworld + :operation (roslisp:symbol-code + 'giskard_msgs-srv:updateworld-request + :alter) + :body body + :pose (cl-transforms-stamped:to-msg pose))) + (:add-environment + (roslisp:make-request + 'giskard_msgs-srv:updateworld + :operation (roslisp:symbol-code + 'giskard_msgs-srv:updateworld-request + :add) + :rigidly_attached nil + :body (roslisp:make-msg + 'giskard_msgs-msg:worldbody + :type (roslisp:symbol-code + 'giskard_msgs-msg:worldbody + :urdf_body) + :name name + :urdf (roslisp:get-param rob-int:*environment-description-parameter* nil) + :joint_state_topic joint-state-topic) + :pose (cl-transforms-stamped:to-msg pose))) + (:remove + (roslisp:make-request + 'giskard_msgs-srv:updateworld + :operation (roslisp:symbol-code + 'giskard_msgs-srv:updateworld-request + :remove) + :body (roslisp:make-msg 'giskard_msgs-msg:worldbody :name name))) + (:remove-all + (roslisp:make-request + 'giskard_msgs-srv:updateworld + :operation (roslisp:symbol-code + 'giskard_msgs-srv:updateworld-request + :remove_all))) + (:attach + (roslisp:make-request + 'giskard_msgs-srv:updateworld + :operation (roslisp:symbol-code + 'giskard_msgs-srv:updateworld-request + :add) + :rigidly_attached t + :body body + :pose (cl-transforms-stamped:to-msg pose))) + (:detach + (roslisp:make-request + 'giskard_msgs-srv:updateworld + :operation (roslisp:symbol-code + 'giskard_msgs-srv:updateworld-request + :detach) + :body (roslisp:make-msg 'giskard_msgs-msg:worldbody :name name)))))) (defun ensure-giskard-environment-service-input-parameters () ) @@ -168,7 +177,8 @@ (defun call-giskard-environment-service (add-or-remove-or-attach-or-detach - &key name pose dimensions joint-state-topic) + &key name pose dimensions mesh-path + joint-state-topic) (ensure-giskard-environment-service-input-parameters) (cpl:with-failure-handling @@ -183,16 +193,30 @@ (cpl:retry))))) (let ((service (get-giskard-environment-service))) (if service - (roslisp:msg-slot-value - (roslisp:call-persistent-service - service - (make-giskard-environment-request - add-or-remove-or-attach-or-detach - :name name - :pose pose - :dimensions dimensions - :joint-state-topic joint-state-topic)) - 'giskard_msgs-srv:error_msg) + (when (string-equal + (roslisp:msg-slot-value + (roslisp:call-persistent-service + service + (make-giskard-environment-request + add-or-remove-or-attach-or-detach + :name name + :pose pose + :mesh-path mesh-path + :dimensions dimensions + :joint-state-topic joint-state-topic)) + 'giskard_msgs-srv:error_msg) + "Cannot load URDF file.") + (roslisp:msg-slot-value + (roslisp:call-persistent-service + service + (make-giskard-environment-request + add-or-remove-or-attach-or-detach + :name name + :pose pose + :mesh-path nil + :dimensions dimensions + :joint-state-topic joint-state-topic)) + 'giskard_msgs-srv:error_msg)) nil)))) ;;;;;;;;;;;;;;;;;;;;;;;; UTILS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -209,67 +233,135 @@ cram-tf:*fixed-frame* 0.0 (btr:pose (btr:get-environment-object))) :joint-state-topic "kitchen/joint_states"))) -;;;;;;;;;;;;;;;;;;;;;;;; EVENT HANDLERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defmethod coe:on-event giskard-attach-object ((event cpoe:object-attached-robot)) - (unless cram-projection:*projection-environment* - (let* ((arm - (cpoe:event-arm event)) - (object-name - (cpoe:event-object-name event)) - (object-name-string +(defun update-object-pose-in-collision-scene (object-name) + (when object-name + (let* ((object-name-string (roslisp-utilities:rosify-underscores-lisp-name object-name)) (btr-object - (btr:object btr:*current-bullet-world* object-name)) - (link (if (cpoe:event-arm event) - (cut:var-value - '?ee-link - (car (prolog:prolog - `(and (rob-int:robot ?robot) - (rob-int:end-effector-link ?robot ,arm ?ee-link))))) - (cpoe:event-link event)))) - - (when (cut:is-var link) - (error "[GISKARD OBJECT-ATTACHED] Couldn't find robot's EE link.")) - (unless btr-object - (error "[GISKARD OBJECT-ATTACHED] there was no corresponding btr object.")) + (btr:object btr:*current-bullet-world* object-name))) + (call-giskard-environment-service + :alter + :name object-name-string + :pose (cl-transforms-stamped:pose->pose-stamped + cram-tf:*fixed-frame* 0.0 (btr:pose btr-object)) + :mesh-path (when btr-object + (second (assoc (car (btr:item-types btr-object)) + btr::*mesh-files*))) + :dimensions (with-slots (cl-transforms:x cl-transforms:y cl-transforms:z) + (btr:calculate-bb-dims btr-object) + (list cl-transforms:x cl-transforms:y cl-transforms:z)))))) - ;; TODO: hack for pivoting!! - (when (string-equal link "ur5_wrist_3_link") - (setf link "refills_finger")) +(defun add-object-to-collision-scene (object-name) + (let* ((object-name-string + (roslisp-utilities:rosify-underscores-lisp-name object-name)) + (btr-object + (btr:object btr:*current-bullet-world* object-name)) + (robot-links-object-is-attached-to + (btr:object-attached (btr:get-robot-object) btr-object))) + ;; to update an object pose, first remove the old object together with the pose + (call-giskard-environment-service + :remove + :name object-name-string) + ;; add it at the new perceived pose + (call-giskard-environment-service + :add + :name object-name-string + :pose (cl-transforms-stamped:pose->pose-stamped + cram-tf:*fixed-frame* 0.0 (btr:pose btr-object)) + :mesh-path (when btr-object + (second (assoc (car (btr:item-types btr-object)) + btr::*mesh-files*))) + :dimensions (with-slots (cl-transforms:x cl-transforms:y cl-transforms:z) + (btr:calculate-bb-dims btr-object) + (list cl-transforms:x cl-transforms:y cl-transforms:z))) + ;; reattach the object if it was attached somewhere + (when robot-links-object-is-attached-to + (let* ((link (car robot-links-object-is-attached-to)) + (map-to-link-transform + (cl-transforms-stamped:lookup-transform + cram-tf:*transformer* + cram-tf:*fixed-frame* + link + :timeout cram-tf:*tf-default-timeout* + :time 0)) + (link-to-map-transform + (cram-tf:transform-stamped-inv map-to-link-transform)) + (map-to-obj-transform + (cram-tf:pose->transform-stamped + cram-tf:*fixed-frame* + object-name-string + 0.0 + (btr:pose btr-object))) + (link-to-object-transform + (cram-tf:multiply-transform-stampeds + link object-name-string + link-to-map-transform map-to-obj-transform)) + (link-to-object-pose + (cram-tf:strip-transform-stamped link-to-object-transform))) + (call-giskard-environment-service + :attach + :name object-name-string + :pose link-to-object-pose + :mesh-path (when btr-object + (second (assoc (car (btr:item-types btr-object)) + btr::*mesh-files*))) + :dimensions (with-slots (cl-transforms:x cl-transforms:y cl-transforms:z) + (btr:calculate-bb-dims btr-object) + (list cl-transforms:x cl-transforms:y cl-transforms:z))))))) - (let* ((map-to-ee-transform (cl-transforms-stamped:lookup-transform - cram-tf:*transformer* - cram-tf:*fixed-frame* - link - :timeout cram-tf:*tf-default-timeout* - :time 0)) - (ee-to-map-transform (cram-tf:transform-stamped-inv map-to-ee-transform)) - (map-to-obj-transform (cram-tf:pose->transform-stamped - cram-tf:*fixed-frame* - object-name-string - 0.0 - (btr:pose btr-object))) - (ee-to-object-transform (cram-tf:multiply-transform-stampeds - link object-name-string - ee-to-map-transform map-to-obj-transform)) - (ee-to-object-pose (cram-tf:strip-transform-stamped ee-to-object-transform))) - ;; TODO: another hack for pivoting!! - ;; take the object pose just directly from TF, - ;; giskard is publishing the tf frame - ;; giskard only publishes TF for attached objects, - ;; not the other objects in the collision scene - (handler-case - (setf ee-to-object-pose - (cram-tf:strip-transform-stamped - (cl-transforms-stamped:lookup-transform - cram-tf:*transformer* - link - object-name-string - :timeout cram-tf:*tf-default-timeout* - :time (roslisp:ros-time)))) - (cl-transforms-stamped:transform-stamped-error ())) +(defun detach-object-in-collision-scene (object-name) + (let* ((object-name-string + (roslisp-utilities:rosify-underscores-lisp-name object-name)) + (btr-object + (btr:object btr:*current-bullet-world* object-name))) + (when btr-object + (let ((attached-to-another-link-as-well? + (> (length + (btr:object-name-attached-links + (btr:get-robot-object) + object-name)) + 1))) + (unless attached-to-another-link-as-well? + (call-giskard-environment-service + :detach + :name object-name-string)))))) +(defun attach-object-to-arm-in-collision-scene (object-name arm link) + (let* ((object-name-string + (roslisp-utilities:rosify-underscores-lisp-name object-name)) + (btr-object + (btr:object btr:*current-bullet-world* object-name)) + (link (if arm + (cut:var-value + '?ee-link + (car (prolog:prolog + `(and (rob-int:robot ?robot) + (rob-int:end-effector-link ?robot ,arm ?ee-link))))) + link))) + (when (cut:is-var link) + (error "[GISKARD OBJECT-ATTACHED] Couldn't find robot's EE link.")) + (when btr-object + (let* ((map-to-ee-transform + (cl-transforms-stamped:lookup-transform + cram-tf:*transformer* + cram-tf:*fixed-frame* + link + :timeout cram-tf:*tf-default-timeout* + :time 0)) + (ee-to-map-transform + (cram-tf:transform-stamped-inv map-to-ee-transform)) + (map-to-obj-transform + (cram-tf:pose->transform-stamped + cram-tf:*fixed-frame* + object-name-string + 0.0 + (btr:pose btr-object))) + (ee-to-object-transform + (cram-tf:multiply-transform-stampeds + link object-name-string + ee-to-map-transform map-to-obj-transform)) + (ee-to-object-pose + (cram-tf:strip-transform-stamped ee-to-object-transform))) ;; remove the object first, maybe it was already attached to something (call-giskard-environment-service :remove @@ -278,81 +370,78 @@ :attach :name object-name-string :pose ee-to-object-pose + :mesh-path (when btr-object + (second (assoc (car (btr:item-types btr-object)) + btr::*mesh-files*))) :dimensions (with-slots (cl-transforms:x cl-transforms:y cl-transforms:z) (btr:calculate-bb-dims btr-object) (list cl-transforms:x cl-transforms:y cl-transforms:z))))))) -(defmethod coe:on-event giskard-detach-object ((event cpoe:object-detached-robot)) +(defun full-update-collision-scene () + (mapcar (lambda (object) + (when (typep object 'btr:item) + (let ((object-name (btr:name object))) + (add-object-to-collision-scene object-name) + (when (btr:object-attached + (btr:get-robot-object) + (btr:object btr:*current-bullet-world* object-name)) + (attach-object-to-arm-in-collision-scene + object-name + nil + (car (btr:object-name-attached-links + (btr:get-robot-object) + object-name))))))) + (btr:objects btr:*current-bullet-world*))) + +;;;;;;;;;;;;;;;;;;;;;;;; EVENT HANDLERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defmethod coe:clear-belief giskard-clear () (unless cram-projection:*projection-environment* - (let* ((object-name - (cpoe:event-object-name event)) - (object-name-string - (roslisp-utilities:rosify-underscores-lisp-name object-name)) - (btr-object - (btr:object btr:*current-bullet-world* object-name))) - (when btr-object - (let ((attached-to-another-link-as-well? - (btr:object-attached (btr:get-robot-object) btr-object))) - (unless attached-to-another-link-as-well? - (call-giskard-environment-service - :detach - :name object-name-string))))))) + (reset-collision-scene))) + +(defmethod coe:on-event giskard-attach-object ((event cpoe:object-attached-robot)) + (unless cram-projection:*projection-environment* + (attach-object-to-arm-in-collision-scene + (cpoe:event-object-name event) + (cpoe:event-arm event) + (cpoe:event-link event)))) + +(defmethod coe:on-event giskard-detach-object 1 ((event cpoe:object-detached-robot)) + (unless cram-projection:*projection-environment* + (let ((object-name (cpoe:event-object-name event))) + (if object-name + ;; if object-name is given, detach given object + (detach-object-in-collision-scene object-name) + ;; otherwise detach all objects from the given arm + (let* ((arm + (cpoe:event-arm event)) + (link + (if arm + (cut:var-value + '?link + (car + (prolog:prolog + `(and (rob-int:robot ?rob) + (rob-int:end-effector-link ?rob ,arm ?link))))) + (cpoe:event-link event)))) + (unless (cut:is-var link) + (mapcar #'detach-object-in-collision-scene + (btr:link-attached-object-names + (btr:get-robot-object) + link)))))))) + +(defmethod coe:on-event giskard-detach-object-after 3 ((event cpoe:object-detached-robot)) + (unless cram-projection:*projection-environment* + (update-object-pose-in-collision-scene (cpoe:event-object-name event)))) (defmethod coe:on-event giskard-perceived ((event cpoe:object-perceived-event)) (unless cram-projection:*projection-environment* - (let* ((object-name - (desig:desig-prop-value (cpoe:event-object-designator event) :name)) - (object-name-string - (roslisp-utilities:rosify-underscores-lisp-name object-name)) - (btr-object - (btr:object btr:*current-bullet-world* object-name)) - (robot-links-object-is-attached-to - (btr:object-attached (btr:get-robot-object) btr-object))) - ;; to update an object pose, first remove the old object together with the pose - (call-giskard-environment-service - :remove - :name object-name-string) - ;; add it at the new perceived pose - (call-giskard-environment-service - :add - :name object-name-string - :pose (cl-transforms-stamped:pose->pose-stamped - cram-tf:*fixed-frame* 0.0 (btr:pose btr-object)) - :dimensions (with-slots (cl-transforms:x cl-transforms:y cl-transforms:z) - (btr:calculate-bb-dims btr-object) - (list cl-transforms:x cl-transforms:y cl-transforms:z))) - ;; reattach the object if it was attached somewhere - (when robot-links-object-is-attached-to - (let* ((link (car robot-links-object-is-attached-to)) - (map-to-link-transform - (cl-transforms-stamped:lookup-transform - cram-tf:*transformer* - cram-tf:*fixed-frame* - link - :timeout cram-tf:*tf-default-timeout* - :time 0)) - (link-to-map-transform - (cram-tf:transform-stamped-inv map-to-link-transform)) - (map-to-obj-transform - (cram-tf:pose->transform-stamped - cram-tf:*fixed-frame* - object-name-string - 0.0 - (btr:pose btr-object))) - (link-to-object-transform - (cram-tf:multiply-transform-stampeds - link object-name-string - link-to-map-transform map-to-obj-transform)) - (link-to-object-pose - (cram-tf:strip-transform-stamped link-to-object-transform))) - (call-giskard-environment-service - :attach - :name object-name-string - :pose link-to-object-pose - :dimensions (with-slots (cl-transforms:x cl-transforms:y cl-transforms:z) - (btr:calculate-bb-dims btr-object) - (list cl-transforms:x cl-transforms:y cl-transforms:z)))))))) + (add-object-to-collision-scene + (desig:desig-prop-value (cpoe:event-object-designator event) :name)))) -(defmethod coe:clear-belief giskard-clear () +(defmethod cram-occasions-events:on-event giskard-env 3 ((event cpoe:environment-manipulation-event)) (unless cram-projection:*projection-environment* - (reset-collision-scene))) + (mapcar (lambda (attachment-info) + (update-object-pose-in-collision-scene (car attachment-info))) + (btr:attached-objects (btr:get-environment-object))))) + diff --git a/cram_external_interfaces/cram_giskard/src/environment-manipulation-goals.lisp b/cram_external_interfaces/cram_giskard/src/environment-manipulation-goals.lisp index e673d307e3..ff5b6ba781 100644 --- a/cram_external_interfaces/cram_giskard/src/environment-manipulation-goals.lisp +++ b/cram_external_interfaces/cram_giskard/src/environment-manipulation-goals.lisp @@ -36,18 +36,48 @@ (type symbol handle-link) (type (or number null) joint-state) (type boolean prefer-base)) + ;; (make-giskard-goal-multiple + ;; :all-constraints (mapcar + ;; (lambda (joint-state) + ;; (list + ;; (when prefer-base (make-prefer-base-constraint)) + ;; (make-open-or-close-constraint + ;; open-or-close arm handle-link joint-state) + ;; (make-base-velocity-constraint + ;; *base-max-velocity-slow-xy* + ;; *base-max-velocity-slow-theta*) + ;; (make-avoid-joint-limits-constraint) + ;; (make-head-pointing-at-hand-constraint arm))) + ;; (list (/ joint-state 2) joint-state)) + ;; :collisions (make-constraints-vector + ;; ;; (make-avoid-all-collision) + ;; (append + ;; (make-allow-collision-with-environment-attachments) + ;; (list + ;; (ecase open-or-close + ;; (:open (make-allow-hand-collision + ;; (list arm) (rob-int:get-environment-name) handle-link)) + ;; (:close (make-allow-arm-collision + ;; (list arm) (rob-int:get-environment-name)))))))) (make-giskard-goal :constraints (list (when prefer-base (make-prefer-base-constraint)) (make-open-or-close-constraint - open-or-close arm handle-link joint-state)) + open-or-close arm handle-link joint-state) + (make-base-velocity-constraint + *base-max-velocity-slow-xy* *base-max-velocity-slow-theta*) + (make-avoid-joint-limits-constraint) + (make-head-pointing-at-hand-constraint arm)) :collisions (make-constraints-vector - (make-avoid-all-collision 0.05) - (ecase open-or-close - (:open (make-allow-hand-collision - (list arm) (rob-int:get-environment-name) handle-link)) - (:close (make-allow-arm-collision - (list arm) (rob-int:get-environment-name))))))) + ;; (make-avoid-all-collision) + (append + (make-allow-collision-with-environment-attachments) + (list + (ecase open-or-close + (:open (make-allow-hand-collision + (list arm) (rob-int:get-environment-name) handle-link)) + (:close (make-allow-arm-collision + (list arm) (rob-int:get-environment-name))))))))) (defun call-environment-manipulation-action (&key action-timeout @@ -59,123 +89,27 @@ (type (or number null) joint-angle action-timeout) (type boolean prefer-base)) - (call-action - :action-goal (make-environment-manipulation-goal - open-or-close arm handle-link joint-angle prefer-base) - :action-timeout action-timeout)) - - -#+the-plan -( - (setf (btr:joint-state (btr:get-environment-object) "iai_fridge_door_joint") - 0.0) - (btr-belief::publish-environment-joint-state - (btr:joint-states (btr:get-environment-object))) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type parking-arms)))) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type releasing) - (gripper right)))) - (giskard::call-grasp-bar-action :arm :right :bar-length 0.8) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type gripping) - (gripper right)))) - (giskard::call-environment-manipulation-action :open-or-close :open - :arm :right - :handle-link :iai-fridge-door-handle) - (giskard:call-giskard-cartesian-action - :goal-pose-right (cl-transforms-stamped:make-pose-stamped "r_gripper_tool_frame" 0.0 (cl-transforms:make-3d-vector -0.1 0 0) (cl-transforms:make-identity-rotation)) - :collision-mode :allow-all) - (coe:on-event (make-instance 'cpoe:robot-state-changed)) - (setf (btr:joint-state (btr:get-environment-object) - "iai_fridge_door_joint") 1.45) - (btr-belief::publish-environment-joint-state - (btr:joint-states (btr:get-environment-object))) - (giskard::call-environment-manipulation-action :open-or-close :close - :arm :right - :handle-link :iai-fridge-door-handle) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type releasing) - (gripper right)))) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type parking-arms)))) - (setf (btr:joint-state (btr:get-environment-object) "iai_fridge_door_joint") - 0.0) - (btr-belief::publish-environment-joint-state - (btr:joint-states (btr:get-environment-object))) - ) - -#+the-dishwasher-plan -( - (setf (btr:joint-state (btr:get-environment-object) - "sink_area_dish_washer_door_joint") - 0.0) - (btr-belief::publish-environment-joint-state - (btr:joint-states (btr:get-environment-object))) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type parking-arms)))) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type releasing) - (gripper right)))) - (giskard::call-grasp-bar-action - :arm :right - :bar-axis (cl-transforms-stamped:make-vector-stamped - "iai_kitchen/sink_area_dish_washer_door_handle" 0.0 - (cl-transforms:make-3d-vector 0 1 0)) - :bar-perpendicular-axis - (cl-transforms-stamped:make-vector-stamped - "iai_kitchen/sink_area_dish_washer_door_handle" 0.0 - (cl-transforms:make-3d-vector 0 0 1)) - :bar-center (cl-transforms-stamped:make-point-stamped - "iai_kitchen/sink_area_dish_washer_door_handle" 0.0 - (cl-transforms:make-3d-vector 0.0 0 0)) - :bar-length 0.2) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type gripping) - (gripper right)))) - (giskard::call-environment-manipulation-action - :open-or-close :open - :arm :right - :handle-link :sink-area-dish-washer-door-handle - :joint-state (cram-math:degrees->radians 35)) - (coe:on-event (make-instance 'cpoe:robot-state-changed)) - (setf (btr:joint-state (btr:get-environment-object) - "sink_area_dish_washer_door_joint") - (cram-math:degrees->radians 35)) - (btr-belief::publish-environment-joint-state - (btr:joint-states (btr:get-environment-object))) - (giskard::call-environment-manipulation-action - :open-or-close :close - :arm :right - :handle-link :sink-area-dish-washer-door-handle) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type releasing) - (gripper right)))) - (pr2-pms:with-real-robot - (exe:perform - (desig:an action - (type parking-arms)))) - (setf (btr:joint-state (btr:get-environment-object) - "sink_area_dish_washer_door_joint") - (cram-math:degrees->radians 0)) - (btr-belief::publish-environment-joint-state - (btr:joint-states (btr:get-environment-object))) - ) + (if (eq open-or-close :open) + (dotimes (i 2) + (call-action + :action-goal (make-environment-manipulation-goal + open-or-close arm handle-link (/ joint-angle 2.0) prefer-base) + :action-timeout action-timeout + :check-goal-function (lambda (result status) + (declare (ignore result)) + (when (or (not status) + (member status '(:preempted :aborted :timeout))) + (make-instance + 'common-fail:environment-manipulation-goal-not-reached + :description "Giskard action failed."))))) + (call-action + :action-goal (make-environment-manipulation-goal + open-or-close arm handle-link joint-angle prefer-base) + :action-timeout action-timeout + :check-goal-function (lambda (result status) + (declare (ignore result)) + (when (or (not status) + (member status '(:preempted :aborted :timeout))) + (make-instance + 'common-fail:environment-manipulation-goal-not-reached + :description "Giskard action failed.")))))) diff --git a/cram_external_interfaces/cram_giskard/src/hash-table-conversions.lisp b/cram_external_interfaces/cram_giskard/src/hash-table-conversions.lisp index 3ef15f569e..175ab1b4ad 100644 --- a/cram_external_interfaces/cram_giskard/src/hash-table-conversions.lisp +++ b/cram_external_interfaces/cram_giskard/src/hash-table-conversions.lisp @@ -149,7 +149,7 @@ `(("header" . ,(make-header-hash-table stamp frame-id)) ("pose" - . (("origin" + . (("position" . ,(make-point-hash-table x y z)) ("orientation" . ,(make-quaternion-hash-table q1 q2 q3 w))))) diff --git a/cram_external_interfaces/cram_giskard/src/making-goal-messages.lisp b/cram_external_interfaces/cram_giskard/src/making-goal-messages.lisp index 1365f54234..a5e8c8c4ac 100644 --- a/cram_external_interfaces/cram_giskard/src/making-goal-messages.lisp +++ b/cram_external_interfaces/cram_giskard/src/making-goal-messages.lisp @@ -30,9 +30,13 @@ (in-package :giskard) (defparameter *avoid-joint-limits-percentage* 40) -(defparameter *prefer-base-low-cost* 0.001) +(defparameter *prefer-base-low-cost* 0.0001) (defparameter *avoid-collisions-distance* 0.10 "In cm, not used atm") (defparameter *unmovable-joint-weight* 9001) +(defparameter *collision-avoidance-hint-threshold* 0.25 "In cm") +(defparameter *collision-avoidance-hint-spring-offset* 0.05 "In m.") +(defparameter *collision-avoidance-hint-velocity* 1.0 "In m/s") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UTILS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -43,8 +47,10 @@ (apply #'vector (alexandria:flatten entries)) (apply #'vector (remove NIL entries))))) -(defun make-giskard-goal (&key constraints joint-constraints cartesian-constraints - collisions (goal-type :plan_and_execute)) +(defun make-giskard-goal (&key + constraints joint-constraints cartesian-constraints + collisions + (goal-type :plan_and_execute_and_cut_off_shaking)) (roslisp:make-message 'giskard_msgs-msg:MoveGoal :type (roslisp:symbol-code 'giskard_msgs-msg:MoveGoal goal-type) @@ -56,6 +62,28 @@ :joint_constraints (make-constraints-vector joint-constraints) :collisions (make-constraints-vector collisions))))) +(defun make-giskard-goal-multiple (&key + all-constraints + joint-constraints + cartesian-constraints + collisions + (goal-type + :plan_and_execute_and_cut_off_shaking)) + (roslisp:make-message + 'giskard_msgs-msg:MoveGoal + :type (roslisp:symbol-code 'giskard_msgs-msg:MoveGoal goal-type) + :cmd_seq (map + 'vector + (lambda (constraints) + (roslisp:make-message + 'giskard_msgs-msg:movecmd + :constraints (make-constraints-vector constraints) + :cartesian_constraints (make-constraints-vector + cartesian-constraints) + :joint_constraints (make-constraints-vector joint-constraints) + :collisions (make-constraints-vector collisions))) + all-constraints))) + (defun cram-name-list->ros-frame-vector (cram-names-list) "@artnie used this function but actually other CRAM users probably don't need it..." (if cram-names-list @@ -128,7 +156,8 @@ ("odom_y_joint" . ,base-weight) ("odom_z_joint" . ,base-weight))))))))))))) -(defun make-align-planes-constraint (root-frame tip-frame root-vector tip-vector) +(defun make-align-planes-constraint (root-frame tip-frame root-vector tip-vector + &key avoid-collisions-not-much) (declare (type string root-frame tip-frame) (type cl-transforms-stamped:vector-stamped root-vector tip-vector)) (roslisp:make-message @@ -140,9 +169,14 @@ `(("root" . ,root-frame) ("tip" . ,tip-frame) ("root_normal" . ,(to-hash-table root-vector)) - ("tip_normal" . ,(to-hash-table tip-vector)))))) - -(defun make-align-planes-tool-frame-constraint (arm root-vector tip-vector) + ("tip_normal" . ,(to-hash-table tip-vector)) + ,@(when avoid-collisions-not-much + `(("weight" . ,(roslisp-msg-protocol:symbol-code + 'giskard_msgs-msg:constraint + :weight_above_ca)))))))) + +(defun make-align-planes-tool-frame-constraint (arm root-vector tip-vector + &key avoid-collisions-not-much) (declare (type keyword arm) (type cl-transforms-stamped:vector-stamped root-vector tip-vector)) (let ((tool-frame @@ -154,7 +188,8 @@ (when (cut:is-var tool-frame) (error "[giskard] Tool frame was not defined.")) (make-align-planes-constraint - cram-tf:*odom-frame* tool-frame root-vector tip-vector))) + cram-tf:*odom-frame* tool-frame root-vector tip-vector + :avoid-collisions-not-much avoid-collisions-not-much))) (defun make-pointing-constraint (root-frame tip-frame goal-pose &optional pointing-vector) @@ -175,6 +210,37 @@ ,@(when pointing-vector `(("pointing_axis" . ,(to-hash-table pointing-vector)))))))) +(defun make-head-pointing-constraint (goal-pose) + (declare (type cl-transforms-stamped:pose-stamped goal-pose)) + (let ((camera-frame + (cut:var-value + '?camera-frame + (car (prolog:prolog + `(and (rob-int:robot ?robot) + (rob-int:camera-frame ?robot ?camera-frame))))))) + (when (cut:is-var camera-frame) + (error "[giskard] Camera frame was not defined.")) + (make-pointing-constraint + (cl-transforms-stamped:frame-id goal-pose) + camera-frame + goal-pose))) + +(defun make-head-pointing-at-hand-constraint (arm) + (declare (type keyword arm)) + (let ((tool-frame + (cut:var-value + '?frame + (car (prolog:prolog + `(and (rob-int:robot ?robot) + (rob-int:robot-tool-frame ?robot ,arm ?frame) + (rob-int:camera-frame ?robot ?camera-frame))))))) + (when (cut:is-var tool-frame) + (error "[giskard] Tool frame was not defined.")) + (make-head-pointing-constraint + (cl-transforms-stamped:pose->pose-stamped + tool-frame 0.0 + (cl-transforms:make-identity-pose))))) + (defun make-open-or-close-constraint (open-or-close arm handle-link goal-joint-state) (declare (type keyword open-or-close arm) (type keyword handle-link) @@ -231,35 +297,31 @@ ("root" . ,root-link)))))) -(defun make-cartesian-constraint (root-frame tip-frame goal-pose max-velocity) +(defun make-cartesian-constraint (root-frame tip-frame goal-pose + &key max-velocity avoid-collisions-much) (declare (type string root-frame tip-frame) (type cl-transforms-stamped:pose-stamped goal-pose) - (type number max-velocity)) - (list - (roslisp:make-message - 'giskard_msgs-msg:constraint - :type - "CartesianPosition" - :parameter_value_pair - (alist->json-string - `(("root_link" . ,root-frame) - ("tip_link" . ,tip-frame) - ("goal" . ,(to-hash-table goal-pose)) - ("max_velocity" . ,max-velocity)))) - (roslisp:make-message - 'giskard_msgs-msg:constraint - :type - "CartesianOrientationSlerp" - :parameter_value_pair - (alist->json-string - `(("root_link" . ,root-frame) - ("tip_link" . ,tip-frame) - ("goal" . ,(to-hash-table goal-pose)) - ;; ("max_velocity" . ,max-velocity) ; can be used, but very experimental - ))))) + (type (or number null) max-velocity) + (type boolean avoid-collisions-much)) + (roslisp:make-message + 'giskard_msgs-msg:constraint + :type + "CartesianPose" + :parameter_value_pair + (alist->json-string + `(("root_link" . ,root-frame) + ("tip_link" . ,tip-frame) + ("goal" . ,(to-hash-table goal-pose)) + ,@(when max-velocity + `(("translation_max_velocity" . ,max-velocity))) + ,@(when avoid-collisions-much + `(("weight" . ,(roslisp-msg-protocol:symbol-code + 'giskard_msgs-msg:constraint + :weight_below_ca)))))))) (defun make-joint-constraint (joint-state weights) - (declare (type list joint-state weights)) + (declare (type list joint-state) + (type (or list number keyword) weights)) "`joint-state' is a list of two elements: (joint-names joint-positions). `weights' is a list of the same length as `joint-names' and `joint-positions'." (mapcar (lambda (joint-name joint-position weight) @@ -274,14 +336,103 @@ ("weight" . ,weight))))) (first joint-state) (second joint-state) - weights)) + (etypecase weights + (list + weights) + ((or number keyword) + (make-list (length (first joint-state)) + :initial-element (case weights + (:avoid-collisions-not-much + (roslisp-msg-protocol:symbol-code + 'giskard_msgs-msg:constraint + :weight_above_ca)) + (t + weights))))))) (defun make-unmovable-joints-constraint (joint-names - &optional (weight *unmovable-joint-weight*)) + &optional (weight + *unmovable-joint-weight*)) + (declare (type list joint-names) + (type (or number null) weight)) (make-joint-constraint (list joint-names (joints:joint-positions joint-names)) - (make-list (length joint-names) :initial-element weight ))) + weight)) + +(defun make-base-collision-avoidance-hint-constraint (environment-link + vector + &optional + (threshold + *collision-avoidance-hint-threshold*) + (spring-offset + *collision-avoidance-hint-spring-offset*) + (max-velocity + *collision-avoidance-hint-velocity*)) + (declare (type string environment-link) + (type cl-transforms-stamped:vector-stamped vector) + (type number threshold spring-offset max-velocity)) + (let ((base-link + (cut:var-value + '?link + (car (prolog:prolog + `(and (rob-int:robot ?robot) + (rob-int:robot-base-link ?robot ?link))))))) + (when (cut:is-var base-link) + (error "[giskard] Robot base link was not defined.")) + (roslisp:make-message + 'giskard_msgs-msg:constraint + :type + "CollisionAvoidanceHint" + :parameter_value_pair + (alist->json-string + `(("link_name" . ,base-link) + ("avoidance_hint" . ,(to-hash-table vector)) + ("max_threshold" . ,threshold) + ("max_velocity" . ,max-velocity) + ("spring_threshold" . ,(+ threshold spring-offset)) + ("body_b" . ,(roslisp-utilities:rosify-underscores-lisp-name + (rob-int:get-environment-name))) + ("link_b" . ,environment-link) + ("weight" . ,(roslisp-msg-protocol:symbol-code + 'giskard_msgs-msg:constraint + :weight_collision_avoidance))))))) + +(defun make-base-velocity-constraint (max-linear-velocity max-angular-velocity) + (declare (type number max-linear-velocity max-angular-velocity)) + (roslisp:make-message + 'giskard_msgs-msg:constraint + :type + "CartesianVelocityLimit" + :parameter_value_pair + (alist->json-string + `(("root_link" . ,cram-tf:*odom-frame*) + ("tip_link" . ,cram-tf:*robot-base-frame*) + ("max_linear_velocity" . ,max-linear-velocity) + ("max_angular_velocity" . ,max-angular-velocity))))) + +(defun make-ee-velocity-constraint (arm + max-linear-velocity max-angular-velocity) + (declare (type number max-linear-velocity max-angular-velocity) + (type keyword arm)) + (let ((link + (cut:var-value + '?link + (car (prolog:prolog + `(and (rob-int:robot ?robot) + (rob-int:end-effector-link ?robot ,arm ?link))))))) + (when (cut:is-var link) + (error "[giskard] Robot ee link was not defined.")) + (roslisp:make-message + 'giskard_msgs-msg:constraint + :type + "CartesianVelocityLimit" + :parameter_value_pair + (alist->json-string + `(("root_link" . ,cram-tf:*odom-frame*) + ("tip_link" . ,link) + ("max_linear_velocity" . ,max-linear-velocity) + ("max_angular_velocity" . ,max-angular-velocity) + ("hard" . 0)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NON-JSON CONSTRAINTS ;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -387,7 +538,7 @@ `(and (rob-int:robot ?robot) (rob-int:arm-links ?robot ,arm ?arm-links)))))) arms))) - (make-allow-robot-links-collision arm-links body-b body-b-link))) + (make-allow-robot-links-collision arm-links body-b body-b-link))) (defun make-allow-hand-collision (arms body-b &optional body-b-link) (declare (type list arms) @@ -401,7 +552,7 @@ `(and (rob-int:robot ?robot) (rob-int:hand-links ?robot ,hand ?hand-links)))))) arms))) - (make-allow-robot-links-collision hand-links body-b body-b-link))) + (make-allow-robot-links-collision hand-links body-b body-b-link))) (defun make-allow-fingers-collision (arms body-b &optional body-b-link) (declare (type list arms) @@ -414,11 +565,12 @@ (prolog:prolog `(and (rob-int:robot ?robot) (rob-int:hand-links ?robot ,arm ?hand-links) - (setof ?finger-link - (and (member ?finger-link ?hand-links) - (rob-int:hand-finger-link - ?robot ,arm ?finger-link)) - ?finger-links)))))) + (prolog:setof + ?finger-link + (and (member ?finger-link ?hand-links) + (rob-int:hand-finger-link + ?robot ,arm ?finger-link)) + ?finger-links)))))) arms))) (make-allow-robot-links-collision finger-links body-b body-b-link))) @@ -441,3 +593,18 @@ (if environment-link (roslisp-utilities:rosify-underscores-lisp-name environment-link) (roslisp:symbol-code 'giskard_msgs-msg:collisionentry :all))))) + +(defun make-allow-collision-with-environment-attachments () + (mapcar (lambda (attachment-info) + (roslisp:make-message + 'giskard_msgs-msg:collisionentry + :type (roslisp:symbol-code + 'giskard_msgs-msg:collisionentry + :allow_collision) + :robot_links (vector + (roslisp:symbol-code 'giskard_msgs-msg:collisionentry :all)) + :body_b (roslisp-utilities:rosify-underscores-lisp-name + (car attachment-info)) + :link_bs (vector + (roslisp:symbol-code 'giskard_msgs-msg:collisionentry :all)))) + (btr:attached-objects (btr:get-environment-object)))) diff --git a/cram_external_interfaces/cram_giskard/src/neck-goals.lisp b/cram_external_interfaces/cram_giskard/src/neck-goals.lisp index 0fb85bbf78..4742f27149 100644 --- a/cram_external_interfaces/cram_giskard/src/neck-goals.lisp +++ b/cram_external_interfaces/cram_giskard/src/neck-goals.lisp @@ -170,5 +170,6 @@ (call-action :action-goal (make-neck-joint-action-goal joint-state) :action-timeout action-timeout - :check-goal-function (lambda () + :check-goal-function (lambda (result status) + (declare (ignore result status)) (ensure-neck-joint-goal-reached goal-configuration))))) diff --git a/cram_external_interfaces/cram_giskard/src/package.lisp b/cram_external_interfaces/cram_giskard/src/package.lisp index f50ba09d0f..c0d4412d24 100644 --- a/cram_external_interfaces/cram_giskard/src/package.lisp +++ b/cram_external_interfaces/cram_giskard/src/package.lisp @@ -50,4 +50,6 @@ ;; misc-goals #:call-grasp-bar-action ;; collision-scene - #:reset-collision-scene)) + #:reset-collision-scene + ;; process-module + #:giskard-pm)) diff --git a/cram_external_interfaces/cram_giskard/src/process-module.lisp b/cram_external_interfaces/cram_giskard/src/process-module.lisp new file mode 100644 index 0000000000..7e5e98cb9e --- /dev/null +++ b/cram_external_interfaces/cram_giskard/src/process-module.lisp @@ -0,0 +1,87 @@ +;;; +;;; Copyright (c) 2016, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :giskard) + +(cpm:def-process-module giskard-pm (motion-designator) + (destructuring-bind (command argument-1 &rest rest-args) + (desig:reference motion-designator) + (ecase command + (cram-common-designators:move-tcp + (giskard:call-arm-cartesian-action + :goal-pose-left argument-1 + :goal-pose-right (first rest-args) + :collision-mode (second rest-args) + :collision-object-b (third rest-args) + :collision-object-b-link (fourth rest-args) + :collision-object-a (fifth rest-args) + :move-base (sixth rest-args) + :prefer-base (seventh rest-args) + :align-planes-left (eighth rest-args) + :align-planes-right (ninth rest-args))) + (cram-common-designators:move-joints + (giskard:call-arm-joint-action + :goal-configuration-left argument-1 + :goal-configuration-right (first rest-args) + :align-planes-left (third rest-args) + :align-planes-right (fourth rest-args) + :avoid-collisions-not-much (fifth rest-args))) + (cram-common-designators:move-arm-pull + (giskard:call-environment-manipulation-action + :open-or-close :open + :arm argument-1 + :handle-link (fifth rest-args) + :joint-angle (second rest-args) + :prefer-base (eighth rest-args))) + (cram-common-designators:move-arm-push + (giskard:call-environment-manipulation-action + :open-or-close :close + :arm argument-1 + :handle-link (fifth rest-args) + :joint-angle (second rest-args) + :prefer-base (eighth rest-args))) + (cram-common-designators:move-head + (when argument-1 + (giskard:call-neck-action + :goal-pose argument-1)) + (when (car rest-args) + (giskard:call-neck-joint-action + :goal-configuration (car rest-args)))) + (cram-common-designators:move-base + (giskard:call-base-action + :goal-pose argument-1 + :base-velocity (first rest-args))) + (cram-common-designators:move-torso + (giskard:call-torso-action + :goal-joint-state argument-1)) + (cram-common-designators:move-gripper-joint + (giskard:call-gripper-action + :action-type-or-position argument-1 + :arm (first rest-args) + :effort (second rest-args)))))) diff --git a/cram_external_interfaces/cram_giskard/src/torso-goals.lisp b/cram_external_interfaces/cram_giskard/src/torso-goals.lisp index 4321854573..48f5f29a8e 100644 --- a/cram_external_interfaces/cram_giskard/src/torso-goals.lisp +++ b/cram_external_interfaces/cram_giskard/src/torso-goals.lisp @@ -93,4 +93,6 @@ (call-action :action-goal (make-torso-action-goal goal-joint-state) :action-timeout action-timeout - :check-goal-function (lambda () (ensure-torso-goal-reached goal-joint-state)))) + :check-goal-function (lambda (result status) + (declare (ignore result status)) + (ensure-torso-goal-reached goal-joint-state)))) diff --git a/cram_external_interfaces/cram_ik_interface/src/ik.lisp b/cram_external_interfaces/cram_ik_interface/src/ik.lisp index bc177314b6..3b6403dbbd 100644 --- a/cram_external_interfaces/cram_ik_interface/src/ik.lisp +++ b/cram_external_interfaces/cram_ik_interface/src/ik.lisp @@ -139,9 +139,10 @@ then return = (0.0 -1 1 -2 2 -3 3 -4 4)" (remove-duplicates (cons 0.0 (sort - (loop for x = lower-lim then (+ x sampling-step) - until (> x upper-lim) - collect x) + (append (loop for x = lower-lim then (+ x sampling-step) + until (> x upper-lim) + collect x) + (list upper-lim)) (lambda (x y) (< (abs x) (abs y))))) ;; remove duplicates in case current value is diff --git a/cram_external_interfaces/cram_joint_states/cram-joint-states.asd b/cram_external_interfaces/cram_joint_states/cram-joint-states.asd index 3975506df3..685b24b232 100644 --- a/cram_external_interfaces/cram_joint_states/cram-joint-states.asd +++ b/cram_external_interfaces/cram_joint_states/cram-joint-states.asd @@ -35,10 +35,15 @@ roslisp-utilities cl-transforms cram-language ; for fluents + cram-prolog ; for monitoring + cram-process-modules ; for monitoring + cram-designators ; for monitoring cram-tf + cram-common-designators sensor_msgs-msg) :components ((:module "src" :components ((:file "package") - (:file "joint-states" :depends-on ("package")))))) + (:file "joint-states" :depends-on ("package")) + (:file "monitoring" :depends-on ("package" "joint-states")))))) diff --git a/cram_external_interfaces/cram_joint_states/package.xml b/cram_external_interfaces/cram_joint_states/package.xml index 02bac33325..999913fd24 100644 --- a/cram_external_interfaces/cram_joint_states/package.xml +++ b/cram_external_interfaces/cram_joint_states/package.xml @@ -14,6 +14,10 @@ roslisp_utilities cl_transforms cram_language + cram_prolog + cram_process_modules + cram_designators cram_tf + cram_common_designators sensor_msgs diff --git a/cram_external_interfaces/cram_joint_states/src/monitoring.lisp b/cram_external_interfaces/cram_joint_states/src/monitoring.lisp new file mode 100644 index 0000000000..6508e2ea1a --- /dev/null +++ b/cram_external_interfaces/cram_joint_states/src/monitoring.lisp @@ -0,0 +1,69 @@ +;;; +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :joints) + +(defun monitor-joint-state (&key + joint-name joint-angle-threshold + comparison-function) + (declare (type string joint-name) + (type number joint-angle-threshold) + (type function comparison-function)) + (cpl:wait-for + (cpl:fl-funcall (lambda (joint-state-msg-fluent) + (funcall comparison-function + (car (joints:joint-positions + (list joint-name) + joint-state-msg-fluent)) + joint-angle-threshold)) + *robot-joint-states-msg*)) + (roslisp:ros-info (joints monitor) + "Joint ~a reached threshold ~a." + joint-name joint-angle-threshold)) + + +(cpm:def-process-module joint-state-pm (motion-designator) + (destructuring-bind (command argument-1 argument-2 argument-3) + (desig:reference motion-designator) + (ecase command + (cram-common-designators:monitor-joint-state + (monitor-joint-state + :joint-name argument-1 + :joint-angle-threshold argument-2 + :comparison-function argument-3))))) + + +(prolog:def-fact-group joint-state-pm-facts (cpm:matching-process-module + cpm:available-process-module) + + (prolog:<- (cpm:matching-process-module ?motion-designator joint-state-pm) + (or (desig:desig-prop ?motion-designator (:type :monitoring-joint-state)))) + + (prolog:<- (cpm:available-process-module joint-state-pm) + (prolog:not (cpm:projection-running ?_)))) diff --git a/cram_external_interfaces/cram_joint_states/src/package.lisp b/cram_external_interfaces/cram_joint_states/src/package.lisp index 9ffae64b72..a377c5c4c1 100644 --- a/cram_external_interfaces/cram_joint_states/src/package.lisp +++ b/cram_external_interfaces/cram_joint_states/src/package.lisp @@ -42,4 +42,6 @@ #:joint-states #:joint-positions #:joint-velocities - #:full-joint-states-as-hash-table)) + #:full-joint-states-as-hash-table + ;; monitoring + #:joint-state-pm)) diff --git a/cram_external_interfaces/cram_nav_pcontroller/src/nav-pcontroller.lisp b/cram_external_interfaces/cram_nav_pcontroller/src/nav-pcontroller.lisp index 4b8633bdc5..a7662f30e6 100644 --- a/cram_external_interfaces/cram_nav_pcontroller/src/nav-pcontroller.lisp +++ b/cram_external_interfaces/cram_nav_pcontroller/src/nav-pcontroller.lisp @@ -89,7 +89,7 @@ (let ((goal-pose-in-fixed-frame (cram-tf:ensure-pose-in-frame goal-pose cram-tf:*fixed-frame*))) (when visualize - (cram-tf:visualize-marker goal-pose :topic "low-level-goals")) + (cram-tf:visualize-marker goal-pose :ns "low-level-goals")) (multiple-value-bind (result status) (cpl:with-failure-handling ((simple-error (e) diff --git a/cram_external_interfaces/cram_nav_pcontroller/src/process-module.lisp b/cram_external_interfaces/cram_nav_pcontroller/src/process-module.lisp index 9971f71518..7a8b63c837 100644 --- a/cram_external_interfaces/cram_nav_pcontroller/src/process-module.lisp +++ b/cram_external_interfaces/cram_nav_pcontroller/src/process-module.lisp @@ -30,8 +30,9 @@ (in-package :navp) (cpm:def-process-module navp-pm (motion-designator) - (destructuring-bind (command destination-pose) + (destructuring-bind (command destination-pose velocity) (desig:reference motion-designator) + (declare (ignore velocity)) (ecase command (cram-common-designators:move-base (call-nav-pcontroller-action destination-pose :visualize t))))) diff --git a/cram_external_interfaces/cram_robosherlock/src/robosherlock-ros.lisp b/cram_external_interfaces/cram_robosherlock/src/robosherlock-ros.lisp index 1a81fa4a85..e098ff10c0 100644 --- a/cram_external_interfaces/cram_robosherlock/src/robosherlock-ros.lisp +++ b/cram_external_interfaces/cram_robosherlock/src/robosherlock-ros.lisp @@ -29,11 +29,13 @@ (in-package :rs) +(defparameter *ros-action* "RoboSherlock/query_action") + (defun make-robosherlock-action-client () (actionlib-client:make-simple-action-client 'robosherlock-action - "RoboSherlock/query_action" "robosherlock_msgs/RSQueryAction" - 60)) + *ros-action* "robosherlock_msgs/RSQueryAction" + 120)) (roslisp-utilities:register-ros-init-function make-robosherlock-action-client) @@ -74,27 +76,39 @@ (destructuring-bind (key &rest values) key-value-pair (let ((value (car values))) - ;; below are the only keys supported by RS at the moment - ;; TODO: make sure that an already perceived object doesn't get reperceived with its original SHAPE and SIZE... + ;; below are the only keys supported by RS atm (if (or (eql key :type) (eql key :shape) (eql key :color) (eql key :location) - (eql key :size)) + (eql key :size) + (eql key :material)) (list key - (etypecase value ; RS is only case-sensitive on "TYPE"s - (keyword (remove #\- - (if (eql key :type) - (string-capitalize (symbol-name value)) - (string-downcase (symbol-name value))))) - (string value) - (list (mapcar (lambda (item) - (etypecase item - (keyword - (string-downcase (symbol-name item))) - (string - item))) - value)) + (etypecase value + ;; RS is only case-sensitive on "TYPE"s + (keyword + (remove #\- + (if (eql key :type) + (string-capitalize + (symbol-name + (case value + ;; (:bowl :ikea-red-bowl) + ;; (:cup :ikea-red-cup) + ;; (:spoon :soup-spoon) + (t value)))) + (string-downcase + (symbol-name value))))) + (string + value) + (list + (mapcar (lambda (item) + (etypecase item + (keyword + (string-downcase + (symbol-name item))) + (string + item))) + value)) (desig:location-designator (desig:desig-prop-value (or (desig:desig-prop-value value :on) @@ -118,8 +132,9 @@ (if (string-equal string "") nil (roslisp-utilities:lispify-ros-underscore-name string :keyword)))) - `((:name ,(to-keyword ;; (roslisp:msg-slot-value message :uid) - (format nil "~a-1" (roslisp:msg-slot-value message :type)))) + `((:name ,(to-keyword + ;; (roslisp:msg-slot-value message :uid) + (format nil "~a-1" (roslisp:msg-slot-value message :type)))) (:type ,(to-keyword (roslisp:msg-slot-value message :type))) (:shape ,(map 'list #'to-keyword (roslisp:msg-slot-value message :shape))) (:color ,(map 'list #'to-keyword (roslisp:msg-slot-value message :color))) @@ -139,20 +154,25 @@ :description "couldn't find the object")) (etypecase quantifier (keyword (ecase quantifier - ((:a :an) (parse-result (aref result 0)) - ;; this case should return a lazy list but I don't like them so... - ) + ;; this case should return a lazy list + ;; but I don't like them so... + ((:a :an) (parse-result (aref result 0))) (:the (if (= number-of-objects 1) (parse-result (aref result 0)) (cpl:fail 'common-fail:perception-low-level-failure - :description "There was more than one of THE object"))) + :description (format nil + "There was more ~ + than one of THE ~ + object")))) (:all (map 'list #'parse-result result)))) (number (if (= number-of-objects quantifier) (map 'list #'parse-result result) (cpl:fail 'common-fail:perception-low-level-failure - :description (format nil "perception returned ~a objects ~ - although there should've been ~a" - number-of-objects quantifier)))))))) + :description (format nil "perception returned ~a ~ + objects although there ~ + should've been ~a" + number-of-objects + quantifier)))))))) (defun map-rs-color-to-rgb-list (rs-color) (when (stringp rs-color) @@ -177,7 +197,7 @@ (if cad-model :templatealignment (if (eq type :spoon) - :2destimate + :3destimate ;:2destimate (if obj-part :handleannotator :3destimate))))) @@ -213,10 +233,28 @@ (ecase (second (find :type rs-answer :key #'car)) (:KoellnMuesliKnusperHonigNuss :breakfast-cereal) + (:muesli + :breakfast-cereal) + (:milk + :milk) (:CupEcoOrange :cup) (:EdekaRedBowl :bowl) + (:IkeaRedBowl + :bowl) + (:SoupSpoon + :spoon) + (:spoon + :spoon) + (:IkeaRedCup + :cup) + (:bowl + :bowl) + (:cup + :cup) + (:mug + :cup) (:WeideMilchSmall :milk) (:BLUEPLASTICSPOON @@ -249,8 +287,11 @@ ;; (find :color keyword-key-value-pairs-list :key #'car)) ;; (setf rs-answer (remove :color rs-answer :key #'car))) (setf rs-answer (remove :color rs-answer :key #'car)) ; <- if we don't do this - ; might end up asking about mutliple colors + ; might end up asking about mutliple colors + (setf rs-answer (remove :material rs-answer :key #'car)) ; <- if we don't do this + ; might end up asking about different materials (setf rs-answer (remove :shape rs-answer :key #'car)); <- SHAPE comes from original query + (setf rs-answer (remove :size rs-answer :key #'car)) ; <- don't care about size ;; (when (and (find :pose rs-answer :key #'car) ;; (find :pose keyword-key-value-pairs-list :key #'car)) ;; (remove :pose keyword-key-value-pairs-list :key #'car)) diff --git a/cram_external_interfaces/kdl_ik_service/src/kdl_ik_service/ik.py b/cram_external_interfaces/kdl_ik_service/src/kdl_ik_service/ik.py index d8cd27ef46..0f1ac1992b 100644 --- a/cram_external_interfaces/kdl_ik_service/src/kdl_ik_service/ik.py +++ b/cram_external_interfaces/kdl_ik_service/src/kdl_ik_service/ik.py @@ -4,6 +4,9 @@ import kdl_parser_py.urdf # from kdl_parser_py import tf2_kdl import math +import os # for suppress_stderr +import sys # for suppress_stderr +from contextlib import contextmanager # for suppress_stderr # ======================== Hacks (TBF) =============================================================== def hacky_urdf_parser_fix(urdf_str): @@ -29,6 +32,16 @@ def hacky_urdf_parser_fix(urdf_str): fixed_urdf += line + '\n' return fixed_urdf +@contextmanager +def suppress_stderr(): + """The URDF parser spits too much Unknown Tag, so need to muffle it.""" + with open(os.devnull, "w") as devnull: + old_stdout = sys.stderr + sys.stderr = devnull + try: + yield + finally: + sys.stderr = old_stdout # ================================= API =================================================== def calculate_ik(base_link, tip_link, seed_joint_state, goal_transform_geometry_msg, log_fun): @@ -41,7 +54,8 @@ def calculate_ik(base_link, tip_link, seed_joint_state, goal_transform_geometry_ """ robot_urdf_string = rospy.get_param('robot_description') robot_urdf_string_fixed = hacky_urdf_parser_fix(robot_urdf_string) - urdf_obj = urdf_parser_py.urdf.URDF.from_xml_string(robot_urdf_string_fixed) + with suppress_stderr(): + urdf_obj = urdf_parser_py.urdf.URDF.from_xml_string(robot_urdf_string_fixed) _, kdl_tree = kdl_parser_py.urdf.treeFromUrdfModel(urdf_obj) kdl_chain = kdl_tree.getChain(base_link, tip_link) @@ -65,19 +79,21 @@ def calculate_ik(base_link, tip_link, seed_joint_state, goal_transform_geometry_ result_joint_state_kdl = solve_ik(ik_solver, num_joints, seed_joint_state_kdl, goal_frame_kdl) # check if calculated joint state results in the correct end-effector position using FK - goal_pose_reached = check_ik_result_using_fk(fk_solver, result_joint_state_kdl, goal_frame_kdl,log_fun) + goal_pose_reached = check_ik_result_using_fk(fk_solver, result_joint_state_kdl, goal_frame_kdl, log_fun) if not goal_pose_reached: # try with joint seed states as 0 log_fun("Cannot reach goal using the IK solution with the provided seed state. Trying with zeros") - result_joint_state_kdl_with_zero_seed = solve_ik(ik_solver, num_joints, PyKDL.JntArray(num_joints), goal_frame_kdl) + result_joint_state_kdl_with_zero_seed = solve_ik(ik_solver, num_joints, PyKDL.JntArray(num_joints), + goal_frame_kdl) goal_pose_reached = check_ik_result_using_fk(fk_solver, result_joint_state_kdl_with_zero_seed, goal_frame_kdl, log_fun) result_joint_state_kdl = result_joint_state_kdl_with_zero_seed if goal_pose_reached else result_joint_state_kdl # check if calculated joint state is within joint limits joints_within_limits = check_result_joints_are_within_limits(num_joints, result_joint_state_kdl, - kdl_joint_limits_min, kdl_joint_limits_max) + kdl_joint_limits_min, + kdl_joint_limits_max) log_fun("Result Joint State Within Limits: " + str(joints_within_limits)) log_fun("Can Reach Goal Pose With Solution: " + str(goal_pose_reached)) @@ -103,10 +119,15 @@ def get_joint_limits_from_urdf(joint_name, urdf_obj): [joint_found] = [joint for joint in urdf_joints if joint.name == joint_name] except ValueError as e: raise ValueError("Error while trying to find joint named: %s in the urdf. Reason: %s" % (joint_name, e)) - if joint_found.joint_type != 'fixed': - return joint_found.limit.upper, joint_found.limit.lower - else: + # Continuous joints (0 as joint limits will mess up the IK solution) + if joint_found.joint_type == 'continuous' and joint_found.limit.upper == joint_found.limit.lower == 0: + return 2 * math.pi, -2 * math.pi + # Fixed joints + elif joint_found.joint_type == 'fixed': return None, None + # Prismatic/Revolute/any other joints + else: + return joint_found.limit.upper, joint_found.limit.lower def get_kdl_joint_limit_arrays(kdl_chain, urdf_obj): diff --git a/cram_knowrob/cram_cloud_logger/src/cloud-logger-query-handler.lisp b/cram_knowrob/cram_cloud_logger/src/cloud-logger-query-handler.lisp index 3f306874d7..80bb3ca7f4 100644 --- a/cram_knowrob/cram_cloud_logger/src/cloud-logger-query-handler.lisp +++ b/cram_knowrob/cram_cloud_logger/src/cloud-logger-query-handler.lisp @@ -18,8 +18,13 @@ (defun get-grasp-type-lookup-table() (let ((lookup-table (make-hash-table :test 'equal))) (setf (gethash ":TOP" lookup-table) "TopGrasp") + (setf (gethash ":TOP-FRONT" lookup-table) "TopFrontGrasp") + (setf (gethash ":TOP-LEFT" lookup-table) "TopLeftGrasp") + (setf (gethash ":TOP-RIGHT" lookup-table) "TopRightGrasp") (setf (gethash ":BOTTOM" lookup-table) "BottomGrasp") (setf (gethash ":LEFT" lookup-table) "LeftGrasp") + (setf (gethash ":LEFT-SIDE" lookup-table) "LeftSideGrasp") + (setf (gethash ":RIGHT-SIDE" lookup-table) "RightSideGrasp") (setf (gethash ":RIGHT" lookup-table) "RightGrasp") (setf (gethash ":FRONT" lookup-table) "FrontGrasp") (setf (gethash ":BACK" lookup-table) "BackGrasp") @@ -39,8 +44,9 @@ (defun attach-event-to-situation (event-prolog-url situation-prolog-url) (get-url-from-send-query-1 "SubAction" "add_subaction_with_task" situation-prolog-url "SubAction" event-prolog-url)) -(defun send-belief-perceived-at (object-type transform) - (get-url-from-send-query-1 "Object" "belief_perceived_at" object-type transform "Object")) +(defun send-belief-perceived-at (object-type transform object-id) + (send-query-1-without-result "belief_perceived_at" object-type transform object-id) + object-id) (defun send-belief-new-object-query (object-type) (get-url-from-send-query-1 "Object" "belief_new_object" object-type "Object")) @@ -63,21 +69,28 @@ (progn (print "Previous episode recording is still running. Stopping the recording ...") (stop-episode))) + (setf ccl::*is-logging-enabled* t) + (ccl::init-logging) (ccl::clear-detected-objects) - (setf ccl::*episode-name* (get-url-from-send-query-1 "RootAction" "mem_episode_start" "RootAction"))) + (setf ccl::*episode-name* (get-url-from-send-query-1 "RootAction" "mem_episode_start" "RootAction")) + (ccl::start-situation *episode-name*)) (defun stop-episode () + (ccl::stop-situation *episode-name*) (send-query-1-without-result "mem_episode_stop" (concatenate 'string "'" (uiop:getenv "KNOWROB_MEMORY_DIR") "'")) - (setf ccl::*episode-name* nil)) + (setf ccl::*episode-name* nil) + (setf ccl::*is-logging-enabled* nil)) (defun send-query-1-without-result (query-name &rest query-parameters) - (let ((query (create-query query-name query-parameters))) - (send-query-1 query) + (let* ((query (create-query query-name query-parameters)) + (result (send-query-1 query))) + (when (not result) + (break)) (print "DONE REASONING"))) (defun send-query-1 (query) (print query) - (json-prolog:prolog-simple-1 query)) + (print (json-prolog:prolog-simple-1 query))) (defun get-url-from-send-query-1 (url-parameter query-name &rest query-parameters) (let* ((query (create-query query-name query-parameters)) @@ -94,17 +107,16 @@ (let* ((object-name (get-designator-property-value-str object-designator :NAME)) (object-ease-id (get-ease-object-id-of-detected-object-by-name object-name))) (when object-ease-id - (send-query-1-without-result "add_participant_with_role" action-inst object-ease-id "'http://www.ease-crc.org/ont/EASE-OBJ.owl#AffectedObject'")))) + (send-query-1-without-result "add_participant_with_role" action-inst object-ease-id "'http://www.ease-crc.org/ont/SOMA.owl#AffectedObject'")))) (defun send-grasp-action-parameter (action-inst grasp) (let ((grasp-type (gethash (write-to-string grasp) *grasp-type-lookup-table*))) - (send-parameter action-inst "GraspingOrientation" grasp-type))) + (send-parameter action-inst grasp-type))) -(defun send-parameter(action-inst parameter-type region-type) - (let ((parameter-type-url (concatenate 'string "'""http://www.ease-crc.org/ont/EASE.owl#" parameter-type "'")) - (region-type-url (concatenate 'string "'""http://www.ease-crc.org/ont/EASE.owl#" region-type "'"))) - (send-query-1-without-result "add_parameter" action-inst parameter-type-url region-type-url))) +(defun send-parameter(action-inst region-type) + (let ((region-type-url (concatenate 'string "'""http://www.ease-crc.org/ont/SOMA.owl#" region-type "'"))) + (send-query-1-without-result "add_grasping_parameter" action-inst region-type-url))) diff --git a/cram_knowrob/cram_cloud_logger/src/knowrob-action-name-handler.lisp b/cram_knowrob/cram_cloud_logger/src/knowrob-action-name-handler.lisp index 496ee9c760..b2c6ddc10c 100644 --- a/cram_knowrob/cram_cloud_logger/src/knowrob-action-name-handler.lisp +++ b/cram_knowrob/cram_cloud_logger/src/knowrob-action-name-handler.lisp @@ -7,8 +7,8 @@ ("retracting" "Retracting") ("lifting" "Lifting") ("putting" "Lowering") - ("setting-gripper" "Positioning") - ("positioning-arm" "Positioning") + ("setting-gripper" "SettingGripper") + ("positioning-arm" "PositioningArm") ("opening" "Opening") ("opening-gripper" "Opening") ("closing" "Closing") @@ -22,7 +22,7 @@ ("going" "MovingTo") ("navigating" "Navigating") ("searching" "LookingFor") - ("fetching" "PickingUp") + ("fetching" "Fetching") ("delivering" "PuttingDown") ("transporting" "Transporting") ("turning-towards" "LookingFor") @@ -36,7 +36,7 @@ (defparameter *action-name-mapper* (init-action-name-mapper)) (defun get-knowrob-action-name-uri (cram-action-name designator) - (concatenate 'string "'http://www.ease-crc.org/ont/EASE-ACT.owl#" (get-knowrob-action-name cram-action-name designator) "'")) + (concatenate 'string "'http://www.ease-crc.org/ont/SOMA.owl#" (get-knowrob-action-name cram-action-name designator) "'")) (defun get-knowrob-action-name (cram-action-name designator) (let* ((lower-cram-action-name (string-downcase cram-action-name)) diff --git a/cram_knowrob/cram_cloud_logger/src/neem-interface.pl b/cram_knowrob/cram_cloud_logger/src/neem-interface.pl index 6f7cd71cd7..f550cd3b7d 100644 --- a/cram_knowrob/cram_cloud_logger/src/neem-interface.pl +++ b/cram_knowrob/cram_cloud_logger/src/neem-interface.pl @@ -1,19 +1,29 @@ :- rdf_meta(mem_event_create(r,r,r)). :- use_module(library('db/mongo/client')). -mem_episode_start(Action) :- tripledb_load('package://knowrob/owl/knowrob.owl',[graph(tbox),namespace(knowrob)]),tell([is_episode(Episode), is_action(Action), has_type(Task,ease_act:'PhysicalTask'), executes_task(Action,Task),is_setting_for(Episode,Action)]),!. +mem_episode_start(Action) :- tripledb_drop(),forall(mng_collection(roslog,Coll),mng_drop(roslog,Coll)), + tripledb_load('package://knowrob/owl/knowrob.owl',[graph(tbox),namespace(knowrob)]), + tell([is_episode(Episode), is_action(Action), has_type(Task,soma:'PhysicalTask'), + executes_task(Action,Task),is_setting_for(Episode,Action)]),!. + mem_episode_stop(NeemPath) :- get_time(CurrentTime), atom_concat(NeemPath,'/',X1), atom_concat(X1,CurrentTime,X2), memorize(X2),tripledb_drop(),forall(mng_collection(roslog,Coll),mng_drop(roslog,Coll)). mem_event_set_failed(Action) :- tell(action_failed(Action)). mem_event_set_succeeded(Action) :- tell(action_succeeded(Action)). mem_event_add_diagnosis(Situation, Diagnosis) :- tell(satisfies(Situation, Diagnosis)). -add_subaction_with_task(Action,SubAction,TaskType) :- tell([is_action(SubAction), has_type(Task,TaskType), executes_task(SubAction,Task), has_subevent(Action,SubAction)]), !. -mem_event_end(Event) :- get_time(CurrentTime),tell([is_time_interval(TimeInterval),holds(Event,dul:hasTimeInterval,TimeInterval), occurs(Event) until CurrentTime]),!. -mem_event_begin(Event) :- get_time(CurrentTime),tell([is_time_interval(TimeInterval),holds(Event,dul:hasTimeInterval,TimeInterval), occurs(Event) since CurrentTime]),!. -belief_perceived_at(ObjectType, Frame, Object) :- get_time(CurrentTime),tell([has_type(Object,ObjectType),is_at(Object,Frame) since CurrentTime]). -%belief_perceived_at(ObjectType, Frame, Object) :- tell(has_type(Object,ObjectType)). + +add_subaction_with_task(Action,SubAction,TaskType) :- tell([is_action(SubAction), has_type(Task,TaskType), executes_task(SubAction,Task), has_subevent(Action,SubAction)]),notify_synchronize(event(Event)), !. + +mem_event_end(Event) :- get_time(CurrentTime),ask(triple(Event,dul:'hasTimeInterval',TimeInterval)),tripledb_forget(TimeInterval, soma:'hasIntervalEnd', _),tell(holds(TimeInterval, soma:'hasIntervalEnd', CurrentTime)),!. + +mem_event_begin(Event) :- get_time(CurrentTime),tell(occurs(Event) since CurrentTime),!. + +%belief_perceived_at(ObjectType, Frame, Object) :- get_time(CurrentTime),tell([has_type(Object,ObjectType),is_at(Object,Frame) since CurrentTime]). +belief_perceived_at(ObjectType, Frame, Object) :- tell([has_type(Object,ObjectType)]). add_participant_with_role(Action, ObjectId, RoleType) :- tell([has_participant(Action,ObjectId), has_type(Role, RoleType), has_role(ObjectId,Role) during [0.0,0.0]]). add_parameter(Task,ParameterType,RegionType) :- tell([has_type(Parameter, ParameterType), has_type(Region,RegionType),has_assignment(Parameter,Region) during [0.0,0.1], has_parameter(Task, Parameter)]). -add_grasping_parameter(Action,GraspingOrientationType) :- ask(executes_task(Action, Task)), tell([has_type(GraspingOrientation,GraspingOrientationType), has_type(GraspingOrientationConcept,'http://www.ease-crc.org/ont/EASE.owl#GraspingOrientation'), has_parameter(Task,GraspingOrientationConcept),holds(GraspingOrientationConcept, dul:classifies, GraspingOrientation),has_region(Action,GraspingOrientation)]),!. + +add_grasping_parameter(Action,GraspingOrientationType) :- ask(executes_task(Action, Task)), tell([has_type(GraspingOrientation,GraspingOrientationType), has_type(GraspingOrientationConcept,'http://www.ease-crc.org/ont/SOMA.owl#GraspingOrientation'), has_parameter(Task,GraspingOrientationConcept),holds(GraspingOrientationConcept, dul:classifies, GraspingOrientation),has_region(Action,GraspingOrientation)]),!. + add_comment(Entity,Comment) :- tell(triple(Entity, 'http://www.w3.org/2000/01/rdf-schema#comment', Comment)). ros_logger_start :- process_create(path('rosrun'),['mongodb_log', 'mongodb_log.py','__name:=topic_logger', '--mongodb-name', 'roslog', '/tf_projection', '/tf'],[process(PID)]),asserta(ros_logger_pid(PID)). ros_logger_stop :- ros_logger_pid(PID), @@ -25,4 +35,3 @@ [stdin(pipe(In)), detached(true), process(TLPID)]), writeln(In,'y'),flush_output(In), process_wait(TLPID, _), print_message(informational,'Topic Logger stopped'). - diff --git a/cram_knowrob/cram_cloud_logger/src/object-interface.lisp b/cram_knowrob/cram_cloud_logger/src/object-interface.lisp index a220f32263..e7e25b7b20 100644 --- a/cram_knowrob/cram_cloud_logger/src/object-interface.lisp +++ b/cram_knowrob/cram_cloud_logger/src/object-interface.lisp @@ -96,7 +96,7 @@ (defun create-reasoning-url (predicate-name) - (concatenate 'string "'http://www.ease-crc.org/ont/EASE-ACT.owl#" predicate-name "'")) + (concatenate 'string "'http://www.ease-crc.org/ont/SOMA.owl#" predicate-name "'")) ;;(defun log-reasoning-task (predicate-name parameter reasoning-result) ;; (let diff --git a/cram_knowrob/cram_cloud_logger/src/utils-for-perform.lisp b/cram_knowrob/cram_cloud_logger/src/utils-for-perform.lisp index ea08bfd1dd..0d5aee7a5e 100644 --- a/cram_knowrob/cram_cloud_logger/src/utils-for-perform.lisp +++ b/cram_knowrob/cram_cloud_logger/src/utils-for-perform.lisp @@ -32,9 +32,9 @@ (defun get-ease-object-lookup-table() (let ((lookup-table (make-hash-table :test 'equal))) - (setf (gethash "BOWL" lookup-table) "'http://www.ease-crc.org/ont/EASE-OBJ.owl#Bowl'") - (setf (gethash "CUP" lookup-table) "'http://www.ease-crc.org/ont/EASE-OBJ.owl#Cup'") - (setf (gethash "DRAWER" lookup-table) "'http://www.ease-crc.org/ont/EASE-OBJ.owl#Drawer'") + (setf (gethash "BOWL" lookup-table) "'http://www.ease-crc.org/ont/SOMA.owl#Bowl'") + (setf (gethash "CUP" lookup-table) "'http://www.ease-crc.org/ont/SOMA.owl#Cup'") + (setf (gethash "DRAWER" lookup-table) "'http://www.ease-crc.org/ont/SOMA.owl#Drawer'") lookup-table)) (cpl:define-task-variable *action-parents* '()) @@ -80,7 +80,11 @@ (convert-to-ease-object-type-url detected-object-type))) (if (gethash object-name *detected-objects*) (print "Object exists") - (let ((object-id (send-belief-perceived-at object-type (get-transform-of-detected-object detected-object)))) + (let ((object-id (send-belief-perceived-at object-type + (get-transform-of-detected-object detected-object) + (concatenate 'string + "'" "http://www.ease-crc.org/ont/SOMA.owl#" + (roslisp-utilities:rosify-underscores-lisp-name (make-symbol object-name)) "'")))) (setf (gethash object-name *detected-objects*) object-id) (when (string-equal object-type "'http://www.ontologydesignpatterns.org/ont/dul/DUL.owl#DesignedArtifact'") (send-comment object-id (concatenate 'string "Unknown Object: "(write-to-string detected-object-type)))))))) @@ -95,7 +99,10 @@ ;;(log-cram-finish-action action-id) (set-event-status-to-failed action-id) (set-event-diagnosis action-id (ccl::get-failure-uri (subseq (write-to-string e) 2 (search " " (write-to-string e))))) - ;;(log-failure action-id e) + (let ((action-designator-parameters (desig:properties (or (second (desig:reference designator)) designator)))) + (log-action-designator-parameters-for-logged-action-designator action-designator-parameters action-id)) + (ccl::stop-situation action-id) + ;;(equate action-id (log-perform-call (second (desig:reference designator))))) (print "plan failure"))) @@ -113,13 +120,12 @@ ;;(log-cram-sibling-action ;; (car *action-parents*) action-id (get-knowrob-action-name cram-action-name designator)) (push action-id *action-parents*) - (ccl::start-situation action-id) (multiple-value-bind (perform-result action-desig) (call-next-method) ;;(let ((referenced-action-id (log-perform-call action-desig))) (let ((referenced-action-id "") - (action-designator-parameters (desig:properties action-desig))) + (action-designator-parameters (desig:properties (or action-desig designator)))) (log-action-designator-parameters-for-logged-action-designator action-designator-parameters action-id) (when (string-equal cram-action-name "detecting") (handle-detected-object perform-result)) @@ -137,7 +143,7 @@ (if *is-logging-enabled* (let* ((cram-action-name (get-knowrob-action-name-uri (get-designator-property-value-str designator :TYPE) designator)) (event-name-url (attach-event-to-situation cram-action-name (get-parent-uri)))) - (when (string-equal cram-action-name "'http://www.ease-crc.org/ont/EASE-ACT.owl#PhysicalTask'") + (when (string-equal cram-action-name "'http://www.ease-crc.org/ont/SOMA.owl#PhysicalTask'") (send-comment event-name-url (concatenate 'string "Unknown Action: " (get-designator-property-value-str designator :TYPE)))) event-name-url) "NOLOGGING")) diff --git a/cram_knowrob/cram_knowrob_vr/launch/simulation.launch b/cram_knowrob/cram_knowrob_vr/launch/simulation.launch index 23f60e90eb..68c0cd1a32 100644 --- a/cram_knowrob/cram_knowrob_vr/launch/simulation.launch +++ b/cram_knowrob/cram_knowrob_vr/launch/simulation.launch @@ -10,7 +10,7 @@ + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> @@ -36,7 +36,7 @@ diff --git a/cram_knowrob/cram_knowrob_vr/src/experiment-log-generator.lisp b/cram_knowrob/cram_knowrob_vr/src/experiment-log-generator.lisp index 124f1bd58f..2f36ac3f52 100644 --- a/cram_knowrob/cram_knowrob_vr/src/experiment-log-generator.lisp +++ b/cram_knowrob/cram_knowrob_vr/src/experiment-log-generator.lisp @@ -41,13 +41,22 @@ (defparameter *experiment-log-failures-to-count* '(common-fail:searching-failed common-fail:fetching-failed common-fail:delivering-failed - common-fail:perception-low-level-failure common-fail:navigation-low-level-failure - common-fail:manipulation-low-level-failure common-fail:ptu-low-level-failure)) + common-fail:navigation-goal-not-reached + common-fail:manipulation-goal-not-reached + common-fail:gripper-low-level-failure + ;; common-fail:perception-low-level-failure common-fail:navigation-low-level-failure + ;; common-fail:manipulation-low-level-failure common-fail:ptu-low-level-failure + common-fail:environment-manipulation-goal-not-reached + common-fail:object-unreachable + common-fail:object-nowhere-to-be-found + common-fail:environment-unreachable)) (defvar *experiment-log-current-demo-run-object-failures* nil) (defvar *experiment-log-current-execution-time-bowl* 0) (defvar *experiment-log-current-execution-time-cup* 0) (defvar *experiment-log-current-execution-time-spoon* 0) +(defvar *experiment-log-current-execution-time-breakfast-cereal* 0) +(defvar *experiment-log-current-execution-time-milk* 0) (defun experiment-log (string &key @@ -69,7 +78,8 @@ :if-does-not-exist :create) (format stream "RUN_ID,OBJ_TYPE,FAIL_TYPE,TRANSPORT_FAIL,~ SEARCH_FAIL,FETCH_FAIL,DELIVER_FAIL,~ - PERCEPT_FAIL,NAV_FAIL,MANIP_FAIL,TIME_SEC~%~%~%"))) + NAV_FAIL,MANIP_FAIL,GRIP_FAIL,ENV_MANIP_FAIL,~ + REACH_FAIL,FIND_FAIL,ENV_REACH_FAIL,TIME_SEC~%~%~%"))))) (with-open-file (stream file-path :direction :output :if-exists :append @@ -152,33 +162,39 @@ new-prop-list)) (defun get-experiment-log-failures (failure-symbol &optional object-type) - (let ((failure-num - (if object-type - (getf (getf *experiment-log-current-demo-run-object-failures* - object-type) - failure-symbol) - (+ (getf (getf *experiment-log-current-demo-run-object-failures* - 'bowl) - failure-symbol) - (getf (getf *experiment-log-current-demo-run-object-failures* - 'cup) - failure-symbol) - (getf (getf *experiment-log-current-demo-run-object-failures* - 'spoon) - failure-symbol))))) - (if (eql failure-symbol 'common-fail:perception-low-level-failure) - (/ failure-num 5) - failure-num))) + (if object-type + (getf (getf *experiment-log-current-demo-run-object-failures* + object-type) + failure-symbol) + (+ (getf (getf *experiment-log-current-demo-run-object-failures* + :bowl) + failure-symbol) + (getf (getf *experiment-log-current-demo-run-object-failures* + :cup) + failure-symbol) + (getf (getf *experiment-log-current-demo-run-object-failures* + :spoon) + failure-symbol) + (getf (getf *experiment-log-current-demo-run-object-failures* + :breakfast-cereal) + failure-symbol) + (getf (getf *experiment-log-current-demo-run-object-failures* + :milk) + failure-symbol)))) (defun get-experiment-log-transport-duration (&optional object-type) (if object-type (case object-type - (bowl *experiment-log-current-execution-time-bowl*) - (cup *experiment-log-current-execution-time-cup*) - (spoon *experiment-log-current-execution-time-spoon*)) + (:bowl *experiment-log-current-execution-time-bowl*) + (:cup *experiment-log-current-execution-time-cup*) + (:spoon *experiment-log-current-execution-time-spoon*) + (:breakfast-cereal *experiment-log-current-execution-time-breakfast-cereal*) + (:milk *experiment-log-current-execution-time-milk*)) (+ *experiment-log-current-execution-time-bowl* *experiment-log-current-execution-time-cup* - *experiment-log-current-execution-time-spoon*))) + *experiment-log-current-execution-time-spoon* + *experiment-log-current-execution-time-breakfast-cereal* + *experiment-log-current-execution-time-milk*))) (defun experiment-log-current-demo-run-failures (&optional object-type) @@ -193,21 +209,34 @@ 'common-fail:delivering-failed object-type)) (transporting-failed (+ searching-failures fetching-failures delivering-failures)) - (navigation-failures + (nav-failures + (get-experiment-log-failures + 'common-fail:navigation-goal-not-reached object-type)) + (manip-failures + (get-experiment-log-failures + 'common-fail:manipulation-goal-not-reached object-type)) + (grip-failures + (get-experiment-log-failures + 'common-fail:gripper-low-level-failure object-type)) + (env-manip-failures (get-experiment-log-failures - 'common-fail:navigation-low-level-failure object-type)) - (manipulation-failures + 'common-fail:environment-manipulation-goal-not-reached object-type)) + (obj-reach-failures (get-experiment-log-failures - 'common-fail:manipulation-low-level-failure object-type)) - (perception-failures + 'common-fail:object-unreachable object-type)) + (obj-find-failures (get-experiment-log-failures - 'common-fail:perception-low-level-failure object-type)) + 'common-fail:object-nowhere-to-be-found object-type)) + (env-reach-failures + (get-experiment-log-failures + 'common-fail:environment-unreachable object-type)) (duration (get-experiment-log-transport-duration object-type))) - (experiment-log (format nil "SUM,~a,~a,~a,~a,~a,~a,~a,~f" + (experiment-log (format nil "SUM,~a,~a,~a,~a,~a,~a,~a,~a,~a,~a,~a,~f" transporting-failed searching-failures fetching-failures delivering-failures - perception-failures navigation-failures manipulation-failures + nav-failures manip-failures grip-failures env-manip-failures + obj-reach-failures obj-find-failures env-reach-failures duration)) (when *experiment-log-detailed?* (experiment-log (format nil "~%"))))) @@ -220,16 +249,22 @@ (experiment-log (format nil "~%~%")) (experiment-log (format nil ""))) - (setf (getf *experiment-log-current-demo-run-object-failures* 'bowl) + (setf (getf *experiment-log-current-demo-run-object-failures* :bowl) + (generate-empty-failure-property-list)) + (setf (getf *experiment-log-current-demo-run-object-failures* :cup) + (generate-empty-failure-property-list)) + (setf (getf *experiment-log-current-demo-run-object-failures* :spoon) (generate-empty-failure-property-list)) - (setf (getf *experiment-log-current-demo-run-object-failures* 'cup) + (setf (getf *experiment-log-current-demo-run-object-failures* :breakfast-cereal) (generate-empty-failure-property-list)) - (setf (getf *experiment-log-current-demo-run-object-failures* 'spoon) + (setf (getf *experiment-log-current-demo-run-object-failures* :milk) (generate-empty-failure-property-list)) (setf *experiment-log-current-execution-time-bowl* 0 *experiment-log-current-execution-time-cup* 0 - *experiment-log-current-execution-time-spoon* 0)) + *experiment-log-current-execution-time-spoon* 0 + *experiment-log-current-execution-time-breakfast-cereal* 0 + *experiment-log-current-execution-time-milk* 0)) (defun experiment-log-finish-demo-run () (setf *experiment-log-current-object* nil) @@ -244,25 +279,43 @@ (defun experiment-log-start-object-transport (object-type) (setf *experiment-log-current-object* object-type) (case object-type - (bowl (setf *experiment-log-current-execution-time-bowl* (roslisp:ros-time))) - (cup (setf *experiment-log-current-execution-time-cup* (roslisp:ros-time))) - (spoon (setf *experiment-log-current-execution-time-spoon* (roslisp:ros-time))))) + (:bowl (setf *experiment-log-current-execution-time-bowl* + (roslisp:ros-time))) + (:cup (setf *experiment-log-current-execution-time-cup* + (roslisp:ros-time))) + (:spoon (setf *experiment-log-current-execution-time-spoon* + (roslisp:ros-time))) + (:breakfast-cereal (setf *experiment-log-current-execution-time-breakfast-cereal* + (roslisp:ros-time))) + (:milk (setf *experiment-log-current-execution-time-milk* + (roslisp:ros-time))))) (defun experiment-log-finish-object-transport-successful (object-type) (when *experiment-log-detailed?* (experiment-log (format nil "TRANSPORTING SUCCEEDED~%"))) (case object-type - (bowl (setf *experiment-log-current-execution-time-bowl* - (- (roslisp:ros-time) *experiment-log-current-execution-time-bowl*))) - (cup (setf *experiment-log-current-execution-time-cup* - (- (roslisp:ros-time) *experiment-log-current-execution-time-cup*))) - (spoon (setf *experiment-log-current-execution-time-spoon* - (- (roslisp:ros-time) *experiment-log-current-execution-time-spoon*))))) + (:bowl (setf *experiment-log-current-execution-time-bowl* + (- (roslisp:ros-time) + *experiment-log-current-execution-time-bowl*))) + (:cup (setf *experiment-log-current-execution-time-cup* + (- (roslisp:ros-time) + *experiment-log-current-execution-time-cup*))) + (:spoon (setf *experiment-log-current-execution-time-spoon* + (- (roslisp:ros-time) + *experiment-log-current-execution-time-spoon*))) + (:breakfast-cereal (setf *experiment-log-current-execution-time-breakfast-cereal* + (- (roslisp:ros-time) + *experiment-log-current-execution-time-breakfast-cereal*))) + (:milk (setf *experiment-log-current-execution-time-milk* + (- (roslisp:ros-time) + *experiment-log-current-execution-time-milk*))))) (defun experiment-log-finish-object-transport-failed (object-type) (when *experiment-log-detailed?* (experiment-log (format nil "TRANSPORTING FAILED~%"))) (case object-type - (bowl (setf *experiment-log-current-execution-time-bowl* 0)) - (cup (setf *experiment-log-current-execution-time-cup* 0)) - (spoon (setf *experiment-log-current-execution-time-spoon* 0)))) + (:bowl (setf *experiment-log-current-execution-time-bowl* 0)) + (:cup (setf *experiment-log-current-execution-time-cup* 0)) + (:spoon (setf *experiment-log-current-execution-time-spoon* 0)) + (:breakfast-cereal (setf *experiment-log-current-execution-time-breakfast-cereal* 0)) + (:milk (setf *experiment-log-current-execution-time-milk* 0)))) diff --git a/cram_learning/cram_ralf_costmaps/CMakeLists.txt b/cram_learning/cram_ralf_costmaps/CMakeLists.txt new file mode 100644 index 0000000000..7fbed4b846 --- /dev/null +++ b/cram_learning/cram_ralf_costmaps/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 2.8.3) +project(cram_ralf_costmaps) +find_package(catkin REQUIRED) +catkin_package() + diff --git a/cram_learning/cram_ralf_costmaps/cram-ralf-costmaps.asd b/cram_learning/cram_ralf_costmaps/cram-ralf-costmaps.asd new file mode 100644 index 0000000000..1d80829cba --- /dev/null +++ b/cram_learning/cram_ralf_costmaps/cram-ralf-costmaps.asd @@ -0,0 +1,47 @@ +;;; +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; Sebastian Koralewski +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(defsystem cram-ralf-costmaps + :author "Sebastian Koralewski" + :maintainer "Gayane Kazhoyan" + :license "BSD" + + :depends-on (cram-prolog + cram-designators + cram-robot-interfaces + cram-manipulation-interfaces + cram-designator-specification + cram-location-costmap) + :components + ((:module "src" + :components + ((:file "package") + (:file "data" :depends-on ("package")) + (:file "prolog" :depends-on ("data" "package")))))) diff --git a/cram_learning/cram_ralf_costmaps/package.xml b/cram_learning/cram_ralf_costmaps/package.xml new file mode 100644 index 0000000000..926cf4dedc --- /dev/null +++ b/cram_learning/cram_ralf_costmaps/package.xml @@ -0,0 +1,21 @@ + + cram_ralf_costmaps + 0.7.0 + + CRAM interfaces to resolve location designators using + Sebastian's learning framework results + + Gayane Kazhoyan + Sebastian Koralewski + Gayane Kazhoyan + BSD + + catkin + + cram_prolog + cram_designators + cram_robot_interfaces + cram_manipulation_interfaces + cram_designator_specification + cram_location_costmap + diff --git a/cram_learning/cram_ralf_costmaps/src/data.lisp b/cram_learning/cram_ralf_costmaps/src/data.lisp new file mode 100644 index 0000000000..a20b616a11 --- /dev/null +++ b/cram_learning/cram_ralf_costmaps/src/data.lisp @@ -0,0 +1,100 @@ +;;; +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; Sebastian Koralewski +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :ralf-cm) + +(defvar *ralf-on* t) + +(defparameter *gaussians* + `((:iai-kitchen + (:reachable-for + (:breakfast-cereal + (:oven-area-area-right-drawer-main + ,(cl-transforms:make-3d-vector 0.75288949 0.75126507 0.0) + #2a((0.00334272 -0.00167905) (-0.00167905 0.01173699)))) + (:bowl + (:sink-area-left-middle-drawer-main + ,(cl-transforms:make-3d-vector 0.48262422 0.60007345 0.0) + #2a((0.01696884 -0.02503274) (-0.02503274 0.18154158))) + (:dining-area-jokkmokk-table-main + ,(cl-transforms:make-3d-vector -2.58749167 -0.17260023 0.0) + #2a((0.0004593 0.00107521) (0.00107521 0.01146658)))) + (:sink-area-left-middle-drawer-main + (NIL + ,(cl-transforms:make-3d-vector 0.3703701 1.28296277 0.0) + #2a((0.02345756 0.03769117) (0.03769117 0.0812215)))) + (:iai-fridge-door + (NIL + ,(cl-transforms:make-3d-vector 0.39157908 -0.65701128 0.0) + #2a((0.02198436 0.01780009) (0.01780009 0.031634)))) + (:oven-area-area-right-drawer-main + (NIL + ,(cl-transforms:make-3d-vector 0.52883482 2.06610992 0.0) + #2a((0.01591575 0.01717804) (0.01717804 0.02525052)))))) + (:store + (:reachable-for + (:balea-bottle + (:|DMShelfW100_EVZDYXFU| + ,(cl-transforms:make-3d-vector 1.61739825 -0.48690506 0.0) + #2a((0.03400717 -0.0018618) (-0.0018618 0.00555095))) + (:|DMFloorT6W100_YVLKGJSB| + ,(cl-transforms:make-3d-vector 3.28376786 -0.32065618 0.0) + #2A((0.00813238 -0.00511833) (-0.00511833 0.04660763)))) + (:dish-washer-tabs + (:|DMShelfW100_EVZDYXFU| + ,(cl-transforms:make-3d-vector 1.50413393 -0.49667084 0.0) + #2A((0.02513883 -0.003428) (-0.003428 0.00710252))) + (:|DMFloorT6W100_YVLKGJSB| + ,(cl-transforms:make-3d-vector 3.27839074 -0.70688138 0.0) + #2A((0.01067973 0.00101954) (0.00101954 0.02411302))))) + (:visible-for + (:balea-bottle + (:|DMShelfW100_EVZDYXFU| + ,(cl-transforms:make-3d-vector 1.71370355 -0.45481486 0.0) + #2a((0.06825158 0.00364417) (0.00364417 0.01066443)))) + (:dish-washer-tabs + (:|DMShelfW100_EVZDYXFU| + ,(cl-transforms:make-3d-vector 1.5766955 -0.46052179 0.0) + #2A((0.06646969 0.00576317) (0.00576317 0.01174357)))))))) + +(defun calculate-learned-mean-and-covariance (environment-name + location-type + object-type + reference-location-name) + (flet ((find-entry (key place) + (cdr (find key place :key #'car)))) + + (or (and *ralf-on* + (find-entry reference-location-name + (find-entry object-type + (find-entry location-type + (find-entry environment-name + *gaussians*))))) + '(nil nil)))) diff --git a/cram_learning/cram_ralf_costmaps/src/package.lisp b/cram_learning/cram_ralf_costmaps/src/package.lisp new file mode 100644 index 0000000000..216820736c --- /dev/null +++ b/cram_learning/cram_ralf_costmaps/src/package.lisp @@ -0,0 +1,35 @@ +;;; +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; Sebastian Koralewski +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :cl-user) + +(defpackage cram-ralf-costmaps + (:nicknames #:ralf-cm) + (:use #:common-lisp #:cram-prolog)) diff --git a/cram_learning/cram_ralf_costmaps/src/prolog.lisp b/cram_learning/cram_ralf_costmaps/src/prolog.lisp new file mode 100644 index 0000000000..95d3bfabd2 --- /dev/null +++ b/cram_learning/cram_ralf_costmaps/src/prolog.lisp @@ -0,0 +1,89 @@ +;;; +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; Sebastian Koralewski +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :ralf-cm) + +(defmethod costmap:costmap-generator-name->score + ((name (eql 'learned-pose-distribution))) + 3) + +(def-fact-group ralf-costmaps (costmap:desig-costmap) + (<- (costmap:desig-costmap ?some-designator ?costmap) + (desig:current-designator ?some-designator ?designator) + (once (or (and (rob-int:reachability-designator ?designator) + (equal ?location-type :reachable-for)) + (and (rob-int:visibility-designator ?designator) + (equal ?location-type :visible-for)))) + (spec:property ?designator (:object ?some-object-designator)) + (desig:current-designator ?some-object-designator ?object-designator) + (spec:property ?object-designator (:type ?object-type)) + (rob-int:environment-name ?environment-name) + (costmap:costmap ?costmap) + (-> (man-int:object-type-subtype :container ?object-type) + ;; opening/closing doors/drawers + (and (spec:property ?object-designator (:urdf-name ?container-name)) + ;; (spec:property ?object-designator (:part-of ?btr-environment)) + ;; (spec:property ?designator (:arm ?arm)) + (lisp-fun calculate-learned-mean-and-covariance + ?container-name nil + (?learned-mean ?learned-covariance)) + (lisp-pred identity ?learned-mean) + (costmap:costmap-add-function + learned-pose-distribution + (costmap:make-gauss-cost-function + ?learned-mean ?learned-covariance) + ?costmap)) + ;; fetching or placing items + (and + (once + (or + ;; if the object has a pose property, it's a recently perceived obj + (and (spec:property ?object-designator (:pose ?_)) + (spec:property ?object-designator (:location ?some-obj-loc))) + ;; otherwise, it's an object in hand or somewhere else on the robot + ;; or a yet unperceived object (latter only for visibility cms) + (spec:property ?designator (:location ?some-obj-loc)))) + (desig:current-designator ?some-obj-loc ?object-location) + (once (or (spec:property ?object-location (:on ?obj-loc-object)) + (spec:property ?object-location (:in ?obj-loc-object)))) + (desig:current-designator ?obj-loc-object ?object-location-object) + (spec:property ?object-location-object (:urdf-name ?ref-loc-name)) + (lisp-fun calculate-learned-mean-and-covariance + ?environment-name ?location-type + ?object-type ?ref-loc-name + (?learned-mean ?learned-covariance)) + (format "means: ~a~%~%" ?learned-mean) + (format "cov: ~a~%~%" ?learned-covariance) + (lisp-pred identity ?learned-mean) + (costmap:costmap-add-function + learned-pose-distribution + (costmap:make-gauss-cost-function + ?learned-mean ?learned-covariance) + ?costmap))))) diff --git a/cram_learning/cram_sim_log_generator/src/main.lisp b/cram_learning/cram_sim_log_generator/src/main.lisp index 8f3cf80bd1..a53c031235 100644 --- a/cram_learning/cram_sim_log_generator/src/main.lisp +++ b/cram_learning/cram_sim_log_generator/src/main.lisp @@ -1,6 +1,6 @@ (in-package :cslg) (defparameter *mongo-logger* nil) -(defparameter num-experiments 1) +(defparameter num-experiments 5) (defparameter connection-retries 0) (defparameter *start-time* 0) (defparameter *global-timer* 0) @@ -30,19 +30,18 @@ (defun main () (ros-load:load-system "cram_pr2_description" :cram-pr2-description) ;;(ros-load:load-system "cram_boxy_description" :cram-boxy-description) - (setf cram-bullet-reasoning-belief-state:*spawn-debug-window* nil) + ;;(setf cram-bullet-reasoning-belief-state:*spawn-debug-window* nil) (setf cram-tf:*tf-broadcasting-enabled* t) + (setf cram-urdf-projection-reasoning::*projection-checks-enabled* nil) (roslisp-utilities:startup-ros :name "cram" :anonymous nil) ;;(setq roslisp::*debug-stream* nil) (print "Init bullet world") - (setf ccl::*is-logging-enabled* t) - (ccl::init-logging) (loop for x from 0 to (- num-experiments 1) do (progn (print "Start") (ccl::start-episode) ;;(urdf-proj:with-simulated-robot (demo::demo-random nil )) - (urdf-proj:with-simulated-robot (demo::demo-random nil '(:bowl) )) + (urdf-proj:with-simulated-robot (demo::setting-demo '(:bowl))) (ccl::stop-episode) (print "End"))) (ccl::finish-logging)) diff --git a/cram_pr2/cram_pr2_process_modules/cram-pr2-process-modules.asd b/cram_pr2/cram_pr2_process_modules/cram-pr2-process-modules.asd index ee8e466ecb..4951cba13e 100644 --- a/cram_pr2/cram_pr2_process_modules/cram-pr2-process-modules.asd +++ b/cram_pr2/cram_pr2_process_modules/cram-pr2-process-modules.asd @@ -42,6 +42,7 @@ ;; cram-knowrob-world-state cram-robosherlock cram-giskard + cram-joint-states ; for joint state monitoring pm ;; cram-nav-pcontroller ) diff --git a/cram_pr2/cram_pr2_process_modules/launch/gazebo_kitchen_and_pr2.launch b/cram_pr2/cram_pr2_process_modules/launch/gazebo_kitchen_and_pr2.launch index ddc1dcd4c7..7def31130d 100644 --- a/cram_pr2/cram_pr2_process_modules/launch/gazebo_kitchen_and_pr2.launch +++ b/cram_pr2/cram_pr2_process_modules/launch/gazebo_kitchen_and_pr2.launch @@ -10,7 +10,7 @@ - + diff --git a/cram_pr2/cram_pr2_process_modules/package.xml b/cram_pr2/cram_pr2_process_modules/package.xml index b9dd1fc157..f8dd74ae5f 100644 --- a/cram_pr2/cram_pr2_process_modules/package.xml +++ b/cram_pr2/cram_pr2_process_modules/package.xml @@ -21,5 +21,6 @@ cram_knowrob_world_state cram_robosherlock cram_giskard + cram_joint_states diff --git a/cram_pr2/cram_pr2_process_modules/src/giskard.lisp b/cram_pr2/cram_pr2_process_modules/src/giskard.lisp index c8c4821d7d..51dba06942 100644 --- a/cram_pr2/cram_pr2_process_modules/src/giskard.lisp +++ b/cram_pr2/cram_pr2_process_modules/src/giskard.lisp @@ -29,56 +29,10 @@ (in-package :pr2-pms) -(cpm:def-process-module giskard-pm (motion-designator) - (destructuring-bind (command argument-1 &rest rest-args) - (desig:reference motion-designator) - (ecase command - (cram-common-designators:move-tcp - (giskard:call-arm-cartesian-action - :goal-pose-left argument-1 - :goal-pose-right (first rest-args) - :collision-mode (second rest-args) - :collision-object-b (third rest-args) - :collision-object-b-link (fourth rest-args) - :collision-object-a (fifth rest-args) - :move-base (sixth rest-args) - :prefer-base (seventh rest-args) - :align-planes-left (eighth rest-args) - :align-planes-right (ninth rest-args))) - (cram-common-designators:move-joints - (giskard:call-arm-joint-action - :goal-configuration-left argument-1 - :goal-configuration-right (first rest-args) - :align-planes-left (second rest-args) - :align-planes-right (third rest-args))) - (cram-common-designators:move-arm-pull - (giskard:call-environment-manipulation-action - :open-or-close :open - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-arm-push - (giskard:call-environment-manipulation-action - :open-or-close :close - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-head - (giskard:call-neck-action - :goal-pose argument-1)) - (cram-common-designators:move-base - (giskard:call-base-action - :goal-pose argument-1)) - (cram-common-designators:move-torso - (giskard:call-torso-action - :goal-joint-state argument-1))))) - (prolog:def-fact-group giskard-pm (cpm:matching-process-module cpm:available-process-module) - (prolog:<- (cpm:matching-process-module ?motion-designator giskard-pm) + (prolog:<- (cpm:matching-process-module ?motion-designator giskard:giskard-pm) (or (desig:desig-prop ?motion-designator (:type :moving-tcp)) (desig:desig-prop ?motion-designator (:type :moving-arm-joints)) (desig:desig-prop ?motion-designator (:type :pulling)) @@ -86,5 +40,5 @@ (desig:desig-prop ?motion-designator (:type :going)) (desig:desig-prop ?motion-designator (:type :moving-torso)))) - (prolog:<- (cpm:available-process-module giskard-pm) + (prolog:<- (cpm:available-process-module giskard:giskard-pm) (prolog:not (cpm:projection-running ?_)))) diff --git a/cram_pr2/cram_pr2_process_modules/src/with-real-robot.lisp b/cram_pr2/cram_pr2_process_modules/src/with-real-robot.lisp index 9645c52523..10d03958a1 100644 --- a/cram_pr2/cram_pr2_process_modules/src/with-real-robot.lisp +++ b/cram_pr2/cram_pr2_process_modules/src/with-real-robot.lisp @@ -32,6 +32,7 @@ (defmacro with-real-robot (&body body) `(cram-process-modules:with-process-modules-running (rs:robosherlock-perception-pm ;; navp:navp-pm - pr2-grippers-pm pr2-ptu-pm giskard-pm) + pr2-grippers-pm pr2-ptu-pm giskard:giskard-pm joints:joint-state-pm + common-desig:wait-pm) (cpl-impl::named-top-level (:name :top-level) ,@body))) diff --git a/cram_pr2/cram_pr2_sim_process_modules/cram-pr2-sim-process-modules.asd b/cram_pr2/cram_pr2_sim_process_modules/cram-pr2-sim-process-modules.asd index a5478672f8..f6b9714361 100644 --- a/cram_pr2/cram_pr2_sim_process_modules/cram-pr2-sim-process-modules.asd +++ b/cram_pr2/cram_pr2_sim_process_modules/cram-pr2-sim-process-modules.asd @@ -39,6 +39,7 @@ cram-common-designators cram-language ; for with-real-robot cram-giskard + cram-joint-states cram-urdf-projection) :components diff --git a/cram_pr2/cram_pr2_sim_process_modules/package.xml b/cram_pr2/cram_pr2_sim_process_modules/package.xml index 022102e759..86c2d9fcd7 100644 --- a/cram_pr2/cram_pr2_sim_process_modules/package.xml +++ b/cram_pr2/cram_pr2_sim_process_modules/package.xml @@ -18,5 +18,6 @@ cram_common_designators cram_language cram_giskard + cram_joint_states cram_urdf_projection diff --git a/cram_pr2/cram_pr2_sim_process_modules/src/giskard.lisp b/cram_pr2/cram_pr2_sim_process_modules/src/giskard.lisp index 081c2bd4ca..ceeb67ecc9 100644 --- a/cram_pr2/cram_pr2_sim_process_modules/src/giskard.lisp +++ b/cram_pr2/cram_pr2_sim_process_modules/src/giskard.lisp @@ -29,61 +29,10 @@ (in-package :pr2-sim-pms) -(cpm:def-process-module giskard-pm (motion-designator) - (destructuring-bind (command argument-1 &rest rest-args) - (desig:reference motion-designator) - (ecase command - (cram-common-designators:move-tcp - (giskard:call-arm-cartesian-action - :goal-pose-left argument-1 - :goal-pose-right (first rest-args) - :collision-mode (second rest-args) - :collision-object-b (third rest-args) - :collision-object-b-link (fourth rest-args) - :collision-object-a (fifth rest-args) - :move-base (sixth rest-args) - :prefer-base (seventh rest-args) - :align-planes-left (eighth rest-args) - :align-planes-right (ninth rest-args))) - (cram-common-designators:move-joints - (giskard:call-arm-joint-action - :goal-configuration-left argument-1 - :goal-configuration-right (first rest-args) - :align-planes-left (second rest-args) - :align-planes-right (third rest-args))) - (cram-common-designators:move-arm-pull - (giskard:call-environment-manipulation-action - :open-or-close :open - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-arm-push - (giskard:call-environment-manipulation-action - :open-or-close :close - :arm argument-1 - :handle-link (fifth rest-args) - :joint-angle (second rest-args) - :prefer-base (eighth rest-args))) - (cram-common-designators:move-head - (giskard:call-neck-action - :goal-pose argument-1)) - (cram-common-designators:move-base - (giskard:call-base-action - :goal-pose argument-1)) - (cram-common-designators:move-torso - (giskard:call-torso-action - :goal-joint-state argument-1)) - (cram-common-designators:move-gripper-joint - (giskard:call-gripper-action - :action-type-or-position argument-1 - :arm (first rest-args) - :effort (second rest-args)))))) - (prolog:def-fact-group giskard-pm (cpm:matching-process-module cpm:available-process-module) - (prolog:<- (cpm:matching-process-module ?motion-designator giskard-pm) + (prolog:<- (cpm:matching-process-module ?motion-designator giskard:giskard-pm) (or (desig:desig-prop ?motion-designator (:type :moving-tcp)) (desig:desig-prop ?motion-designator (:type :moving-arm-joints)) (desig:desig-prop ?motion-designator (:type :pulling)) @@ -96,5 +45,5 @@ (desig:desig-prop ?motion-designator (:type :closing-gripper)) (desig:desig-prop ?motion-designator (:type :moving-gripper-joint)))) - (prolog:<- (cpm:available-process-module giskard-pm) + (prolog:<- (cpm:available-process-module giskard:giskard-pm) (prolog:not (cpm:projection-running ?_)))) diff --git a/cram_pr2/cram_pr2_sim_process_modules/src/with-real-robot.lisp b/cram_pr2/cram_pr2_sim_process_modules/src/with-real-robot.lisp index 23d94cfc69..06d3ff2393 100644 --- a/cram_pr2/cram_pr2_sim_process_modules/src/with-real-robot.lisp +++ b/cram_pr2/cram_pr2_sim_process_modules/src/with-real-robot.lisp @@ -31,6 +31,6 @@ (defmacro with-real-robot (&body body) `(cram-process-modules:with-process-modules-running - (giskard-pm bullet-perception-pm) + (giskard:giskard-pm bullet-perception-pm joints:joint-state-pm) (cpl-impl::named-top-level (:name :top-level) ,@body))) diff --git a/cram_boxy/cram_boxy_description/CMakeLists.txt b/cram_robot_descriptions/cram_boxy_description/CMakeLists.txt similarity index 100% rename from cram_boxy/cram_boxy_description/CMakeLists.txt rename to cram_robot_descriptions/cram_boxy_description/CMakeLists.txt diff --git a/cram_boxy/cram_boxy_description/cram-boxy-description.asd b/cram_robot_descriptions/cram_boxy_description/cram-boxy-description.asd similarity index 100% rename from cram_boxy/cram_boxy_description/cram-boxy-description.asd rename to cram_robot_descriptions/cram_boxy_description/cram-boxy-description.asd diff --git a/cram_boxy/cram_boxy_description/package.xml b/cram_robot_descriptions/cram_boxy_description/package.xml similarity index 100% rename from cram_boxy/cram_boxy_description/package.xml rename to cram_robot_descriptions/cram_boxy_description/package.xml diff --git a/cram_boxy/cram_boxy_description/src/arms.lisp b/cram_robot_descriptions/cram_boxy_description/src/arms.lisp similarity index 93% rename from cram_boxy/cram_boxy_description/src/arms.lisp rename to cram_robot_descriptions/cram_boxy_description/src/arms.lisp index e5ff998509..80f60339f7 100644 --- a/cram_boxy/cram_boxy_description/src/arms.lisp +++ b/cram_robot_descriptions/cram_boxy_description/src/arms.lisp @@ -41,6 +41,8 @@ arm-joints arm-links hand-links hand-link hand-finger-link gripper-joint gripper-meter-to-joint-multiplier + gripper-minimal-position + gripper-convergence-delta standard<-particular-gripper-transform end-effector-link robot-tool-frame tcp-in-ee-pose @@ -111,6 +113,8 @@ (<- (gripper-joint :boxy-description :right "right_gripper_joint")) (<- (gripper-meter-to-joint-multiplier :boxy-description 1.0)) + (<- (gripper-minimal-position :boxy-description ?_ 0.0)) + (<- (gripper-convergence-delta :boxy-description ?_ 0.001)) (<- (standard<-particular-gripper-transform :boxy-description ?transform) (symbol-value *standard-to-boxy-gripper-transform* ?transform)) @@ -142,8 +146,14 @@ (<- (robot-joint-states :boxy-description :arm :left :carry-top-basket ?joint-states) (robot-joint-states :boxy-description :arm :left :carry ?joint-states)) - (<- (robot-joint-states :boxy-description :arm :left :hand-over ?joint-states) - (robot-joint-states :boxy-description :arm :left :carry ?joint-states)) + (<- (robot-joint-states :boxy-description :arm :left :hand-over + (("left_arm_0_joint" -0.32) + ("left_arm_1_joint" 1.8) + ("left_arm_2_joint" -0.74) + ("left_arm_3_joint" -1.49) + ("left_arm_4_joint" 2.29) + ("left_arm_5_joint" 1.68) + ("left_arm_6_joint" 0.2)))) (<- (robot-joint-states :boxy-description :arm :right :carry (("right_arm_0_joint" 1.858d0) diff --git a/cram_boxy/cram_boxy_description/src/general-knowledge.lisp b/cram_robot_descriptions/cram_boxy_description/src/general-knowledge.lisp similarity index 96% rename from cram_boxy/cram_boxy_description/src/general-knowledge.lisp rename to cram_robot_descriptions/cram_boxy_description/src/general-knowledge.lisp index ffd6fb3577..1bf715836e 100644 --- a/cram_boxy/cram_boxy_description/src/general-knowledge.lisp +++ b/cram_robot_descriptions/cram_boxy_description/src/general-knowledge.lisp @@ -30,10 +30,11 @@ (in-package :boxy-descr) (def-fact-group boxy-metadata (robot-odom-frame - robot-base-frame + robot-base-frame robot-base-link robot-torso-link-joint) (<- (robot-odom-frame :boxy-description "odom")) (<- (robot-base-frame :boxy-description "base_footprint")) + (<- (robot-base-link :boxy-description "base_link")) (<- (robot-torso-link-joint :boxy-description "triangle_base_link" "triangle_base_joint"))) diff --git a/cram_boxy/cram_boxy_description/src/neck.lisp b/cram_robot_descriptions/cram_boxy_description/src/neck.lisp similarity index 100% rename from cram_boxy/cram_boxy_description/src/neck.lisp rename to cram_robot_descriptions/cram_boxy_description/src/neck.lisp diff --git a/cram_boxy/cram_boxy_description/src/package.lisp b/cram_robot_descriptions/cram_boxy_description/src/package.lisp similarity index 100% rename from cram_boxy/cram_boxy_description/src/package.lisp rename to cram_robot_descriptions/cram_boxy_description/src/package.lisp diff --git a/cram_donbot/cram_donbot_description/CMakeLists.txt b/cram_robot_descriptions/cram_donbot_description/CMakeLists.txt similarity index 100% rename from cram_donbot/cram_donbot_description/CMakeLists.txt rename to cram_robot_descriptions/cram_donbot_description/CMakeLists.txt diff --git a/cram_donbot/cram_donbot_description/cram-donbot-description.asd b/cram_robot_descriptions/cram_donbot_description/cram-donbot-description.asd similarity index 100% rename from cram_donbot/cram_donbot_description/cram-donbot-description.asd rename to cram_robot_descriptions/cram_donbot_description/cram-donbot-description.asd diff --git a/cram_donbot/cram_donbot_description/package.xml b/cram_robot_descriptions/cram_donbot_description/package.xml similarity index 100% rename from cram_donbot/cram_donbot_description/package.xml rename to cram_robot_descriptions/cram_donbot_description/package.xml diff --git a/cram_donbot/cram_donbot_description/src/knowledge.lisp b/cram_robot_descriptions/cram_donbot_description/src/knowledge.lisp similarity index 91% rename from cram_donbot/cram_donbot_description/src/knowledge.lisp rename to cram_robot_descriptions/cram_donbot_description/src/knowledge.lisp index 8f44b4f551..48a951e452 100644 --- a/cram_donbot/cram_donbot_description/src/knowledge.lisp +++ b/cram_robot_descriptions/cram_donbot_description/src/knowledge.lisp @@ -31,8 +31,8 @@ (defparameter *tcp-in-ee-pose* (cl-transforms:make-pose - (cl-transforms:make-3d-vector 0 0 0.2581d0) - (cl-transforms:make-quaternion 0 0 -0.7071067811849626d0 -0.7071067811881324d0))) + (cl-transforms:make-3d-vector 0 0 0.2211) + (cl-transforms:make-quaternion 0 0 0.7071067811849626d0 0.7071067811881324d0))) (defparameter *standard-to-donbot-gripper-transform* (cl-transforms-stamped:make-identity-transform)) @@ -49,9 +49,9 @@ (def-fact-group donbot-metadata (robot-odom-frame - robot-base-frame robot-torso-link-joint - arm - neck + robot-base-frame robot-base-link + robot-torso-link-joint + arm neck camera-frame camera-minimal-height camera-maximal-height camera-horizontal-angle camera-vertical-angle) @@ -59,6 +59,7 @@ (<- (robot-odom-frame :iai-donbot "odom")) (<- (robot-base-frame :iai-donbot "base_footprint")) + (<- (robot-base-link :iai-donbot "base_link")) (<- (robot-torso-link-joint :iai-donbot "ur5_base_link" "arm_base_mounting_joint")) (<- (arm :iai-donbot :left)) @@ -69,17 +70,21 @@ (<- (camera-frame :iai-donbot "rs_camera_depth_optical_frame")) ; realsense, virtual (<- (camera-frame :iai-donbot "rs_camera_color_optical_frame")) ; virtual + ;; The visibility costmap makes no sense for Donbot, as it can move its arm anywhere. ;; (<- (camera-minimal-height :iai-donbot 0.5)) ;; (<- (camera-maximal-height :iai-donbot 1.2)) ;; These are values taken from the Kinect's wikipedia page for the 360 variant - (<- (camera-horizontal-angle donbot 0.99483)) - (<- (camera-vertical-angle donbot 0.75049))) + (<- (camera-horizontal-angle :iai-donbot 0.99483)) + (<- (camera-vertical-angle :iai-donbot 0.75049))) (def-fact-group donbot-arm-facts (arm-joints arm-links hand-links hand-link hand-finger-link - gripper-joint gripper-meter-to-joint-multiplier + gripper-joint + gripper-meter-to-joint-multiplier + gripper-minimal-position + gripper-convergence-delta standard<-particular-gripper-transform end-effector-link robot-tool-frame @@ -105,7 +110,9 @@ "gripper_finger_left_link" "gripper_finger_right_link" "gripper_gripper_left_link" - "gripper_gripper_right_link"))) + "gripper_gripper_right_link" + "marco_left_finger_link" + "marco_right_finger_link"))) (<- (hand-link :iai-donbot :left ?link) (bound ?link) @@ -123,6 +130,8 @@ (<- (gripper-joint :iai-donbot :left "gripper_joint")) (<- (gripper-meter-to-joint-multiplier :iai-donbot 1.0)) + (<- (gripper-minimal-position :iai-donbot ?_ 0.0)) + (<- (gripper-convergence-delta :iai-donbot ?_ 0.001)) (<- (standard<-particular-gripper-transform :iai-donbot ?transform) (symbol-value *standard-to-donbot-gripper-transform* ?transform)) @@ -236,12 +245,14 @@ costmap:orientation-samples costmap:orientation-sample-step costmap:reachability-orientation-offset + costmap:visibility-orientation-offset costmap:visibility-costmap-size) (<- (costmap:costmap-padding :iai-donbot 0.5)) (<- (costmap:costmap-manipulation-padding :iai-donbot 0.5)) - (<- (costmap:costmap-in-reach-distance :iai-donbot 1.1)) + (<- (costmap:costmap-in-reach-distance :iai-donbot 1.25)) (<- (costmap:costmap-reach-minimal-distance :iai-donbot 0.1)) (<- (costmap:orientation-samples :iai-donbot 1)) (<- (costmap:orientation-sample-step :iai-donbot 0.3)) (<- (costmap:reachability-orientation-offset :iai-donbot 1.57)) + (<- (costmap:visibility-orientation-offset :iai-donbot 1.57)) (<- (costmap:visibility-costmap-size :iai-donbot 2.0))) diff --git a/cram_donbot/cram_donbot_description/src/package.lisp b/cram_robot_descriptions/cram_donbot_description/src/package.lisp similarity index 100% rename from cram_donbot/cram_donbot_description/src/package.lisp rename to cram_robot_descriptions/cram_donbot_description/src/package.lisp diff --git a/cram_hsrb/cram_hsrb_description/CMakeLists.txt b/cram_robot_descriptions/cram_hsrb_description/CMakeLists.txt similarity index 100% rename from cram_hsrb/cram_hsrb_description/CMakeLists.txt rename to cram_robot_descriptions/cram_hsrb_description/CMakeLists.txt diff --git a/cram_hsrb/cram_hsrb_description/cram-hsrb-description.asd b/cram_robot_descriptions/cram_hsrb_description/cram-hsrb-description.asd similarity index 100% rename from cram_hsrb/cram_hsrb_description/cram-hsrb-description.asd rename to cram_robot_descriptions/cram_hsrb_description/cram-hsrb-description.asd diff --git a/cram_hsrb/cram_hsrb_description/package.xml b/cram_robot_descriptions/cram_hsrb_description/package.xml similarity index 100% rename from cram_hsrb/cram_hsrb_description/package.xml rename to cram_robot_descriptions/cram_hsrb_description/package.xml diff --git a/cram_hsrb/cram_hsrb_description/src/arms.lisp b/cram_robot_descriptions/cram_hsrb_description/src/arms.lisp similarity index 95% rename from cram_hsrb/cram_hsrb_description/src/arms.lisp rename to cram_robot_descriptions/cram_hsrb_description/src/arms.lisp index d842163f03..c1b487e192 100644 --- a/cram_hsrb/cram_hsrb_description/src/arms.lisp +++ b/cram_robot_descriptions/cram_hsrb_description/src/arms.lisp @@ -47,6 +47,8 @@ hand-links hand-link hand-finger-link gripper-joint gripper-meter-to-joint-multiplier + gripper-minimal-position + gripper-convergence-delta standard<-particular-gripper-transform end-effector-link robot-tool-frame @@ -85,6 +87,8 @@ (<- (gripper-joint :hsrb :left "hand_motor_joint")) (<- (gripper-meter-to-joint-multiplier :hsrb 1.0)) + (<- (gripper-minimal-position :hsrb ?_ 0.0)) + (<- (gripper-convergence-delta :hsrb ?_ 0.001)) (<- (standard<-particular-gripper-transform :hsrb ?transform) (symbol-value *standard-to-hsrb-gripper-transform* ?transform)) diff --git a/cram_hsrb/cram_hsrb_description/src/general-knowledge.lisp b/cram_robot_descriptions/cram_hsrb_description/src/general-knowledge.lisp similarity index 86% rename from cram_hsrb/cram_hsrb_description/src/general-knowledge.lisp rename to cram_robot_descriptions/cram_hsrb_description/src/general-knowledge.lisp index 0714947b51..ab2d05250c 100644 --- a/cram_hsrb/cram_hsrb_description/src/general-knowledge.lisp +++ b/cram_robot_descriptions/cram_hsrb_description/src/general-knowledge.lisp @@ -34,15 +34,19 @@ (cl-transforms:make-3d-vector 10.0 0.0 1.5)) (def-fact-group hsrb-metadata (robot-odom-frame - robot-base-frame robot-torso-link-joint + robot-base-frame robot-base-link + robot-torso-link-joint arm camera-frame camera-horizontal-angle camera-vertical-angle robot-neck-links robot-neck-joints + robot-neck-pan-joint-forward-facing-axis-sign + robot-neck-tilt-joint-forward-facing-axis-sign robot-joint-states robot-pose) (<- (robot-odom-frame :hsrb "odom")) (<- (robot-base-frame :hsrb "base_footprint")) + (<- (robot-base-link :hsrb "base_link")) (<- (robot-torso-link-joint :hsrb "arm_lift_link" "arm_lift_joint")) (<- (camera-frame :hsrb "head_center_camera_frame")) @@ -55,6 +59,12 @@ (<- (robot-neck-links :hsrb "head_pan_link" "head_tilt_link")) (<- (robot-neck-joints :hsrb "head_pan_joint" "head_tilt_joint")) + ;; TODO: this needs to be corrected for this robot: + (<- (robot-neck-pan-joint-forward-facing-axis-sign :hsrb + cl-transforms:x +1)) + (<- (robot-neck-tilt-joint-forward-facing-axis-sign :hsrb + cl-transforms:x +1)) + (<- (robot-joint-states :hsrb :neck ?_ :forward ((?pan_joint 0.0) (?tilt_joint 0.0))) (robot-neck-joints :hsrb ?pan_joint ?tilt_joint)) diff --git a/cram_hsrb/cram_hsrb_description/src/package.lisp b/cram_robot_descriptions/cram_hsrb_description/src/package.lisp similarity index 100% rename from cram_hsrb/cram_hsrb_description/src/package.lisp rename to cram_robot_descriptions/cram_hsrb_description/src/package.lisp diff --git a/cram_robot_descriptions/cram_kukabot_description/CMakeLists.txt b/cram_robot_descriptions/cram_kukabot_description/CMakeLists.txt new file mode 100644 index 0000000000..0af7829aac --- /dev/null +++ b/cram_robot_descriptions/cram_kukabot_description/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 2.8.3) +project(cram_kukabot_description) +find_package(catkin REQUIRED) +catkin_package() + diff --git a/cram_robot_descriptions/cram_kukabot_description/cram-kukabot-description.asd b/cram_robot_descriptions/cram_kukabot_description/cram-kukabot-description.asd new file mode 100644 index 0000000000..591c1a8cc4 --- /dev/null +++ b/cram_robot_descriptions/cram_kukabot_description/cram-kukabot-description.asd @@ -0,0 +1,42 @@ +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Intelligent Autonomous Systems Group/ +;;; Technische Universitaet Muenchen nor the names of its contributors +;;; may be used to endorse or promote products derived from this software +;;; without specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(defsystem cram-kukabot-description + :author "Gayane Kazhoyan" + :maintainer "Gayane Kazhoyan" + :license "BSD" + + :depends-on (cram-prolog + cram-robot-interfaces + cram-location-costmap ; for robot-specific costmap metadata + ) + :components + ((:module "src" + :components + ((:file "package") + (:file "knowledge" :depends-on ("package")))))) diff --git a/cram_robot_descriptions/cram_kukabot_description/package.xml b/cram_robot_descriptions/cram_kukabot_description/package.xml new file mode 100644 index 0000000000..42904200a0 --- /dev/null +++ b/cram_robot_descriptions/cram_kukabot_description/package.xml @@ -0,0 +1,16 @@ + + cram_kukabot_description + 0.7.0 + + Prolog predicates describing Kukabot the robot + + Gayane Kazhoyan + Gayane Kazhoyan + BSD + + catkin + + cram_prolog + cram_robot_interfaces + cram_location_costmap + diff --git a/cram_robot_descriptions/cram_kukabot_description/src/knowledge.lisp b/cram_robot_descriptions/cram_kukabot_description/src/knowledge.lisp new file mode 100644 index 0000000000..56be9cff96 --- /dev/null +++ b/cram_robot_descriptions/cram_kukabot_description/src/knowledge.lisp @@ -0,0 +1,272 @@ +;;; +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :kukabot-descr) + +(defparameter *tcp-in-ee-pose* + (cl-transforms:make-pose + (cl-transforms:make-3d-vector 0 0 0.2291) + (cl-transforms:make-quaternion 0 0 1 0))) + +(defparameter *standard-to-donbot-gripper-transform* + (cl-transforms-stamped:make-identity-transform)) + +(defparameter *ee-p-camera* + (cl-transforms:make-pose + (cl-transforms:make-3d-vector -0.001328999336864145d0 + 0.06619000048451928d0 + 0.11668299973270257d0) + (cl-transforms:make-quaternion 0.11535978142567395d0 + -0.0013328246250186582d0 + 0.0036558132247416775d0 + 0.9933161528121878d0))) + + +(def-fact-group kukabot-metadata (robot-odom-frame + robot-base-frame robot-base-link + robot-torso-link-joint + arm neck + camera-frame + camera-minimal-height camera-maximal-height + camera-horizontal-angle camera-vertical-angle) + + (<- (robot-odom-frame :kmr-iiwa "odom")) + + (<- (robot-base-frame :kmr-iiwa "base_link")) + (<- (robot-base-link :kmr-iiwa "base_link")) + (<- (robot-torso-link-joint :kmr-iiwa "angle_adapter_plate" "angle_adapter_plate_joint")) + + (<- (arm :kmr-iiwa :left)) + + (<- (neck :kmr-iiwa :left)) + + (<- (camera-frame :kmr-iiwa "camera_link")) ; rgb camera for barcodes etc. + ;; (<- (camera-frame :kmr-iiwa "rs_camera_depth_optical_frame")) ; realsense, virtual + ;; (<- (camera-frame :kmr-iiwa "rs_camera_color_optical_frame")) + ; virtual + + ;; The visibility costmap makes no sense for Kukabot, as it can move its arm anywhere. + ;; (<- (camera-minimal-height :kmr-iiwa 0.7)) + ;; (<- (camera-maximal-height :kmr-iiwa 2.0)) + + ;; These are values taken from the Kinect's wikipedia page for the 360 variant + (<- (camera-horizontal-angle :kmr-iiwa 0.99483)) + (<- (camera-vertical-angle :kmr-iiwa 0.75049))) + + +(def-fact-group kukabot-arm-facts (arm-joints + arm-links + hand-links hand-link hand-finger-link + gripper-joint + gripper-meter-to-joint-multiplier + gripper-minimal-position + gripper-convergence-delta + standard<-particular-gripper-transform + end-effector-link + robot-tool-frame + tcp-in-ee-pose + robot-joint-states) + + (<- (arm-joints :kmr-iiwa :left ("iiwa_joint_1" + "iiwa_joint_2" + "iiwa_joint_3" + "iiwa_joint_4" + "iiwa_joint_5" + "iiwa_joint_6" + "iiwa_joint_7"))) + + (<- (arm-links :kmr-iiwa :left ("iiwa_link_1" + "iiwa_link_2" + "iiwa_link_3" + "iiwa_link_4" + "iiwa_link_5" + "iiwa_link_6" + "iiwa_link_7"))) + + (<- (hand-links :kmr-iiwa :left ("wrist_collision" + "fwk_fwa_050_frame_in" + "camera_holder_link" + "gripper_base_link" + "gripper_finger_left_link" + "gripper_finger_right_link"))) + + (<- (hand-link :kmr-iiwa :left ?link) + (bound ?link) + (or (and (lisp-fun search "gripper_" ?link ?pos) + (lisp-pred identity ?pos)) + (and (lisp-fun search "finger" ?link ?pos) + (lisp-pred identity ?pos)))) + + (<- (hand-finger-link :kmr-iiwa ?arm ?link) + (bound ?link) + (hand-link :kmr-iiwa ?arm ?link) + (lisp-fun search "finger" ?link ?pos) + (lisp-pred identity ?pos)) + + (<- (gripper-joint :kmr-iiwa :left "gripper_joint")) + + (<- (gripper-meter-to-joint-multiplier :kmr-iiwa 1.0)) + (<- (gripper-minimal-position :kmr-iiwa ?_ 0.0)) + (<- (gripper-convergence-delta :kmr-iiwa ?_ 0.001)) + + (<- (standard<-particular-gripper-transform :kmr-iiwa ?transform) + (symbol-value *standard-to-donbot-gripper-transform* ?transform)) + + (<- (end-effector-link :kmr-iiwa :left "iiwa_link_7")) + + (<- (robot-tool-frame :kmr-iiwa :left "gripper_tool_frame")) + + (<- (tcp-in-ee-pose :kmr-iiwa ?pose) + (symbol-value *tcp-in-ee-pose* ?pose)) + + (<- (robot-joint-states :kmr-iiwa :arm :left :carry + (("iiwa_joint_1" 0.0) + ("iiwa_joint_2" -1.28) + ("iiwa_joint_3" 0.0) + ("iiwa_joint_4" 1.29) + ("iiwa_joint_5" 0.0) + ("iiwa_joint_6" -1.0) + ("iiwa_joint_7" 1.57)))) + (<- (robot-joint-states :kmr-iiwa :arm :left :park + (("iiwa_joint_1" 0.0) + ("iiwa_joint_2" -1.23) + ("iiwa_joint_3" 0.0) + ("iiwa_joint_4" 1.38999978643) + ("iiwa_joint_5" 0.0) + ("iiwa_joint_6" -0.85) + ("iiwa_joint_7" 0.0)))) + (<- (robot-joint-states :kmr-iiwa :arm :left :carry-top ?joint-states) + (robot-joint-states :kmr-iiwa :arm :left :carry ?joint-states)) + (<- (robot-joint-states :kmr-iiwa :arm :left :carry-side-gripper-vertical + ?joint-states) + (robot-joint-states :kmr-iiwa :arm :left :carry ?joint-states))) + + + +(def-fact-group kukabot-neck-facts (robot-neck-links + robot-neck-joints + robot-neck-base-link + camera-in-neck-ee-pose + neck-camera-z-offset + neck-camera-pose-unit-vector-multiplier + neck-camera-resampling-step + neck-camera-x-axis-limit + neck-camera-y-axis-limit + neck-camera-z-axis-limit + robot-joint-states) + + (<- (robot-neck-links :kmr-iiwa . ?links) + (arm-links :kmr-iiwa :left ?links)) + + (<- (robot-neck-joints :kmr-iiwa . ?joints) + (arm-joints :kmr-iiwa :left ?joints)) + + (<- (robot-neck-base-link :kmr-iiwa "iiwa_link_0")) + + (<- (camera-in-neck-ee-pose :kmr-iiwa ?pose) + (symbol-value *ee-p-camera* ?pose)) + + (<- (neck-camera-z-offset :kmr-iiwa 0.7)) + (<- (neck-camera-pose-unit-vector-multiplier :kmr-iiwa 0.5)) + (<- (neck-camera-resampling-step :kmr-iiwa 0.2)) + (<- (neck-camera-x-axis-limit :kmr-iiwa 0.5)) + (<- (neck-camera-y-axis-limit :kmr-iiwa 0.5)) + (<- (neck-camera-z-axis-limit :kmr-iiwa 0.2)) + + (<- (robot-joint-states :kmr-iiwa :neck ?there-is-only-one-neck :away + (("iiwa_joint_1" 0.0) + ("iiwa_joint_2" -1.23) + ("iiwa_joint_3" 0.0) + ("iiwa_joint_4" 1.38999978643) + ("iiwa_joint_5" 0.0) + ("iiwa_joint_6" -0.85) + ("iiwa_joint_7" 0.0)))) + (<- (robot-joint-states :kmr-iiwa :neck ?there-is-only-one-neck :forward + (("iiwa_joint_1" 0.87564548888) + ("iiwa_joint_2" -1.18868177242) + ("iiwa_joint_3" -0.611353182624) + ("iiwa_joint_4" 1.53584067968) + ("iiwa_joint_5" 1.81510903672) + ("iiwa_joint_6" -1.63964857509) + ("iiwa_joint_7" -0.16138790158)))) + (<- (robot-joint-states :kmr-iiwa :neck ?there-is-only-one-neck :down + (("iiwa_joint_1" 0.0) + ("iiwa_joint_2" -1.23) + ("iiwa_joint_3" 0.0) + ("iiwa_joint_4" 1.38999978643) + ("iiwa_joint_5" 0.0) + ("iiwa_joint_6" -0.85) + ("iiwa_joint_7" 0.0)))) + (<- (robot-joint-states :kmr-iiwa :neck ?there-is-only-one-neck :right + (("iiwa_joint_1" 0.0) + ("iiwa_joint_2" -1.23) + ("iiwa_joint_3" 0.0) + ("iiwa_joint_4" 1.38999978643) + ("iiwa_joint_5" 0.0) + ("iiwa_joint_6" -0.85) + ("iiwa_joint_7" 0.0)))) + (<- (robot-joint-states :kmr-iiwa :neck ?there-is-only-one-neck + :right-separators + (("iiwa_joint_1" 0.0) + ("iiwa_joint_2" -1.23) + ("iiwa_joint_3" 0.0) + ("iiwa_joint_4" 1.38999978643) + ("iiwa_joint_5" 0.0) + ("iiwa_joint_6" -0.85) + ("iiwa_joint_7" 0.0)))) + (<- (robot-joint-states :kmr-iiwa :neck ?there-is-only-one-neck + :right-separators-preplace-state + (("iiwa_joint_1" 0.0) + ("iiwa_joint_2" -1.23) + ("iiwa_joint_3" 0.0) + ("iiwa_joint_4" 1.38999978643) + ("iiwa_joint_5" 0.0) + ("iiwa_joint_6" -0.85) + ("iiwa_joint_7" 0.0))))) + + +(def-fact-group location-costmap-metadata (costmap:costmap-padding + costmap:costmap-manipulation-padding + costmap:costmap-in-reach-distance + costmap:costmap-reach-minimal-distance + costmap:orientation-samples + costmap:orientation-sample-step + costmap:reachability-orientation-offset + costmap:visibility-orientation-offset + costmap:visibility-costmap-size) + (<- (costmap:costmap-padding :kmr-iiwa 0.5)) + (<- (costmap:costmap-manipulation-padding :kmr-iiwa 0.3)) + (<- (costmap:costmap-in-reach-distance :kmr-iiwa 1.4)) + (<- (costmap:costmap-reach-minimal-distance :kmr-iiwa 0.1)) + (<- (costmap:orientation-samples :kmr-iiwa 3)) + (<- (costmap:orientation-sample-step :kmr-iiwa 0.7854)) + (<- (costmap:reachability-orientation-offset :kmr-iiwa 0.0)) + (<- (costmap:visibility-orientation-offset :kmr-iiwa ?offset) + (costmap:reachability-orientation-offset :kmr-iiwa ?offset)) + (<- (costmap:visibility-costmap-size :kmr-iiwa 2.0))) diff --git a/cram_robot_descriptions/cram_kukabot_description/src/package.lisp b/cram_robot_descriptions/cram_kukabot_description/src/package.lisp new file mode 100644 index 0000000000..57a032d6df --- /dev/null +++ b/cram_robot_descriptions/cram_kukabot_description/src/package.lisp @@ -0,0 +1,34 @@ +;;; +;;; Copyright (c) 2020, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :cl-user) + +(defpackage cram-kukabot-description + (:nicknames #:kukabot-descr) + (:use #:common-lisp #:cram-prolog #:cram-robot-interfaces)) diff --git a/cram_pr2/cram_pr2_description/CMakeLists.txt b/cram_robot_descriptions/cram_pr2_description/CMakeLists.txt similarity index 100% rename from cram_pr2/cram_pr2_description/CMakeLists.txt rename to cram_robot_descriptions/cram_pr2_description/CMakeLists.txt diff --git a/cram_pr2/cram_pr2_description/cram-pr2-description.asd b/cram_robot_descriptions/cram_pr2_description/cram-pr2-description.asd similarity index 100% rename from cram_pr2/cram_pr2_description/cram-pr2-description.asd rename to cram_robot_descriptions/cram_pr2_description/cram-pr2-description.asd diff --git a/cram_pr2/cram_pr2_description/package.xml b/cram_robot_descriptions/cram_pr2_description/package.xml similarity index 100% rename from cram_pr2/cram_pr2_description/package.xml rename to cram_robot_descriptions/cram_pr2_description/package.xml diff --git a/cram_pr2/cram_pr2_description/src/arm-kinematics.lisp b/cram_robot_descriptions/cram_pr2_description/src/arm-kinematics.lisp similarity index 91% rename from cram_pr2/cram_pr2_description/src/arm-kinematics.lisp rename to cram_robot_descriptions/cram_pr2_description/src/arm-kinematics.lisp index 6ffbd1b079..cf33676341 100644 --- a/cram_pr2/cram_pr2_description/src/arm-kinematics.lisp +++ b/cram_robot_descriptions/cram_pr2_description/src/arm-kinematics.lisp @@ -159,6 +159,8 @@ hand-links hand-link hand-finger-link gripper-joint gripper-meter-to-joint-multiplier + gripper-minimal-position + gripper-convergence-delta standard<-particular-gripper-transform end-effector-link robot-tool-frame tcp-in-ee-pose @@ -191,12 +193,16 @@ (lisp-fun search "finger" ?link ?pos) (lisp-pred identity ?pos)) + ;; (<- (gripper-joint :pr2 :left "l_gripper_joint")) + ;; (<- (gripper-joint :pr2 :right "r_gripper_joint")) (<- (gripper-joint :pr2 :left "l_gripper_l_finger_joint")) (<- (gripper-joint :pr2 :left "l_gripper_r_finger_joint")) (<- (gripper-joint :pr2 :right "r_gripper_l_finger_joint")) (<- (gripper-joint :pr2 :right "r_gripper_r_finger_joint")) (<- (gripper-meter-to-joint-multiplier :pr2 5.0)) + (<- (gripper-minimal-position :pr2 ?_ 0.013)) + (<- (gripper-convergence-delta :pr2 ?_ 0.005)) (<- (standard<-particular-gripper-transform :pr2 ?transform) (symbol-value *standard-to-pr2-gripper-transform* ?transform)) @@ -263,6 +269,14 @@ ("l_forearm_roll_joint" 0.8809236347313467d0) ("l_wrist_flex_joint" -0.9276887874976607d0) ("l_wrist_roll_joint" 2.3644392879261957d0)))) + (<- (robot-joint-states :pr2 :arm :left :carry-tray + (("l_shoulder_pan_joint" 0.5093452794519218d0) + ("l_shoulder_lift_joint" -0.3409151070391534d0) + ("l_upper_arm_roll_joint" 0.7237617139225473d0) + ("l_elbow_flex_joint" -1.1711686511880242d0) + ("l_forearm_roll_joint" 0.9029896286150922d0) + ("l_wrist_flex_joint" -1.5572577906669434d0) + ("l_wrist_roll_joint" 1.9999842405583337d0)))) (<- (robot-joint-states :pr2 :arm :left :tucked (("l_shoulder_pan_joint" 0.1709440184822959d0) ("l_shoulder_lift_joint" 1.1472294789783886d0) @@ -306,6 +320,14 @@ ("r_forearm_roll_joint" -0.5d0) ("r_wrist_flex_joint" -0.7163017685583473d0) ("r_wrist_roll_joint" 0.37943005734078916d0)))) + (<- (robot-joint-states :pr2 :arm :right :carry-tray + (("r_shoulder_pan_joint" -0.5091745530984966d0) + ("r_shoulder_lift_joint" -0.3407352620327657d0) + ("r_upper_arm_roll_joint" -0.7233501125737374d0) + ("r_elbow_flex_joint" -1.1711969086974978d0) + ("r_forearm_roll_joint" -0.9033955737280515d0) + ("r_wrist_flex_joint" -1.5575236188499488d0) + ("r_wrist_roll_joint" 1.1418180038095498d0)))) (<- (robot-joint-states :pr2 :arm :right :tucked (("r_shoulder_pan_joint" -0.08181428617939712d0) ("r_shoulder_lift_joint" 0.9781030555170612d0) diff --git a/cram_pr2/cram_pr2_description/src/package.lisp b/cram_robot_descriptions/cram_pr2_description/src/package.lisp similarity index 100% rename from cram_pr2/cram_pr2_description/src/package.lisp rename to cram_robot_descriptions/cram_pr2_description/src/package.lisp diff --git a/cram_pr2/cram_pr2_description/src/pr2-knowledge.lisp b/cram_robot_descriptions/cram_pr2_description/src/pr2-knowledge.lisp similarity index 84% rename from cram_pr2/cram_pr2_description/src/pr2-knowledge.lisp rename to cram_robot_descriptions/cram_pr2_description/src/pr2-knowledge.lisp index c2d4705d7c..16fde2dc6d 100644 --- a/cram_pr2/cram_pr2_description/src/pr2-knowledge.lisp +++ b/cram_robot_descriptions/cram_pr2_description/src/pr2-knowledge.lisp @@ -31,21 +31,26 @@ (defparameter *forward-looking-position-in-base-frame* (cl-transforms:make-3d-vector 10.0 0.0 1.5)) -(def-fact-group pr2-metadata (robot-base-frame robot-torso-link-joint - robot-odom-frame - camera-frame camera-minimal-height camera-maximal-height +(def-fact-group pr2-metadata (robot-odom-frame + robot-base-frame robot-base-link + robot-torso-link-joint + camera-frame + camera-minimal-height camera-maximal-height camera-horizontal-angle camera-vertical-angle robot-neck-links robot-neck-joints + robot-neck-pan-joint-forward-facing-axis-sign + robot-neck-tilt-joint-forward-facing-axis-sign robot-joint-states robot-pose) (<- (robot-odom-frame :pr2 "odom_combined")) (<- (robot-base-frame :pr2 "base_footprint")) + (<- (robot-base-link :pr2 "base_link")) (<- (robot-torso-link-joint :pr2 "torso_lift_link" "torso_lift_joint")) + (<- (camera-frame :pr2 "narrow_stereo_optical_frame")) (<- (camera-frame :pr2 "head_mount_kinect_rgb_optical_frame")) (<- (camera-frame :pr2 "openni_rgb_optical_frame")) - (<- (camera-frame :pr2 "narrow_stereo_optical_frame")) (<- (camera-minimal-height :pr2 1.27)) (<- (camera-maximal-height :pr2 1.60)) @@ -57,6 +62,11 @@ (<- (robot-neck-links :pr2 "head_pan_link" "head_tilt_link")) (<- (robot-neck-joints :pr2 "head_pan_joint" "head_tilt_joint")) + (<- (robot-neck-pan-joint-forward-facing-axis-sign :pr2 + cl-transforms:x +1)) + (<- (robot-neck-tilt-joint-forward-facing-axis-sign :pr2 + cl-transforms:x -1)) + (<- (robot-joint-states :pr2 :neck ?_ :forward ((?pan_joint 0.0) (?tilt_joint 0.0))) (robot-neck-joints :pr2 ?pan_joint ?tilt_joint)) @@ -77,7 +87,7 @@ costmap:visibility-costmap-size) (<- (costmap:costmap-padding :pr2 0.3)) (<- (costmap:costmap-manipulation-padding :pr2 0.4)) - (<- (costmap:costmap-in-reach-distance :pr2 1.0)) + (<- (costmap:costmap-in-reach-distance :pr2 1.05)) (<- (costmap:costmap-reach-minimal-distance :pr2 0.2)) (<- (costmap:orientation-samples :pr2 1)) (<- (costmap:orientation-sample-step :pr2 0.3)) diff --git a/cram_robot_descriptions/cram_tiago_description/CMakeLists.txt b/cram_robot_descriptions/cram_tiago_description/CMakeLists.txt new file mode 100644 index 0000000000..2ed5faad54 --- /dev/null +++ b/cram_robot_descriptions/cram_tiago_description/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 2.8.3) +project(cram_tiago_description) +find_package(catkin REQUIRED) +catkin_package() + diff --git a/cram_robot_descriptions/cram_tiago_description/cram-tiago-description.asd b/cram_robot_descriptions/cram_tiago_description/cram-tiago-description.asd new file mode 100644 index 0000000000..1dd68890de --- /dev/null +++ b/cram_robot_descriptions/cram_tiago_description/cram-tiago-description.asd @@ -0,0 +1,43 @@ +;;; +;;; Copyright (c) 2022, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(defsystem cram-tiago-description + :author "Gayane Kazhoyan" + :maintainer "Gayane Kazhoyan" + :license "BSD" + + :depends-on (cram-prolog + cram-robot-interfaces + cram-location-costmap ; for robot-specific costmap metadata + ) + :components + ((:module "src" + :components + ((:file "package") + (:file "knowledge" :depends-on ("package")))))) diff --git a/cram_robot_descriptions/cram_tiago_description/package.xml b/cram_robot_descriptions/cram_tiago_description/package.xml new file mode 100644 index 0000000000..6341d653db --- /dev/null +++ b/cram_robot_descriptions/cram_tiago_description/package.xml @@ -0,0 +1,16 @@ + + cram_tiago_description + 0.8.0 + + Prolog predicates describing the Tiago robot + + Gayane Kazhoyan + Gayane Kazhoyan + BSD + + catkin + + cram_prolog + cram_robot_interfaces + cram_location_costmap + diff --git a/cram_robot_descriptions/cram_tiago_description/src/knowledge.lisp b/cram_robot_descriptions/cram_tiago_description/src/knowledge.lisp new file mode 100644 index 0000000000..c59cb6311a --- /dev/null +++ b/cram_robot_descriptions/cram_tiago_description/src/knowledge.lisp @@ -0,0 +1,436 @@ +;;; +;;; Copyright (c) 2022, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :tiago-descr) + +(defparameter *forward-looking-position-in-base-frame* + (cl-transforms:make-3d-vector 10.0 0.0 0.9)) + +;; TODO: this can be different for different hands +#+use-this-function-to-calculate-tcp-in-ee-pose +(defun calculate-tcp-in-ee-pose-from-bullet (robot-name arm-alias) + (let* ((map-P-tcp + (btr:link-pose + (btr:get-robot-object) + (cut:var-value + '?link + (cut:lazy-car + (prolog:prolog + `(rob-int:robot-tool-frame ,robot-name ,arm-alias ?link)))))) + (map-P-ee + (btr:link-pose + (btr:get-robot-object) + (cut:var-value + '?link + (cut:lazy-car + (prolog:prolog + `(rob-int:end-effector-link ,robot-name ,arm-alias ?link)))))) + (ee-T-map + (cl-transforms:transform-inv + (cl-transforms:pose->transform map-P-ee)))) + (cl-transforms:transform ee-T-map map-P-tcp))) +(defparameter *tcp-in-ee-pose* + (cl-transforms:make-pose + ;; The X should've been 0.150575d0, but the grasping frame is defined + ;; on Tiago in such a shitty way that have to use a custom offset :/ + (cl-transforms:make-3d-vector 0.24d0 0 0) + (cl-transforms-stamped:make-quaternion 0.7071054825100438d0 + -1.2986782349788673d-6 + 1.298673464711353d-6 + 0.707108079858281d0))) + +;; This is std-gripper-T-gripper +;; standard Z - towards object +;; standard X - from one finger to another +;; standard Y - right hand rule +#+visualize-the-gripper-frame-with-the-following-function +(defun visualize-gripper-frame-in-bullet (robot-name arm-alias) + (btr:add-vis-axis-object + (btr:link-pose + (btr:get-robot-object) + (cut:var-value + '?link + (cut:lazy-car + (prolog:prolog + `(rob-int:robot-tool-frame ,robot-name ,arm-alias ?link))))))) +(defparameter *standard-to-tiago-gripper-transform* + (cl-transforms:make-transform + (cl-transforms:make-identity-vector) + (cl-transforms:matrix->quaternion + #2A((0 1 0) + (0 0 1) + (1 0 0))))) + +(def-fact-group tiago-metadata (robot-odom-frame + robot-base-frame robot-base-link + robot-torso-link-joint) + (<- (robot-odom-frame :tiago-dual "odom")) + (<- (robot-base-frame :tiago-dual "base_footprint")) + (<- (robot-base-link :tiago-dual "base_link")) + (<- (robot-torso-link-joint :tiago-dual "torso_lift_link" "torso_lift_joint"))) + +(def-fact-group tiago-camera-data (camera-frame + camera-minimal-height + camera-maximal-height + camera-horizontal-angle + camera-vertical-angle) + + (<- (camera-frame :tiago-dual "xtion_optical_frame")) + (<- (camera-frame :tiago-dual "xtion_rgb_optical_frame")) + (<- (camera-frame :tiago-dual "xtion_depth_frame")) + + #+calculate-with-the-following-function-in-bullet + (defun calculate-cam-min-and-max-height-from-bullet (robot-name) + (let* ((torso-joint-name + (cut:var-value + '?joint + (cut:lazy-car + (prolog:prolog + `(rob-int:robot-torso-link-joint ,robot-name ?link ?joint))))) + (torso-low-limit + (rob-int:get-joint-lower-limit torso-joint-name)) + (torso-high-limit + (rob-int:get-joint-upper-limit torso-joint-name)) + (camera-link-name + (cut:var-value + '?link + (cut:lazy-car + (prolog:prolog + `(rob-int:camera-frame ,robot-name ?link))))) + camera-low-z camera-high-z) + (setf (btr:joint-state (btr:get-robot-object) torso-joint-name) + torso-low-limit) + (setf camera-low-z + (cl-transforms:z + (cl-transforms:origin + (btr:link-pose (btr:get-robot-object) camera-link-name)))) + (setf (btr:joint-state (btr:get-robot-object) torso-joint-name) + torso-high-limit) + (setf camera-high-z + (cl-transforms:z + (cl-transforms:origin + (btr:link-pose (btr:get-robot-object) camera-link-name)))) + (list camera-low-z camera-high-z))) + (<- (camera-minimal-height :tiago-dual 1.0665)) + (<- (camera-maximal-height :tiago-dual 1.4165)) + + ;; These are values taken from the Kinect's wikipedia page + ;; for the 360 variant of a Kinect. + ;; Tiago has an xtion but it should be more or less similar. + (<- (camera-horizontal-angle :tiago-dual 0.99483)) ; ca 57 degrees + (<- (camera-vertical-angle :tiago-dual 0.75049)) ; ca 43 degrees + ) + +(def-fact-group tiago-neck-data (robot-neck-links + robot-neck-joints + robot-neck-pan-joint-forward-facing-axis-sign + robot-neck-tilt-joint-forward-facing-axis-sign + robot-joint-states + robot-pose) + + (<- (robot-neck-links :tiago-dual "head_1_link" "head_2_link")) + (<- (robot-neck-joints :tiago-dual "head_1_joint" "head_2_joint")) + + (<- (robot-neck-pan-joint-forward-facing-axis-sign :tiago-dual + cl-transforms:x +1)) + (<- (robot-neck-tilt-joint-forward-facing-axis-sign :tiago-dual + cl-transforms:x +1)) + + (<- (robot-joint-states :tiago-dual :neck ?_ :forward + ((?pan_joint 0.0) (?tilt_joint 0.0))) + (robot-neck-joints :tiago-dual ?pan_joint ?tilt_joint)) + + (<- (robot-pose :tiago-dual :neck ?_ :forward ?pose-stamped) + (robot-base-frame :tiago-dual ?base-frame) + (lisp-fun cl-transforms:make-identity-rotation ?identity-quaternion) + (symbol-value *forward-looking-position-in-base-frame* ?forward-point) + (lisp-fun cl-transforms-stamped:make-pose-stamped + ?base-frame 0.0 ?forward-point ?identity-quaternion + ?pose-stamped))) + + +(def-fact-group tiago-arm-facts (arm + arm-links arm-joints + hand-links hand-link hand-finger-link + gripper-joint + gripper-meter-to-joint-multiplier + gripper-minimal-position + gripper-convergence-delta + standard<-particular-gripper-transform + end-effector-link robot-tool-frame + tcp-in-ee-pose + robot-joint-states) + + (<- (arm :tiago-dual :right)) + (<- (arm :tiago-dual :left)) + + (<- (arm-links :tiago-dual :left + "arm_left_1_link" + "arm_left_2_link" + "arm_left_3_link" + "arm_left_4_link" + "arm_left_5_link" + "arm_left_6_link" + "arm_left_7_link" + "arm_left_tool_link" + "wrist_left_ft_link" + "wrist_left_ft_tool_link" + "gripper_left_link" + "gripper_left_left_finger_link" + "gripper_left_right_finger_link" + "gripper_left_tool_link")) + (<- (arm-links :tiago-dual :right + "arm_right_1_link" + "arm_right_2_link" + "arm_right_3_link" + "arm_right_4_link" + "arm_right_5_link" + "arm_right_6_link" + "arm_right_7_link" + "arm_right_tool_link" + "wrist_right_ft_link" + "wrist_right_ft_tool_link" + "gripper_right_link" + "gripper_right_left_finger_link" + "gripper_right_right_finger_link" + "gripper_right_tool_link")) + + (<- (arm-joints :tiago-dual :left ("arm_left_1_joint" + "arm_left_2_joint" + "arm_left_3_joint" + "arm_left_4_joint" + "arm_left_5_joint" + "arm_left_6_joint" + "arm_left_7_joint"))) + (<- (arm-joints :tiago-dual :right ("arm_right_1_joint" + "arm_right_2_joint" + "arm_right_3_joint" + "arm_right_4_joint" + "arm_right_5_joint" + "arm_right_6_joint" + "arm_right_7_joint"))) + + (<- (hand-links :tiago-dual :left ("gripper_left_link" + "gripper_left_left_finger_link" + "gripper_left_right_finger_link" + "gripper_left_tool_link"))) + (<- (hand-links :tiago-dual :right ("gripper_right_link" + "gripper_right_left_finger_link" + "gripper_right_right_finger_link" + "gripper_right_tool_link"))) + + (<- (hand-link :tiago-dual :left ?link) + (bound ?link) + (lisp-fun search "gripper_left" ?link ?pos) + (lisp-pred identity ?pos)) + (<- (hand-link :tiago-dual :right ?link) + (bound ?link) + (lisp-fun search "gripper_right" ?link ?pos) + (lisp-pred identity ?pos)) + + (<- (hand-finger-link :tiago-dual ?arm ?link) + (bound ?link) + (hand-link :tiago-dual ?arm ?link) + (lisp-fun search "finger" ?link ?pos) + (lisp-pred identity ?pos)) + + (<- (gripper-joint :tiago-dual :left "gripper_left_left_finger_joint")) + (<- (gripper-joint :tiago-dual :left "gripper_left_right_finger_joint")) + (<- (gripper-joint :tiago-dual :right "gripper_right_left_finger_joint")) + (<- (gripper-joint :tiago-dual :right "gripper_right_right_finger_joint")) + + (<- (gripper-meter-to-joint-multiplier :tiago-dual 1.0)) + (<- (gripper-minimal-position :tiago-dual ?_ 0.0)) + (<- (gripper-convergence-delta :tiago-dual ?_ 0.005)) + + (<- (standard<-particular-gripper-transform :tiago-dual ?transform) + (symbol-value *standard-to-tiago-gripper-transform* ?transform)) + + (<- (end-effector-link :tiago-dual :left "arm_left_tool_link")) + (<- (end-effector-link :tiago-dual :right "arm_right_tool_link")) + + (<- (robot-tool-frame :tiago-dual :left "gripper_left_grasping_frame")) + (<- (robot-tool-frame :tiago-dual :right "gripper_right_grasping_frame")) + + (<- (tcp-in-ee-pose :tiago-dual ?pose) + (symbol-value *tcp-in-ee-pose* ?pose)) + + (<- (robot-joint-states :tiago-dual :arm :left :park ?joint-states + ;; (("arm_left_1_joint" -0.5) + ;; ("arm_left_2_joint" 1.3) + ;; ("arm_left_3_joint" 2.1) + ;; ("arm_left_4_joint" 2.0) + ;; ("arm_left_5_joint" -1.95) + ;; ("arm_left_6_joint" 1.0) + ;; ("arm_left_7_joint" 0.0)) + ) + (robot-joint-states :tiago-dual :arm :left :carry-top ?joint-states)) + (<- (robot-joint-states :tiago-dual :arm :left :carry ?joint-states + ;; (("arm_left_1_joint" -1.0) + ;; ("arm_left_2_joint" 0.0) + ;; ("arm_left_3_joint" 1.5) + ;; ("arm_left_4_joint" 2.2) + ;; ("arm_left_5_joint" -1.5) + ;; ("arm_left_6_joint" 0.5) + ;; ("arm_left_7_joint" 0.0)) + ) + (robot-joint-states :tiago-dual :arm :left :carry-top ?joint-states)) + (<- (robot-joint-states :tiago-dual :arm :left :carry-top (("arm_left_1_joint" 0.27) + ("arm_left_2_joint" -1.07) + ("arm_left_3_joint" 1.5) + ("arm_left_4_joint" 1.96) + ("arm_left_5_joint" -2.0) + ("arm_left_6_joint" 1.2) + ("arm_left_7_joint" 0.5)))) + (<- (robot-joint-states :tiago-dual :arm :left :hand-over (("arm_left_1_joint" 1.4) + ("arm_left_2_joint" -0.45) + ("arm_left_3_joint" 1.7) + ("arm_left_4_joint" 1.8) + ("arm_left_5_joint" 0.4) + ("arm_left_6_joint" -1.4) + ("arm_left_7_joint" 1.5)) + ;; (("arm_left_1_joint" 1.4) + ;; ("arm_left_2_joint" -1.07) + ;; ("arm_left_3_joint" 2.0) + ;; ("arm_left_4_joint" 1.7) + ;; ("arm_left_5_joint" -2.0) + ;; ("arm_left_6_joint" 1.2) + ;; ("arm_left_7_joint" 1.0)) + )) + (<- (robot-joint-states :tiago-dual :arm :left :carry-top-basket ?joint-states) + (robot-joint-states :tiago-dual :arm :left :carry-top ?joint-states)) + + (<- (robot-joint-states :tiago-dual :arm :right :park ?joint-states + ;; (("arm_right_1_joint" -0.5) + ;; ("arm_right_2_joint" 1.3) + ;; ("arm_right_3_joint" 2.1) + ;; ("arm_right_4_joint" 2.0) + ;; ("arm_right_5_joint" -1.95) + ;; ("arm_right_6_joint" 1.0) + ;; ("arm_right_7_joint" 0.0)) + ) + (robot-joint-states :tiago-dual :arm :right :carry-top ?joint-states)) + (<- (robot-joint-states :tiago-dual :arm :right :carry ?joint-states + ;; (("arm_right_1_joint" -1.0) + ;; ("arm_right_2_joint" 0.0) + ;; ("arm_right_3_joint" 1.5) + ;; ("arm_right_4_joint" 2.2) + ;; ("arm_right_5_joint" -1.5) + ;; ("arm_right_6_joint" 0.5) + ;; ("arm_right_7_joint" 0.0)) + ) + (robot-joint-states :tiago-dual :arm :right :carry-top ?joint-states)) + (<- (robot-joint-states :tiago-dual :arm :right :carry-top (("arm_right_1_joint" 0.27) + ("arm_right_2_joint" -1.07) + ("arm_right_3_joint" 1.5) + ("arm_right_4_joint" 2.0) + ("arm_right_5_joint" -2.0) + ("arm_right_6_joint" 1.2) + ("arm_right_7_joint" 0.5)))) + (<- (robot-joint-states :tiago-dual :arm :right :hand-over (("arm_right_1_joint" 1.4) + ("arm_right_2_joint" -0.45) + ("arm_right_3_joint" 1.7) + ("arm_right_4_joint" 1.8) + ("arm_right_5_joint" 0.4) + ("arm_right_6_joint" -1.4) + ("arm_right_7_joint" 1.5)))) + (<- (robot-joint-states :tiago-dual :arm :right :carry-top-basket ?joint-states) + (robot-joint-states :tiago-dual :arm :right :carry-top ?joint-states))) + + +(def-fact-group tiago-cm-metadata (costmap:costmap-padding + costmap:costmap-manipulation-padding + costmap:costmap-in-reach-distance + costmap:costmap-reach-minimal-distance + costmap:orientation-samples + costmap:orientation-sample-step + costmap:visibility-costmap-size) + ;; This is the radius of the base link, + #+calculate-aabb-of-the-base-link-with-the-following-function + (defun calculate-radius-x-and-y-of-base-link-from-bullet (robot-name) + (let* ((base-link + (cut:var-value + '?link + (cut:lazy-car + (prolog:prolog + `(rob-int:robot-base-link ,robot-name ?link))))) + (base-link-aabb + (btr:aabb + (btr:rigid-body (btr:get-robot-object) + (intern (format nil "~a.~a" + robot-name + base-link) + :keyword)))) + (aabb-dims + (cl-bullet:bounding-box-dimensions base-link-aabb)) + (aabb-dims-x + (cl-transforms:x aabb-dims)) + (aabb-dims-y + (cl-transforms:y aabb-dims)) + (radius-x + (/ aabb-dims-x 2.0)) + (radius-y + (/ aabb-dims-y 2.0))) + (list radius-x radius-y))) + (<- (costmap:costmap-padding :tiago-dual 0.27)) + (<- (costmap:costmap-manipulation-padding :tiago-dual 0.3)) + ;; This is the length of the outstretched arm from base center to fingertip + ;; But shorten it slightly (10-20cm): + ;; the robot will rarely reach with an outstretched arm + #+calculate-arm-length-from-bullet-with-this-function + (defun calculate-arm-length-from-bullet (robot-name arm-name) + (let* ((base-frame + (cut:var-value + '?link + (cut:lazy-car + (prolog:prolog + `(rob-int:robot-base-link ,robot-name ?link))))) + (tcp-frame + (cut:var-value + '?link + (cut:lazy-car + (prolog:prolog + `(rob-int:robot-tool-frame ,robot-name ,arm-name ?link))))) + (base-P-tcp + (cl-transforms:transform + (cl-transforms:transform-inv + (cl-transforms:pose->transform + (btr:link-pose (btr:get-robot-object) base-frame))) + (btr:link-pose (btr:get-robot-object) tcp-frame))) + (base-P-tcp-origin + (cl-transforms:origin base-P-tcp)) + (projected-on-the-floor + (cl-transforms:copy-3d-vector base-P-tcp-origin :z 0.0)) + (length (cl-transforms:v-norm projected-on-the-floor))) + length)) + (<- (costmap:costmap-in-reach-distance :tiago-dual 0.93)) + (<- (costmap:costmap-reach-minimal-distance :tiago-dual 0.2)) + (<- (costmap:orientation-samples :tiago-dual 1)) + (<- (costmap:orientation-sample-step :tiago-dual 0.3)) + (<- (costmap:visibility-costmap-size :tiago-dual 2))) diff --git a/cram_robot_descriptions/cram_tiago_description/src/package.lisp b/cram_robot_descriptions/cram_tiago_description/src/package.lisp new file mode 100644 index 0000000000..3c669b5e57 --- /dev/null +++ b/cram_robot_descriptions/cram_tiago_description/src/package.lisp @@ -0,0 +1,34 @@ +;;; +;;; Copyright (c) 2022, Gayane Kazhoyan +;;; All rights reserved. +;;; +;;; Redistribution and use in source and binary forms, with or without +;;; modification, are permitted provided that the following conditions are met: +;;; +;;; * Redistributions of source code must retain the above copyright +;;; notice, this list of conditions and the following disclaimer. +;;; * Redistributions in binary form must reproduce the above copyright +;;; notice, this list of conditions and the following disclaimer in the +;;; documentation and/or other materials provided with the distribution. +;;; * Neither the name of the Institute for Artificial Intelligence/ +;;; Universitaet Bremen nor the names of its contributors may be used to +;;; endorse or promote products derived from this software without +;;; specific prior written permission. +;;; +;;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +;;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +;;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +;;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +;;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +;;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +;;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +;;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +;;; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +;;; POSSIBILITY OF SUCH DAMAGE. + +(in-package :cl-user) + +(defpackage cram-tiago-description + (:nicknames #:tiago-descr) + (:use #:common-lisp #:cram-prolog #:cram-robot-interfaces)) diff --git a/cram_tutorials/cram_bullet_world_tutorial/launch/world.launch b/cram_tutorials/cram_bullet_world_tutorial/launch/world.launch index 23c475d1d5..28d888a4dc 100644 --- a/cram_tutorials/cram_bullet_world_tutorial/launch/world.launch +++ b/cram_tutorials/cram_bullet_world_tutorial/launch/world.launch @@ -7,7 +7,7 @@ + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> @@ -35,7 +35,7 @@ diff --git a/cram_tutorials/cram_bullet_world_tutorial/src/setup.lisp b/cram_tutorials/cram_bullet_world_tutorial/src/setup.lisp index c3ee407b35..e42516f1d3 100644 --- a/cram_tutorials/cram_bullet_world_tutorial/src/setup.lisp +++ b/cram_tutorials/cram_bullet_world_tutorial/src/setup.lisp @@ -33,20 +33,8 @@ ;; roslaunch cram_bullet_world_tutorial world.launch (defun init-projection () - (def-fact-group costmap-metadata () - (<- (costmap:costmap-size :iai-kitchen 12 12)) - (<- (costmap:costmap-origin :iai-kitchen -6 -6)) - (<- (costmap:costmap-resolution :iai-kitchen 0.05)) - - (<- (costmap:costmap-padding :pr2 0.2)) - (<- (costmap:costmap-manipulation-padding :pr2 0.2)) - (<- (costmap:costmap-in-reach-distance :pr2 0.6)) - (<- (costmap:costmap-reach-minimal-distance :pr2 0.2))) - (cram-occasions-events:clear-belief) - (setf cram-tf:*tf-default-timeout* 2.0) - (setf prolog:*break-on-lisp-errors* t)) (roslisp-utilities:register-ros-init-function init-projection) diff --git a/cram_tutorials/cram_pick_place_tutorial/launch/world.launch b/cram_tutorials/cram_pick_place_tutorial/launch/world.launch index 23c475d1d5..28d888a4dc 100644 --- a/cram_tutorials/cram_pick_place_tutorial/launch/world.launch +++ b/cram_tutorials/cram_pick_place_tutorial/launch/world.launch @@ -7,7 +7,7 @@ + command="$(find xacro)/xacro '$(find iai_kitchen)/urdf_obj/iai_kitchen_python.urdf.xacro'"/> @@ -35,7 +35,7 @@ diff --git a/jupyter/common-lisp-jupyter.rosinstall b/jupyter/common-lisp-jupyter.rosinstall new file mode 100644 index 0000000000..378f9346e5 --- /dev/null +++ b/jupyter/common-lisp-jupyter.rosinstall @@ -0,0 +1,105 @@ +## Jupyter Common Lisp kernel package -- common-lisp-jupyter -- and its dependencies +#################################################################################### + +## TODO: assign specific commit numbers to ensure upstream updates don't break stuff + +## The repo addresses are taken from +## https://github.com/quicklisp/quicklisp-projects/blob/master/projects//source.txt + +- git: + local-name: common-lisp-jupyter + uri: https://github.com/yitzchak/common-lisp-jupyter.git +# version: master + +- git: + local-name: bordeaux-threads + uri: https://github.com/sionescu/bordeaux-threads.git + +# bordeaux-threads dep +- git: + local-name: global-vars + uri: https://github.com/lmj/global-vars.git + +- git: + local-name: cl-base64 + uri: https://gitlab.common-lisp.net/nyxt/cl-base64.git + +- git: + local-name: cl-indentify + uri: https://github.com/yitzchak/cl-indentify.git + +- git: + local-name: closer-mop + uri: https://github.com/pcostanza/closer-mop.git + +- git: + local-name: dissect + uri: https://github.com/Shinmera/dissect.git + +- git: + local-name: eclector + uri: https://github.com/robert-strandh/eclector.git + +# eclector dep +- git: + local-name: acclimation + uri: https://github.com/robert-strandh/Acclimation.git + +- git: + local-name: ironclad + uri: https://github.com/sharplispers/ironclad.git + +- git: + local-name: multilang-documentation + uri: https://github.com/Shinmera/multilang-documentation.git + +# multilang-documentation dep +- git: + local-name: documentation-utils + uri: https://github.com/Shinmera/documentation-utils.git + +# documentation-utils dep +- git: + local-name: trivial-indent + uri: https://github.com/Shinmera/trivial-indent.git + +# multilang-documentation dep +- git: + local-name: language-codes + uri: https://github.com/Shinmera/language-codes.git + +# multilang-documentation dep +- git: + local-name: system-locale + uri: https://github.com/Shinmera/system-locale.git + +# sudo apt install libzmq3-dev +- git: + local-name: pzmq + uri: https://github.com/orivej/pzmq.git + +# pzmq dep, newest version, our cram_3rdparty version is outdated +#- git: +# local-name: cffi +# uri: https://gitlab.common-lisp.net/cffi/cffi.git + +- git: + local-name: puri + uri: https://gitlab.common-lisp.net/clpm/puri.git + +- git: + local-name: static-vectors + uri: https://github.com/sionescu/static-vectors.git + +- git: + local-name: trivial-do + uri: https://github.com/yitzchak/trivial-do.git + +- git: + local-name: trivial-mimes + uri: https://github.com/Shinmera/trivial-mimes.git + +- git: + local-name: shasht + uri: https://github.com/yitzchak/shasht.git +