diff --git a/README.md b/README.md new file mode 100644 index 0000000..98f782c --- /dev/null +++ b/README.md @@ -0,0 +1,209 @@ +get the code +============ + + $ git clone git@github.com:josch/sisyphus.git + $ cd sisyphus + + +compile evaluation library +========================== + + $ wget http://sourceforge.net/projects/moast/files/Pallet%20Viewer/Version%203/palletandtruckviewer-3.0.tar.gz + $ tar xf palletandtruckviewer-3.0.tar.gz + $ cd palletandtruckviewer-3.0 + $ patch -p0 < ../palletViewer-sharedlib.diff + $ autoreconf -fi + $ ./configure --libdir=`pwd`/.. + $ make + $ make install-strip + $ cd .. + +test evaluation library (optional) +================================== + + $ python evaluate_multi.py examples/icra2012/packlist_R1.xml examples/icra2012/scorecog.xml + + $ python evaluate.py examples/icra2012/Challenge2.order.xml examples/icra2012/packlist_R2.xml examples/icra2012/scorecog.xml + + $ python evaluate.py examples/icra2012/Challenge2.order.xml examples/icra2012/packlist_R3.xml examples/icra2012/scorecogoverlap.xml + +generate packlist files +======================= + + $ ./run.sh examples/icra2011/palDay1R1Order.xml packlist.xml examples/icra2011/scoreAsPlannedConfig1.xml + +Usage +===== + +bruteforce2.py takes an order.xml and tries different strategies to create many +lists of layerlists. Each layerlist is built with a different selection of +strategies. Available strategies are article rotation and pallet rotation which +can both be either true or false. Per default, bruteforce2.py tries all +combinations of article and pallet rotations, which means that for each new +layer, there are four possibilities how articles can be arranged in it. + +A layerlist is the result of one specific combinations of strategies. For +example: first layer with article rotation and pallet rotation, second layer +without article rotation but with pallet rotation, third layer with neither and +so forth. + +bruteforce2.py outputs those layerlists one per line in python pickle gzipped +and base64 encoded format. Python pickle is used as a fast serialization +format. The data is gzipped because it is given to bruteforce3.py as a +commandline argument and those must not exceed an OS specific value. The data +is base64 encoded to avoid zero bytes, newlines and other whitespace characters +in them. + +As a result, the output of bruteforce2.py can not only be saved in a file, but +you can also used split(1) on it to distribute it onto many machines for +evaluations. You can also use head(1), tail(1), sort(1) or uniq(1) on the +output. + +bruteforce3.py takes as arguments an order.xml, a packlist.xml output file, a +scoring.xml file and a number of layerlists, encoded as described above. For +each layerlist it will try every possible permutation of how to place them on +top of each other and evaluate each of them by using palletViewer. + +Multiple instances of bruteforce3.py can be run on the same machine. Before +bruteforce3.py exits, it will put a file lock on score_max.lock and read the +currently highest score from score_max. If the just calculated score is higher, +it will write its own score into score_max and update the contents of +packlist.xml as well. + +Since score_max always contains the currently highest score, it can always +easily be checked during a run, what the currently highest score achieved is. + +Since packlist.xml always contains the best packlist found so far, +bruteforce3.py can always be aborted in the middle of execution, should it take +too long to evaluate while still maintaining the current best packlist. One +does not need to wait until run.sh finished execution. + +Since score_max contains the highest score, it should be removed before each +new run. This is already done by run.sh. + +environment variables +===================== + +bruteforce2 +----------- + + rot_article - try different article rotations (default: True) + rot_pallet - try different pallet rotations (default: True) + rot_article_default - default article rotation (default: False) + rot_pallet_default - default pallet rotation (default: False) + iterations - maximum number of iterations (default: -1) + randomize - try random strategies instead of sequential (default: False) + +bruteforce3 +----------- + + multi_pallet - respect pallet max height and spread over multiple pallets (default: False) + permutations - whether to try all layer permutations or not permute at all (default: True) + iterations - maximum number of iterations (default: -1) + randomize - try random strategies instead of sequential (default: False) + +For orders that are too big to enumerate all possible permutations of layer +strategies and orderings, using randomize and iterations for bruteforce2.py and +bruteforce3.py is recommended. + +The according line in run.sh could be changed to: + +iterations=100 randomize=1 python bruteforce2.py $1 | randomize=1 iterations=1000 xargs --max-procs=4 --max-args=1 python bruteforce3.py $1 $2 $3 + +utility scripts +=============== + + add_approach_points.py + + takes a single or multi pallet packlist.xml and adds the three approach + points to all the articles in it, relative to each articles position + + barcodes.py + + takes an order.xml and prints all barcodes in it + + densities.py + + takes an order.xml and prints the density of all articles + + descriptions.py + + takes an order.xml and prints a table with the description, ID, type, + family, size and weight of every article + + evaluate_multi.py + + takes a multiple pallet packlist.xml and a scoring.xml and prints out + the score that this packlist achieves + + evaluate.py + + takes an order.xml, a single pallet packlist.xml and a scoring.xml and + prints out the score that this packlist achieves + + num_articles_order.py + + takes an order.xml and prints the number of articles within + + num_articles_packlist.py + + takes a single or multi pallet packlist.xml and prints the number of + articles within + + pallets.py + + takes an order.xml and prints a table with the length, width, maximum + load height and maximum load weight + + split_multi.py + + takes a multiple pallet packlist.xml and outputs pairs of single pallet + packlist.xml and order.xml files by appending _$i.xml and _order_$i.xml + to the original packlist.xml filename, respectively. The integer $i + starts at 0 and will be incremented with each subsequent pallet. + +evaluation of multi pallet packlists +==================================== + +palletViewer cannot parse multi pallet packlists, hence the packlists have to +be split into several single pallet packlists. Each of those packlists is then +given to palletViewer for evaluation. The individual results are averaged for a +final score. To avoid each of the palletViewer instances complain about missing +articles, an according order.xml file is created for each single pallet +packlist.xml. + +Multi pallet packlists can evaluated like this: + + python evaluate_multi.py packlist.xml scoring.xml + +Or manually like this: + + python split_multi.py packlist.xml + python evaluate.py packlist.xml_order_0.xml packlist_R1.xml_0.xml scoring.xml + python evaluate.py packlist.xml_order_1.xml packlist_R1.xml_1.xml scoring.xml + ... + +bugs +==== + +there is a "memory leak" in bruteforce3.py. Every loop iteration where a new +permutation is tried out will stay in memory. This is not needed and should not +be the case. This is the reason why run.sh supplies bruteforce3.py with only +one layerlist at a time because otherwise, memory consumption would grow too +big. + +ICRA 2012 VMAC +============== + +Sisyphus won the IEEE ICRA 2012 Virtual Manufacturing Automation Competition. +Here is some media about our submission: + +Round1: ./examples/icra2012/packlist_R1.xml + +Round2: ./examples/icra2012/packlist_R2.xml + +Round3: ./examples/icra2012/packlist_R3.xml + +announcement: http://youtu.be/8fYF-Ldi1NQ + +presentation: http://youtu.be/FSqjGiVt50I