aboutsummaryrefslogtreecommitdiff
path: root/docs/tex
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tex')
-rw-r--r--docs/tex/Behaviors.tex143
-rw-r--r--docs/tex/ClassOverview.tex186
2 files changed, 329 insertions, 0 deletions
diff --git a/docs/tex/Behaviors.tex b/docs/tex/Behaviors.tex
new file mode 100644
index 0000000..9021581
--- /dev/null
+++ b/docs/tex/Behaviors.tex
@@ -0,0 +1,143 @@
+\documentclass{article}
+\usepackage{fullpage}
+\begin{document}
+ \title{Behaviors: An Introduction and Exercises}
+ \author{Russell Cohen}
+ \date{\today}
+ \maketitle
+ \section{What is a behavior?}
+ At its most basic, a behavior is machine with two input terminals and two
+ output terminals. One of these input terminals is external input. The
+ other is feedback from the behavior. Similarly, the behavior has two output
+ terminals. One gets released externally as output, and the other gets fed
+ back to the behavior. At their core, behaviors have nothing to do with
+ pixels are light effects -- this is merely how we commonly use them.
+ \section{How do I write a behavior?}
+ At the core of a behavior is its \texttt{ProcessResponse} method which
+ tells a behavior what to get on input. As you might expect, it has 2
+ input ports, and two output ports. The `type' of inputs and outputs can be
+ anything -- numbers, strings, lists, however, in our system, the inputs
+ and outputs are all python dictionaries. This allows us to have an
+ arbitrary number of named parameters. As sample input might look
+ something like \texttt{{'Location':(20,20), 'Height':10}}. When we
+ return a value, we return a tuple of (list<dict>,list<dict>). Note that on a
+ process response method you will actually be given a \textbf{List of
+ dictionaries} and you should iterate over them.
+ \textbf{Important:} You should not directly modify the inputs! Use
+ \texttt{dict(input)} to create a copy of them!
+ \section{Exercise 1: addFive}
+ Our goal: Create a behavior that will add 5 to the 'Value' field of the
+ input. If no 'Value' field exists, we will set it to five. Below is a
+ sample \verb processResponse method to do this. Note that process
+ response is the only part of a behavior that must be written (everything
+ else happens behind the scenes when you \textbf{inherit} from the
+ \texttt{Behavior} class.
+ \begin{verbatim}
+ def processResponse(self, inputs, recurrences):
+ output = [] #empty list
+ for inp in inputs:
+ inpCopy = dict(inp)
+ if not ('Value' in inpCopy):
+ inpCopy['Value'] = 0
+ inpCopy['Value'] += 5
+ output.append(inpCopy)
+ return (output, []) #empty list, no recurrences
+ \end{verbatim}
+ \section{Exercise 2: A Sum-er}
+ Create a behavior that outputs the sum of all previous input. Hint:
+ You will need to use recurrences!
+ \section{Declaring and Configuring Behaviors}
+ Once you've written your behavior (or are using an already written
+ behavior, you will need to tell the light installation to use the
+ behavior. This is done via XML in the configuration file. When you
+ run the system, you specify a configuration file eg:
+ \texttt{python LightInstallation.py config/ConfigFile.xml}
+
+ Behaviors are specified in the \verb BehaviorConfiguration section.
+ A sample behavior follows:
+ \begin{verbatim}
+ <Behavior>
+ <Class>behaviors.EchoBehavior</Class>
+ <Args>
+ <Id>echo</Id>
+ <RenderToScreen>False</RenderToScreen>
+ </Args>
+ </Behavior>
+ \end{verbatim}
+
+ The ``Class'' attribute specifies the \textbf{Python} class for this
+ behavior. (The \verb behaviors. prefix tells Python to look in the
+ behaviors folder). You may recall that all classes SmootLight take a
+ single python dictionary as an argument -- this is embodied by the
+ \texttt{Args} tag. A dictionary is created from the XML at runtime
+ -- this dictionary would be: \texttt{{'Id':'echo',
+ 'RenderToScreen':False}}
+ The id we specify is the id that we can reference this behavior by
+ later. The \verb RenderToScreen attribute specifies whether or not
+ outputs from this behavior should be directed to the screen (some
+ behaviors act only as the building blocks for other
+ behaviors, and are never rendered directly to the screen)
+
+ \section{Behavior Chains}
+ I have mentioned several times that the system allows for behaviors to
+ be chained together to create many different effects -- often the
+ ``motion'' effect and the ``coloring'' effects are two separate
+ behaviors. The result you see on the screen are these two pieces
+ connected together. This allows us to build up many different behaviors
+ from a library of simple pieces. Let's look at how we actually
+ accomplish this.
+
+ Behavior Chaining is accomplished through the behavior chain class.
+ Here is an example of a behavior we declare (in XML) via a behavior
+ chain:
+ \begin{verbatim}
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>runcolordecay</Id>
+ <Inputs>
+ <Id>pygame</Id>
+ <Id>randomLoc</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>colorchange</Id>
+ <Id>running</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RecursiveHooks>{'running':'acceleratedie'}</RecursiveHooks>
+ <RenderToScreen>True</RenderToScreen>
+ <Mapper>gaussmap</Mapper>
+ </Args>
+ </Behavior>
+ \end{verbatim}
+
+ Note the importance of the `Id' field -- that is how we reference all
+ other components of the system. Let's walk through what is going on
+ here. We declare this behavior just like any other -- however, for
+ class, we specify \verb BehaviorChain . The \verb Inputs tag specifies
+ which inputs will be routed to this behavior. In this case, it is
+ \verb pygame and \verb randomLoc , two previously declared behaviors.
+ Inputs from these behaviors will be passed to the behavior chain via
+ sensorInputs. Next, we have the meet of this chain, the behaviors it is
+ composed of. This states that first, an input is routed through
+ \texttt{colorchange}. \verb colorchange adds a color field to the
+ sensor data. Next, the input is routed to \verb running a behavior
+ that makes pixels run back and forth. Finally, the input is routed to
+ \verb decay , a behavior that adds a decay ``PixelEvent'' that makes
+ individual pixels turn on and then decay.
+
+ The next item we see is \verb RecursiveHooks . This is a special
+ feature of the \verb BehaviorChain that allows us to augment the
+ reccurences recursive events have. We specify that we will augment the
+ recursive behavior of \verb running with another behavior,
+ \verb acceleratedie which modifies increases the speed of the running
+ behavior, and stops the behavior after a certain number of iterations.
+ Note that recursive hooks take data in via their \textbf{external input}
+ port, and \textbf{not} their recursive port.
+
+ Finally, we state that this behavior will indeed be rendered directly to
+ the screen. We also specify which PixelMapper we want to use.
+
+ Phew. This isn't as complicated as it sounds. I promise.
+
+ \end{document}
diff --git a/docs/tex/ClassOverview.tex b/docs/tex/ClassOverview.tex
new file mode 100644
index 0000000..00d55ec
--- /dev/null
+++ b/docs/tex/ClassOverview.tex
@@ -0,0 +1,186 @@
+\documentclass{article}
+\usepackage{fullpage}
+\begin{document}
+ \title{150 Smoots Lighting Installation Design Document}
+ \author{Russell Cohen}
+ \date{\today}
+ \maketitle
+ \newcommand{\classDoc}[5]{
+ \subsection{#1}
+ \begin{itemize}
+ \item \textbf{Inherits from: } #2
+ \item \textbf{Inherited by: } #3
+ \item \textbf{Brief Description: } #4
+ \item \textbf{Argument Requirements: } #5
+ \end{itemize}
+ }
+ \section{Intro}
+ \textbf{NB: These docs give an overview of the classes and methods but
+ may lag behind the code for certain in-flux functionality. For
+ up-to-the minute docs, please use pydoc.} \\
+ The system, which we will describe henceforth as SmootLight is a
+ modular system designed with the following goals in mind:
+ \begin{itemize}
+ \item The system must abstract away from all components while
+ remaining useful (\verb=Renderer=, \verb=Input=, \verb=Behavior=)
+ \item The system must be modular and be easy to write new code for.
+ \item More goals as I think of them
+ \end{itemize}
+ We accomplish this in the following manner:
+ \begin{itemize}
+ \item The system is configured by an XML file which specifies its
+ components.
+ \item All classes are initialized with a dictionary as an argument
+ containing anything a class may need. All objects are passed
+ between members as python dictionaries because their easy
+ serialization.
+ \end{itemize}
+ \section{Overview}
+ \begin{itemize}
+ \item
+ \section{Operations Class Patterns}
+ \classDoc{SmootCoreObject}{None}{All 2nd level classes (PixelAssembler, Renderer,
+ Input, Behavior)}
+ {SmootCoreObject is essentially a super-object
+ that makes things easy for us. It does the following actions:
+ \begin{itemize}
+ \item Defines a constructor that sets argDict
+ \item Defines a \texttt{\_\_getitem\_\_} , which lets us acces items in
+ argDict as if the class was a dictionary.
+ (\texttt{self['itemName']}). It also automatically maps the
+ initial contents of the argDict to class attributes.
+ \item Defines validateArgs and validateArgDict which
+ validate the incoming arguments against a dictionary
+ containing argument names as keys and an error message to
+ display if they are missing as a values. This file should
+ be named classname.params and look like a python dict
+ (\texttt{\{'key':value, 'key2':value2\}} )
+ \end{itemize}
+ }
+ {No required parameters in argDict}
+ \classDoc{PixelAssembler}{SmootCoreObject}{LineLayout, ZigzagLayout}{
+ PixelAssembler is a class that defines the positions of lights. It
+ provides a method \texttt{getLightLocations} which give a list of
+ all light locations for a given strip. Inheriting classes must
+ define \texttt{layoutFunc} which returns the next location given the
+ previous location. (They may simply override
+ \texttt{getLightLocations}
+ instead, if they wish, but be careful when doing so). In
+ heriting classes may defint \texttt{initLayout} which is called at
+ initialization.}{\begin{itemize}
+ \item \texttt{lightToLightSpacing}: this is the length of wire
+ between 2 adjacent LEDs. Common values are 4 or 12.
+ \item \texttt{numLights}: Number of lights in a strip.
+ \item \texttt{originLocation}: Location of the first light.
+ \end{itemize}}
+ \classDoc{Renderer}{SmootCoreObject}{PygameRenderer, IndoorRenderer}{
+ Renderer is a class that serves as an abstract class for renderers
+ interacting with the system. Inheriting classes must define
+ render, which is passed a \texttt{lightSystem} object. Inheriting
+ classes may define initRenderer which is called on initiation.
+ }{No required arguments}
+ \classDoc{Input}{SmootCoreObject, threading.Thread}{PygameInput,
+ TCPInput,UDPInput}{Input is a abstract class which facilitates Inputs.
+ It does this by providing a method that is polled at a periodic
+ interval within which the inheriting class can raise an event.
+ Inheriting classes must define \texttt{sensingLoop} which is
+ called at the interval specified in the config. Inheriting
+ classes should call respond with an dictionary as an argument
+ to raise an event. Classes using (not
+ inheriting) input must pass a scope into
+ the argDict which offers a \texttt{processInput}
+ method. Inputs are marked as Daemon threads, and
+ are therefore killed when their parent is
+ killed.}{\begin{itemize}
+ \item \texttt{InputId}: The string id of a given input. Must be
+ unique.
+ \item Optional:\texttt{RefreshInterval}: The interval in
+ seconds (will soon be changed to milliseconds) between
+ sucessive calls to the sensingLoop method. TODO: make
+ timeout.
+ \end{itemize}}
+ \classDoc{Behavior}{SmootCoreObject}{EchoBehavior, DebugBehavior}{
+Abstract class for a behavior. On every time step, the behavior is passed the
+inputs from all sensors it is bound to as well as any recursive inputs that it
+spawned during the last time step. Inheriting classes MUST define \texttt{processResponse}. Look
+at the Behaviors documentation for more details.}
+{\begin{itemize}
+ \item \texttt{Inputs}: A list of input Ids specifying input to the
+ behavior.
+\end{itemize}}
+\classDoc{PixelEvent}{SmootCoreObject}{StepResponse}{
+ Abstract class defining the behavior of a light after it has been turned on.
+ Inheriting classes should defint \texttt{lightState} which is passed a
+ timeDelay in ms as an argument. \texttt{lightState} should return a
+ color or None if the response is complete.}{\begin{itemize}
+ \item \texttt{Color}: The color of response. \textit{This is may be
+ removed in the future}
+ \end{itemize}
+ }
+\section{The Screen Class and Its Relatives}
+\classDoc{Screen}{None}{None}
+{The \texttt{Screen} class is a representation of an entire system of pixels,
+ distributed over space. The Screen class and its relatives process
+ responses (mapped to pixels via a LayoutEngine), and add PixelEvents
+ to the individual pixels. The Screen provides an instance that
+ renderers can call to determine the color of all the individual pixels. It contains a list of PixelStrips, which each
+ address the individual pixels. \texttt{Screen} offers a
+ \texttt{respond} method which takes a dictionary containing information
+ about a response. TODO: detail the contents of this dictionary (maybe
+ somewhere else). Note: \texttt{Screen} will not process its
+ responses until \texttt{timeStep} is called which processes all responses that
+ have been queued since the last time that \texttt{timeStep} was
+ called. Screen also offers an iterator over \textit{all} lights,
+ accesible by using an expression like: \texttt{for light in screen:}. For
+ addressing of specific \texttt{PixelStrips} , \texttt{self.pixelStrips}
+ is exposed.}{No required parameters}
+\classDoc{PixelStrip}{None}{None}
+{The \texttt{PixelStrip} class is a representation of a string of Pixels that are
+ connected in physical space (eg. a strip of lights). A \texttt{PixelStrip} takes a
+ \texttt{LayoutBuilder} (\textit{Name up for debate, currently known as layout
+ engine}) as an argument. The \texttt{argDict} of the
+ \texttt{LayoutBuilder} is
+ passed becomes the \texttt{argDict} of the \texttt{PixelStrip}.
+ \texttt{PixelStrip} generally shouldn't be
+ adressed directly unless you need Strip-Identification for rendering
+ purposes. You should never, for example, call \texttt{respond} on a
+ \texttt{PixelStrip}
+ directly, unless you really know what you're doing. Well, actually you
+ should never need to do that.
+ never. Don't do it.}{Takes a \texttt{LayoutBuilder} as an argument.}
+ \end{itemize}
+ \section{Best Practices}
+ \subsection{Variable and function naming}
+ I'm pretty bad about being consistent. However, in all future
+ code, please adhere to the following:
+ \begin{itemize}
+ \item Classes: \texttt{FirstLetterCaps}
+ \item Functions: \texttt{camelCase}
+ \item Property Names: \texttt{FirstLetterCaps}
+ \item Constants: \texttt{ALL\_CAPS\_WITH\_UNDERSCORES}
+ \end{itemize}
+ \subsection{Time}
+ For time, use the \texttt{util.TimeOps.time()} method to return the current
+ time in ms.
+ \subsection{Acessing a Component Given an Id}
+ Use \texttt{util.ComponentRegistry.getComponent(id)}. This provides any
+ component access to any other components. We may consider a way to
+ make this read-only.
+ \subsection{Acessing Pixels}
+ The ideal method for acessing Pixels in a screen is to use its
+ iterator. Iterating over the individual PixelStrips is also an
+ acceptable method.
+ \subsection{Determining the state of a \texttt{Pixel}}
+ The best practice for determining the color of a \texttt{Pixel} is to call
+ \texttt{state}. This ensures
+ all current active responses running on the Pixel contribute correctly.
+ \subsection{Color}
+ For color, use a tuple of (R,G,B) 0-255 for each. Colors can be
+ easily manipulated with members of the Util class.
+ \subsection{Locations}
+ Locations are stored (x,y), in whatever unit you light system is
+ in. (Whatever unit you use when you define spacing).
+ \subsection{Constant Strings (key strings, 'Location', 'Color', etc.)}
+ Use the util.Strings module. It contains many currently in use
+ Strings, and ensures consistency.
+ \end{document}