For fun, here’s a quick preview of this year’s Halloween costume (our what-now-seems-to-be-annual Halloween Party is on this coming Saturday, but as it’s the 31st I thought I’d put it on to scare any kids coming to the door).
I hope those of you on the path of Hurricane Sandy have made it all safely through the “Frankenstorm” and that life returns to normal for you very soon.
Some interesting news has come through from my friend Micah Dickerson, a Product Manager on the AutoCAD team. He organised the Autodesk-internal APPHACK event I travelled across to the Bay Area for, earlier in the year, and he’s just launched another one that’s open to Autodesk Developer Network members and runs until November 14th, with the main prize-giving held at AU 2012 in Las Vegas.
There are some nice prizes up for grabs:
Grand prize: US$5,000
2nd prize: US$2,000
3rd prize: US$1,000
4th prizes: 10 finalists will receive a recently-released tablet computer worth ~$500 *
[* This being the week it’s been for tablet announcements, that could really mean anything! :-)]
If you’re eligible to enter – you’re an ADN member and can make it to Las Vegas to demo your entry on November 26th – then all you have to do is either write a cool app or plugin for AutoCAD 2013, or dig one up that you’ve already written (but not made commercially available). It’s worth noting that you get extra points for keeping in the theme of the event, “Connecting AutoCAD to the Cloud” but that this theme “is open to creative interpretation”. For more information, check out the main contest page (and be sure to read the official rules, of course).
I really enjoyed participating in the Autodesk-internal APPHACK: while this one is a bit different – as participants are doing so virtually – I’m definitely looking forward to seeing the entries when I get to Las Vegas. And drinking a beer or three with the finalists at the ADN party afterwards, of course…
I had a fantastic surprise at the beginning of the week: a friend from work – to whom I’d shown my retro-foolings with the Raspberry Pi – brought a plastic bag to my desk containing an original Sinclair ZX Spectrum and power supply. He had talked about my project to a friend of his back home in Rome, who thought I’d like it (he was otherwise going to throw it away).
The computer was in very good condition externally, at least:
I was impressed by the condition of the keyboard, in particular, as these very quickly became dirty and damaged, back in the day. Perhaps Italy is a less corrosive environment for computers than the UK? :-)
Everything worked when I plugged it in and turned it on (I could hear the distinctive click of the speaker when I hit the keys) but it didn’t display on a modern TV set: it turns out that the Spectrum uses an RF modulator – allowing it to work with TV sets available back in the 80s/90s – but that it’s a simple matter to bypass this component, as the Spectrum generates composite video anyway. There’s even a video on YouTube that steps through the process.
So I dusted off my soldering iron and got cracking with the mod. Opening up the case made it apparent I’d received a fairly early model – which I assume means it's 16 rather than 48K – and you can see a little rust where there was some water damage:
The mod itself went fairly well – I ended up with a not-too-ugly bypass of the modulator unit:
The only problem came when I tried to reconnect the keyboard, as the membrane’s connectors are notoriously fragile (especially after 30 years). At first a few keys worked, but they soon stopped.
Not holding much hope of being able to repair this effectively, I got on the web and found a site that still provides them (and they’re newly manufactured!). A few days after placing my order, I received the replacement membrane through the post.
On to replacing the keyboard membrane…
First I had to get the Spectrum’s metal face-plate off. This took but a little work with my wife’s hair-dryer (you’d be right in thinking this is one of the rare times I’ve had call to use one of these, in recent years ;-) followed by some gentle prying, revealing the rubber keyboard mat:
And under the rubber keyboard we can see the original membrane:
Here are the old and new keyboard membranes, side-by-side:
Replacing the membrane was very easy, then it was a mere matter of replacing the keyboard, face-plate (I didn’t even need additional glue) and screws.
Then it was time to plug it back in and connect it via a standard yellow composite video cable into my TV...
... write some code…
... and see it in action…
So what about playing games? Games for the ZX Spectrum were originally loaded from cassette tape via an audio jack. Many of these games are available online, but in digital format.
A future project is to use one of the tape-related utilities to create a bunch of WAVs or MP3s for the games I want to load and then put them on an old iPod (I have an old iPod Photo that looks sufficiently retro for the task ;-), so that I can relive the experience of loading and playing games. I’ll still probably use the Raspberry Pi to do any serious playing – I’d like to keep my Spectrum in good condition – but it’d be fun to get working.
My friend also tells me that he may well be able to bring me back a Commodore 64 from his next visit to Rome. I can’t wait!
As part of my preparation for AU 2012, I’ve been working on updating the various Windows 8 samples I’ll be showing to work with the RTM version of the OS. The first to be migrated was the Apollonian Viewer for WinRT, which is part of the cloud & mobile series from earlier in the year.
The project was easy enough to get working: I mostly had to update to version 2.3.0 (or 2.3.1, as this was the latest available) of SharpDX and made a few minor code changes (there was previously a SafeDispose() function that seems to have disappeared and a Colors class has been renamed Color) on top of the changes that were made in my update to the original post.
Since mentioning my earlier involvement with DesignScript, I’ve been meaning to follow up with a quick post on why this programming language is different to the others people are currently using with AutoCAD.
Hence the title of the post, which stands for “Yet Another Scripting Language?”, inspired by two acronyms, Yacc and YAG (this is a subject-line often used by long-time Autodeskers leaving the company and stands for “Yet Another Gone”… I’m not sure if this term is used in the outside world – a quick Google would indicate not, but then you never know).
Anyway, back to the question: why did Autodesk choose to reinvent the wheel by creating another programming language? This question was clearly asked a lot when we first started developing it, but the ultimate answer is that it’s unlike anything we have today – in AutoCAD or even elsewhere, I suspect.
The primary reason it’s so different is its associative nature.
[Now I’m pretty sure what I’m writing here has been covered in a number of other places, but I tend to feel it’s better to be safe than sorry. And I just felt like writing something about DesignScript today.]
Let’s take a look at what the term “associativity” means, in this context. Take the following pseudo-code:
a = 0
b = a + 1
a = 2
In a traditional programming language, the value of b at the end of this code’s execution would be 1. The difference with DesignScript is that the associations you create in your code are remembered by the DesignScript runtime, so that when changes are made to variables others depend on, a ripple of changes makes its way through the network, updating any dependent variables. So the above code – when run from DesignScript – would result in b having a value of 3.
In itself this may not seem like a dramatic departure from what we have today, but as you flesh out a model – as described by DesignScript, specifying dependencies in your code to map relationships between geometry – you end up with something that makes it really easy to play around with variables, tweaking the design to meet your particular requirements (whether they be aesthetic or functional). This is one reason this technology is likely to see adoption in domains where people want to explore design variations.
The vision behind DesignScript is very broad: you can already integrate data coming from analysis and simulation tools (Ecotect is one such example) and the interfaces are there for developers outside the company also to integrate their own systems.
So DesignScript is intended as a way to map relationships such as constraints using code. How does it relate to existing parametric systems? It’s philosophically different, in many ways: rather than building a model with the constraints built in – as meta-data on existing geometry or data in its own right – you’re creating them via code. This approach has similarities to a project I came across a few years ago, where a company called Resolver Systems used Python scripting to create a spreadsheet that is essentially generated by executing code. Incidentally, I first heard about this product, Resolver One, on Channel 9. It’s very interesting the conceptual similarities between it and DesignScript: both attempt to unravel inherent model complexity in a way that people can understand and manipulate as code.
One last comment about DesignScript… you might also ask “why didn’t you just add some extensions to an existing AutoCAD-capable scripting language, to facilitate moving code across to it?” That possibility was certainly considered but eventually discarded: while DesignScript is ultimately a programming language – from what I recall it has a number of similarities to Scala, although there may have been other, more recent influences – one of the primary design goals was for it to be fairly easy for non-programmers to pick up. And it doesn’t make sense to port or migrate your code from (say) AutoLISP or VBA to DesignScript: the philosophical differences are such that you couldn’t (or wouldn’t) just move code across from one environment to the other.
A final note… many of these comments and observations are based on my somewhat stale knowledge of what’s been happening with DesignScript, so please don’t assume what I’ve said here is 100% accurate. Hopefully Luke Church (who has been largely responsible for the language’s design, over the last few years) will step with with comments if he sees anything glaringly incorrect.
It’s been a hectic week and I haven’t been able to find much time to work on a final post for today, so I had a quick delve in my “interesting” folder and found this little gem.
Not long ago, someone asked me by email about the reason for making the various co-ordinate properties (X/Y/Z) of Autodesk.AutoCAD.Geometry.Point2d and Point3d read-only, essentially making these classes immutable.
But not having designed the .NET API in AutoCAD, I wasn’t aware of the specific design decision behind it. As it was an internal question – i.e. coming from an Autodesk employee – I suggested they contact the person who did in fact design the API, my good friend and colleague Albert Szilvasy. The response Albert gave (and was passed back to me) was the following:
The same reason why System.String is immutable.
The problem is that a mutable type is confusing to use when it appears as a property return value. For example:
class A
{
publicPoint3d prop {get;}
};
A a;
a.prop.X = 1.0;
Would this syntax mean that I can set the X value of a read-only property? Or would this simply mean that I set the X value of a temporary point object returned by prop?
With my AUv recording out of the way, I’ve been starting to think more seriously about my AU sessions, over the last few days. The “big one” (with 100+ registered attendees and counting) is about moving code from a desktop application to the cloud, and will basically summarise the process I followed in my “cloud & mobile” series of earlier in the year. Which means I’ll go through the process of pulling some code out of a desktop-based application and placing it behind a web-service, before calling the service from a variety of platforms/environments (AutoCAD via .NET, iOS, Android, WinRT, Unity 3D and WebGL).
Pretty much all of these should be easily demoable during the session, but I was a bit concerned about the Android piece: until now I’ve only been able to execute the Android version of my Apollonian Viewer application on my Kindle Fire device, which doesn’t have an easy way of connecting to a projector. So I set out with the intention of getting the app working on my desktop (whether inside Windows or OS X), so that I wouldn’t even have to worry about cables or connectivity issues.
There were two main routes open to me for this. The first (which I should probably point out didn’t work for my particular situation, before anyone starts trying it without reading to the end) was presented by Philippe Leefsma, over on ADN’s Cloud & Mobile DevBlog: to install a Virtual Machine based on Android-x86, a x86 port of the Android OS. It took my a while to track down a usable “generic” ISO image: they seem not to have posted one for the latest version, 4.0-RC2 – all the versions posted for download are targeting specific hardware configurations – so I ended up having to take a chance on an unstable nightly build posted here.
Following the steps Philippe suggested, I managed to get a new Android VM sitting alongside the ones I have for Windows 7 & 8 on my Parallels Desktop installation on OS X:
When launched, it started a fancy new Android session directly on my desktop:
Running netcfg inside a terminal window on the device told me its IP address, which I could then use to connect to it via adb. From there it was straightforward to debug on the device, connecting to it from my project in Eclipse. This also installed the app, so that can we can also see it in our list when not debugging:
Launching it, though, leads to a crash:
The reason it didn’t work – and I half knew this, but wanted to go through the process of setting this up, anyway – was that OpenGL ES 2.0 is not supported by Android-x86, at least not right now.
Which left the second option… to get the Android emulator to run OpenGL ES 2.0. The good news is that since earlier this year this has been possible, it seems. It was a bit fiddly to set up – this page helped a lot – but it took me some time to actually get a GPU-enabled emulator instance running OpenGL ES 2.0.
Here are the settings I used – I found I couldn’t set the “GPU emulation” hardware setting on an existing emulator, for some reason, but creating a new virtual device solved that:
One of the major issues was that even if it’s possible to get the emulator set as GPU-enabled the emulator reports itself as not supporting OpenGL ES 2.0. So in your code you need to find a way to suppress the standard check again this property when you’re testing with an emulator.
Thankfully Rajawali, the 3D framework I’m using for my application, added this capability some time ago. It was a simple matter to change the application to set the protected checkOpenGLVersion boolean to false, which allowed the application to execute and me to find the remaining issues to fix (which basically comprised the fact that for performance reasons 3D primitives – such as Spheres, the only one my application creates – no longer have a default material attached, so we have to create one).
And so I could run the application inside an OpenGL ES 2.0-capable emulator. Yay!
Here’s the base environment:
Here are the applications:
And here are the launch screens for the Apollonian Viewer:
And finally we see our spheres, even if the lighting looks like it needs some adjustment:
Now that I have at least the basics working, I’ll probably get back to working on the core material. At some point I may take the time to see what’s up with the lighting – perhaps my lights need adjustment or I’m using the wrong material – but for now I’m just happy to see the app working inside an emulator.
Over the weekend, from Friday to Sunday, I spent far more hours than I’d have liked finishing off my AU Virtual class for this year, “Secure Your AutoCAD Environment” (I’m increasingly involved in security-related activities for the AutoCAD development organisation). Preparing material for AU Virtual is often pretty tough, whether it’s being recorded in person (I’ve done a couple of those) or being in advance and needing extensively editing.
This year’s format was a bit different, in that it required multiple modules to be recorded separately as opposed to a single, monolithic recording. Better from a consumption perspective, apparently, and probably also a bit better in terms of getting presenters to chunk up their material and record it separately, but it felt to me like it added some overhead during the recording and editing phase.
Anyway, it’s now all done and has been uploaded to the AU website. Hopefully that’s it until I start to get viewers’ questions through.
Now I can start to think about other things, once again. I still have my physical AU classes to prepare for, although thankfully most of the coding is done: I mainly need to update the various projects to make sure they work with the latest releases of products & frameworks that were in Beta when I wrote the code – particularly Visual Studio 2012, ASP.NET MVC 4 and Windows 8 – but it shouldn’t be too arduous.
Speaking of Windows 8… I’ve now installed the RTM build both on my dedicated build machine and inside a Parallels VM, and it looks great. I’m looking forward to using it more as a primary OS.
And speaking of Parallels, the big news on that front is that the Kinect SDK now has a version that supports working in a VM – something I begged Microsoft for over a year ago. Thankfully they listened (it wasn’t just me asking, of course) and delivered v1.6 of the Kinect SDK and its accompanying Developer Toolkit, which allow me to connect my Kinect up to my Mac and run my AutoCAD-related Kinect projects, albeit inside a Windows VM inside Parallels. This should help me do more with Kinect as I now no longer have to switch across to my secondary machine to work with it.
And the final bit of “hot of the press” excitement is around the newly expanded Raspberry Pi Model B, now with 512 MB of RAM. It probably won’t make much difference to the face-recognition security cam project, but may well let me run more advanced games in more complex console emulators. Happy days!
Way back when, I helped integrate the initial incarnation of DesignScript – although at the time we were using its working name, D# – inside AutoCAD. The father of the language, Robert Aish, was put in touch with me on October 17th 2008 and by the time I headed for Las Vegas on November 30th we had a working prototype (which was good enough to demonstrate at the Design Computation Symposium and even to be included in a video shown during the AU 2008 mainstage presentation). It was quite an intense period, believe it or not.
Here’s an old screenshot for chuckles:
It was a really interesting project: working with Robert was a great experience, and we managed to create a demo app that had its claws deeply into AutoCAD in many areas (aside from a nice UI-level integration, we made heavy use of transient graphics for performance purposes, for instance).
A lot has clearly happened since then: professional language designers have become involved in the project, creating a design-centric, multi-paradigm (which in this case means primarily associative and imperative) programming language. A team of coders have created a core implementation that works extensively with AutoCAD geometry (as opposed to the small number of types we delivered with the initial demo).
I’m really looking forward to taking this version of DesignScript for a spin and posting a few samples on this blog. While it’s ultimately a technology that’s targeted at problems that would benefit from algorithmic or computational design – and mostly in the AEC space – I suspect that it could also be used more broadly. We’ll see!
In the meantime, here’s a quick snapshot of DesignScript inside AutoCAD 2013 (you need to be running the 64-bit version to install the Labs release) with the script from “Tutorial 1” loaded and executed:
I was originally inspired to use this device to present the results of the Facecam while having dinner at a friend’s place. He’s a fellow geek – even his welcome mat says so – so we Googled around for a solution and came up with the DreamCheeky, mainly because someone had already created a Linux driver for it.
The device is USB-powered and I’m thankfully able to power both this and the Logitech webcam directly from the Raspberry Pi: I don’t need to resort to a powered USB hub, which is sometimes needed if your webcam needs more juice than the average.
Here are the steps I followed to install and build the necessary components on the Raspberry Pi:
I’m not 100% happy with the above process: for home use it’s OK, but as the required library, libhid is licensed under the GPL license there are serious limitations on how you might want to release this as
We realise that this is a serious impediment. The GPL is a "viral" licence, and you will only be able to use libhid in other GPL projects. We would like to change the licence, but libhid uses the MGE UPS SYSTEMS HID Parser, which is GPL, and thus we cannot. Our solution is to rewrite the HID parser. One of these days. We are also in contact with MGE, trying to convince them to loosen their licence. If the licencing issues are solved, we are likely to re-release libhid under the Artistic Licence.
That said, there is apparently hope that it’ll be possible at some point to swap this module out for an alternative.
Once the needed components are built, it should be a simple matter of calling the dcled command to test whether it displays text properly or not. Here are the usage instructions for dcled:
[pi@alarmpi ~]$ dcled --help
Usage- dcled [opts] [files]
--brightness -b How bright, 0-2
--clock -c Show the time
--clock24h -C Show the 24h time
--bcdclock -B Show the time in binary
--debug -d Mostly useless
--echo -e Send copy to stdout
--help -h Show this message
--message -m A single line message to scroll
--nodev -n Don't use the device
--preamble -p Send a graphic before the text.
--repeat -r Keep scrolling forever
--fastprint -f Jump to end of message.
--speed -s General delay in ms
--test -t Output a test pattern
--font -g Select a font
--fontdir -G Select a font directory
Available preamble graphics:
1 - dots - A string of random dots
2 - static - Warms up like an old TV
3 - squiggle - A squiggly line
4 - clock24 - Shows the 24 hour time
5 - clock - Shows the time
6 - spiral - Draws a spiral
7 - fire - A nice warm hearth
8 - bcdclock - Shows the time in binary
Optional fonts:
1 - small - Very small characters
2 - sga - Standard galactic alphabet
3 - small_inv - Very small inverted characters
You can easily test the unit, then, by using this command to send a repeatedly scrolling message to the screen:
sudo dcled -r "This is a test"
If you see the following message, then you’ve probably forgotten to run as root via sudo:
hid_force_open failed with return code 6
Couldn't find the device. Was expecting to find a readable
device that matched vendor 1d34 and product 13. Is the
device plugged in? Do you have permission?
You can also use the lsusb command to check whether the device has been recognised by the Pi.
Now we have the driver working, it’s a fairly simple matter to create another daemon to look for files in a certain folder and then send the messages they contain to the message-board before deleting them. We’ll use the "-p 7” option to cause the message to be posted with a flame-like pre- & post-amble.
Here’s the C/C++ code I used to implement this:
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
#include<syslog.h>
#include<dirent.h>
#include<string.h>
#include<string>
#include<vector>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<syslog.h>
usingnamespace std;
// Input and output folder locations
constchar * inDir = "/home/pi/faces/out";
// Get the list of files in a directory
int getdir(string dir, vector<string> &files)
{
DIR *dp;
struct dirent *dirp;
if((dp = opendir(dir.c_str())) == NULL)
{
char msg[200];
snprintf(
msg,
sizeof(msg)-1,
"Error(%d) opening %s",
errno,
dir.c_str()
);
syslog(LOG_INFO, msg);
return errno;
}
while ((dirp = readdir(dp)) != NULL)
{
files.push_back(string(dirp->d_name));
}
closedir(dp);
sort(files.begin(), files.end());
return 0;
}
int main(void)
{
// Our process ID and Session ID
pid_t pid, sid;
// Fork off the parent process
pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
// If we got a good PID, then we can exit the parent process
if (pid > 0)
{
exit(EXIT_SUCCESS);
}
// Change the file mode mask
umask(0);
// Open any logs here
openlog("ledmsgd", LOG_PID|LOG_CONS, LOG_USER);
// Create a new SID for the child process
sid = setsid();
if (sid < 0)
{
// Log the failure
syslog(LOG_INFO, "Unable to get SID.");
closelog();
exit(EXIT_FAILURE);
}
// Change the current working directory
if (chdir("/") < 0)
{
// Log the failure
syslog(LOG_INFO, "Unable to change working directory.");
closelog();
exit(EXIT_FAILURE);
}
// Close out the standard file descriptors
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// Daemon-specific initialization goes here
struct stat st = {0};
if (stat(inDir, &st) == -1)
{
mkdir(inDir, 0700);
}
vector<string> files = vector<string>();
constchar *contents = NULL;
/* The Big Loop */
syslog(LOG_INFO, "main loop begins");
while (1)
{
// Get the files in our "in" directory
files.clear();
getdir(inDir, files);
if ((int)files.size() >= 3)
contents = files[2].c_str();
else
contents = NULL;
if (contents != NULL)
{
syslog(LOG_INFO, "found a file");
syslog(LOG_INFO, contents);
char input[256];
input[0] = 0;
strcat(input, inDir);
strcat(input, "/");
strcat(input, contents);
char cmd[200];
snprintf(
cmd,
sizeof(cmd)-1,
"dcled -p 7 %s",
input
);
system(cmd);
remove(input);
}
sleep(0.5); /* wait half a second */
}
closelog();
exit(EXIT_SUCCESS);
}
The simplest way to get this source onto the device is to wget it from this blog. Then it’s a simple matter of building it (again, apologies for the lack of makefile):
That should be it for getting the last of our components in place. At this stage, you should now have an at least partially functional security webcam, assuming you’ve been able to train and copy across a face database in the form of a facedata.xml file.
For fun, here’s a quick test of my own device at my home’s front door. I hadn’t realised that the human eye (and brain) manages to create the effect of scrolling text from an LED message-board better than when not filtered through a video recording (even when in HD), but then I suppose that saves me the trouble of attempting to protect the innocent (i.e. my Facebook friends, if you can call them that. ;-)
I looked at the debug images that were stored in the ~/faces/debug folder, and saw that in general my face was getting detected appropriately, even if the recognition process clearly still needs tweaking to reduce (eliminate?) the false positives:
Part of the issue clearly stems that we don’t look the same when captured via a security camera (especially when recording a video about the experience :-) as we do when we get tagged in photos on Facebook. It’s very possible the issue goes deeper than that, but I’m going to leave my investigations there, for now.
Recent Comments
Archives
More...