You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
8.3 KiB
Markdown

about
=====
sisyphus is a piece of software I wrote the context of my graduate automation
project. My class was taking part in the IEEE ICRA 2012 Virtual Manufacturing
Automation Competition and part of the competition, was to efficiently stack
boxes of different sizes on a pallet.
As the knapsack problem is NP hard, sisyphus implements hybrid between
heuristic and bruteforce approach.
The heuristic is, to group articles of same height into layers, and then stack
those layers on top of each other.
Different techniques to form layers and different orderings of stacking them
are then tried out in a bruteforce manner.
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