The manatee watches...

GPGL Reference, Courtesy of Graphtec July 23, 2011

I recently purchased as cutting plotter for myself as a fun toy to play with. In particular, I picked up Graphtec's Silhouette machine from US Cutter for a very reasonable price.

Now, being the computer nerd that I am, one of my first inclinations, after seeing the device in action, was wondering how I could control the device directly myself. That is to say, I didn't want to have to import my files into the Silhouette Studio software for every drawing I wanted to make; in particular because I run Linux on my personal desktop, and there is no Linux version of the software available.

After a short bit of research, I discovered that the device communicates via Graphtec's proprietary "GPGL" language, (it stands for Graphtec Plotter Graphics Language, I believe). This is in contrast with the more common HPGL specification found in many other plotters. I did a significant amount of searching on the matter, but came up empty handed when it came to GPGL references. I read some sites that suggested that the Silhouette also communicated via HPGL, but my tests with that came up largely empty.

So, I sent a kindly worded email to Graphtec support asking if they could provide a reference directly. I didn't expect a response back and had resigned myself to the tribulations of USB sniffing. I spent the day, in between work, investigating how to perform USB packet logging on both OS X and Windows (hint: use Windows).

And then, just when I was about to really dive in and start doing it the hard way, Graphtec came through for me. A wonderful gentleman named Neil emailed me back:

Hi Dave, Thank you for your interest in Graphtec products. I have attached the HPGL and GPGL command sets found in Graphtec cutters for your reference. The reference documents are provided "as is" and we cannot provide additional assistance. I wish you good luck with your endeavor. Best regards, Neil

Here are the documents he sent:

Just like that, I had what I needed! I may or may not have responded back to Neil with professions of love and adulation. I also asked for some quick clarification on one, undocumented point: how does one switch the plotter between GPGL and HPGL mode? He promptly responded back:

My understanding is that the newer Graphtec FC8000 have the capability to autoswitch when they receive either GPGL or HPGL commands, but previous cutters such as the CE5000-40 (Craft Robo Pro) require the user to change the command language from the front panel to match incoming data.

The Silhouette does not have an option to manually switch between the two specifications, and in my testing, it does not seem as though the Silhouette automatically switches into HPGL mode either (perhaps someone can correct me on this). That being said, it does seem to be responding to GPGL commands.

I am still feeling my way around the spec a bit — the Silhouette is not responding to every command documented in the pdf, and some combinations of commands seem to cause the Silhouette to stop responding. I suspect part of this may be due to my naivety when it comes to USB programming in general, something I am new at.

To help confirm this, I installed a USB sniffer on my wife's Windows computer, along with with Silhouette Studio software. I had the plotter draw out two simple lines, each about the length of the page. Here is the primary data payload that I saw sent back and forth (in hex): 03 21 31 30 2c 30 03 54 54 03 48 03 54 42 35 30 2c 31 03 54 42 35 30 2c 30 03 46 43 30 03 54 42 39 39 03 46 4d 31 03 54 42 35 30 2c 31 03 46 4f 35 35 38 37 03 26 31 30 30 2c 31 30 30 2c 31 30 30 03 5c 33 30 2c 33 30 03 5a 34 31 32 30 2c 35 35 35 38 03 46 58 31 30 2c 30 03 4c 30 03 4d 35 30 38 2c 35 39 35 03 44 39 33 33 2c 34 31 36 39 03 4d 32 38 35 31 2c 34 35 30 34 03 44 33 38 35 36 2c 34 39 36 03 26 31 2c 31 2c 31 03 54 42 35 30 2c 30 03 46 4f 30 03 48 03 03

This can be converted into ASCII as:

\x03!10,0\x03TT\x03H\x03TB50\x031\x03TB50,0\x03FC0\x03TB99\x03FM1\x03TB50,1\x03FO5587\x03&100,100,100\x03\\30,30\x03Z4120,5558\x03FX10,0\x03L0\x03M508,595\x03D933,4169\x03M2851,4504\x03D3856,496\x03&1,1,1\x03TB50,0\x03FO0\x03H\x03\x03

The first thing I noticed was that the software was sending ASCII character 3, (end of text) instead of semicolons. Then, I looked for the commands that would have drawn the two lines. They are buried in there as "M508,595;D933,4169;M2851,4504;D3856,496;" (semicolons substituted for EOT). Everything else is setup and teardown for the process. I am still working to decipher the exact meaning of some of the commands: things like "TT;", "TB50,0;", "FM1;", "\\30,30;", and "FO0;" are not listed in the provided documentation, and other commands, such as "Z4120,5588;"and "&100,100,100;" do not convey their meaning well to me (I think Z specifies the overall page size).

So, I still have some more tinkering to do, but at least I have an awesome starting point! I thought I should share what I have so that others can find it in the future. Here is a table of all the GPGL commands for quick searching and reference:

Command Description Format
D Draw Dx1,y1,x2,y2,...xn,yn[t]
E Relative Draw Ex1,y1,x2,y2,...xn,yn[t]
M Move Mx,y
O Relative Move Ox,y
MP Move Polar MPr,θ[t]
DP Draw Polar DPr1,θ1,r2,θ2,...rn,θn[t]
EP Relative Draw Polar EPr1,θ1t
OP Relative Move Polar MPr1,θ1t
RP Radius Plot RPθ,l1,l2
L Line Type Lp
B Line Scale Bl
$ Font $n,(m)
S Alpha Scale Sn,(m)
Q Alpha Space Ql(k)
R Alpha Rotate
I Alpha Italic Ip
LP Label Position LPn[t]
A Alpha Reset A
RC Replot Character RCc,x1,y1,[P,]x2,y2,[P1,]...xn,yn[t]
H Home H
^ Offset ^x,y
^P Offset Polar ^Px,y[,θdegrees[f][t]]
J New Pen Jn,(m)
! Speed !l[,n][t]
* Pen Acceleration & Force *a,f[,n][t]
FC Cutter Offset FCp,q[,n][t]
FD Blade Rotation Control FDθ[t]
\ Write Lower Left \x,y
Z Write Upper Right Zx,y
/ Rotate /x,y,θ
> Clipping >x1,y1,x2,y2,...xn,yn[t]
& Factor &p,q,r
SO Set Origin SOn
T Buzzer Tn
F Chart Feed Fl[t]
G Gin G
C Call Gin C
? Read Offset ?
[ Read Lower Left [
U Read Upper Right U
V Read Status Word1 V
@ Read Status Word2 @
# Read Status Word3 #
= Term =t1,t2
" Error Mask "m
: Clear :
; Interface Clear ;
BS Buffer Size BSs1,s2,s3,s4
X Axis Xp,q,r[,t1,t2][t]
% Hatching %n,x,y,d,θ[t]
(n=1...3)
%n,r1,r2,θ1,θ2,d,θ[t]
(n=11...13)
%n,d,θ,x1,y1,...xn,yn[t]
(n=21..23)

Welcome to the Future Dec. 29, 2010

Just a quick post: I am currently sitting in a comfortable chair, 31,842 feet in the air, traveling at 430 miles per hour. It is -69°F outside the window I am looking through. I am remotely connected via SSH into a computer in the basement of my house, and from their into a connected to a laptop in my home office. I tracking my location on a thin, color touch screen embedded in the seat in front of me that tracks my movement through the sky at every moment. This, ladies and gentlemen, is amazing. Absolutely, ground shakingly amazing.

And as if that weren't enough, I am carrying on an IM conversation with my friend who is on his cell phone, currently taking a poo while at work. That's awe inspiring, man.

The Magical Word-o-Matic - or - Markov Text Analysis for Fun and Non-Profit Oct. 29, 2009

I've just completed a fun new side project. I call it "The Magical Word-o-Matic". What follows is a technical analysis about how it works. If technical stuff isn't your thing, feel free to skip over this and jump straight to the fun part.


I've been reading the Iliad and I've found that the names of the characters are, simply put, quite awesome. One of the interesting things about the Greek names was that they all seemed to be composed of very similar phonemes. I started wondering if there was a way I could programmatically combine together common letter combinations to create my own bad-ass Greek names.

I started brainstorming very forms of statistical analysis I could run on the names to generate a finite-state-machine of sorts that would create names on the fly (yes, I am a huge nerd.) Then, earlier this week, I stumbed upon Markov Text Analysis quite by accident. I did some more research and discovered that this was exactly the kind of algorithm I'd been brainstorming in my head. Not only that, but the technique is generally applicable to language and text analysis; you can analyze words at the character level (as I wanted to do to create Greek names) or at the word level, generating sentences and whole compositions.

Markov analysis works by taking the input and generating from it a set of probable next steps for each item in the input. That is to say, it tells you, given your current state, what you should do next. Take the word "Mississippi". If we analyze this at the character level, we'll get something that looks like the following:

start -'M': 100% M -'i': 100% i -'s': 50% -'p':25% -end: 25% s -s: 50% -i: 50% p: -p: 50% -i: 50%

Explained further: The first letter in our text will always be an 'M' and after an 'M' will always come an 'i'. All of our newly generated words will therefore start with 'Mi'. After 'i', things become more interesting - 'i' can be followed by an 's', 'p', or it can simply be the end of the word. 's' and 'p' in turn can result in more s's and p's or another 'i'. The following words could all therefore be generated: "Mi", "Misi", "Mippppppissssipi". Adding more words to the input allow for different starting and ending letters, along with different letter combinations throughout.

Now, obviously a word like "Mipppppppppppi" looks a little silly thanks to the ridiculous number of repeating letters. English never has more than two repeating letters in a row (to the best of my knowledge.) English only has a single word that actually contains more than two letters in a row - "Goddessship" - and that's a rather silly word so its safe to build our analyzer as though we never want more than two repeating letters. To account for this, we need to make our analysis smarter - make it aware of the fact that its input won't generally have more than 2 repeating letters. To do this, we simply make it look at 2 letters at a time when it does its analysis and generation. Analyzing "Mississippi" this way, we get:

start -'Mi': 100% Mi -'ss': 100% is -'si': 100% ss -'is': 50% -'ip': 50% si -'ss': 50% -'pp': 50% ip -'pi': 100% pp -'i': 100% pi -end: 100%

Now possible words look more like "Missippi" or "Mississississippi". Much more sane, relatively speaking. You may notice that, if you entered in a word that has 4 repeating letters, you can end up back in a a situation where you have long chains of single letters. If you spelled the word "Missssissippi", then you end end up with a chance that the letters 'ss' get followed up by another 'ss'. This can be fixed by increasing the analysis size to 3 characters or more, but you end up with a trade off - larger analysis sizes require larger inputs to generate unique combinations. From anecdotal testing, a analysis size of two seems to give a good result in terms of the naturalness of the word.

You may also notice that, if you step through the above analysis, not all character pairs are reachable. You will always start with "Mi" which will always be followed by "ss" and from there you'll find yourself only able to repeat "issississi" or bail out with an "ippi". This is not terribly interesting.

There are two ways to fix this. One is to enter more words into the input. If the new words contain similar letter pairs, new avenues for combination are introduced. This actually works well assuming that the words one adds to the input are similar, but we can achieve better results with smaller inputs as well. We do this by analyzing words in two letter chunks but only recording single letters for the next step in our word. Analyzing "Mississippi" this way, we get:

start -'Mi': 100% Mi -'s': 100% is -'s': 100% ss -'i': 100% si -'s': 50% -'p': 50% ip -'p': 100% pp -'i': 100% pi -end: 100%

Now, before we get too excited, one will note that this generates the same words as the previous analysis, just slower. That's fair, but one will find that, with a larger source input, this will allow for a more dynamic spelling vocabulary.

Also, one will note that we included a two letter output for our starting step. That is because each subsequent step requires two letters for input, so we need two letters to start with. We could have also started with:

start -'M': 100% M -'i': 100%

That would require making our generator more complex however, as it would have to include logic to do a single letter step after the first letter. The end result would be the same.

So, where does this leave us? It leaves us with some kickass, made-up Greek warrior names, that's where. Names like "Dolocheptor", "Adresius", and "Ilionestor". Moreover, when you input the text of Lewis Carroll's Jabberwocky, you get words like "throgovested", "Jabbersnack", and "swortled". All and all, a few hours time well spent, if I do say so myself. Of course, if you want to use your own source text, you're more than welcome to give it a whirl.

Urban Screen July 24, 2009

Urban Screen's projector art is captivatingly hypnotic.

tags

Insanely Twisted Shadow Planet July 20, 2009

I would like to bring you attention to Insanely Twisted Shadow Planet, a side scroller that looks brilliantly beautiful:

The most exciting factor here is the involvlment of Michel Gagné, a classically trained animator with an obvious penchant for style.

tags