Closure(s)
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.
Current State of The ToyBrains
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.
Accidental Aesthetics
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 from Timo on Vimeo.
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.
Panning An LED Spotlight Along a Trail
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.
Command Line Audio Editing With Sox
For my ritual spoken word software piece, I recruited a bunch of my friends to say the text of the ritual. Each “stanza” of the ritual has a call and a response, so I broke each recording up into individual clips for each call and response. That gave me about 28 files per person, and over 100 clips total.
The different participants all recorded on different hardware, and at different volume levels. I also wasn’t super-precise about trimming the clips, so each file had silence at the beginning.
This left me with two problems: some participants were much softer than others, and some of the clips lagged each other, which made for bad chorus effects.
To trim the clips, I used sox, a Linux tool for manipulating sounds, with the command:
for file in *.wav; do sox $file $file.wav silence 1 0.1 2%
This results in a file named foo.wav.wav for each foo.wav file in the directory, so I cleaned up with:
rename -f “s/.wav././g” *
Note that this scribbles over the originals, so keep backups. I’m glad I did, because 2% turned out to be a little aggressive, and trimmed off the beginning of clips starting with an “ma-” sound, such as “make us a…”. This is likely because the sound faded in slowly, and so got counted as part of the noise rather than the beginning of a sound.
There is useful documentation for the sox silence filter here.
Turning the volume up on the files was done with:
for file in *.wav; do sox $file $file.wav gain -l 8; done
and another pass of rename, as above. Adjust the “8” up or down to suit your needs. Positive numbers make it louder, negative make it quieter.
If you want to preview a sox effect, just replace “sox” in the command with “play”, and leave off the output file. For example,
play myfile.wav gain -l 8
will play myfile.wav with increased gain, but won’t change the file.
We Make Ritual Noise
For a festival that I attend, I’m writing a soundscape in boodler to provide the vocal component for a ritual. Here, I’m going to annotate what I need to do to run Boodler on my laptop, which I’ll have at the festival.
The main thing is that Boodler seems to default to OSS, and I use PulseAudio, so to invoke the ritual, you need to run:
boodler -o pulse –external disturbingrelics com.gizmosmith.disturbingrelics/Example
The -o option tells it to use PulseAudio, –external makes it load from a directory instead of a .boop package for testing purposes, and the rest is the agent to run.
To organize all the sound clips I’m using, I have a boodler package for each person’s reading of the ritual script. The script is in a call and response format, with 14 calls and responses, so each package has 28 audio clips, one each for the call and response. I named all the clips “call_N_…” and “response_N_…” (for N in 1..14) so that the program can figure out the call/response pairs by name.
Each package starts out as a directory with the 28 files and a metadata file in them. For the directory “sage”, I create the package with:
boodle-mgr –import create sage
and then install it with:
boodle-mgr install ./com.gizmosmith.sage.1.0.boop
So, about that re-distillation prevention on PDFs…
I got a PDF of my transcript from a university I used to attend. I won’t say which, but it’s in Salisbury and not very imaginatively named. The transcript had a variety of password-protection baloney on it, which I didn’t want.
Stripping the password is easy if you know it, because you can open the PDF in acrobat reader, select “print”, “print to file” and print to a postscript file (with a .ps extension). That removes the password protection, giving you a clear postscript file, which, in theory, you can distill back to PDF.
Unfortunately, the postscript file is marked as unredistillable (if that’s even a word). There is a fix for this, though: the exact opposite of what is described here.
Find the lines that say:
%ADOBeginClientInjection: DocumentSetup Start "No Re-Distill" %% Removing the following eleven lines is illegal, subject to the Digital Copyright Act of 1998. mark currentfile eexec 54dc5232e897cbaaa7584b7da7c23a6c59e7451851159cdbf40334cc2600 30036a856fabb196b3ddab71514d79106c969797b119ae4379c5ac9b7318 33471fc81a8e4b87bac59f7003cddaebea2a741c4e80818b4b136660994b 18a85d6b60e3c6b57cc0815fe834bc82704ac2caf0b6e228ce1b2218c8c7 67e87aef6db14cd38dda844c855b4e9c46d510cab8fdaa521d67cbb83ee1 af966cc79653b9aca2a5f91f908bbd3f06ecc0c940097ec77e210e6184dc 2f5777aacfc6907d43f1edb490a2a89c9af5b90ff126c0c3c5da9ae99f59 d47040be1c0336205bf3c6169b1b01cd78f922ec384cd0fcab955c0c20de 000000000000000000000000000000000000000000000000000000000000 cleartomark %ADOEndClientInjection: DocumentSetup Start "No Re-Distill"
and cut them out of the file. Yes, the file says this is illegal, and it might even be true, but that’s how it’s done.
Converting .MPG to .AVI with Linux programs
I am trying to convert .mpg files from a sony camera into other, smaller versions for distribution. The files are in the mpeg2video codec, with a resolution of 720×480 at 29.97 fps. Normally, I’d use ffmpeg for this, but apparently “This program is only provided for compatibility and will be removed in a future release. Please use avconv instead.” Thanks Ubuntu, I’m sure that won’t screw up a few thousand people’s video conversion scripts.
Anyway, let’s see what man avconv
has to say. I want no sound, and I want to start 55 seconds into the film, to cut off most of a boring first minute. Seeking into the video is -ss 00:00:55
. The option -an
drops the audio. So, avconv -i blue_ball.mpg -an -ss 00:00:55 blue_ball.avi
should do it. And, in fact, it does.
Modkit Micro Alpha
Modkit Micro Alpha does not run on Ubuntu 12.04 64-bit without the user moving some directories around and installing ia32-libs.
It also does not save projects more than once per launch, or compile code at all, on Ubuntu or Mac OSX.
I appreciate that the point of Modkit’s Kickstarter campaign was not to sell a finished product, but to get the money to produce one. That said, people who have paid money for a thing may want that thing to work. Modkit is now in the uncomfortable position of having sold the moon, and being expected to deliver it.
ToyBrain Version 2 Firmware Troubles
I’ve started trying to load a bootloader onto the V2 hardware for the ToyBrains, as part of attempting to make a luminous fez for my girlfriend. I ran into a few problems.
The first problem I had was that the IC I’m using is the ATMega328, not the ATMega328P. So far, the only difference I can find between the two is their voltage range, but they have different ID strings. To get around this, I duplicated the chip definition for the 328P in avrdude.conf, and replaced the ID with the proper ID for a 328 (no P). This seemed to work for getting the Arduino IDE to burn the bootloader to my chip.
Unfortunately, I had made the Arduino boards.txt file description of my board by copying the Arduino Nano section. This includes a fuse setting for an external clock crystal. The toybrain boards don’t have a clock crystal, and use the internal RC oscillator of the Atmega328 instead. This meant that when the board was reflashed, it had no clock, and so not only could it not be programmed from the IDE, it also couldn’t be reflashed with a new bootloader using the USBTinyISP. The big symptom of this is that avrdude immediately fails to init, and if I used the -F (force, which you should never do) flag, it reported a part ID of 0x000000.
To fix that problem, I wired two small caps and a crystal to add an external oscillator to the board, tacked it to the appropriate pins, and reset the flags.
At this point, I think I have the bootloader installed, and the fuses at least mostly correct. The Lilypad Arduino with the ATMega328P uses these fuses: Low: 0xE2 High: 0xD8 Extended: 0x05, which mean that the clock is internal, and not divided by 8, so it runs at 8MHz. The bootloader settings set the size of the bootloader, which is the same as the one I am using (ATmegaBOOT_168_atmega328_pro_8MHz.hex), and the boot interrupt vector.
However, I still get a problem when I attempt to upload a program to the device. If I set the upload speed to 57600, avrdude beefs about the chip ID. If I set it to 19200, avrdude says the programmer is not responding.
My current guesses at the cause of the problem are these:
- My clock settings are slightly off, so the chip is running at the wrong speed for the bootloader. As a result, the serial data rate is bad, and the data that avrdude gets back is nonsense. This can be fixed by applying the above fuse settings via the USBTinyICSP.
- I have the reset vector or bootloader size setting wrong, and so the chip doesn’t start the bootloader correctly when it is reset. Again, this is a matter of fixing the fuses.
- Something else that I haven’t considered yet, e.g. there is something wrong with my hardware.
I’m going to work on it more tonight and see if I can get it going.
Recent Comments