Clemens KlopfensteinSerena KieferLukas Tiberio KlopfensteinLorenz Cuno Klopfenstein
about - feeds - home
Lorenz Cuno Klopfenstein

Posts by date

This week I spent some time improving the interface and the underlying engine of the DMX Lightshow application. Every channel does now smoothly adjust its output values in order to make sudden changes less ugly (changes from one animation to the next are much more smooth as well). Additionally, each channel can now abstract one or more real DMX channels: this way it's now possible to register two or more channels on a single slider and change all channels simultaneously.

The interface.

I also made some changes to the interface (nothing groundbreaking): it's still ugly as hell, but at least it is also slightly more usable. Anyway, I'm a long way from the point where I'll confidently be able to use the application in a live scenario: I need way more shortcuts and presets in order to easily do some of the most common tasks (like fading out all channels at once).

Applet selection and channel assignment.

The application is also pretty modular: all applets (there's only one at the time, though  :D) are simply loaded by the interface they expose. Same goes for animations that can be applied to every single channel.

Enough talk... here's a new experiment!  ;)
I tried to play along "19:08", by my brother's band Spasmodicamente, but without any preparation and doing everything interactively (my brother would yell all changes and cues from behind, but I didn't get everyone of them and felt pretty helpless while I was clicking wildly around...). So, the show is pretty lame, but there is some potential!


Video on Vimeo.

By the way... you can download the music by Spasmodicamente from their website for free!  ;)

Posted on Posted on Thursday, December 04, 2008
Views 2 Views
comments posted 0 comments posted

I spent last week trying to go on with my "DMX Lightshow" project: first of all, I finally decided to build a WPF-based interface; since the application will have to refresh at least 40 times per second, having GPU-accelerated graphics will certainly help (and learning WPF can't harm either). I also ended up architecting a nice framework around the basic API of the SIUDI-6C controller.

For instance, the DMX framework now includes a small animation engine that, based on the time signature and the tempo assigned by the user, will ensure that every single animation is correctly timed and executed during the timespan of one or multiple time units (4/4 bars usually, but odd signatures are supported as well).

I tried to keep everything as modular as possible: the workspace can be assembled by the user by adding "modules". Each module will drive one or more DMX channels and will expose a graphical interface especially tailored to the type of appliance that is connected to its channels. At the moment I have only a couple of pretty simple slider-based modules (good enough for the dimmer I currently use), but in the future I'd also like to add modules for lights such as blinders or strobe lights, as soon as I buy them...  :)

Current interface.

The picture above is the current main interface: it's not very pretty, but these are my first steps both with WPF and with DMX...  :)

Anyway, since everything works (more or less), I collected 4 lamps I found lying around at home and plugged them in. Then I fired up "Fear of a Blank Planet" by Porcupine Tree and experimented a bit with the basic animations I built in (the usual cosine and sine functions, plus some others). Some excerpts of my masterpiece:


Video on Vimeo.

I hope I'll have time to improve the application a bit during the next weeks (I found out several weak spots while recording the video above): stay tuned for the next video and, eventually, for some technical posts about WPF.

Posted on Posted on Thursday, November 27, 2008
Views 28 Views
comments posted 3 comments posted

One of the last steps in the production of my game for the XNA Contest was the gathering of all the needed sound clips and the implementation of a little game component that would take care of playing the different audio cues, based on what would happen during the game. (more...)

Posted on Posted on Sunday, November 23, 2008
Tagged as Tagged as XNA Contest
Views 10 Views
comments posted 0 comments posted

More than a year ago I was working at my thesis using the wireless TMote modules and TinyOS on Cygwin. Today, since the whole TinyOS SDK was still laying around on my hard disk, I decided to compress everything and to back it up, in order to free some space.

But it seems that, as it was installed, Cygwin completely messed up the folder's permissions: the only user with access was the very familiar sounding user "S-1-5-21-3632630550-1273522795-1072632642-1004" (WTF?). Neither the standard user nor the administrator had any permission on the whole folder.

In this case, the only thing you can do is to launch a command promt as administrator (the GUI permission interface doesn't work at all):

Admin command prompt, taking ownership of the folder.

Launch the following command:

takeown /F <folder> /R

This will assign ownership of the entire folder (and its subfolders) to the current user (the administrator). However, you still have no permissions:

icacls <folder> /grant:r <User>:(F) /T

The /grant:r part tells Icacls to grant permissions and to revoke (:r) all previously assigned permissions. This will clean up everything. The (F) part tells the utility to assign "Full" permissions to the specified user. Finally, the /T option extends all changes to all subfolder recursively.

Posted on Posted on Friday, November 21, 2008
Tagged as Tagged as Windows
Views 10 Views
comments posted 0 comments posted

Setup: notebook, DMX controller, DMX dimmer and lamp. My adventures with the DMX Lightshow go on.  :)
After successfully installing and setting up the SIUDI-6C DMX controller I ordered a DMX dimmer on the german Pro Lighting internet shop.

The package was delivered today:
it's a nice Eurolite "EDX-4" 4-channel dimmer, that is, a piece of hardware that has four standard power sockets and can adjust the power output on each of them, on a more or less linear scale from 0 to 100%. An arbitrary number of lights can be connected to each socket (without exceeding the unit's total power limit of course): the beauty of it is that since it uses standard Shuko sockets you can connect almost everything to it (even my old and dusty bedside lamp).

The Eurolite EDX-4 unit.

I didn't expect it to be so big. My hand is on the picture for scale reference purposes.  :D

This evening I decided to give the dimmer unit a try and wrote a little .NET managed library that wraps the programming interface included in the SIUDI-6C SDK by Sunlite. Then I quickly threw together a very ugly interface that enables to interactively set the output value on a single DMX channel, hooked the dimmer on the DMX controller, switched the power on and... lo' and behold, it works!  :D


Video hosted by Vimeo.

Ok, the hardware part would be ready... now it's time to get working on the software! I think I'll try to build something using WPF, which is a fairly new technology to me and seems to have a lot of interesting additions in .NET 3.5 SP1. We'll see.  :)

Posted on Posted on Thursday, November 20, 2008
Views 17 Views
comments posted 0 comments posted

I'm continuing to add more functionalities to the website and this time I've been working on "e-mail notifications" (which are sent to whoever commented on a post when a new comment is written). In order to send those e-mails asynchronously I decided to add the Quartz.NET Job Scheduler to the project and try to get it working.

So, after struggling to setup NHibernate, use the new ASP.NET MVC framework and getting Lucene.NET and NHibernate.Search to work, let's tackle the next library...  :S

Quartz.NET logo The latest version (1.0) of the library should be compatible with "partial trust" scenarios, but nonetheless still failed to work on the live website. I digged around in the source code to find the pieces of code which didn't work: I've documented my findings on the Quartz.NET mailing list and it should be fixed in the next versions (actually, the Common Logging framework would need to be fixed too for partial trust scenarios).

Anyway, if you need Quartz.NET now, here's what you need to do.

Remove the Common Logging library

After grabbing the source code from SourceForge, the first thing to do is to remove all references to the Common Logging library (which, as said, doesn't run on medium trust right now). To do so, remove the dll reference from the Quartz project:

Remove the Common Logging dll reference from the project.

Ok, now we end up with a lot of errors in the code.  :D Instead of removing the references to the logging library from the code, we can simply re-route all calls to a fake stub of the library, implementing some of the classes and copying the interface signatures with Reflector.

First of all, ILog.cs:

namespace Quartz {
	public interface ILog {
		// Methods
		void Debug(object message);
		void Debug(object message, Exception exception);
		void Error(object message);
		void Error(object message, Exception exception);
		void Fatal(object message);
		void Fatal(object message, Exception exception);
		void Info(object message);
		void Info(object message, Exception exception);
		void Trace(object message);
		void Trace(object message, Exception exception);
		void Warn(object message);
		void Warn(object message, Exception exception);

		// Properties
		bool IsDebugEnabled { get; }
		bool IsErrorEnabled { get; }
		bool IsFatalEnabled { get; }
		bool IsInfoEnabled { get; }
		bool IsTraceEnabled { get; }
		bool IsWarnEnabled { get; }
	}
}

Then ILoggerFactoryAdapter.cs:

namespace Quartz {
	public interface ILoggerFactoryAdapter {
		// Methods
		ILog GetLogger(string name);
		ILog GetLogger(Type type);
	}
}

Then create an implementation of ILog (I called it LogImpl) which simply does nothing on each call and returns false on all properties. Finally, let's implement LogManager.cs:

namespace Quartz {
	public sealed class LogManager {
		public static ILog GetLogger(string name) {
			return new LogImpl();
		}
		public static ILog GetLogger(Type type) {
			return new LogImpl();
		}

		// Properties
		public static ILoggerFactoryAdapter Adapter { get; set; }
	}
}

We don't need to implement the full class, just the methods used by Quartz, and return an instance of our stub logger.

Fixing Quartz.NET

Ok, now that the Common Logging library has been removed cleanly, we need to fix some of the calls in Quartz.NET which are not allowed in partial trust. Let's start with /Impl/StdSchedulerFactory.cs: in the Initialize() method you'll find a call to GetEnvironmentVariable() that must be removed.

string requestedFile = null;// Environment.GetEnvironmentVariable(PropertiesFile);

And then the same function call must be removed from the OverrideWithSysProps() method:

private static NameValueCollection OverrideWithSysProps(NameValueCollection props)
{
    NameValueCollection retValue = new NameValueCollection(props);
    /*ICollection keys = Environment.GetEnvironmentVariables().Keys;

    foreach (string key in keys)
    {
        retValue.Set(key, props[key]);
    }*/
    return retValue;
}

Ok, now to the /Core/QuartzScheduler.cs file. This class calls the GetAssembly() method to get the library's version number when initialized: this isn't allowed either on medium trust, so we'll have to remove that code.

/// 
/// Initializes the <see cref="QuartzScheduler"/> class.
/// 
static QuartzScheduler()
{
	//Assembly asm = Assembly.GetAssembly(typeof(QuartzScheduler));
	//versionInfo = FileVersionInfo.GetVersionInfo(asm.Location);
	//versionInfo = new FileVersionInfo();
}

And finally, remove all code in the "Version" properties with some hard-coded arbitrary values (you won't need them in most cases I think), like so:

public string Version
{
    get {
		//return versionInfo.FileVersion;
		return "1.0.0";
	}
}

That's it! Recompile the whole thing and add the new library to your project.  :)

Lazy?

If you don't want to mess with the source code and simply want a working version of Quartz.NET 1.0, download it here.

Posted on Posted on Wednesday, November 19, 2008
Tagged as Tagged as Hacks Website ASP.NET
Views 16 Views
comments posted 0 comments posted

Today I'm starting another new exciting pet-project of mine!  :) I'm planning to buy some DMX hardware (DMX is a simple protocol to control lighting shows and such) and build a custom piece of software, that I could then use on live shows to give life to the gig with rhythmic lighting, effects and whatnot.

The most immediate use for it would by on gigs of my brother's band, Spasmodicamente. That would be totally awesome.  :D

So, for starts, I went looking for a cheap DMX controller that can be used interactively by a computer. There are several solutions by different companies, but the most convincing seemed to be those made by Nicolaudie-Sunlite. Different models exist, some of them are pretty expensive but they also include much stuff I don't really need. Fortunately, Sunlite also sells simple kits that come with a software development kit to program the thing.

Unboxing

Two days ago I ordered one SIUDI-6C (the cheapest model, since I wasn't completely sure it was going to work). It cost 100 € plus 25 € for shipping and it was one of the quickest deliveries I ever witnessed in my life! This morning at 10 o'clock it arrived safely in my hands (that's roughly a single day from France to central Italy). Thank you Sunlite!  :)

The unwrapped box.

The nice cardboard box is definitely overkill for the three items contained in it:

Contents of the box.

The little blue plastic box is the SIUDI-6C DMX controller. The disc contains a collection of software (most of which I won't use anyway), the SDK and some documentation (it's not MSDN, but it will do). A standard printer usb cable is also in the box.

Installing

As soon as I plugged the controller in the usb slot, Vista went searching for drivers on Windows Update for almost ten minutes. Without success.  :) Anyway, all drivers are on the CD (and on the website as well).

Just make sure you don't install the drivers in the /drivers folder, but directly install the SDK in /siudi/siudi5-6_developerkit.exe. The first set of drivers cannot be installed (on Vista) because of some error in the INF file. After some hacking around in the file I managed to get them installed (and thought all was well) but the example programs did not work: "no DMX interface installed". Duh.

Then I exumed my old XP disc, installed it on the former Linux partition (won't need that for this project, that's for sure) and tried again: same story. Those drivers simply do not work. I was almost about to send a mail to Sunlite, but I tried the (slighty smaller) driver pack included with the SDK and that did the trick!  :)
Now the little fellow is blinking like mad and responds to some basic DMX command.

The SIUDI-6C DMX Controller

So, now I'm ready to do some nice stuff with my new gadget! I ordered some other hardware that can be controlled via DMX today (a DMX dimmer), therefore I will probably have something working by the end of the next week.

Posted on Posted on Friday, November 14, 2008
Views 19 Views
comments posted 0 comments posted

I'm finally getting back to my XNA series of posts, which will eventually lead to the release of the - cleaned up - source code of my little game (I just hope that I'll be able to do so before XNA 6.0 comes out...).

Anyway, one of the truly biggest problems I had while developing the game, was to figure out HOW exactly to point an object towards another point in space. This sounds really basic, probably is, but my math skills are so weak that I had to think about it almost an entire day before finding a solution. Perhaps this will be useful to similarly counfounded people, like me.  :D

The main problem is that you are trying to orient something along a vector, which starts in one tridimensional point and ends in another one. These two points in space are sufficient to give us a simple directional vector (the distance between the two points), but not enough for a full translation matrix (or a rotational matrix, in this case). This is because there are infinite positions in which the object we are trying to rotate could be in, while still pointing to the correct destination point. To exemplificate:

Awful scheme of the problem.

Yes, I know the drawing is extremely ugly.  :) You try doing something better with Paint.NET!

Anyway, assume the two balls are the two points I was talking about and the black thick line is the distance vector between them. Then, the disc around the red ball (or that what should look like a disc) is the plane on which all possible "up" vectors of the object could be, while still having its nose pointed straight at the blue ball.

The problem thus is that we have too much "correct" solutions: but we must decide for one (and consistently). Therefore, the simple way to do it is to simply pick a completely arbitrary vector:

//Get distance between points
Vector3 dist = ballBlue.Position - ballRed.Position;
dist.Normalize();

//Get angle to arbitrary vector and compute the rotation axis
float theta = (float)Math.Acos(Vector3.Dot(dist, Vector3.Up));
Vector3 cross = Vector3.Cross(Vector3.Up, dist);
cross.Normalize();

Quaternion rotation = Quaternion.CreateFromAxisAngle(cross, theta);

The code is pretty straightforward: first of all you compute theta, the angle between the distance vector and the arbitrary vector (in this case I chose the up vector, but you can use whichever makes more sense in your case). Then we compute the cross product between those two vector and normalize it: this will yield a nice vector (one of those on the "correct" plane I mentioned above) that can be used to generate a rotation quaternion or a matrix.

The result in my game: notice the arrow pointing towards the golden point in space.

And this is the result in my game: notice the golden "thing" above the spaceship? It's a green arrow that points exactly towards the yellow point in space on the right.

Posted on Posted on Thursday, November 13, 2008
Tagged as Tagged as XNA Contest 3d
Views 13 Views
comments posted 0 comments posted

While I was implementing the data import/export functionalities of MotoX Stopwatch, having decided to use the XmlSerializer to load and save human readable files, I found out that the serializer doesn't work for TimeSpan values for some reason!  :S

It appears to be a known problem and several other people have already posted their workarounds. However, here's my solution using Cobra: mark the TimeSpan properties (which cannot be serialized normally) with the XmlIgnore attriute. This will force the serializer to skip them. Then declare new string properties, which you will never use in your code, that simply wrap the original TimeSpan value.

use System.Xml
use System.Xml.Serialization

class StopWatchInfo
	has Serializable

	# ... normal properties ...
	
	# The next property will be ignored by the serializer
	var time as TimeSpan
		is public
		has XmlIgnore
		
	# This property wraps the one above for the serializer
	pro timeWrap as String
		get
			return .time.toString
		set
			ret = TimeSpan()
			if TimeSpan.tryParse(value, out ret)
				.time = ret
			else
				.time = TimeSpan.zero

Remember that the serializer uses the property names of the class, therefore "timeWrap" will appear in the output file instead of "time". To avoid this, you'll want to rename the wrapping property adding an XmlAttribute to it.

Posted on Posted on Tuesday, November 11, 2008
Views 6 Views
comments posted 0 comments posted

This evening I pulled together the last updates to my side project OnTopReplica and published it under version 2.1.

The update contains two nice features: first of all you can now adjust the opacity of the window by turning the mouse wheel. This also makes possible to set the opacity in finer increments than through the default menu.

Additionally, the fullscreen mode has been completely overhauled and now adapts much more nicely to the screen (in fact it now leaves the taskbar free and doesn't cover potential notifications). There's also a new click-through mode (you can enable it in the "resize" menu and by setting the window opacity to non-opaque) which transforms the default fullscreen mode into an "overlay" mode: the window will sit in the foreground as usual, but you will be able to click on every window underneath. Very cool to watch movies in full resolution!  ;)

Hope you like it! Download it here.

Posted on Posted on Monday, November 10, 2008
Views 14 Views
comments posted 1 comments posted