Month: July 2013
About 10 years ago, 10.58 if you want to get really precise, I took the class CS2135 Programming Language Concepts. I remember being really impressed with a lot of the power and expressiveness of functional programming.
This evening, I was working on a little goofy project, and it turned out that doing it with a closure was the clean and useful way to go. I find it amusing that when I finally got around to using these techniques, it was just kind of a natural thing.
The (half done) code is all over here.
The fuse settings on the current device are low:0xe2, high:0xda, and extended:0x5. I can talk to it via ICSP, and get the correct component signature (0x1e9514) back. What all of this says to me is that the ICSP settings are correct, and the onboard oscillator is running, so the chip is capable of having the bootloader installed.
It is entirely likely that I was using the wrong bootloader for my boards. I am using an ATMega328 running at 8MHz, so I suspect that the correct bootloader is ATmegaBOOT_168_atmega328_pro_8MHz.hex. This is important because an bootloader created for the wrong clock speed can still be loaded onto a board, but won’t be able to communicate over the serial port. The timings of the serial signals would be messed up, because any delay operations will become either too long or too short, depending on if the clock is too slow or too fast.
I got the latest version of the Arduino IDE, and modified the appropriate files as described at the end of this entry. In order to burn the bootloader, I had to be root, so I started the Arduino IDE as root and burned the bootloader, which apparently worked on the first try.
I quit and restarted the IDE, because I didn’t want to keep running as root, and plugged in my FTDI cable. Unfortunately, the IDE couldn’t compile my little test program because the arduino IDE ships with an old version of avr-gcc (4.3.2) and the ATMega328 wasn’t supported until later. I have avr-gcc 4.5.3, so I renamed the avr folder in /arduino-1.0.5/hardware/tools to avr_old. This forces the IDE to use the system avr-gcc, because it can’t find its own. With this, I was able to compile.
Next, I attempted to upload the compiled program to the board. The upload failed with the error message “avrdude: stk500_recv(): programmer is not responding”.
I switched to using the programmer to upload the sketch, and wrote a sketch that blinks an LED on analog pin 5. Originally, the sketch used analog pin 7, because that’s where my debug LED is hooked up, but it turns out that while you can use A0-A5 as digital outputs, you can’t do that with A6 or A7.
At any rate, the system can now blink an LED on A5. This verifies that the onboard clock is working, that the memory can be written to, and that the compiler is generating valid code. The clock speed is even correct, because a blink program with a 1 second period even generates 1 second blinks.
Now I just need to figure out why uploading via USB/serial doesn’t work, and I’ll be golden.
Works from a “school” of art share some common elements. Looking at paintings by Dali, Magritte, and Breton, one can say that they share something that is not shared with a Monet. People not trained in the academic study of art might have a hard time naming or articulating that quality, but it is definitely present.
The artists named above are all painters. If one wants to get truly pedantic, it’s possible to claim that their works all have the common quality “flat surface covered by pigments mixed with a binder”. The actual common quality is more a matter of their treatment of form, especially in relation to the expected juxtaposition of forms in the real world, and their engagement with the representation of the unconscious world, that is to say, the realms of dream, delusion, and insanity, as well as direct handling of the duality of representation and reality.
From the fact that this common quality does not directly relate to the material used, we can infer that there can exist works that do not use the same material, and yet have the same quality. This inference is supported by the existance of surrealist sculpture.
However, some materials and creative processes force a certain common developmental aesthetic. Three cases of a unified aesthetic that is incidental to the product, but nonetheless shared, are: the textures used in 3D modeling, the debug output of computer vision systems, and the appearance of DIY/prototyped electromechanical devices from the current generation of hacker spaces.
These aesthetics are unified within themselves, but they are not of a piece with each other. Textures adopt the form that they do because the technology demands it. The technology is defined, and the aesthetic is fully constrained by it. Computer vision systems develop their aesthetic because they must map the world through the system’s understanding into a form that is understood by the human user. The technology is not fully defined, but the system is confined on on three fronts: The input of the real world, the representation available in the system, and what users can “read” in realtime. Prototyped devices have the fewest constraints. The technology is incompletely defined, and the form of it is also undefined, so it is shaped by expedience and available tools. It is the most accidental aesthetic, because it is the one that forms when no other aesthetic is selected.
This is an example of a texture for a human head from here. The distortion would be corrected by remapping onto a model of a human head.
Textures are the most rigidly constrained accidental aesthetic. This description comes from a common modeling file format, but the technology is similar across many modeling processes. The model consists of three files. The first file, the model file, describes the 3D points that make up the surfaces of the model. It also includes a reference to the second file, which is a material file. The material file describes a set of materials that the object is made of, and how light interacts with them. Each material may refer to a third file, which is the texture. A texture is a flat image file. Regions of the flat image file are mapped onto surfaces of the model by a one-to-one (usually) mapping from vertices on the model to vertices on the texture. The vertices on the texture define a shape which is then “cut out” and “applied” to the corresponding shape on the model. Because of the way this works, and the tools used to create this mapping, the texture is frequently a flat representation of the 3D object, in much the way a map of the earth is a flat representation of the 3D world.
Altering the texture would result in changes to its display on the model, so the texture is completely constrained by the model. Because it is a flat image file, the texture is also constrained in the ways that it can be displayed to the user. Because of this complete constraint, the textures display a very strong unity of aesthetic.
Robot Readable World is a compilation of the debugging output of computer vision algorithms. The computer system operates on the video stream to produce data streams which are not visible to humans. These video outputs are intended to allow human debuggers to determine what the system “sees”, that is, to map the data structures into human-readable form and present it mixed with the incoming images so that the person can relate from real objects to the system’s “perception”. Because these are merely explanations of the state of the system, rather than a key part of its functioning, they can be altered and rearranged to provide the maximally useful representation for human readers. The data underneath may not change, but the presentation can be altered.
As a result, these systems are unconstrained at at least one end, the presentation to the user. However, they are constrained at the other end to operate on images. The images are in turn, constrained by the postions and relations of objects in the real world. A computer vision system that operates in a made-up or simulated environment would have no practical use to humans unless they also inhabited that environment. This is not to say that this is not done, as vision approaches could be used in video games, but it is less likely.
This dog treat dispenser is an example of the third accidental aesthetic: the design of DIY electronics. Some hallmarks of this aesthetic are the exposed circuit boards, the surface texturing of 3D printed or laser cut (in this case, 3D printed) parts, visible and accessible wiring, and the use of visible, commercially available screws and other connectors.
This project, a controller for a coffee roaster, has the same aesthetic, despite being constructed by a different person, unknown to the maker of the dog treat dispenser.
This is the least constrained of the three accidental aesthetics. The maker can choose the parts used to create the device, and the form of the finished device. However, the tools available to the user to create the device will drive certain decisions in its eventual form. A 3D printer provides a way to quickly create certain forms, but has a distinct material, texture, and color for those forms. Laser cutting allows a form to be built from layers of flat materials, but again, some building techniques work better than others. Off the shelf commercial components have to be connected together, which leads to visible wires. All of these decisions, to print or not print, laser or not laser, wire or make PCBs have a bias in them that each artist/creator navigates, and the sequence of the decisions leads to a particular aesthetic for the piece.
This describes something I’m planning to do, rather than something I’ve done, but I don’t think it is total hogwash.
I attend an event where it would be useful, for shock and awe reasons, to pan a spotlight along a segment of trail, stop, and pan back to the beginning of the segment.
Building a spotlight to do this is easy. You put a few big, powerful red LEDs behind collimating lenses, mount that on a servo pan-tilt unit, and tell an Arduino what positions to put the servos at to do the sweep.
That last bit is where it falls apart. At first, I was playing with ideas around converting coordinates from the space around the spotlight into rotations of the spotlight axes, and how to establish what the coordinates are, and how to do that transformation. Then I realized that I was overthinking it, and all I really need to do is this:
- Make a program that moves the light in accordance with the mouse. Up and down on the mouse are rotation in one axis, left and right are rotation in the other axis. Clicking memorizes a point.
- Pan the spotlight along the trail to generate the sequence of points that the spotlight has to hit. Record the positions of the two servos at each of those points with the “click to memorize” function.
- The positions of the servos are points in a 2-D space. Spline or otherwise interpolate between those points to generate an arbitrary number of points.
- Move the servo through the interpolated points, stop, move it back, repeat until the batteries die.
Figuring out the points this way takes care of any nonlinearity in the servos, curvature of the terrain, etc, by having the device that was used to measure the points be the same device that later executed them.
The idea of moving a system through the course of actions you want it to take isn’t a new one. Industrial robots frequently have “teaching pendants” that allow a human to put the robot through the sequence of actions it would take to perform an operation. Once the human is done, the robot starts repeating those actions, with great accuracy and reliability.