[Open Manufacturing] Recipe representation

87 views
Skip to first unread message

Bryan Bishop

unread,
Dec 23, 2008, 1:11:39 PM12/23/08
to openmanufacturing, kan...@gmail.com
Hey all,

Maybe the most important component of the packaging formats that we
want is the 'recipe', which WordNet defines as 'directions for making
something': instructions, directions, steps, commands, etc. This is
already partially implemented in manufacturing environments as CAM, or
computer-aided manufacturing.

http://en.wikipedia.org/wiki/Computer-aided_manufacturing
"Traditionally, CAM has been considered as a numerical control (NC)
programming tool wherein three-dimensional (3D) models of components
generated in CAD software are used to generate CNC code to drive
numerically controlled machine tools."

In other words, the CAD models can be taken and converted into gcode,
which is what linuxcnc.org is about. Here's what gcode looks like:

=========
G1 X0.0 Y1.0 F20.0 ----go to X1.0, Y0.0 at a feed rate of 20 inches/minute
G2 X1.0 Y0.0 I0.0 J-1.0 ----go in an arc from X0.0, Y1.0 to X1.0 Y0.0,
with the center of the arc at X0.0, Y0.0
G1 X0.0 Y1.0 F20.0 ----go to X1.0, Y0.0 at a feed rate of 20 inches/minute
G2 X1.0 Y0.0 R1.0 ----go in an arc from X0.0, Y1.0 to X1.0 Y0.0, with
a radius of R=1.0
=========
http://en.wikipedia.org/wiki/G-code

A month ago I posted a link to TreeMaker:
http://groups.google.com/group/openmanufacturing/browse_thread/thread/aa37d3d4badd1bb6/0b326bd815e465f1?lnk=gst&q=treemaker#0b326bd815e465f1

Lang's TreeMaker program generates origami crease patterns from a
basic stick-figure structure that the user inputs to represent flaps
and folds of the final construction. Admittedly not the best possible
way to do it, but whatever- another option would be to write a program
that converts a 3D model from STL to an "unfolded version" where each
triangle is a flap or something (this would be huge, but maybe there
are some "resize origami crease pattern" algorithms that could be
used). The other program that he has, ReferenceFinder, asks the user
either for a vertex point in some coordinate grid, or the two points
of a line in a reference grid. The idea here is to generate all
possible folds that could quickly get you to that location. The output
of the ReferenceFinder software is something like "Fold A to B" and it
also shows a diagram of the locations. I don't know why
ReferenceFinder doesn't read TMD files, the output of TreeMaker, to
generate total and complete instructions for folding the generated
crease patterns.

Somebody designed and built an origami folding machine:
http://www.cs.dartmouth.edu/~robotics/papers/djb-icra04.pdf

No doubt, the instructions for the machines are not straight up
English "fold here, here and here". However, importantly, the
computerized data format for the representation (to give to the
folding machine) of the folds to make, can be converted into English
output -- it has all of the same information, put there in a
systematic fashion. The other way around, of trying to convert English
folding instructions into a format that a machine can understand, is
less likely to happen. Ask any two people to give instructions for
folding an origami paper crane, and they will give you two different
versions, with different punctuation, grammar and other linguistic
delights that are mostly unpredictable.

What other types of recipes are there? Well, there's cooking recipes.
These look like:

=========
Chocolate Chip Cookie Ingredients
* 3/4 cup sugar
* 3/4 cup packed brown sugar
* 1 cup butter, softened
* 2 large eggs,beaten
* 1 teaspoon vanilla extract
* 2 1/4 cups all-purpose flour
* 1 teaspoon baking soda
* 3/4 teaspoon salt
* 2 cups semisweet chocolate chips
* if desired, 1 cup chopped pecans

Chocolate Chip Cookie Recipe Directions: Preheat oven to 375 degrees.
Mix sugar, brown sugar, butter, vanilla and eggs in a large bowl by
hand. Stir in flour, baking soda, and salt. The dough will be very
stiff. Stir in chocolate chips and pecans if desired. Drop dough by
rounded tablespoonfuls 2 inches apart onto ungreased cookie sheet.
Bake 8 to 10 minutes or until light brown. The centers will be soft.
Let cool completely then remove from cookie sheet.
=========

And there's even an XML format for representing kitchen recipes for
book-writing:
http://www.happy-monkey.net/recipebook/
http://www.happy-monkey.net/recipebook/doc/pseudocode.txt

Sadly, this isn't too useful for our purposes:

=========
<recipe>
<title>Peanutbutter And Celery</title>
<recipeinfo>
<blurb>A crunchy snack that is easy to share with friends.</blurb>
<author>Little Johnny</author>
<source>Johnny's Mom</source>
<yield>4 sticks</yield>
</recipeinfo>
<ingredientlist>
<ingredient><quantity>4</quantity> <unit>tsp.<unit> of
<fooditem>peanutbutter<fooditem></ingredient>
<ingredient><quantity>2</quantity> <unit>ribs<unit> of
<fooditem>celery<fooditem></ingredient>
</ingredientlist>
<preparation>Ask Mom to cut the celery ribs in half. Stick
<equipment>a teaspoon</equipment> in a jar of
peanutbutter. Spread the peanut butter in the hollow part of the
celery. Repeat until all four are done.</preparation>
<serving>Serve with a glass of milk.</serving>
</recipe>
=========

And we've come across PSL too many times here as well:

Process Specification Language: http://www.mel.nist.gov/psl/
http://www.nist.gov/msidlibrary/doc/process-descriptions.pdf
.. which looks like:

=========
<!-- <processdesc xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> -->
<process xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<prepareLeftovers concurrentSubActivities="true">
<subactivities>
<reheatFood-ref ref="rf1"/>
<readNewspaper-ref ref="rn1"/>
</subactivities>
</prepareLeftovers>
<reheatFood id="rf1">
<oven rdf:resource="#myMicrowave"/>
<frozenMeal rdf:resource="#tunaCasserole"/>
</reheatFood>
<readNewspaper id="rn1">
<newspaper rdf:resource="#2001May29WashingtonPost"/>
</readNewspaper>
</process>
=========
(That kind example provided by Joshua Lubell.)

I am nearly convinced that PSL is what we want, although the lack of
examples is a show-stopper. On the other hand, NIST MEL does provide a
number of good forms of documentation on the overall language, even
including files for the ISO "Common Logic" standard:
http://philebus.tamu.edu/cl/
So maybe there's some hope yet from that end? Conrad Bock hasn't
replied to my emails yet, sadly. He does seem to still be alive since
his website has been updated within the past two months.

All of these formats, and more, show that there are some common themes
in recipes. There are always tools and actions that must be done on
the manipulated materials. There are always specifics to each action.
"Put screw here", "place screw there"; these specifics are
communicable to both human and machine -- especially in the case of
the robot that folds origami. While the robot maybe doesn't visually
look for folds and creases, it does have an internal representation,
which is as much as we can expect for a human user to have. There is
also specific information in the case of gcode for CNC machines. All
of these computational representations can be used to generate
human-readable formats. Maybe with a little touch-up to make sentences
end with the correct words and punctuation, or don't have improper
plurals where a singular is proper, that sort of thing.

Anyway, to highlight the theme again, in a bit of a
proposal-sort-of-way, adding on to my previous emails:
http://groups.google.com/group/openmanufacturing/browse_thread/thread/8465dc23eb48e332/e185e43b59db6b7d?lnk=gst&q=todo#e185e43b59db6b7d

.. we could have:
* all "specific information", for the likes of the gcode-reading CNC
machines, or the location of where to fold and crease for the origami
folding machine, can be in separate files within the "dot skdb" file.
Not within the metadata.
* yaml metadata for .skdb files would have the list of dependencies.
Recipe may be too big to fit into here reliably.
* in the .skdb, have a file devoted (metadata for pkg points to this
file) to the recipe. The recipe is PSL or something like it, which
would be like a 'function structure' (gxml standard) where arcs coming
into a node are 'input types' and arcs coming out are 'outputs', and
the node could be labeled ('convert' maybe?), such that SKDB could be
searched (via the metadata) for packages that satisfy the input arcs
and output arcs. The specific information, again, is already in the
dot skdb file within the files that the 'recipe file' points to (i.e.,
the parameters for the gcode operations). These arcs and nodes in the
'function structure' format (or PSL format) would be akin to
"dimensional analysis" and "GNU units" support.
* to serialize instructions, the 'cnc machine' dot skdb package would
be given the parameters and-- just like every other package-- have a
'serialize instructions to English' function in its internal python
scripts. Uh, a better example might be an origami folding machine
instead of 'cnc machine' since it's easier to read 'fold' rather than
complicated English for doing mechanical cuts on metals etc.

Again, it goes back to one of the big roadblocks being the lack of PSL
tutorials; I'm not entirely well versed in sitting down in front of
ISO "Common Logic" and trying to figure out what an implementation
looks like. But even with the PSL example above, a few questions
become apparent, like-- at what point do we do the SKDB tie-ins? For
instance, what meaningful mapping can we make between the
"rdf:resource" attributes of the elements? They seem to reference
physical objects; would they instead represent the names of packages?
But what about the specific dimensional analysis that we've been
talking about? "provides 20 W of electricity" or "3 gallons/sec water
input required", that's not really captured by the PSL above. And then
what about the idea of having the recipe.psl file point to the extra
parameters for the machines? The example above talks about a
microwave; the microwave accepts a number of parameters, which should
be in a configuration file in the dot skdb package, so how is this
file adequately referenced?

Uh, also, from PSL 1.0 specs there's another example worth including:
=============================================

The following is an example instance of a PSL exchange file. For the
completed pilot
implementation, the project has used a KIF-like syntax for the
exchange (as shown
below). Future versions of this PSL specification document will go
into more detail about
the syntax and grammar of the PSL exchange language, which may or may
not resemble
KIF, as the specification evolves.

(doc make-gt350 "Make GT350")
(and (doc make-interior "Make Interior")
(forall (?a : (activation-of ?a make-interior))
(exists (?o1 : (instance-of ?o1 a002-bench)) (in ?o1 ?a)))
(and (duration make-interior 5) (beginof make-interior 7)))
(and (doc make-drive "Make Drive")
(forall (?a : (activation-of ?a make-drive))
(exists (?o1 : (instance-of ?o1 a003-bench)) (in ?o1 ?a))))
(and (doc make-trim "Make Trim")
(forall (?a : (activation-of ?a make-trim))
(exists
(?o1 ?o2 : (instance-of ?o1 a002-bench)
(instance-of ?o2 a005-bench))
(and (in ?o1 ?a) (in ?o2 ?a)))))
(doc make-chassis "Make Chassis")
(doc final-assembly "Final Assembly")
(doc make-harness "Make Harness")
(doc make-wires "Make Wires")
(doc assemble-engine "Assemble Engine")
(doc machine-block "Machine Block")
(doc change-mould "Change Mould")
(doc setup-furnace "Setup Furnace")
(doc analyze-metal "Analyze Metal")
(doc melt "Melt")
(doc wait "Wait")
(doc clear-cavities "Clear Cavities")
(doc setup-racks "Setup Racks")
(doc pour "Pour")
(doc remove-racks "Remove Racks")
(doc batch-complete "Batch Complete")
(and (doc make-gt350-proc "Make GT350 Process")
(subactivity make-interior-1 make-gt350-proc)
(subactivity make-drive-1 make-gt350-proc)
(subactivity make-trim-1 make-gt350-proc)
(subactivity make-chassis-1 make-gt350-proc)
(subactivity final-assembly-1 make-gt350-proc)
(subactivity j2 make-gt350-proc) (subactivity j1 make-gt350-proc)
(subactivity make-harness-1 make-gt350-proc)
(subactivity make-wires-1 make-gt350-proc)
(subactivity assemble-engine-1 make-gt350-proc)
(subactivity j4 make-gt350-proc) (subactivity j3 make-gt350-proc)
(subactivity machine-block-1 make-gt350-proc)
(subactivity change-mould-1 make-gt350-proc)
(subactivity setup-furnace-1 make-gt350-proc)
(subactivity analyse-metal-1 make-gt350-proc)
(subactivity melt-1 make-gt350-proc)
(subactivity wait-1 make-gt350-proc)
(subactivity clear-cavities-1 make-gt350-proc)
(subactivity j8 make-gt350-proc) (subactivity j7 make-gt350-proc)
(subactivity j6 make-gt350-proc) (subactivity j5 make-gt350-proc)
(subactivity setup-racks-1 make-gt350-proc)
(subactivity pour-1 make-gt350-proc)
(subactivity remove-racks-1 make-gt350-proc)
(subactivity batch-complete-1 make-gt350-proc)
(idef-process make-gt350-proc))
(and (doc make-interior-1
"The occurrence of Make-Interior in the Dec-19 schematic")
(forall (?a : (activation-of ?a make-interior-1))
(activation-of ?a make-interior))
(forall (?a : (activation-of ?a make-interior-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc make-drive-1
"The occurrence of Make-Drive in the Dec-19 schematic")
(forall (?a : (activation-of ?a make-drive-1))
(activation-of ?a make-drive))
(forall (?a : (activation-of ?a make-drive-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc make-trim-1
"The occurrence of Make-Trim in the Dec-19 schematic")
(forall (?a : (activation-of ?a make-trim-1))
(activation-of ?a make-trim))
(forall (?a : (activation-of ?a make-trim-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc make-chassis-1
"The occurrence of Make-Chassis in the Dec-19 schematic")
(forall (?a : (activation-of ?a make-chassis-1))
(activation-of ?a make-chassis))
(forall (?a : (activation-of ?a make-chassis-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc final-assembly-1
"The occurrence of Final-Assembly in the Dec-19 schematic")
(forall (?a : (activation-of ?a final-assembly-1))
(activation-of ?a final-assembly))
(forall (?a : (activation-of ?a final-assembly-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc j2 "J2")
(forall (?j : (activation-of ?j j2))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(follows j2 final-assembly-1 make-gt350-proc)
(and (and_split j2 make-gt350-proc)
(subactivity make-interior-1 j2)
(subactivity make-drive-1 j2) (subactivity make-trim-1 j2)
(subactivity assemble-engine-1 j2)
(subactivity make-chassis-1 j2)))
(and (doc j1 "J1")
(forall (?j : (activation-of ?j j1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(and (and_split j1 make-gt350-proc)
(subactivity make-interior-1 j1)
(subactivity make-drive-1 j1) (subactivity make-trim-1 j1)
(subactivity j3 j1) (subactivity make-chassis-1 j1)))
(and (doc make-harness-1
"The occurrence of Make-Harness in the Dec-26 schematic")
(forall (?a : (activation-of ?a make-harness-1))
(activation-of ?a make-harness))
(forall (?a : (activation-of ?a make-harness-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc make-wires-1
"The occurrence of Make-Wires in the Dec-26 schematic")
(forall (?a : (activation-of ?a make-wires-1))
(activation-of ?a make-wires))
(forall (?a : (activation-of ?a make-wires-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc assemble-engine-1
"The occurrence of Assemble-Engine in the Dec-26 schematic")
(forall (?a : (activation-of ?a assemble-engine-1))
(activation-of ?a assemble-engine))
(forall (?a : (activation-of ?a assemble-engine-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc j4 "J4")
(forall (?j : (activation-of ?j j4))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(follows j4 assemble-engine-1 make-gt350-proc)
(and (and_split j4 make-gt350-proc)
(subactivity machine-block-1 j4)
(subactivity make-harness-1 j4)
(subactivity make-wires-1 j4)))
(and (doc j3 "J3")
(forall (?j : (activation-of ?j j3))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(and (and_split j3 make-gt350-proc) (subactivity j5 j3)
(subactivity make-harness-1 j3)
(subactivity make-wires-1 j3)))
(and (doc machine-block-1
"The occurrence of Machine-Block in the Dec-27 schematic")
(forall (?a : (activation-of ?a machine-block-1))
(activation-of ?a machine-block))
(forall (?a : (activation-of ?a machine-block-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc l93 "L93")
(follows clear-cavities-1 machine-block-1 make-gt350-proc))
(and (doc change-mould-1
"The occurrence of Change-Mould in the Dec-1 schematic")
(forall (?a : (activation-of ?a change-mould-1))
(activation-of ?a change-mould))
(forall (?a : (activation-of ?a change-mould-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc setup-furnace-1
"The occurrence of Setup-Furnace in the Dec-1 schematic")
(forall (?a : (activation-of ?a setup-furnace-1))
(activation-of ?a setup-furnace))
(forall (?a : (activation-of ?a setup-furnace-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc analyse-metal-1
"The occurrence of Analyze-Metal in the Dec-1 schematic")
(forall (?a : (activation-of ?a analyse-metal-1))
(activation-of ?a analyze-metal))
(forall (?a : (activation-of ?a analyse-metal-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc melt-1 "The occurrence of Melt in the Dec-1 schematic")
(forall (?a : (activation-of ?a melt-1)) (activation-of ?a melt))
(forall (?a : (activation-of ?a melt-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc wait-1 "The occurrence of Wait in the Dec-1 schematic")
(forall (?a : (activation-of ?a wait-1)) (activation-of ?a wait))
(forall (?a : (activation-of ?a wait-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc clear-cavities-1
"The occurrence of Clear-Cavities in the Dec-1 schematic")
(forall (?a : (activation-of ?a clear-cavities-1))
(activation-of ?a clear-cavities))
(forall (?a : (activation-of ?a clear-cavities-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc j8 "J8")
(forall (?j : (activation-of ?j j8))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(follows j8 setup-racks-1 make-gt350-proc)
(and (and_split j8 make-gt350-proc)
(subactivity analyse-metal-1 j8) (subactivity melt-1 j8)))
(and (doc j7 "J7")
(forall (?j : (activation-of ?j j7))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(follows setup-furnace-1 j7 make-gt350-proc)
(and (and_split j7 make-gt350-proc)
(subactivity analyse-metal-1 j7) (subactivity melt-1 j7)))
(and (doc j6 "J6")
(forall (?j : (activation-of ?j j6))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(follows j6 setup-furnace-1 make-gt350-proc)
(and (xor_split j6 make-gt350-proc)
(subactivity change-mould-1 j6)))
(and (doc j5 "J5")
(forall (?j : (activation-of ?j j5))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?j ?p)))
(and (xor_split j5 make-gt350-proc) (subactivity j6 j5)
(subactivity change-mould-1 j5)))
(and (doc l121 "L121")
(follows remove-racks-1 batch-complete-1 make-gt350-proc))
(and (doc l122 "L122") (follows pour-1 remove-racks-1 make-gt350-proc))
(and (doc l124 "L124") (follows setup-racks-1 pour-1 make-gt350-proc))
(and (doc l120 "L120")
(follows batch-complete-1 wait-1 make-gt350-proc))
(and (doc l123 "L123")
(follows wait-1 clear-cavities-1 make-gt350-proc))
(and (doc setup-racks-1
"The occurrence of Setup-Racks in the Dec-1-1 schematic")
(forall (?a : (activation-of ?a setup-racks-1))
(activation-of ?a setup-racks))
(forall (?a : (activation-of ?a setup-racks-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc pour-1 "The occurrence of Pour in the Dec-1-1 schematic")
(forall (?a : (activation-of ?a pour-1)) (activation-of ?a pour))
(forall (?a : (activation-of ?a pour-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc remove-racks-1
"The occurrence of Remove-Racks in the Dec-1-1 schematic")
(forall (?a : (activation-of ?a remove-racks-1))
(activation-of ?a remove-racks))
(forall (?a : (activation-of ?a remove-racks-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))
(and (doc batch-complete-1
"The occurrence of Batch-Complete in the Dec-1-1 schematic")
(forall (?a : (activation-of ?a batch-complete-1))
(activation-of ?a batch-complete))
(forall (?a : (activation-of ?a batch-complete-1))
(exists (?p : (activation-of ?p make-gt350-proc))
(subactivity-occurrence ?a ?p))))

=============================================

That spec also had a PSL->XML example:
=============================================

<rdf:RDF>
<Class ID="Paint"/>
<Class ID="PaintBrush"/>
<Class ID="PaintMixer"/>
<Class ID="PaintThinner"/>
<Class ID="SandPaper"/>
<Property ID="grit">
<rdfs:range rdf:resource="#Grit"/>
<rdfs:domain rdf:resource="#SandPaper"/>
</Property>
<Class ID="Grit"/>
<c:Grit rdf:ID="100"/>
<c:Grit rdf:ID="200"/>
<c:Paint rdf:ID="paint-primer"/>
<c:Paint rdf:ID="paint-blue"/>
<c:PaintBrush rdf:ID="brush"/>
<c:PaintMixer rdf:ID="mixer"/>
<c:PaintThinner rdf:ID="thinner"/>
<c:SandPaper rdf:ID="s1">
<c:grit rdf:resource="#100"/>
</c:SandPaper>
<c:SandPaper rdf:ID="s2">
<c:grit rdf:resource="#200"/>
</c:SandPaper>
</rdf:RDF>

<timepoints>
<timepoint id="p1">start</timepoint>
<timepoint id="p2">done mixing paint</timepoint>
<timepoint id="p3">done applying first coat of paint</timepoint>
<timepoint id="p4">done cleaning brush</timepoint>
<timepoint id="p5">done sanding with 100 grit sand paper</timepoint>
<timepoint id="p6">done mixing paint</timepoint>
<timepoint id="p7">done applying second coat of paint</timepoint>
<timepoint id="p8">done cleaning brush</timepoint>
<timepoint id="p9">done sanding with 200 grit sand paper</timepoint>
</timepoints>

<activity id="a2">
<name>Paint</name>
<subactivities>
<activity id="a3">
<name>Mix paint</name>
<requires>
<resource rdf:resource="#Paint"/>
<resource rdf:resource="#PaintMixer"/>
</requires>
</activity>
<activity id="a4">
<name>Apply paint</name>
<requires>
<resource rdf:resource="#Paint"/>
<resource rdf:resource="#PaintBrush"/>
</requires>
</activity>
<activity id="a5">
<name>Clean brush</name>
<requires>
<resource rdf:resource="#PaintBrush"/>
<resource rdf:resource="#PaintThinner"/>
</requires>
</activity>
</subactivities>
</activity>

<occurrence activity="a2" begin="p1" end="p4">
<suboccurrences>
<!-- mix first coat -->
<occurrence activity="a3" begin="p1" end="p2">
<objects>
<resource rdf:resource="#paint-primer"/>
<resource rdf:resource="#mixer"/>
</objects>
</occurrence>
<!-- apply first coat -->
<occurrence activity="a4" begin="p2" end="p3">
<objects>
<resource rdf:resource="#paint-primer"/>
<resource rdf:resource="#brush"/>
</objects>
</occurrence>
<!-- clean brush -->
<occurrence activity="a5" begin="p3" end="p4">
<objects>
<resource rdf:resource="#brush"/>
<resource rdf:resource="#thinner"/>
</objects>
</occurrence>
</suboccurrences>
</occurrence>

=============================================

And then Paul's (old) stuff:
http://www.kurtz-fernhout.com/oscomak/prototype.htm

=============== RECIPE INPUT FORM ================
Recipes are entered using a form with these fields:

Recipe Name
Ex: Cynthia's 2 cm X 10 cm Aluminum Bolts

Produces:
Item Quantity Unit* Wear FailureProbability**
Ex. "Aluminum Bolt 2 cm X 10 cm" 10 item 0 0.01
Ex. "Aluminum chips" 0.63 Kg 0 0

Consumes:
Item Quantity Unit Wear FailureProbability
Ex. "Aluminum dowel 4cm diam" 105 cm 0 0
Ex. "Machine oil" 0.002 Kg 0 0
Ex. Electricity 0.02 Kwh 0 0

Uses (as tool or catalyst)
Item Quantity Unit Wear FailureProbability
Ex. Lathe 1 item 0.0001 0.00001
Ex. "Aluminum cutting bit" 1 item 0.01 0.0001
Ex. "CNC program" 1 item 0 0

Directions:
A Large free form text field
Ex. Place the aluminum dowel stock in the lathe and activate the CNC
program. Wait five minutes. Remove bolts. Clean machine of aluminum
chips.

Effort:
ProcessingTime HumanInvolvementPercent NumberOfPeopleRequired
Ex. 5 minutes 20% 1

Author:
Name Affiliation Email FlagIfWantNotificationIfRecipeChanged
"Cynthia Kurtz" "Kurtz-Fernhout Software" use...@domain.com Y

* Items may also need mass specified if not derivable from unit.

** Wear is a fraction of 1.00; at which point the item certainly fails.
Failure probability is per recipe use and is independent of wear (it
could be made a function of wear instead). Wear and failure are
essential to capturing the need for maintenance recipes. Maintenance
recipes (i.e. "lathe construction") address the need to repair or
replace tools and infrastructure as they wear out or fail. In most space
missions so far, the emphasis is on equipment that uses components where
failure is unlikely because of testing and high quality, or where failed
components are replaced by spares, or where the failure of components
and resulting decreased capacity is simply tolerated for the mission
duration. Recording failure probabilities and showing the consequences
in habitat simulations is essential for contest designers to gain
insight into the issues surrounding maintaining and duplicating a space
habitat using just asteroidal ore and sunlight, and thus leading to a
focus of minimizing the need for tools continually supplied from earth
("vitamins").

=================== RECIPE MANAGEMENT OPTIONS =============
The system relies on the users (and administrators) to be self-policing.
The hope is that a very large fraction of the interactions with the
database will be non-malicious and accurate. The tendency towards system
failure from malice or inaccuracy is hopefully offset by people undoing
the effects of such with these management options. Of course these
management options themselves can be used poorly too.

Recipes can be managed by anyone using these options.

Please select an option for managing this recipe:
Great recipe -- applause email to author
Tested recipe and it worked -- noted
Inaccurate recipe - delete, note, or fix
Incorrectly categorized (ex. "phaser" labeled as real) -- recategorize
Dangerous recipe (ex. poison) -- delete
Offensive recipe (ex. profanity) -- delete
Test recipe -- delete

Deleted items are immediately hidden and moved to a cache for review by
the administrator.

Modifying author information:
Name Affiliation Email FlagIfWantNotificationIfRecipeChanged

=================== ITEM SEARCH FORM ===================

Recipes that involve NameOfItem
Ex. Recipes that involve "2 cm X 10 cm Aluminum Bolts"

Produce:
Ex. Cynthia's 2 cm X 10 cm Aluminum Bolts

Consume:
Ex. Airlock door frame (real)
Ex. Communications tower (real)
Ex. Service Robot (sci-fi)

Use at tool/catalyst:
Ex. No recipes use bolts as a tool or catalyst

>>SEARCH ON ANOTHER ITEM<<<<

=============== SPACE HABITAT SIMULATOR ================
This is a very simple non-graphical simulation. Future versions would
ideally allow you to map out process paths as a two or
three dimensional map and watch the movements of materials.

Active Recipes & Priority*:
Bolt manufacturing 3
Mirror fabrication 1
Oxygen production 1
Ore separation 1
Lettuce production 2

Choose Recipes and Priorities >>CHOOSE<<

* Priority relates to how many times a recipe is made during one
simulation run.

Current simulation state:
Items quantity average wear
Bolts 56 items = 5 Kg 0.01
Mylar Mirrors 12 ha = 19 Kg 0.20
Mining machinery 1 item = 1000Kg 0.95
Oxygen 234 Kg
Ore 1267 Kg
Li 2 Kg
Si 12 Kg
Al 56 Kg
H20 15 Kg
Slag 891 Kg
Lettuce 45 Kg
Lettuce producer 3 items = 300 Kg 0.05
Lettuce producer 1 item = 100 Kg 1.00
People 10 people = 500 Kg 0.05

Adjust item quantities >>EDIT<<

Iterate Model using Recipes & Priority >>ITERATE<<**

** Every time this "ITERATE" button is pressed, the recipes listed are
made if their prerequisites are available and the item totals are then
updated for items produced, consumed, or failed.

In the example above the mining machinery is approaching the point of
certain failure (it is at 0.95 of 1.00). At that point, all recipes
using the mining machine can no longer be made, until a "fix broken
mining machine" recipe is made, or the machine is replaced with a new
one, like with a "build new mining machine" recipe. Note that one of the
four lettuce producing systems has already failed and is awaiting a
repair recipe to be written and added to the simulation.

============ CHANGE LOG ===================
This log tracks all changes made to the system, as well as who made them
(if the person entered their identity). Anonymous changes could be
flagged as suspect and reviewed more often.

ADD: Mylar fabrication recipe BY: Paul
ADD: Aluminum bolt fabrication recipe BY: Cynthia
UPDATE: Mylar fabrication recipe BY: Al
ADD: Lettuce production recipe BY: Al
UPDATE: Mylar fabrication recipe BY: Freeman
ADD: Asteroidal ore separation recipe BY: Mark
ADD: Stink bomb BY: Anonymous
UPDATE: Lettuce production recipe BY: Jim
DELETE: Stink bomb BY: Paul
ADD: Aluminum dowel fabrication BY: Cynthia
UPDATE: Mylar fabrication recipe BY: Mark
ADD: Aluminum ore processing recipe BY: Cynthia
UPDATE: Mylar fabrication recipe BY: Jim

Deletions and the original deleted item name might only be shown when
administrators are reviewing the logs (in case the recipe name itself
was offensive). Otherwise, anyone can review the logs to study activity
patterns.

=============================================
=============================================

I finally typed up some 'semantic shell' ideas (nothing new - just for
reference):
http://heybryan.org/shell.html

That's enough for now. Any help in answering the above questions would
be awesome. Also, throwing in the dot g format into dot skdb files
would be great (using BRLCAD explicitly).

- Bryan
http://heybryan.org/
1 512 203 0507

Paul D. Fernhout

unread,
Dec 23, 2008, 5:02:10 PM12/23/08
to openmanu...@googlegroups.com
This is great stuff -- comparing different examples and extracting out
common ideas.

--Paul Fernhout

Bryan Bishop

unread,
Dec 23, 2008, 9:40:25 PM12/23/08
to openmanu...@googlegroups.com, kan...@gmail.com
On Tue, Dec 23, 2008 at 4:02 PM, Paul D. Fernhout wrote:

> On Tue, Dec 23, 2008 at 12:11 PM, Bryan Bishop wrote:
> > Again, it goes back to one of the big roadblocks being the lack of PSL
> > tutorials; I'm not entirely well versed in sitting down in front of
> > ISO "Common Logic" and trying to figure out what an implementation
> > looks like. But even with the PSL example above, a few questions
> > become apparent, like-- at what point do we do the SKDB tie-ins? For
> > instance, what meaningful mapping can we make between the
> > "rdf:resource" attributes of the elements? They seem to reference
> > physical objects; would they instead represent the names of packages?
> > But what about the specific dimensional analysis that we've been
> > talking about? "provides 20 W of electricity" or "3 gallons/sec water
> > input required", that's not really captured by the PSL above. And then
> > what about the idea of having the recipe.psl file point to the extra
> > parameters for the machines? The example above talks about a
> > microwave; the microwave accepts a number of parameters, which should
> > be in a configuration file in the dot skdb package, so how is this
> > file adequately referenced?
>
> This is great stuff -- comparing different examples and extracting out
> common ideas.

Not quite what I was doing there, Paul. The important thing is the
recipe.psl tie-in to other information in a dot skdb package. I'm not
sure to what extent the language allows the referencing of 'rdf
resources' (if that's what they are calling them) external to a single
file. So, for instance, if the 'paint' process is in another package
in the database, is it valid PSL to just have a reference to it? And
if the parameters to the paint function are in a local file, can there
be a reference to that too? Something like <action name="paint"
params="paintbucket.params.dat"> (except, make it into valid XMLized
PSL). Ideally I'd have a place to drop a URI (and, of course, I'd
choose the local file resource handler (file://./ is it?)).

As for the alternative that I mentioned, of using gxml for
functionCAD-like representations, I guess I can modify the classes to
let each vertex point to an extra resource file, which would have
further information for the particulars of whatever ends up solving
that node in a componentized version of the recipe. Here's
functionCAD:

http://function.device.mst.edu:16080/FunctionCAD/

"FunctionCAD is an open source application used by UMR and
collaborating institutions and corporations for the visual
representation of functional models." (it's a GUI thingy; there's also
a plugin to export to a local graphsynth installation).

But I figure still poking around in PSL is a good idea. Mostly because
I'm suspicious of having a solution that has already been in-house. A
sort of reverse-"Not Invented Here" syndrome? ;-)

I've found some PSL archives of the developer discussions:
http://heybryan.org/books/Manufacturing/PSL_incomplete_archives.zip
http://www.mel.nist.gov/psl/p3/semantics/issues-log/
http://www.mel.nist.gov/psl/p4/demo/demo.html
http://www.mel.nist.gov/psl/p2/reqtable.htm

There's also some old mailing lists from the 90s: (on majo...@cme.nist.gov)
psl-semantics
psl-review
.. which I'll go poke in a bit and see if anybody is not dead.

Bryan Bishop

unread,
Dec 24, 2008, 1:45:12 AM12/24/08
to openmanu...@googlegroups.com, kan...@gmail.com
On Tue, Dec 23, 2008 at 8:40 PM, Bryan Bishop <kan...@gmail.com> wrote:
> Not quite what I was doing there, Paul. The important thing is the
> recipe.psl tie-in to other information in a dot skdb package. I'm not
> sure to what extent the language allows the referencing of 'rdf
> resources' (if that's what they are calling them) external to a single
> file. So, for instance, if the 'paint' process is in another package
> in the database, is it valid PSL to just have a reference to it? And
> if the parameters to the paint function are in a local file, can there
> be a reference to that too? Something like <action name="paint"
> params="paintbucket.params.dat"> (except, make it into valid XMLized
> PSL). Ideally I'd have a place to drop a URI (and, of course, I'd
> choose the local file resource handler (file://./ is it?)).

Somewhat answering my own question:
http://simonster.com/mt/archives/000039.html
re: RDF, URIs, URNs, IETF.

"Where URIs don't cut it, however, is when resources don't reside on
the World Wide Web, but in a private data store .... While some RDF
parsers will automatically assume any URI missing a scheme references
a relative path, the RDF specification does not require this behavior.
"

Okay, so I guess that answers my question. I think this means we can
go ahead and do a recipe.psl example. RDF URIs are used to specify the
location of the schema or definition of a class/element within some
namespace, but here I'm just trying to give a specialized way to
(validly) mention a file from which to draw parameters from as an
extension to PSL without violating specs. (Come to think of it, there
should be one other thing than just recipe.psl; the metadata needs to
have similar information.) I'm probably violating way too many rules
here though.

(Still considering functionCAD though. Not as fancy, but quicker.)

Bryan Bishop

unread,
Dec 24, 2008, 11:56:43 PM12/24/08
to openmanufacturing, kan...@gmail.com, mun...@telerama.lm.com
On Tue, Dec 23, 2008 at 12:11 PM, Bryan Bishop <kan...@gmail.com> wrote:
> What other types of recipes are there? Well, there's cooking recipes.

Is cooking fun?

http://web.archive.org/web/20070112225127/http://www.anthus.com/Recipes/CompCook.html

"Those who have savored the joy of sitting down to a meal they have
prepared, whose adrenaline has surged at the challenge of mastering a
complex menu in time for a deadline, whose soul has relaxed at the
gentle rhythms of kneading bread or chopping onions, will hesitate
before answering "No."

And yet the great masses of cookbooks for people who hate to cook, of
10-minute gourmet cookbooks, of Chinese (or French or Indian or
Mexican) cuisine made easy cookbooks, the vast sums of money spent on
dysfunctional appliances and gadgets for the kitchen, the disastrous
rise of prepared and fast foods, all argue that for many people the
answer is indeed "No."

I take as a given that eating is fun, that culinary exploration is
fun, that thinking about recipes and inventing new ones is fun. I
leave open the question of whether or not the manual labor underlying
such enterprises is fun. Let readers consider carefully whether, given
the choice tomorrow evening, they would spend 30 minutes preparing a
Poulet sauté au basilic by hand, or would instead spend 30 seconds
punching in their order to their robot. Cooking may well be a
recreation, like tennis or crossword puzzles, where automation would
miss the point; on the other hand, it may well fall into the category
of drudge work best left to the droids.

So I do not say that the goal of computerized cooking is to free cooks
from cooking, but rather to raise the level at which cooking is
conceived, to make it possible to think about recipes in more abstract
terms than just how a given recipe can be put together."

Mundie's RxOL is based off of postfix and reverse polish notation:

<* Chicken Chasseur (Poulet Sauté Chasseur).
*chicken, 1 kg =cut up
{ *oil
*butter /and } /sauté in, till three-quarters cooked
*mushrooms, 125 g =slice /add =cook
*:chicken =remove
*white wine, 100 ml /add
*shallot, 10 g /add =reduce
*thickened rich veal gravy, 150 ml /add
*tomato sauce, 50 ml /add =simmer, 30 s
*brandy, 15 ml /add
*parsley, 10 g =mince /add
*chervil, 10 g =mince /add
*tarragon, 10 g =mince /add
*:chicken /pour over
*parsley =mince /sprinkle with>

I wonder where this went. The book, Computerized Cooking, was written
1985 and must have went the way of the personal robot. His website was
cached on Google, but it was only an IP address, and something about
him working at the University of Pittsburgh. cc'd.

((David, if you do happen to get this email, we're looking into the
extension of recipe standardization towards open, free manufacturing
and standardized hardware representation.))

marc fawzi

unread,
Dec 25, 2008, 1:08:40 AM12/25/08
to openmanu...@googlegroups.com, kan...@gmail.com, mun...@telerama.lm.com

General Reverse Engineering Robot:

Give it any product (including byte code, music, food, and electronics products) and it will take it apart and reverse engineer the spec (or "recipe")

It exists in the future!

Bryan Bishop

unread,
Dec 27, 2008, 7:57:04 AM12/27/08
to openmanufacturing, kan...@gmail.com
On Wed, Dec 24, 2008 at 10:56 PM, Bryan Bishop wrote:
> On Tue, Dec 23, 2008 at 12:11 PM, Bryan Bishop <kan...@gmail.com> wrote:
>> What other types of recipes are there? Well, there's cooking recipes.
>
> Is cooking fun?

There's a lot of lab protocols that really should be in a more
consistent format:
http://www.protocol-online.org/

Some random clicking brought me to:
http://www.protocol-online.org/cgi-bin/prot/view_cache.cgi?ID=3841
"Chromatin preparation from cultured human cells"

"""
1) cells (HL-60 or lymphoblastoids) are grown to a density of approx.
10 x e6 cells/ml , until they are in log phase. Label cells overnight
with [3H] thymidine at 0.5 mCi/ml. (If the tritium label is very
recent, then it's wise to reduce the amount to prevent radiolysis of
the chromatin).

2) harvest cells: centrifuge at 7,000 x g, 10mins, 4oC and wash the
cell pellet three times in ice cold 1 x PBS/5 mM Na.butyrate

*it is essential that Na.butyrate is present in all solutions
throughout chromatin isolation to prevent histone deacetylation*

3) resuspend cell pellet in 1 x TBS (Tris buffered saline) at 2 x 10 x
e7 cells/ml and add an equal volume of 1.0% [v/v] Tween40/1 x TBS. Add
0.005 vol. of 100 mM PMSF. Leave stirring gently on ice for 1hr. (Put
the suspension in 50 ml Falcon tube with a small magnetic bar or flea;
place the tube in ice on top of a magnetic stirrer).
"""
(And it goes on like that for a while.) I'm sure many people have had
trouble with protocols before because of convoluted terminology, an
author not really expressing what to do properly, and many other
factors.

Definition of an XML Markup Language for Clinical Laboratory
Procedures and Comparison with Generic XML Markup
http://www.clinchem.org/cgi/content/abstract/52/10/1943

GPL'd DTD for CLP-ML:
http://www.clinchem.org/content/vol0/issue2006/images/data/clinchem.2006.071449/DC1/clinchem.2006.071449-2.txt

Basically, CLP-ML has a lot of DTD information on representing some of
the inventory requirements on a clinical lab protocol, and then
there's a simple step-step-step procedural portion for the
representation of what to do. But this isn't any better than just me
hacking functionCAD into a list of elements that you graph to make a
UML-like diagram of processes.

There's also Clinical Document Architecture (CDA), an ANSI standard:
http://en.wikipedia.org/wiki/Clinical_Document_Architecture
http://hl7book.net/index.php?title=CDA

65 MB of examples and 40 projects:
http://www.ringholm.de/download/CDA_R2_examples.zip
.. but remember, this is for clinical documents, not just the subset
covered by CLP-ML. And in fact I'm not seeing many examples in that
giant zip file about clinical protocols.

So again somebody has thought of doing better representation of
recipes. Remembering my basic computer science, every parallel program
(set of instructions) can be simulated on a linear computing
architecture. So, therefore, any simple step-by-step instruction
format should be suitable; maybe one day you'd have to get clever and
represent timing and conditionals as their own steps, rather than as a
control structure over the entire recipe listing.

If only overloading was more dynamic. "We see that there are 20
different solutions to this function, and 30 to this one, but only 5
combinations that make it so that the two functions match up
specifically." If that would be possible, then the recipes could just
be scripted. But as it is, if you're in python for instance, you have
to "import" all of the modules that might be useful for you, which
means runtime memory overhead -- a lot of it is not going to be always
in use.

Here's some code that was checked in 2 years ago to get overloading
working in python:
http://svn.python.org/view/sandbox/trunk/overload/overloading.py?rev=43727&view=auto

========================
# I can't help myself -- this is going to be intense functional code.
# Find all possible candidate signatures.
mros = tuple(t.__mro__ for t in types)
n = len(mros)
candidates = [sig for sig in self.registry
if len(sig) == n and
all(t in mro for t, mro in zip(sig, mros))]
if not candidates:
# No match at all -- use the default function.
return self.default_func
if len(candidates) == 1:
# Unique match -- that's an easy case.
return self.registry[candidates[0]]
========================

In other words, in python the overloading is a brute-force search
through the 'registry' of function signatures. So I'd have to write in
some database searching code if I wanted to expand that, maybe I'll go
talk with Guido about that when he gets back from his current
trip/vacation off the grid. Not sure if I'm interested in doing that
until then.

Sorry to keep going on about this. This email was a draft that I
didn't send, mostly because of some other code that I ended up typing
out that I need to go edit a bit more (just a few classes for
ingredients, steps, and recipes, which are explicitly meant to be used
in combination with the git commit system once they are serialized via
YAML).

Kevin H

unread,
Dec 31, 2008, 4:36:59 PM12/31/08
to openmanu...@googlegroups.com
Bryan,

I can't help but think that what you're after, ultimately, is a domain specific programming language.  Because that's exactly what a programming language does, it's a representation for a set of instructions on how to perform a particular task or produce a particular result.  The only difference is that rather being executed internally by the CPU, it's being executed externally by manufacturing machines.  Then the recipes in this programming language can be manipulated using meta-programming tools.

Kevin

Bryan Bishop

unread,
Dec 31, 2008, 4:46:50 PM12/31/08
to openmanu...@googlegroups.com, kan...@gmail.com

Yes, but since we don't have a universal instruction set architecture
for fabrication plants, the idea is to have an abstraction layer. In
part this is what gcode, the EMC project and others allow us to do. I
am disinterested in CAM-only, or tools that generate only the
instructions for a specific ISA on a manufacturing mainframe--
instead, I also want the ability to generate readable instructions via
adding the serializing functions to the individual packages.

Reply all
Reply to author
Forward
0 new messages