Shallow Thoughts

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Mon, 14 Aug 2017

A Homemade Solar Finder, for the Eclipse

While I was testing various attempts at motorizing my barn-door mount, trying to get it to track the sun, I had to repeatedly find the sun in my telescope.

In the past, I've generally used the shadow of the telescope combined with the shadow of the finderscope. That works, more or less, but it's not ideal: it doesn't work as well with just a telescope with no finder, which includes both of the scopes I'm planning to take to the eclipse; and it requires fairly level ground under the telescope: it doesn't work if there are bushes or benches in the way of the shadow.

For the eclipse, I don't want to waste any time finding the sun: I want everything as efficient as possible. I decided to make a little solar finderscope. One complication, though: since I don't do solar observing very often, I didn't want to use tape, glue or, worse, drill holes to mount it.

So I wanted something that could be pressed against the telescope and held there with straps or rubber bands, coming off again without leaving a mark. A length of an angled metal from my scrap pile seemed like a good size to be able to align itself against a small telescope tube.

[Constructing a solar sight] Then I needed front and rear sights. For the front sight, I wanted a little circle that could project a bulls-eye shadow onto a paper card attached to the rear sight. I looked at the hardware store for small eye-bolts, but no dice. Apparently they don't come that small.I settled for the second-smallest size of screw eye.

The screw eye, alas, is meant to screw into wood, not metal. So I cut a short strip of wood a reasonable size to nestle into the inside of the angle-iron. (That ripsaw Dave bought last year sure does come in handy sometimes.) I drilled some appropriately sized holes and fastened screw eyes on both ends, adding a couple of rubber grommets as spacers because the screw eyes were a little too long and I didn't want the pointy ends of the screws getting near my telescope tube.

I added some masking tape on the sides of the angle iron so it wouldn't rub off the paint on the telescope tube, then bolted a piece of cardboard cut from an old business card to the rear screw eye.

[Homemade solar sight] Voila! A rubber-band-attached solar sight that took about an hour to make. Notice how the shadow of the front sight exactly fits around the rear sight: you line up the shadow with the rear sight to point the scope. It seems to work pretty well, and it should be adaptable to any telescope I use.

I used a wing nut to attach the rear cardboard: that makes it easy to replace it or remove it. With the cardboard removed, the sight might even work for night-time astronomy viewing. That is, it does work, as long as there's enough ambient light to see the rings. Hmm... maybe I should paint the rings with glow-in-the-dark paint.

Tags:
[ 15:25 Aug 14, 2017    More science/astro | permalink to this entry | comments ]

Thu, 10 Aug 2017

A Barn-Door Mount for the Eclipse

[Curved rod barn-door mount] I've been meaning forever to try making a "barn door" tracking mount. Used mainly for long-exposure wide-field astrophotography, the barn door mount, invented in 1975, is basically two pieces of wood with a hinge. The bottom board mounts on a tripod and is pointed toward the North Star; "opening" the hinge causes the top board to follow the motion of the sky, like an equatorial telescope mount. A threaded rod and a nut control the angle of the "door", and you turn the nut manually every so often. Of course, you can also drive it with a motor.

We're off to view the eclipse in a couple of weeks. Since it's my first total eclipse, my plan is to de-emphasize photography: especially during totality, I want to experience the eclipse, not miss it because my eyes are glued to cameras and timers and other equipment. But I still want to take photos every so often. Constantly adjusting a tripod to keep the sun in frame is another hassle that might keep my attention away from the eclipse. But real equatorial mounts are heavy and a time consuming to set up; since I don't know how crowded the area will be, I wasn't planning to take one. Maybe a barn door would solve that problem.

Perhaps more useful, it would mean that my sun photos would all be rotated approximately the right amount, in case I wanted to make an animation. I've taken photos of lunar and partial solar eclipses, but stringing them together into an animation turned out to be too much hassle because of the need to rotate and position each image.

I've known about barn-door mounts since I was a kid, and I knew the basic theory, but I'd never paid much attention to the details. When I searched the web, it sounded complicated -- it turned out there are many types that require completely different construction techniques.

The best place to start (I found out after wasting a lot of time on other sites) is the Wikipedia article on "Barn door tracker", which gives a wonderfully clear overview, with photos, of the various types. I had originally been planning a simple tangent or isosceles type; but when I read construction articles, it seemed that those seemingly simple types might not be so simple to build: the angle between the threaded rod and the boards is always changing, so you need some kind of a pivot. Designing the pivot looked tricky. Meanwhile, the pages I found on curved-rod mounts all insisted that bending the rod was easy, no trouble at all. I decided to try a curved-rod mount first.

The canonical reference is a 2015 article by Gary Seronik: A Tracking Platform for Astrophotography. But I found three other good construction guides: Optical Ed's "Making a Curve Bolt Barn Door", a Cloudy Nights discussion thread "Motorized Barn Door Mount Kit", and Massapoag Pond Photography's "Barn Door Tracker". I'm not going to reprise all their construction details, so refer to those sites if you try making your own mount.

[Barn-door mount, showing piano hinge] The crucial parts are a "piano hinge", a long hinge that eliminates the need to line up two or more hinges, and the threaded rod. Buying a piano hinge in the right size proved impossible locally, but the folks at Metzger's assured me that piano hinges can be cut, so I bought one longer than I needed and cut it to size. I used a 1/4-20 rod, which meant (per the discussions in the Cloudy Nights discussion linked above) that a 11.43-inch radius from the hinge to the holes the rod passes through would call for the nut to turn at a nice round number of 1 RPM.

I was suspicious of the whole "it's easy to bend the threaded rod ina 11.43-inch circle" theory, but it turned out to be true. Draw the circle you want on a sheet of newspaper, put on some heavy gloves and start bending, frequently comparing your rod to the circle you drew. You can fine-tune the curvature later.

I cut my boards, attached the hinge, measured about 11.4" and drilled a hole for the threaded rod. The hole needed to be a bit bigger than 5/8" to let the curved rod pass through without rubbing. Attach the curved rod to the top wood piece with a couple of nuts and some washers, and then you can fine-tune the rod's curvature, opening and closing the hinge and re-bending the rod a little in any place it rubs.

A 5/8" captive nut on the top piece lets you attach a tripod head which will hold your camera or telescope. A 1/4" captive nut on the bottom piece serves to attach the mount to a tripod -- you need a 1/4", not 3/8": the rig needs to mount on a tripod head, not just the legs, so you can align the hinge to the North Star. (Of course, you could build a wedge or your own set of legs, if you prefer.) The 3/4" plywood I was using turned out to be thicker than the captive nuts, so I had to sand the wood thinner in both places. Maybe using half-inch plywood would have been better.

[Wing nut on barn-door mount] The final piece is the knob/nut you'll turn to make the mount track. I couldn't find a good 1/4" knob for under $15. A lot of people make a wood circle and mount the nut in the center, or use a gear so a motor can drive the mount. I looked around at things like jam-jar lids and the pile of metal gears and sprinkler handles in my welding junkpile, but I didn't see anything that looked quite right, so I decided to try a wing nut just for testing, and worry about the knob later. Turns out a wing nut works wonderfully; there's no particular need for anything else if you're driving your barn-door manually.

Testing time! I can't see Polaris from my deck, and I was too lazy to set up anywhere else, so I used a protractor to set the hinge angle to roughly 36° (my latitude), then pointed it approximately north. I screwed my Pro-Optic 90mm Maksutov (the scope I plan to use for my eclipse photos) onto the ball head and pointed it at the moon as soon as it rose. With a low power eyepiece (20x), turning the wing nut kept the moon more or less centered in the field for the next half-hour, until clouds covered the moon and rain began threatening. I didn't keep track of how many turns I was making, since I knew the weather wasn't going to allow a long session, and right now I'm not targeting long-exposure photography, just an easy way of keeping an object in view.

A good initial test! My web searches, and the discovery of all those different types of barn-door mounts and pivots and flex couplings and other scary terms, had seemed initially daunting. But in the end, building a barn-door mount was just as easy as people say it is, and I finished it in a day.

And what about a motor? I added one a few days later, with a stepper and an Arduino. But that's a separate article.

Tags: ,
[ 19:25 Aug 10, 2017    More science/astro | permalink to this entry | comments ]

Sat, 05 Aug 2017

Keeping Git Branches in Sync

I do most of my coding on my home machine. But when I travel (or sit in boring meetings), sometimes I do a little hacking on my laptop. Most of my code is hosted in GitHub repos, so when I travel, I like to update all the repos on the laptop to make sure I have what I need even when I'm offline.

That works great as long as I don't make branches. I have a variable $myrepos that lists all the github repositories where I want to contribute, and with a little shell alias it's easy enough to update them all:

allgit() {
    pushd ~
    foreach repo ($myrepos)
        echo $repo :
        cd ~/src/$repo
        git pull
    end
    popd
}

That works well enough -- as long as you don't use branches.

Git's branch model seems to be that branches are for local development, and aren't meant to be shared, pushed, or synchronized among machines. It's ridiculously difficult in git to do something like, "for all branches on the remote server, make sure I have that branch and it's in sync with the server." When you create branches, they don't push to the server by default, and it's remarkably difficult to figure out which of your branches is actually tracking a branch on the server.

A web search finds plenty of people asking, and most of the Git experts answering say things like "Just check out the branch, then pull." In other words, if you want to work on a branch, you'd better know before you go offline exactly which branches in which repositories might have been created or updated since the last time you worked in that repository on that machine. I guess that works if you only ever work on one project in one repo and only on one or two branches at a time. It certainly doesn't work if you need to update lots of repos on a laptop for the first time in two weeks.

Further web searching does find a few possibilities. For checking whether there are files modified that need to be committed, git status --porcelain -uno works well. For checking whether changes are committed but not pushed, git for-each-ref --format="%(refname:short) %(push:track)" refs/heads | fgrep '[ahead' works ... if you make an alias so you never have to look at it.

Figuring out whether branches are tracking remotes is a lot harder. I found some recommendations like git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done and for remote in `git branch -r`; do git branch --track ${remote#origin/} $remote; done but neither of them really did what I wanted. I was chasing down the rabbit hole of writing shell loops using variables like

  localbranches=("${(@f)$(git branch | sed 's/..//')}")
  remotebranches=("${(@f)$(git branch -a | grep remotes | grep -v HEAD | grep -v master | sed 's_remotes/origin/__' | sed 's/..//')}")
when I thought, there must be a better way. Maybe using Python bindings?

git-python

In Debian, the available packages for Git Python bindings are python-git, python-pygit2, and python-dulwich. Nobody on #python seemed to like any of them, but based on quick attempts with all three, python-git seemed the most straightforward. Confusingly, though Debian calls it python-git, it's called "git-python" in its docs or in web searches, and it's "import git" when you use it.

It's pretty straightforward to use, at least for simple things. You can create a Repo object with

from git import Repo
repo = Repo('.')
and then you can get lists like repo.heads (local branches), repo.refs (local and remote branches and other refs such as tags), etc. Once you have a ref, you can use ref.name, check whether it's tracking a remote branch with ref.tracking_branch(), and make it track one with ref.set_tracking_branch(remoteref). That makes it very easy to get a list of branches showing which ones are tracking a remote branch, something that had proved almost impossible with the git command line.

Nice. But now I wanted more: I wanted to replace those baroque git status --porcelain and git for-each-ref commands I had been using to check whether my repos needed committing or pushing. That proved harder.

Checking for uncommitted files, I decided it would be easiest stick with the existing git status --porcelain -uno. Which was sort of true. git-python lets you call git commands, for cases where the Python bindings aren't quite up to snuff yet, but it doesn't handle all cases. I could call:

    output = repo.git.status(porcelain=True)
but I never did find a way to pass the -uno; I tried u=False, u=None, and u="no" but none of them worked. But -uno actually isn't that important so I decided to do without it.

I found out later that there's another way to call the git command, using execute, which lets you pass the exact arguments you'd pass on the command line. It didn't work to call for-each-ref the way I'd called repo.git.status (repo.git.for_each_ref isn't defined), but I could call it this way:

    foreachref = repo.git.execute(['git', 'for-each-ref',
                                   '--format="%(refname:short) %(push:track)"',
                                   'refs/heads'])
and then parse the output looking for "[ahead]". That worked, but ... ick. I wanted to figure out how to do that using Python.

It's easy to get a ref (branch) and its corresponding tracking ref (remote branch). ref.log() gives you a list of commits on each of the two branches, ordered from earliest to most recent, the opposite of git log. In the simple case, then, what I needed was to iterate backward over the two commit logs, looking for the most recent SHA that's common to both. The Python builtin reversed was useful here:

    for i, entry in enumerate(reversed(ref.log())):
        for j, upstream_entry in enumerate(reversed(upstream.log())):
            if entry.newhexsha == upstream_entry.newhexsha:
                return i, j

(i, j) are the number of commits on the local branch that the remote hasn't seen, and vice versa. If i is zero, or if there's nothing in ref.log(), then the repo has no new commits and doesn't need pushing.

Making branches track a remote

The last thing I needed to do was to make branches track their remotes. Too many times, I've found myself on the laptop, ready to work, and discovered that I didn't have the latest code because I'd been working on a branch on my home machine, and my git pull hadn't pulled the info for the branch because that branch wasn't in the laptop's repo yet. That's what got me started on this whole "update everything" script in the first place.

If you have a ref for the local branch and a ref for the remote branch, you can verify their ref.name is the same, and if the local branch has the same name but isn't tracking the remote branch, probably something went wrong with the local repo (like one of my earlier attempts to get branches in sync, and it's an easy fix: ref.set_tracking_branch(remoteref).

But what if the local branch doesn't exist yet? That's the situation I cared about most, when I've been working on a new branch and it's not on the laptop yet, but I'm going to want to work on it while traveling. And that turned out to be difficult, maybe impossible, to do in git-python.

It's easy to create a new local branch: repo.head.create(repo, name). But that branch gets created as a copy of master, and if you try to turn it into a copy of the remote branch, you get conflicts because the branch is ahead of the remote branch you're trying to copy, or vice versa. You really need to create the new branch as a copy of the remote branch it's supposed to be tracking.

If you search the git-python documentation for ref.create, there are references to "For more documentation, please see the Head.create method." Head.create takes a reference argument (the basic ref.create doesn't, though the documentation suggests it should). But how can you call Head.create? I had no luck with attempts like repo.git.Head.create(repo, name, reference=remotebranches[name]).

I finally gave up and went back to calling the command line from git-python.

repo.git.checkout(remotebranchname, b=name)
I'm not entirely happy with that, but it seems to work.

I'm sure there are all sorts of problems left to solve. But this script does a much better job than any git command I've found of listing the branches in my repositories, checking for modifications that require commits or pushes, and making local branches to mirror new branches on the server. And maybe with time the git-python bindings will improve, and eventually I'll be able to create new tracking branches locally without needing the command line.

The final script, such as it is: gitbranchsync.py.

Tags: , ,
[ 14:39 Aug 05, 2017    More programming | permalink to this entry | comments ]

Sun, 30 Jul 2017

Remapping the Caps Lock key on Raspbian

I've remapped my CapsLock key to be another Ctrl key since time immemorial. (Actually, since the ridiculous IBM PC layout replaced the older keyboards that had Ctrl there already, to the left of the A.)

On normal current Debian distros, that's fairly easy: you can edit /etc/default/keyboard to have XKBOPTIONS="ctrl:nocaps.

You might think that would work in Raspbian, since it also has /etc/default/keyboard and raspi-config writes keyboard options to it if you set any (though of course CapsLock isn't among the choices it offers you). But it doesn't work in the PIXEL desktop: there, that key still acts as a Caps Lock.

Apparently lxde (under PIXEL's hood) overrides the keyboard options in /etc/default/keyboard without actually giving you a UI to set them. But you can add your own override by editing ~/.config/lxkeymap.cfg. Make the option line look something like this:

option = ctrl:nocaps

Then when you restart PIXEL, you should have a Control key where CapsLock used to be.

Tags: ,
[ 10:30 Jul 30, 2017    More linux | permalink to this entry | comments ]

Sun, 23 Jul 2017

Nambé Lake Nutcrackers

[Nambe Lake]

This week's hike was to Nambé Lake, high in the Sangre de Cristos above Santa Fe.

It's a gorgeous spot, a clear, shallow mountain lake surrounded by steep rocky slopes up to Lake Peak and Santa Fe Baldy. I assume it's a glacial cirque, though I can't seem to find any confirmation of that online.

[Clark's nutcracker taking bread from my hand.] There's a raucous local population of Clark's nutcrackers, a grey relative of the jays (but different from the grey jay) renowned for its fearlessness and curiosity. One of my hiking companions suggested they'd take food from my hand if I offered. I broke off a bit of my sandwich and offered it, and sure enough, a nutcracker flew right over. Eventually we had three or four of them hanging around our lunch spot.

The rocky slopes are home to pikas, but they're shy and seldom seen. We did see a couple of marmots in the rocks, and I caught a brief glimpse of a small, squirrel-sized head that looked more grey than brown like I'd expect from a rock squirrel. Was it a pika? I'll never know.

We also saw some great flowers. Photos: Nambé Lake Nutcrackers.

Tags: , ,
[ 09:55 Jul 23, 2017    More | permalink to this entry | comments ]

Sun, 16 Jul 2017

Translating Markdown to LibreOffice or Word

For the Raspberry Pi Zero W book I'm writing, the publisher, Maker Media, wants submissions in Word format (but stressed that LibreOffice was fine and lots of people there use it, a nice difference from Apress). That's fine ... but when I'm actually writing, I want to be able to work in emacs; I don't want to be distracted fighting with LibreOffice while trying to write.

For the GIMP book, I wrote in plaintext first, and formatted it later. But that means the formatting step took a long time and needed exceptionally thorough proofreading. This time, I decided to experiment with Markdown, so I could add emphasis, section headings, lists and images all without leaving my text editor.

Of course, it would be nice to be able to preview what the formatted version will look like, and that turned out to be easy with a markdown editor called ReText, which has a lovely preview mode, as long as you enable Edit->Use WebKit renderer (I'm not sure why that isn't the default).

Okay, a chapter is written and proofread. The big question: how to get it into the Word format the publisher wants?

First thought: ReText has a File->Export menu. Woohoo -- it offers ODT. So I should be able to export to ODT then open the resulting file in LibreOffice.

Not so much. The resulting LibreOffice document is a mess, with formatting that doesn't look much like the original, and images that are all sorts of random sizes. I started going through it, resizing all the images and fixing the formatting, then realized what a big job it was going to be and decided to investigate other options first.

ReText's Export menu also offers HTML, and the HTML it produces looks quite nice in Firefox. Surely I could open that in LibreOffice, then save it (maybe with a little minor reformatting) as DOCX?

Well, no, at least not directly. It turns out LibreOffice has no obvious way to import an HTML file into a normal text document. If you Open the HTML file, it displays okay (except the images are all tiny thumbnails and need to be resized one by one); but LibreOffice can't save it in any format besides HTML or plaintext. Those are the only formats available in the menu in the Save dialog. LibreOffice also has a Document Converter, but it only converts Office formats, not HTML; and there's no Import... in LO's File. There's a Wizards->Web Page, but it's geared to creating a new web page and saving as HTML, not importing an existing HTML-formatted document.

But eventually I discovered that if I "Create a new Text Document" in LibreOffice, I can Select All and Copy in Firefox, followed by Paste into Libre Office. It works great. All the images are the correct size, the formatting is correct needing almost no corrections, and LibreOffice can save it as DOCX, ODT or whatever I need.

Image Captions

I mentioned that the document needed almost no corrections. The exception is captions. Images in a book need captions and figure numbers, unlike images in HTML.

Markdown specifies images as

![Image description][path/to/image.jpg)

Unfortunately, the Image description part is only visible as a mouseover, which only works if you're exporting to a format intended for a web browser that runs on desktop and laptop computers. It's no help in making a visible caption for print, or for tablets or phones that don't have mouseover. And the mouseover text disappears completely when you paste the document from Firefox into LibreOffice.

I also tried making a table with the image above and the caption underneath. But I found it looked just as good in ReText, and much better in HTML, just to add a new paragraph of italics below the image:

![][path/to/image.jpg)

*Image description here*

That looks pretty nice in a browser or when pasted into LibreOffice. But before submitting a chapter, I changed them into real LibreOffice captions.

In LibreOffice, right-click on the image; Add Caption is in the context menu. It can even add numbers automatically. It initially wants to call every caption "Illustration" (e.g. "Illustration 1", "Illustration 2" and so on), and strangely, "Figure" isn't one of the available alternatives; but you can edit the category and change it to Figure, and that persists for the rest of the document, helpfully numbering all your figures in order. The caption dialog when you add each caption always says that the caption will be "Illustration 1: (whatever you typed)" even if it's the fourteenth image you've captioned; but when you dismiss the dialog it shows up correctly as Figure 14, not as a fourteenth Figure 1.

The only problem arises if you have to insert a new image in the middle of a chapter. If you do that, you end up with two Figure 6 (or whatever the number is) and it's not clear how to persuade LibreOffice to start over with its renumbering. You can fix it if you remove all the captions and start over, but ugh. I never found a better way, and web searches on LibreOffice caption numbers suggest this is a perennial source of frustration with LibreOffice.

The bright side: struggling with captions in LibreOffice convinced me that I made the right choice to do most of my work in emacs and markdown!

Tags: ,
[ 14:12 Jul 16, 2017    More writing | permalink to this entry | comments ]

Thu, 06 Jul 2017

Writing a Book on the Raspberry Pi Zero W

It's official: I'm working on another book!

This one will be much shorter than Beginning GIMP. It's a mini-book for Make Media on the Raspberry Pi Zero W and some fun projects you can build with it. [Raspberry Pi Zero W]

I don't want to give too much away at this early stage, but I predict it will include light shows, temperature sensors, control of household devices, Twitter access and web scraping. And lots of code samples.

I'll be posting more about the book, and about various Raspberry Pi Zero W projects I'm exploring during the course of writing it. But for now ... if you'll excuse me, I have a chapter that's due today, and a string of addressable LEDs sitting on my desk calling out to be played with as part of the next chapter.

Tags: , ,
[ 09:50 Jul 06, 2017    More writing | permalink to this entry | comments ]

Sat, 24 Jun 2017

Mutt: Fixing Erroneous Charsets, part 632

Someone forwarded me a message from the Albuquerque Journal. It was all about "New Mexico\222s schools".

Sigh. I thought I'd gotten all my Mutt charset problems fixed long ago. My system locale is set to en_US.UTF-8, and accented characters in Spanish and in people's names usually show up correctly. But I do see this every now and then.

When I see it, I usually assume it's a case of incorrect encoding: whoever sent it perhaps pasted characters from a Windows Word document or something, and their mailer didn't properly re-encode them into the charset they were using to send the message.

In this case, the message had User-Agent: SquirrelMail/1.4.13. I suspect it came from a "Share this" link on the newspaper's website.

I used vim to look at the source of the message, and it had

Content-Type: text/plain; charset=iso-8859-1
For the bad characters, in vim I saw things like
New Mexico<92>s schools

I checked an old web page I'd bookmarked years ago that had a table of the iso-8859-1 characters, and sure enough, hex 0x92 was an apostrophe. What was wrong?

I got some help on the #mutt IRC channel, and, to make a long story short, that web table I was using was wrong. ISO-8859-1 doesn't include any characters in the range 8x-9x, as you can see on the Wikipedia ISO/IEC 8859-1.

What was happening was that the page was really cp1252: that's where those extra characters, like hex 92/octal 222 for an apostrophe, or hex 96/octal 226 for a dash (nitpick: that's an en dash, but it was used in a context that called for an em dash; if someone is going to use something other than the plain old ASCII dash - you'd think they'd at least use the right one. Sheesh!)

Anyway, the fix for this is to tell mutt when it sees iso-8859-1, use cp1252 instead:

charset-hook iso-8859-1 cp1252

Voilà! Now I could read the article about New Mexico's schools.

A happy find related to this: it turns out there's a better way of looking up ISO-8859 tables, and I can ditch that bookmark to the old, erroneous page. I've known about man ascii forever, but someone I'd never thought to try other charsets. Turns out man iso_8859-1 and man iso_8859-15 have built-in tables too. Nice!

(Sadly, man utf-8 doesn't give a table. Of course, that would be a long man page, if it did!)

Tags: , ,
[ 11:06 Jun 24, 2017    More linux | permalink to this entry | comments ]