I created a general-purpose, high-level programming language called bagel. bagel is a lightweight yet extensible Lisp-like
scripting language written in and easily integrated with Java. It's called bagel because it goes so well with Java.
;;; fileOrder: 2;
import com.rst.tools.io.*;
import com.rst.tools.lang.*;
import com.rst.tools.net.*;
;;; Page wrapper
(defineContent :pageHeader (&key page)
(head :contents (block
(title :string (makeString "Mike Brady • " (get:title page)))
(includeViaPageMethod includeMetaData page nil)
(script :src "scripts.js")
(headerLink :href "basic.css" :rel "stylesheet" :type "text/css")
(headerLink :href "images/icon4.png" :rel "icon"))))
(defineContent :pageWrapper (&rest keys &key page)
(body :contents
(block
(div :position 'absolute :width "1028px" :margin-left "-514px" :left "50%" :top "10px"
:contents (block
(div :background-image "url('images/HeaderBG.png')" :background-repeat 'no-repeat
:height "160px"
:contents (block
(div :position 'absolute :left "900px" :top "25px"
:contents (includeViaPageMethod includeTopRightHeader page keys))
(div :position 'absolute :left "256px" :top "123px"
:contents (apply 'include true :mainMenu keys))))
(div :background-image "url('images/BodyBG.png')" :background-repeat 'repeat-y
:width "1028px"
:contents (block
(div :float 'left :position 'relative :left "27px" :top "-30px" :width "197px" :height "500px"
:contents (includeViaPageMethod includeSidebar page keys))
(div :float 'left :position 'relative :left "75px" :width "700px"
:contents (includeViaPageMethod includeMainContent page keys))
; Very important to do this or the wrapping div (with the BodyBG.png) won't include the previous 2 divs.
(div :clear 'both)))
(div :background-image "url('images/FooterBG.png')" :background-repeat 'no-repeat
:width "1028px" :height "50px"
:contents (space))))
(include t :statCounter))))
(defun includeViaPageMethod (_method page keys)
(apply method page (get:id page) (getProp keys :topic) keys))
;;; Main menu
(defineContent :mainMenu (&rest keys &key page)
(link :class "noDecoration" :href (makePageLink :index) :contents (span :class "darkGray size11 expanded" :value "home"))
(horizontalSpacer :width 15)
(link :class "noDecoration" :href (makePageLink :resume) :contents (span :class "darkGray size11 expanded" :value "resume"))
(horizontalSpacer :width 15)
(link :class "noDecoration" :href (makePageLink :projects :topic :penelopeCS) :contents (span :class "darkGray size11 expanded" :value "projects"))
(horizontalSpacer :width 15)
(link :class "noDecoration" :href (makePageLink :movies) :contents (span :class "darkGray size11 expanded" :value "movies"))
(horizontalSpacer :width 15)
(link :class "noDecoration" :href (makePageLink :projects :topic :bagel) :contents (span :class "darkGray size11 expanded" :value "bagel"))
(horizontalSpacer :width 15)
(link :class "noDecoration" :href (makePageLink :code) :contents (span :class "darkGray size11 expanded" :value "code"))
(horizontalSpacer :width 15)
(link :class "noDecoration" :href (makePageLink :writing) :contents (span :class "darkGray size11 expanded" :value "writing"))
(horizontalSpacer :width 15)
(link :class "noDecoration" :href (makePageLink :hobbies) :contents (span :class "darkGray size11 expanded" :value "hobbies")))
(defineContent :mainContentHeader (&key header)
(lineSpacer :height 8)
(span :class "size12 expanded " :value header)
(horizontalRule :class "darkGray")
(lineSpacer :height 20))
(defineMethod includeTopRightHeader ((MBPage this) id topic &key)
(span :class "mediumGray size10" :value "560 W 218th St")
(lineSpacer :height 2)
(span :class "mediumGray size10" :value "Apt 3C")
(lineSpacer :height 2)
(span :class "mediumGray size10" :value "New York, NY 10034"))
(defineContent :sidebarMenuItem (&key link topic name selectedTopic)
(div :float 'right
:contents (link :href (makePageLink link :topic topic)
:contents (block
(span :class (if (wildcardMatch (makeString topic "*") selectedTopic) "size11 expanded black" "size11 expanded2px darkGray") :value name)
(image :src "images/leftArrow.png" :vertical-align 'middle))))
(lineSpacer :height 5 :clear 'both))
(defineContent :mainContentHeader (&key label _contents)
(lineSpacer :height 6)
(span :class "size12 expanded" :value label)
(lineSpacer :height 12)
(div :class "size12" :width "609px" :contents (insert contents))
(lineSpacer :height 15)
(div :position 'relative :left "-27px" :contents (image :src "images/horizontalBar.jpg"))
(lineSpacer :height 10))
(defineContent :rstWebsiteContent (&key content)
(div :clear 'both)
(div :float 'left :width "520px" :contents (include t content)))
;;; Index
;;; _____________________________________________________________________________________________________________________________
(definePage :index IndexPage.class)
(defineMethod includeSidebar ((IndexPage this) id topic &key)
(span :class "size11 expanded2px darkGray"
:value "Hi. My name is Mike Brady, and welcome to my website.")
(lineSpacer :height 20))
(defineMethod includeMainContent ((IndexPage this) id topic &rest keys)
(image :src "images/headShot.jpg" :float 'right)
(div :width "500px"
:contents (flow :contents ((lineSpacer :height 20)
(span :value "Featured Projects" :class "expanded")
(lineSpacer :height 30)
(link :href (makePageLink :projects :topic :bagel) :contents (image :src "images/bagelLogo.png"))
(lineSpacer :height 10)
"I've developed a full-featured object-oriented scripting language called bagel. bagel combines the elegant and
expressive modelling capabilities of Lisp with the modern, lightweight, web-enabled sensibility of Java to create a
wholly new language. Click "
(link :href (makePageLink :projects :topic :bagel.features) :string "here")
" to learn more."
(lineSpacer :height 20)
(link :href (makePageLink :projects :topic :penelopeCS) :contents (image :src "images/PenelopeCSLogo.jpg"))
(lineSpacer :height 10)
"I led the development team creating PenelopeCS, the first robot designed to work in the sterile supply department of
the hospital. Penelope is pure innovation — applying tested robotics technology from the manufacturing world to
to do a real job in the hospital."
(lineSpacer :height 30)
(div :width "395px" :position 'relative
:contents (block
(link :href (makeMovieLink :penelopePress)
:contents (image :src "images/movieStills/PenelopePress.jpg"))
(div :width "180px" :position 'absolute :right "0px" :bottom "0px"
:contents (flow :class "size11"
:contents ("This is me playing the part of a surgeon on TV. Click "
(link :href (makePageLink :movies) :string "here")
" to see this and other of movies."))))))))
(lineSpacer :height 15))
;;; Projects
;;; _____________________________________________________________________________________________________________________________
(definePage :projects ProjectsPage.class)
(defineMethod includeSidebar ((ProjectsPage this) id topic &key)
(span :class "size12 expanded darkGray" :value "projects")
(lineSpacer :height 45)
(include t :sidebarMenuItem :name "penelopeCS" :link :projects :topic :penelopeCS :selectedTopic topic)
(include t :sidebarMenuItem :name "bagel" :link :projects :topic :bagel :selectedTopic topic)
(include t :sidebarMenuItem :name "cpacs" :link :projects :topic :cpacs :selectedTopic topic)
(include t :sidebarMenuItem :name "bsp" :link :projects :topic :bsp :selectedTopic topic)
(include t :sidebarMenuItem :name "websites" :link :projects :topic :websites :selectedTopic topic))
(defineMethod includeMainContent ((ProjectsPage this) id ((equals :penelopeCS) topic) &rest keys)
(include t :mainContentHeader :label "projects > penelopeCS >"
:contents (flow :contents ("I led the development team creating PenelopeCS, a first-in-class robot designed to work in the sterile supply
department of hospitals. Following the Agile development methodology, my team took this robot from
concept to a saleable product. Go to the "
(link :href (makePageLink :index) :string "movies")
" page to watch PenelopeCS in action. You can also click "
(link :href "http://www.roboticsystech.com" :string "here")
" to learn more.")))
(include t :rstWebsiteContent :content :rstWebsitePenelopeCS))
(defineContent :rstWebsitePenelopeCS (&key)
(flowAroundImage :src "images/PenelopeCSIsolatedCloseup.png" :side 'left :left "-27px"
:contents (block
(image :src "images/PenelopeCSLogo.jpg")
(lineSpacer :height 5)
(flow :contents ("The PenelopeCS family of products focuses on automation in the hospital's sterile supply department. There
are many manual, repetitive tasks in this process well suited for automation. RST's core technology focuses
on autonomous robotic workcells that can manipulate, track, sort, and process surgical instruments and supplies.
With the PenelopeCS product line, RST will apply this technology to various sterile supply tasks to increase efficiency,
reduce errors, enhance inventory control, and reduce costs."))
(lineSpacer :height 20)
(horizontalSpacer :width 30)
(image :src "images/PenelopeCSSystem.jpg")))
(span :class "gray expanded" :value "Background")
(lineSpacer :height 10)
(flow :contents ("The sterile supply department is the heart of the hospital's surgical instrument supply chain. Every day, thousands of used instruments
pass through sterile supply to be cleaned, counted, inspected, repacked, and sterilized. A delay or an error in sterile supply can impact
scheduling, cost, and even patient safety in the OR. RST feels the time is right for automation in the sterile supply department.
<p>Robots have been a mainstay in the manufacturing world for decades, helping make everything from cars to cookies. PenelopeCS will bring
some of these tried-and-true automation techniques to one of the most labor-intensive and error-prone departments in the hospital — sterile
supply. "
(lineSpacer :height 15)))
(image :float 'left :floatHorizontalMargin 15 :src "images/PenelopeCSFunctions.jpg")
(span :class "gray expanded" :value "Functions")
(lineSpacer :height 10 :clear nil)
(flow :contents ("The first product in RST's PenelopeCS line will focus on the <i>clean</i> side of sterile supply.
The advance will be dramatic. The robot will ensure that each tray sent to the OR will have exactly
those instruments specified on the count sheet and that they are all in good working order. And like
a good robot, it will do this automatically, precisely, and reliably — 24 hours a day, 7 days a week."
(lineSpacer :height 10 :clear nil)
"Our "
(link :href "http://www.roboticsystech.com/infosterileSupply.html" :string "Sterile Supply 101")
" page describes how sterile supply is divided into a <i>dirty</i> and a <i>clean</i> side. Our flagship PenelopeCS will work on the clean side;
counting, sorting, and packing instruments. The goal is to ensure that the contents of each container have been verified and neatly
packed before it is closed and placed in the autoclave. Furthermore, as these instruments are loaded, PenelopeCS will seamlessly update the
hospital's inventory control system — tracking each container and the instruments within it, while reducing the workload on sterile supply staff.
<p>PenelopeCS will work in conjunction with a variety of third-party instrument identification systems, using either RFIDs or barcodes to \"mark\"
individual instruments with a unique code. The robot is identification system agnostic in this regard. PenelopeCS is based on RST's
extensible hardware/software framework comprised of a <i>Core Robotic Workcell</i> and a diverse set of <i>Plugin Components</i> — task-specific
hardware assemblies installed within the robot's workcell. A variety of RFID and/or barcode scanners will be packaged as <i>Plugins</i> and
integrated within PenelopeCS, providing great flexibility for our customers.")))
;;; bagel
(defineContent :bagelMenuItem (&key topic name selectedTopic)
(span :class "courier size22 greenGray" :value "(" :position 'relative :top "-10px")
(link :href (makePageLink :projects :topic topic)
:class "hoverBold hoverNoDecoration"
:contents (span :class (if (equals topic selectedTopic) "courier size16 greenGray underlined" "courier size16 greenGray")
:position 'relative :top "-10px" :left "-2px"
:value name))
(span :class "courier size22 greenGray" :value ")" :position 'relative :top "-10px")
(horizontalSpacer :width 10))
(defineMethod includeMainContent ((ProjectsPage this) id ((matches ":bagel*") topic) &rest keys)
(include t :mainContentHeader :label "projects > bagel >"
:contents (flow :contents ("I created a general-purpose, high-level programming language called bagel. bagel is a lightweight yet extensible Lisp-like
scripting language written in and easily integrated with Java. It's called bagel because it goes so well with Java.")))
(include t :bagelMenuItem :topic :bagel :name "home" :selectedTopic topic)
(include t :bagelMenuItem :topic :bagel.background :name "background" :selectedTopic topic)
(include t :bagelMenuItem :topic :bagel.features :name "features" :selectedTopic topic)
(include t :bagelMenuItem :topic :bagel.examples :name "examples" :selectedTopic topic)
(lineSpacer :height 20)
(div :min-height "400px"
:contents (block
(image :src "images/bagelLogo.png")
(apply 'includeBagelMainContent this id topic keys))))
;;; :bagel home
(defineMethod includeBagelMainContent ((ProjectsPage this) id ((equals :bagel) topic) &rest keys)
(image :src "images/bagelIs.png")
(lineSpacer :height 20)
(div :position 'absolute
:contents (block
(include t :bagelIsElement :left "30px" :top "140px" :size "size36" :name "object-oriented")
(include t :bagelIsElement :left "90px" :top "50px" :size "size28" :name "flexible")
(include t :bagelIsElement :left "420px" :top "200px" :size "size36" :name "powerful")
(include t :bagelIsElement :left "110px" :top "4210px" :size "size32" :name "fun")
(include t :bagelIsElement :left "190px" :top "250px" :size "size24" :name "persistent")
(include t :bagelIsElement :left "340px" :top "70px" :size "size24" :name "self-aware")
(include t :bagelIsElement :left "440px" :top "130px" :size "size30" :name "concise")
(include t :bagelIsElement :left "300px" :top "0px" :size "size34" :name "elegant")
(include t :bagelIsElement :left "490px" :top "30px" :size "size22" :name "embedded"))))
(defineContent :bagelIsElement (&key left top size name)
(let ((id (java:generateRandomString StringTools.class 10 #\A #\Z)))
(div :position 'absolute :left left :top top
:contents (link :contents (span :id id :class (makeString size " greenGray expanded") :value name :white-space 'nowrap)))
(attachShaker id :dt 70 :nFrames 15)
; (attachFontSizeShifter id :onMouseOver false :nFrames -1 :dt 200 :sizeDelta 0.05)
(attachColorShifter id :onMouseOver false :dt 200 :nFrames -1)))
(defun attachShaker (id &key (shakeDelta 1) (nFrames 20) (dt 50) (onMouseOver true))
(createInlineJSFuncall "new Shaker" id dt nFrames onMouseOver shakeDelta))
(defun attachFontSizeShifter (id &key (sizeDelta 0.05) (shiftOdds 0.1) (minSize 6) (maxSize 42) (nFrames 20) (dt 50) (onMouseOver true))
(createInlineJSFuncall "new FontSizeShifter" id dt nFrames onMouseOver sizeDelta shiftOdds minSize maxSize))
(defun attachColorShifter (id &key (shiftFactor 0.95) (shiftOdds 0.1) (nFrames 20) (dt 50) (onMouseOver true) (minValue 100) (maxValue 200))
(createInlineJSFuncall "new ColorShifter" id dt nFrames onMouseOver shiftFactor shiftOdds minValue maxValue))
;;; :bagel.background
(defineMethod includeBagelMainContent ((ProjectsPage this) id ((equals :bagel.background) topic) &rest keys)
(lineSpacer :height 20)
(image :src "images/bagelSnippet1.jpg" :float 'right :position 'relative :margin-bottom "12px")
(span :value "I created bagel because I was working in Java, but missed the expressiveness and elegance of Lisp. I missed the freedom, the speed, and
the sheer joy of programming in Lisp. Since then, less restrictive scripting languages like Python have become more popular than ever —
perhaps an indication that I was not alone.")
(lineSpacer :height 15)
(span :value "bagel started out as a faithful Common Lisp implementation. I decided at some point though that this was actaully a great opportunity to
incorporate some of the great features of Lisp into a more modern language. So while bagel owes everything to Lisp, it barrows a bit from
Java and the internet era as well.")
(lineSpacer :height 15)
(span :value "The symbiotic relationship between bagel and Java has evolved as well. bagel is written in Java. You create an instance of the class
<code>Interpreter</code> in your Java application and load and run bagel code within that interpreter. You can easily and seamlessly call
Java from bagel and bagel from Java. Generally speaking I find it more natural to express the high-level business logic for my application
in bagel and use Java for the low-level general-purpose functions."))
;;; :bagel.features
(defineMethod includeBagelMainContent ((ProjectsPage this) id ((equals :bagel.features) topic) &rest keys)
(lineSpacer :height 20)
(include t :bagelFeature :title "Syntactic Simplicity"
:contents (flow :contents ((image :src "images/bagelSyntax.jpg" :float 'right :position 'relative :top "-90px")
"bagel's syntax is straight from Lisp. While other languages use a bewhildering array of characters to define syntax
bagel uses just parens and white space.")))
(include t :bagelFeature :title "Mixins"
:contents (flow :contents ("bagel classes can extend any number of superclasses. When you define a class you can <i>mix in</i> whichever classes apply.")))
(include t :bagelFeature :title "Self Awareness"
:contents (flow :contents ("Like Lisp, bagel makes little distinction between data and code. bagel programs can write other programs, and you can easily
extend the language, with your additions being indistinguishable from core bagel.")))
(include t :bagelFeature :title "OODB"
:contents (flow :contents ("bagel classes have an integrated object-oriented database. Instances of any class can be persisted by extending the
<code>PersistedObject</code> class. You can also <i>query</i> the universe of runtime objects.")))
(include t :bagelFeature :title "Values have types, not variables"
:contents (flow :contents ("Like most modern scripting languages, bagel variables aren't typed. Any <i>value</i> can be tested for it's type though.")))
(include t :bagelFeature :title "Powerful Arguments"
:contents (flow :contents ("bagel functions and methods support flexible and expressive argument lists. You can specify that your function takes any
number of arguments, that some are optional with default values, and that some should not be evaluated when the funciton is called.
Most powerfully, you can specify keyword arguments that can be supplied in function calls as keyword-value pairs in any order.")))
(include t :bagelFeature :title "Method Specializers"
:contents (flow :contents ("One of the most unique features of bagel is that it's methods can be specialized on more than just the class of it's arguments.
Methods can even specialize on a string match in bagel.")))
(include t :bagelFeature :title "BSP"
:contents (flow :contents ("bagel is web-enabled. With bagel server pages you can create dynamic websites in bagel. This site is one!")))
(include t :bagelFeature :title "Built-ins"
:contents (flow :contents ("bagel has over 300 built-in primitives. To name a few: <code>defun</code>, <code>let</code>, <code>set</code>, <code>loop</code>,
<code>if</code>, <code>cond</code>, <code>find</code>, <code>defineClass</code>, <code>defineMethod</code>, <code>not</code>,
<code>or</code>, and so on!")))
(include t :bagelFeature :title "Destructuring"
:contents (flow :contents ("You can create a variable structure that matches your data to assign many values in one statement. ")))
(include t :bagelFeature :title "Read"
:contents (flow :contents ("bagel implements Lisp's <code>read</code> function and includes a rich and powerful input stream parser.")))
(include t :bagelFeature :title "Prefix Notation"
:contents (flow :contents ("bagel uses prefix notation from mathematics. <code>f(x, y)</code> becomes <code>f(x y)</code> because the comma serves
no purpose, then suck the function inside the parens to get <code>(f x y)</code>. That's bagel's syntax — simple and clean.")))
(include t :bagelFeature :title "Loop!"
:contents (flow :contents ("bagel fully implements the amazing <code>loop</code> marco from Common Lisp.")))
(include t :bagelFeature :title "Java Integration"
:contents (flow :contents ("Java methods, objects, and instance variables can be accessed from bagel. So <code>myString.toLowerCase()</code> in Java
becomes <code>(java:toLowerCase myString)</code> in bagel.")))
(include t :bagelFeature :title "Multiple Values"
:contents (flow :contents ("Your bagel functions can return more than one value if you'd like."))))
(defineContent :bagelFeature (&key title _contents)
(span :value title :class "expanded")
(lineSpacer :height 10)
(insert contents)
(lineSpacer :height 20))
;;; :bagel.examples
(defineMethod includeBagelMainContent ((ProjectsPage this) id ((equals :bagel.examples) topic)
&key (examples '("HelloWorld.bgl" "Goals.bgl" "ThisPage.bgl" "oodb.bgl" "threads.bgl" "TransformedImages.bgl"))
(selected (first examples)))
(lineSpacer :height 20)
(span :value "Select Example:")
(horizontalSpacer :width 8)
(select :id "exampleSelector" :options (loop for example in examples
for selected = true then nil
do (option :string example :selected selected)))
(lineSpacer :height 10)
(div :width "700px" :height "420px" :overflow 'scroll :border "1px solid #999999" :padding "5px"
:contents (pre :id "exampleContainer" :contents nil))
(loop for example in examples
do (div :display 'none :id example :contents (insertFile (makeString "examples/" example) :escapeForHTML true)))
(apply 'createInlineJSFuncall "new SelectableDIV" "exampleSelector" "exampleContainer" examples)
(lineSpacer :height 20))
(defun readExample (file)
(java:escape HTMLEscaper.class (java:readFile FileTools.class (makeString wwwRoot "/examples/" file))))
;;; CPACS
(defineMethod includeMainContent ((ProjectsPage this) id ((equals :cpacs) topic) &rest keys)
(include t :mainContentHeader :label "projects > cpacs >"
:contents (flow :contents ("While at Boeing I led the development team creating a software tool called CPACS that manifested and laid out all the
cargo going into the Space Shuttle for resupply flights to the International Space Station. This was very advanced
software for the time, tackling the NP-hard 3D bin packing problem. We delivered CPACS to NASA under budget and
ahead of schedule.")))
(image :src "images/cpacs/cpacsLogo.gif")
(lineSpacer :height 10)
(flow :contents ("CPACS is a software application written to support cargo planning and analysis for the "
(link :href "http://www.nasa.gov/topics/shuttle_station/index.html" :string "International Space Station")
". The Space Station will be periodically resupplied using "
(link :href "http://www.nasa.gov/" :string "NASA")
"'s fleet of space shuttles. Each shuttle will transport cargo carriers to and from the station, packed with experiment payloads, crew supplies, spare parts, and other items essential to maintaining station operations. CPACS will help produce near-optimal configurations for these carriers, maximizing the efficiency of this complex logistics system."
(lineSpacer :height 10)
"CPACS is a comprehensive, multi-user planning and automation tool designed to ease this complex load planning task. CPACS provides its users with two major features: an integrated set of graphical user interfaces designed to support the development, analysis, and integration of load plans, and a set of fully automated optimization algorithms which \"pack\" cargo carriers and perform other load planning tasks."
(lineSpacer :height 10)
"The Configuration Editor supports the main functionality of CPACS -- building load plans.
A load plan specifies a position for each item on each packing level.
The screen below shows the stowage tray packing level. On the right we see the trays we are
packing and on the left are some as yet unpositioned cargo items."
(lineSpacer :height 20)
(image :src "images/cpacs/configuration.gif")
(lineSpacer :height 20)
"CPACS draws a cargo item as a black box while the user positions it. He/she can
move the item around within the tray using the mouse. Note how CPACS redraws the
tray views and the weight scale when the new cargo item is added."
(lineSpacer :height 20)
(image :src "images/cpacs/ci-pos.gif")
(lineSpacer :height 20)
"Here's a detailed look at a stowage tray. The cargo items shown in the top-down and
perspective views are listed to the right by part ID. This is the tray's stowage list.
The color of a cargo item indicates its customer. Item number 1, CPACS-PRESS-CI-1462,
is yellow -- so it belongs to the same customer we saw in the Zone Editor example."
(lineSpacer :height 10)
"We can see by the weight scale in the lower left-hand corner, that we are very near
the mass limit for this tray. The scale shows 56.31 lbs as the sum of the weight of the
tray itself, the cargo items, and the weight of the foam that will surround the cargo."
(lineSpacer :height 20)
(image :src "images/cpacs/tray.gif")
(lineSpacer :height 20)
"These are examples of trays that CPACS has packed automatically. For small
problems like these, CPACS can produce a pack in just a few seconds. The
automated algorithms try the cargo items in various orders and orientations
much as a person would. The user can adjust the algorithms so that they
will try more combinations. This makes them run longer, but they may come
up with slightly better results."
(lineSpacer :height 10)
"Whether you pack automatically or manually, CPACS is always keeping track
of several packing constraints for you."
"<table cellpadding=0 cellspacing=20>
<tr valign=center><td align=center><img src='images/cpacs/auto-tray1.gif'>
<td align=center><img src='images/cpacs/auto-tray2.gif'>
<tr valign=center><td align=center><img src='images/cpacs/auto-tray3.gif'>
<td align=center><img src='images/cpacs/auto-tray4.gif'>
</table>"
(lineSpacer :height 20)
"CPACS tracks a wide variety of packing constraints as the configuration is
being developed. Here are some examples ..."
(lineSpacer :height 20)
"<table cellpadding=0>
<tr><td><img alt='o' align=center src='images/cpacs/logo-bullet.gif' width=35 height=32>
<td><i>Weight limits</i>
</tr>
<tr><td> </td>
<td>
No container can be packed beyond its loading limit.
</td>
</tr>
<tr><td><img alt='o' align=center src='images/cpacs/logo-bullet.gif' width=35 height=32>
<td><i>Center of gravity</i>
</tr>
<tr><td> </td>
<td>
Containers also have center of gravity requirements. CPACS will insure that the
CG stays within a given range.
</td>
</tr>
<tr><td><img alt='o' align=center src='images/cpacs/logo-bullet.gif' width=35 height=32>
<td><i>Mass allocations</i>
</tr>
<tr><td> </td>
<td>
A customer's packed cargo cannot weigh more than their mass allocation.
</td>
</tr>
<tr><td><img alt='o' align=center src='images/cpacs/logo-bullet.gif' width=35 height=32>
<td><i>Occlusion</i>
</tr>
<tr><td> </td>
<td>
Occlusion means that two items are occupying the same physical space at the same
time! This is not allowed.
</td>
</tr>
<tr><td><img alt='o' align=center src='images/cpacs/logo-bullet.gif' width=35 height=32>
<td><i>Orientation</i>
</tr>
<tr><td> </td>
<td>
Items can have required orientations. CPACS will inforce this.
</td>
</tr>
<tr><td><img alt='o' align=center src='images/cpacs/logo-bullet.gif' width=35 height=32>
<td><i>Zones</i>
</tr>
<tr><td> </td>
<td>
Customers must keep their cargo within the zones defined in the Zone Editor.
</td>
</tr>
</table>"
(lineSpacer :height 20)
"Once the trays are packed to our liking, we can move on to the next level -- the
stowage rack. This interface is analogous to the tray level. The containers, racks
this time, are on the right and the unpositioned containees, trays, are on the left."
(lineSpacer :height 20)
(image :src "images/cpacs/rsr.gif")
(lineSpacer :height 20)
"This window offers more mass properties detail for the stowage rack. CPACS always keeps
track of weights, centers of gravity, and moments and products of inertia. It's important
to remember that these values represent the <i>integrated</i> stowage rack, including the
trays and cargo items within them."
(lineSpacer :height 20)
(image :src "images/cpacs/rsr-describe.gif")
(lineSpacer :height 20)
"The Mini-Pressurized Logistics Element, or MPLM, is a large cylindrical module that
sits in the orbiter's payload bay. It accommodates various kinds of racks including
the stowage rack we've been working on. Again, the process is similar -- just on a larger
scale."
(lineSpacer :height 20)
(image :src "images/cpacs/mplm.gif")
(lineSpacer :height 20)
"And that pretty much wraps it up! This is the payload bay of the Space
Shuttle orbiter with the MPLM, racks, trays, and cargo items we've been
packing."
(lineSpacer :height 10)
"The final product of this process is a complete configuration for an entire
flight -- including pictures of each container and its cargo."
(lineSpacer :height 20)
(image :src "images/cpacs/orbiter.gif")
(lineSpacer :height 100)
)))
;;; Movies
(definePage :movies MoviesPage.class)
(set movies '(:penelopeCSTour (:title "PenelopeCS Guided Tour" :file "movies/PenelopeCSTour" :blurbImage "images/movieStills/PenelopeCSTour.jpg"
:description "<i>Hello. My name is Penelope. Let me show you around.</i>
<p>In this video Penelope gives a guided tour of the system. Who better than Penelope herself to explain the
features of RST's exciting new product for the hospital sterile supply department")
:penelopeAndM7 (:title "Penelope and the M-7" :file "movies/ATA06" :blurbImage "images/movieStills/PenelopeAndM7.jpg"
:description "RST and SRI International joined forces on May 7th 2006 for a first-ever demonstration of unmanned
telesurgery involving a robotic surgeon and a robotic scrub technician. Penelope 3.0 delivered
supplies to SRI’s M-7 robot which used them to carry out sponging and suturing of a simulated surgical
wound. This demonstration was sponsored by the US Army’s Telemedicine & Advanced Technology
Research Center (<a href='http://www.tatrc.org/' target='_blank'>TATRC</a>).")
:penelopePress (:title "Penelope Press" :file "movies/PenelopePress" :blurbImage "images/movieStills/PenelopePress.jpg"
:description "Some highlights from the press coverage of the original Penelope robot.")
:penelopeCSIntro (:title "PenelopeCS Intro" :file "movies/PenelopeCSIntro" :blurbImage "images/movieStills/PenelopeCSIntro.jpg"
:description "Introducing PenelopeCS, RST's exciting new product for the hospital sterile supply department. This short video
starts with an introduction to the hospital's sterile supply department, including some of the challenges there. It
then goes on to our solution: PenelopeCS.")))
(defun getMovieProp (movieID prop &optional default)
(getProp (getProp movies movieID) prop default))
(defun makeMovieLink (movieID)
(makePageLink :movies :topic :movie :movieID movieID))
(defineMethod includeMainContent ((MoviesPage this) id topic &key movieID)
(include t :mainContentHeader :label "movies >"
:contents (flow :contents ("I've created several promotional movies for my work. It's a quick and fun way to get an overview of some of
the projects I've worked on. I wrote the copy, shot the video, and edited these movies.")))
(lineSpacer :height 20)
(cond (movieID (includeMoviePage this movieID))
(true (includeMoviesList this))))
(defineMethod includeMoviesList ((MoviesPage this))
(loop for (movieID nil) on movies by 'rrest
as title = (getMovieProp movieID :title)
as description = (getMovieProp movieID :description)
as blurbImage = (getMovieProp movieID :blurbImage)
do
(horizontalRule :color "#cfdbec" :height "1px" :class "lineHeight130Percent" :size "1px")
(div :float 'left :padding-right "15px" :width "207px"
:contents (block
(link :href (makeMovieLink movieID) :contents (image :src blurbImage))
(link :href (makeMovieLink movieID) :string "Play movie »")))
(link :href (makeMovieLink movieID) :contents (span :class "size12 expanded" :value title))
(lineSpacer :height 8)
(span :value description)
(lineSpacer :height 20 :clear 'left)))
(defineMethod includeMoviePage ((MoviesPage this) movieID)
(div :background-image "url('/images/MovieBG.jpg')" :background-repeat 'no-repeat
:position 'relative :left "50px" :width "377px" :height "286px"
:contents (div :position 'relative :left "28px" :top "18px" :width "320px" :height "240px" :border "1px solid black"
:contents (webMovie :mp4File (makeString (getMovieProp movieID :file) ".mp4")
:ogvFile (makeString (getMovieProp movieID :file) ".ogv")
:width "320px" :height "240px")))
(lineSpacer :height 20)
(span :class "size12 expanded" :value (getMovieProp movieID :title))
(lineSpacer :height 8)
(span :value (getMovieProp movieID :description))
(lineSpacer :height 15)
(link :href (makePageLink :movies :topic :movies) :string "« More Movies")
(lineSpacer :height 30))
;;; Code
(definePage :code CodePage.class)
(defineMethod includeMainContent ((CodePage this) id topic &key (examples '("Blob.java" "EventHub.java" "HttpServer.java" "LinearMeasurement.java" "Vector3D.java"
"Firmware.asm" "CameraPeer.cpp" "Goals.bgl" "HelloWorld.bgl" "ThisPage.bgl"
"TransformedImages.bgl" "oodb.bgl" "threads.bgl"))
(selected (first examples)))
(include t :mainContentHeader :label "code >"
:contents (flow :contents ("Here are a few examples of my code. I've included examples in Java, C++, assembler, and bagel to give a feel
for my style across multiple languages.")))
(lineSpacer :height 20)
(span :value "Select Example:")
(horizontalSpacer :width 8)
(select :id "exampleSelector" :options (loop for example in examples
for selected = true then nil
do (option :string example :selected selected)))
(lineSpacer :height 10)
(div :width "700px" :height "420px" :overflow 'scroll :border "1px solid #999999" :padding "5px"
:contents (pre :id "exampleContainer" :contents nil))
(loop for example in examples
do (div :display 'none :id example :contents (insertFile (makeString "examples/" example) :escapeForHTML true)))
(apply 'createInlineJSFuncall "new SelectableDIV" "exampleSelector" "exampleContainer" examples)
(lineSpacer :height 20))
;;; Writing
(definePage :writing WritingPage.class)
(defineMethod includeMainContent ((WritingPage this) id topic &key)
(include t :mainContentHeader :label "writing >"
:contents (flow :contents ("Writing is an underapprectiated skill for technical people. Through presentations, demos, or the written word, I've
always enjoyed process of communicating my work to others. Here are a few examples.")))
(lineSpacer :height 20)
(includeWritingMainContent this topic))
(defineMethod includeWritingMainContent ((WritingPage this) ((equals nil) topic) &key (examples '("PhaseIITechReport.pdf" "PenelopeCSAllenPilot.pdf" "PenelopePatent.pdf"
"SBIRTechReport.pdf")))
(select :id "writingExampleSelector" :options (loop for example in examples
for selected = true then nil
do (option :string example :selected selected)))
(lineSpacer :height 10)
(div :width "700px" :id "writingExampleContainer"
:contents (include t :embedContentFile :file (makeString "examples/" (first examples))))
(loop for example in examples
do (div :display 'none :id example :contents (include t :embedContentFile :file (makeString "examples/" example))))
(apply 'createInlineJSFuncall "new SelectableDIV" "writingExampleSelector" "writingExampleContainer" examples)
(lineSpacer :height 20))
(defineContent :embedContentFile (&key file)
(cond ((isPage file)
(include t file))
((wildcardMatch "*.jpg" file true)
(image :src file))
((wildcardMatch "*.pdf" file true)
(embed :src file :width 600 :height 500))
((wildcardMatch "*.mp3" file true)
(embed :src file :width 465 :height 100))
(true (includeFile t (makeString wwwRoot "/" file)))))
;;; Resume
(definePage :resume ResumePage.class)
(defineMethod includeMainContent ((ResumePage this) id topic &key)
(include t :mainContentHeader :label "resume >"
:contents (space))
(lineSpacer :height 20)
(include t :embedContentFile :file "examples/MikeBrady.pdf"))
;;; Hobbies
(definePage :hobbies HobbiesPage.class)
(defineMethod includeMainContent ((HobbiesPage this) id topic &key)
(include t :mainContentHeader :label "hobbies >"
:contents (flow :contents ("Here are a few of my interests outside of work.")))
(lineSpacer :height 20)
(div :min-height "420px"
:contents (span :value "Coming soon.")))
;;; fileOrder: 0
(defineClass (PersistedObject))
(defun className (instance)
(java:getName (java:getBagelClass instance)))
(defun makeStandardToString (instance &rest _components)
(makeString "#<" (className instance) ": " (apply 'makeString components) ">"))
(defun nInstances (ofClass)
(length (funcallResults 'matchAll (list (list ofClass)) true)))
(defun allInstances (ofClass)
(loop for (instance) in (funcallResults 'matchAll (list (list ofClass)) true)
collect instance))
(defun firstInstance (ofClass)
(first (allInstances ofClass)))
(defun matchFirstField (searchClass field value &rest otherFieldValuePairs)
(let ((fieldValuePairs (append (list field value) otherFieldValuePairs)))
(first (eval `(matchFirst ((,searchClass this)) (matchesFields this (quote ,fieldValuePairs)))))))
(defun matchesFields (object fieldValuePairs)
(loop for (field value) on fieldValuePairs by 'rrest
always (equals value (getInstanceVariable object field))))
(defun setDoNotPersist (instance doNotPersist)
(java:setDoNotPersist instance doNotPersist)
instance)
(defun isBagelMethod (thing)
(java:isBagelMethod bagel thing))
;;; Includes the class itself
(defun subclasses (ofClass)
(loop for bagelClass across (java:getSubclasses (java:getBagelClass oodb ofClass nil))
collect (java:getName bagelClass)))