Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Wednesday, April 8, 2020

The Polyhedra Project (video summary)

I finally got some time to edit old footage...and build a garden...and breathe, think, reflect.

Here is a video summarizing my parametric 3d printed magnetic polyhedral assembly tiles. 

About 8 hours in Adobe Premiere to do the bulk of the work, then a few hours to make final edits and export it.



Friday, March 31, 2017

Telegraph Sounder Player

Yesterday I put the finishing touches on my latest project, the telegraph sounder player.

Video link first if you want to see it in action before you read: https://www.youtube.com/watch?v=vKzZMfzuw68



The device on the left is the telegraph sounder player, and the device on the right is the telegraph sounder. The telegraph sounder itself is a vintage telegraph module. The player allows for up to four sounders to be plugged in to it, and plays back random snippets from text files loaded up on an SD card. It uses American Morse Code (as opposed to international). I loaded the SD card with excerpts from my favorite novels as well as full novels from Project Gutenberg.

The project was made for the owner of the telegraph sounder, Don. Don used to work as a telegrapher for a railroad company (US land based telegraph operations used American Morse code). He had a first version of the player built for him during the most recent Build Madison event and came back to Sector67 with notes for some features he would like for the next version.

Features I included in this telegraph player include: SD card playback, 4 sounder support, knob for speed of playback, separate knob for inter-sentence interval length, status led and ON/OFF toggle, CNC milled hardwood box with brass corners, battery power (est. 10 hours of playback), battery charging circuit onboard.

Design process in brief:

I had four 5V relays I found in a bin here at Sector, so I chose to support up to 4 sounders and to use a 5V Arduino for the brains. The relays are each switched by a BJT transistor circuit, and when switched they connect the sounder port to the battery pack.

The ports are barrel jack connectors with a 10uF capacitor across the leads and a high power rating. low resistance resistor. The resistor is mostly just in case the leads going to the telegraph are placed so that they are touching each other.

I had been playing around with trying to minimize the currents induced by the sounder turning off (the clack, as opposed to the click). A large ferrite choke close to the telegraph with many windings of the connector cable worked, but was a little unwieldy. The capacitor doesn't entirely solve the problem, but helps make the clack sharper. Too large a value and the clack actually bounces presumably as the capacitor charges on the induced current, and then discharges back into the sounder and re-enables it somewhat. The 'problem' is in any case limited to the Arduino resetting only when connected to a computer during the disconnection of the sounder, so it was possible to ignore. 

The SD card is connected through a bi-directional level converter. The Arduino has limited memory, so the code handles things by grabbing small chunks of the files into four small buffers for the four ports. The Morse codes are stored as 2-byte unsigned int objects, with the exception of a few special 4-byte unsigned long objects for some of the punctuation. The code can be found here: Arduino Code.

Access to the Arduino is through the bottom of the box, which is attached with screws to corners that are glued inside the box.


The project uses two battery cells that each have overcurrent and undervoltage protection built in. The charging circuit is as described here.

You can find more photos of the project and an additional write up here: https://imgur.com/gallery/fIBFZ

And a video here:
https://www.youtube.com/watch?v=vKzZMfzuw68






Thursday, May 26, 2016

Three wheeled robot simulation

I made a simple simulation to figure out how to orient the wheels of a 3 wheeled robot with independently steering and driving wheels based on a desired instantaneous center of curvature (ICC).  It makes a lot of assumptions (perfect point contacts of the wheels with the ground, no slippage allowed, etc) but is a useful conceptual tool.

Get the latest version here:
https://github.com/eshira/wheelsim (uses Python, numpy, and matplotlib)

The triangle represents the frame. The view is a bird's eye view. Each wheel is mounted on short extensions that pivot about the frame at the vertex of the triangle.  The colored lines are the perpendicular lines to the wheel. Where they meet, a red dot denotes the instantaneous center of curvature, or ICC. The black circle denotes the motion of a point in the middle of the robot.

Below the ICC is at the bottom of the robot frame, marked by the red dot. Points on the robot that fall on the perimeter of the black circle, will move along the black circle if the wheels are driven at the appropriate velocities.

To describe the motion of any particular point on the robot frame, just imagine a circle concentric with the red dot that passes through that point on the frame. The relative linear velocities of the wheels can be described by the relative perimeter lengths of the circles that pass through their center.

Below, we restrict the wheels to only 170 degrees steering rotation (remove 5 degrees from end of range on each side). This creates the red areas, which are places the ICC cannot be without forcing the wheels into the disallowed steering rotations.
The red lines pass through the pivot point of the steering of each wheel. To avoid intersections with the robot frame, and because typical servos only support 180 degrees of rotation anyway, the wheels are mirrored if they pass that boundary. To avoid discontinuous driving caused by having to stop to flip the wheel over to the other side, avoid having the ICC cross this boundary.

Here we have parallel line driving (near vertical direction, along the black line). In this situation, the ICC is very far away. The perimeter of the black circle therefore appears to be completely straight. The wheels are all parallel. The colored lines represent the normals to the wheels, which intersect at the ICC, as they are not quite parallel.

Note that the purple wheel is probably going to collide with the frame if we try to drive straight in the direction of the top tip of the frame. It is probably better to drive as shown below instead.

Above the robot drives along the black line shown, horizontal to the image.

Corrections can be made by turning 'left' and 'right' as shown below.


Thursday, October 23, 2014

Robot Cart Progress -- It Drives!



First assembled prototype. Preliminary tests show that (a) it is capable of driving smoothly and (b) it doesn't draw too much current for the L298 motor driver. Spent yesterday evening hunting down flyback diodes at Sector and I even found two additional L298s, as well as a handful of extra large breadboard-compatible tactile switches (pictured left, in the background).

The Wixel code for the transmitter is done. Next up is integrating the PWM code to the receiver modules, and creating easy to use skeleton code for competition participants to come in and edit.

I still need to get additional batteries, a suitable USB camera with a good wide angle of view and OpenCV compatible drivers, and a few other parts. So far so good though.

Edit: Minor Setbacks
I bought these batteries from Adafruit and these batteries from Sparkfun. The Sparkfun batteries provide enough current to get the cart moving, but if it hits any obstacle and stalls, this triggers the overcurrent protection. Toggling the power on and off resets this protection. The Adafruit batteries can't even run the motors unloaded (wheels not in contact with the ground). They twitch, then die out (presumably, overcurrent protection). This is a shame, because I purchased them on the assumption that they would provide a maximum continuous 2C discharge rate, which they aren't, as far as I can tell. The datasheet seems to say that (bad formatting on it makes it hard to read).

In any case, Sparkfun's comment system and tendency to better document products on the page makes me feel a lot better about purchasing from them when they have the stock I want. Unfortunately neither battery will quite do for my needs, so I need to go back and rethink this.

Also, I wasn't able for whatever reason to get the wixel-pwm library by dpark83 working for me. It isn't particularly well commented which makes it difficult to use. I did find this simpler code, which works well enough for me to use instead.

Since the price for these robots is already quite high, I'm going to try and re-use some parts around Sector. Namely, a bin of old cheap lithium ion batteries without any protection circuits, and a bunch of scrapped prototypes for a battery board that has no documentation, but a ton of features (presumably). Or, in the interest of time, skip the reverse-engineering on the battery boards, and just triple check to make my circuits don't look too explode-y, and go protection-less. So far I haven't made any really serious mistakes with my wiring prototypes...

Friday, July 11, 2014

July Robotics Class Week 1

Photo essay for week 1 of the July robotics class I'm teaching.

A simple H-bridge with switches and LEDs.


Omni-wheel proof of concept; 3d printed plate that fits on a motor shaft.

Printrbot has been printing lots of stuff.

Stickers, buttons, and temporary tattoos for prizes.

Robots under construction.

Another partially finished robot.

Monday, March 24, 2014

Building A Custom Blender Build (and failing)

I decided to compile my own build of Blender on Windows. The main reason is that the sewing addon I want is a patch, not a script, so I have to apply to to the Blender source code and then compile. I'm typically a Unix user (and most often I'm specifically a Darwin user), so when it comes to using the Windows command prompt, or knowing where certain important system files are, or anything a power user might need, I get a bit lost.

I have not yet produced a successful build. To illustrate a point about how difficult these things usually end up being, here are some of the issues I've run into so far:
  • I had no previous setup for Windows so I had to choose what tools to install, namely: a git or svn client, a compiler, a build system
  • I installed mingw64 in a directory with spaces in the pathname which is a no-no
  • I needed to add some directories to my Windows PATH variable
  • I retrieved precompiled libs for Windows but put them in the wrong place initially
  • I was not sure what command to actually use to install using the cmake-generated Makefile (mingw32-make, which confused me because I'm installing 64-bit blender with mingw64)
  • The compiler failed because of libmv, so I just decided to disable that in the build, as I don't need that feature in Blender
  • The process failed due to complaints about the openimageio library...and I had no clue how to proceed, so I decide to switch to using SCons instead of CMake, since somebody mentioned that the daily Blender builds are done with SCons and minGW
  • SCons installer can't find Python in the registry...I find out I need 32-bit Python, and I installed 64-bit Python
  • SCons errors out early, and I learn I need to set a flag BF_TOOLSET=mingw, which I just pass in the command line because SCons doesn't see my user-config.py file for some reason...
  • After a long time, build errors out. More online searches suggest the problem may be due to the fact that I am using gcc 4.8 and I need to get 4.6 instead...
  • Now the build fails compiling files to do with Cycles when using SCons...
  • Now the build fails at the linking stage when compiling with CMake-gui...
The bullet points seem to fly by quickly...but keep in mind that each, on average, required significant time in google searches, trial and error, and CPU time to actually diagnose and get past.

The good news is of course the availability of builds on graphicall.org and of course you can always go to http://www.blender.org/download/. Still, I'm hoping I can get this figured out someday soon.

Saturday, February 19, 2011

Picking and Choosing Your Coeffecients: Playing with the DCT of an Image

Where have I been?
Junior year is a ton of work. I've been extremely busy.

What is the post about? (Super simple version)
Sometimes I want to make a salad.



For my definition of "salad" I have a set of ingredients with which I can make ANY salad I like, ingredients like lettuce, tomatoes, cucumbers...etc.

A recipe for any given salad is essentially a 'linear combination' of those ingredients, for example, 1 tomato, 2 heads lettuce, 4 drops vinegar, 1 lemon. I am scaling and adding things from my dictionary of salad ingredients to make my particular salad.

I may want to play with that list, deleting terms, scaling terms differently, or who knows what. I might just want to demonstrate to you how the salad begins to look more like the salad we want to have as we add more and more of the ingredients in.

I can do this with anything. Here, I do it with images, and I represent them as a linear combination of 'checkerboards.' For example, for one case, we have 64 different checkerboards, which look like this:



I could prepare any image if I had all of these 'checkerboard' ingredients. I could convince you that it was the same image even if I only had a few of those checkerboards available (specifically, imagine I ran out of the ones towards the bottom right...I really don't need them). That's the theory behind lossy image compression.

What is the post about? (Less simple version)
I'm taking the 2 dimensional DCT of 16x16 blocks of this image of a bunny rabbit, then picking and choosing which coefficients to keep before computing the inverse and reconstructing the image. Since M,N=16 so there are 256 basis images.

Some pdfs for your reading pleasure:
-"Lab 6: the Discrete Cosine Transform"
-JPEG Tutorial
-Image Compression and the Discrete Cosine Transform

Results
Original Image:


DC Coefficient only
(the very first term, which is just the average value of the image part)


AC Coefficients only (everything else but the DC Coefficient)


Line Coefficients only (no 'checkerboards' -- 'stripe' coefficients only )


First Four 'Lowest Frequency' Coefficients
(the first 2x2 coefficients from top left)


No Horizontal Stripes


No Vertical Stripes



I'll Do it Later
1. To take the DCT of the whole image (not just a block at a time).
2. To make a animation showing the terms added in a sequential zig-zag, showing the reconstruction of the image from all basis vectors.

Time to start my homework.
-Shira

Wednesday, December 2, 2009

Pacman!

Been a bit busy (and lazy) recently...

Winter break is almost here and as soon as finals are over DIY gift-making will follow.

For now though I've been trying to pick up the introductory topics of AI. With some help and a borrowed copy of Artificial Intelligence: A Modern Approach I'm getting started. The project files are part of an assignment from a course whose resources I got access to.

The project is Pacman. The first problem is to help Pacman find the single food dot. The highlighted paths indicated nodes explored by the AI. The nodes that are most red are the nodes explored earliest. Once a path to the goal state is found, Pacman begins to move, and moves only along that path.

Depth First Search: Pacman searches along one path until he reaches a dead end before going down a branching path. Uses the Stack data structure (LIFO: last in, first out).





Breadth First Search: Pacman searches in layers--first he looks at nodes one step away from his starting position, then at nodes two steps away, and so on. This uses the Queue data structure (FIFO: first in, first out).





I have to take a break from this to study for finals, but there's a lot more of the assignment to complete, involving mazes where Pacman must avoid the ghosts, find all the food dots in a maze, so on...

Happy holidays! Those are coming up, aren't they...

Saturday, October 10, 2009

FingerPaint: Thought Process



This is one of the first real drawings I made with the FingerPaint application I'm working on. After some practice, I can draw rather comfortably with it. I'm definitely not able to use my trackpad or mouse this well.



I've recently ditched post-its and switched to spherical clay balls mounted on the end of pencils. This allows the user to use rotation of the wrist which is more precise than movement from the shoulder.

This means that FingerPaint is now more of a pen and tablet without the tablet.

Tuesday, March 31, 2009

A Widget

I decided to try my hand at Widget development recently, and the result was this (here featured next to my favorite widget):




It doesn't do much, besides prove that I can access the command line from a widget and that I have some basic dynamic html skills. To be more precise, it runs "id -un" and "uname -n" and refreshes with a click of the refresh icon. So if you're connected to the internet through some network, it'll show that address instead of the local address (like, guest-wireless.usc.edu).

Anyhow, I'm making it available here. Maybe you'll come across it, and it will be just perfect because you were just thinking of how handy it would be to have a widget like this. Or maybe you'll download it for kicks, and it will prove itself useful beyond your wildest widgety dreams.

Download the "Name and Location" widget