This is an old revision of the document!
Location costmaps
This tutorial demonstrates the location costmap library of CRAM, including its API, examples of existing costmaps and how to write your own new costmaps.
Setup
- launch the map-server in a terminal with
roslaunch iai_maps map.launch
- load cram_occupancy_grid_costmap in the REPL
- start a node in REPL with (roslisp-utilities:startup-ros)
- define costmap parameters:
(prolog:def-fact-group costmap-metadata () (prolog:<- (location-costmap:costmap-size 10 10)) ; in meters (prolog:<- (location-costmap:costmap-origin -5 -5)) (prolog:<- (location-costmap:costmap-resolution 0.05)) (prolog:<- (location-costmap:costmap-padding 0.01))) ; padding to occupancy map obstacles
Creating and resolving location designators
- create a designator and resolve it:
(defparameter *designator* (desig:a location (visible-for pr2))) (desig:reference *designator*)
Visualization of costmaps
- start rviz and add Map, Marker and MarkerArray
- as “Topic” for the Map select “/map”
- as “Marker Topic” select “/cram_location_marker” and “/cram_location_costmap” respectively.
- to see which costmap was used, call this:
(defparameter *costmap* (cut:var-value '?cm (car (prolog:prolog `(and (location-costmap:desig-costmap ,*designator* ?cm))))))
- to visualize the costmap and see generated values:
(location-costmap:get-cost-map *costmap*)
–> CRAM costmaps calculate values from 0 to 1: 0 – bad sample, 1 – perfect sample
- In rviz you should see something like this:
- to remove visualization markers call
(location-costmap::remove-markers-up-to-index 10000)
Creating your own cost function
To define your own location relations you need to do three things:
- Define a cost function which resolves the relation you want
- Register a name for your cost function
- Define rules for generating a costmap using your cost function associate it with your registered name
Let's define a behind relation.
- create a cost function which returns for each {x, y} in location costmap grid a value between [0, 1]
(defun make-behind-cost-function (ref-x ref-y) "`ref-x' and `ref-y' are the coordinates of the reference point according to which the behind-relation is resolved." (let* ((supp-tf (cl-transforms:make-transform (cl-transforms:make-3d-vector ref-x ref-y 0) (cl-transforms:make-identity-rotation))) (world->supp-tf (cl-transforms:transform-inv supp-tf))) (lambda (x y) (let* ((point (cl-transforms:transform-point world->supp-tf (cl-transforms:make-3d-vector x y 0))) (vector-length (cl-transforms:dot-product point point))) (if (and (< (cl-transforms:x point) 0.0d0) (> (abs (/ (cl-transforms:x point) vector-length)) 0)) (abs (/ (cl-transforms:x point) vector-length)) 0.0d0)))))
- define order for your costmap function and give it a name:
(defmethod location-costmap:costmap-generator-name->score ((name (eql 'behind-cost-function))) 10)
- define the prolog rule for generating costmaps:
(prolog:def-fact-group tutorial-rules (location-costmap:desig-costmap) (prolog:<- (location-costmap:desig-costmap ?designator ?costmap) (desig:desig-prop ?designator (:behind ?pose)) (prolog:lisp-fun cl-transforms:origin ?pose ?pose-origin) (prolog:lisp-fun cl-transforms:x ?pose-origin ?ref-x) (prolog:lisp-fun cl-transforms:y ?pose-origin ?ref-y) (location-costmap:costmap ?costmap) (location-costmap:costmap-add-function behind-cost-function (make-behind-cost-function ?ref-x ?ref-y) ?costmap)))
- resolve a designator with your new awesome costmap:
(defparameter *behind-designator* (desig:make-designator :location `((:behind ,(cl-transforms:make-identity-pose))))) (desig:reference *behind-designator*)
- if you were to visualize the costmap like above you would get this:
(location-costmap:get-cost-map (cut:var-value '?cm (car (prolog:prolog `(and (location-costmap:desig-costmap ,*behind-designator* ?cm))))))
Using other (pre-defined) cost-functions
In the location-costmap package there are other cost function already available for generating costmaps. Here are two examples:
- using gaussian costmap function:
(prolog:def-fact-group tutorial-rules (location-costmap:desig-costmap) (prolog:<- (location-costmap:desig-costmap ?designator ?costmap) (desig:desig-prop ?designator (:behind ?pose)) (prolog:lisp-fun cl-transforms:origin ?pose ?pose-origin) (location-costmap:costmap ?costmap) (location-costmap:costmap-add-function behind-cost-function (location-costmap:make-gauss-cost-function ?pose-origin #2A((0.5 0) (0 0.5))) ?costmap)))
- using range costmap function:
(prolog:def-fact-group tutorial-rules (location-costmap:desig-costmap) (prolog:<- (location-costmap:desig-costmap ?designator ?costmap) (desig:desig-prop ?designator (:behind ?pose)) (location-costmap:costmap ?costmap) (location-costmap:costmap-add-function behind-cost-function (location-costmap:make-range-cost-function ?pose 1.0) ?costmap))) (prolog:def-fact-group tutorial-rules (location-costmap:desig-costmap) (prolog:<- (location-costmap:desig-costmap ?designator ?costmap) (desig:desig-prop ?designator (:behind ?pose)) (location-costmap:costmap ?costmap) (location-costmap:costmap-add-function behind-cost-function (location-costmap:make-range-cost-function ?pose 1.0 :invert t) ?costmap)))