Saturday, August 25, 2012

3D printers - reprap and the limitations of opensource

I've often found the concept of 3D printers interesting, I've looked at building a reprap several times over the last few years.
When SeeMeCNC introduced the H1 I bought one, in the end the total cost wasn't significantly less than sourcing a Mendel, but the low intro price pulled me in.  The build was poorly documented, (something since fixed) and involved a lot of pieces, but it wasn't overly difficult. Overall I have been stunned by the quality of print that can be produced, it takes a lot of messing about to get there, but the quality is better than I would have imagined.
I've since built a mendelmax, and I've designed and started construction on a 3rd printer.
So it's all great then, well no not really, I mentioned above there is a lot of messing about.
I would bet most people not technically minded would give up before they got a decent quality print, and even technically minded people would struggle getting there.
the problem is the vast divergence in hardware and software, the totality of which makes plug and play impractical.
Basically a printer builder, builds the kit, tries to keep theing square and freely moving, wires the electronics (one of several variations) then downloads firmware to the electronics, doing so requires editing C header files in the firmware entering values corresponding to the particular combination of hardware happens to include, compiling and downloading to the board. You then calibrate the printer, so that actual movements correspond to requested ones.
The would be "reprapper" then downloads one of a few options to convert 3D models to gcode, Slic3r and Skeinforge being the most popular, they setup between 50 and literally 100's of parameters, to produce the gcode.
They load another piece of open source software to drive the printer, load the gcode model, home the printer and assuming everything is mechanically sound and calibrated you get a decent print out of the printer.
Reprap is founded on the idea of fast evolution, hence the biological naming "Darwin", "Mendel", Huxley" etc.
Much like most open source initiatives, and evolution in general the problem is you end up driving towards good enough, but good enough in the context of the community that is developing the product. The problem with that is that it limits the broader appeal.
I thing we're at a tipping point in the space as commercial concerns start to drive the technology towards the main stream something the free market is better suited towards than the open source movement, products like the UP and Cube are shunned by the reprap community, but for a price not much more than a self sourced Mendel, you get a ready to run printer that with minimal configuration can produce excellent prints.
So many of the problems with configuration, go away as soon as you have preassembled, known hardware, and commercial concerns exploit this, providing known working configurations for the hardware they provide.
It's an interesting parallel for open source software which I think has many of the same issues, it's targetted at the developers as opposed to trying to entice end users.
I am a big fan of the reprap community, I love the concept, but I'd recommend a prebuilt printer to most of my friends.

Friday, August 10, 2012

BeagleBone and 3D printers

I've been messing around with a couple of 3D printers for the last few months, I'll write a post about those at some point, it's a really interesting technology, with interesting shortcomings that IMO reflect the nature of opensource development.
This post however is about my experiences with a BeagleBone and attempts to use one as a host for a 3D printer, it's a TI AM3359 development board, on the face of it it has more than enough CPU and more than enough IO to easily drive a 3D printer.
My vision was a compact host with a touch screen and ethernet that could do the slicing (produce the tool paths for the printer) as well as send signals to the stepper drivers.
Unfortunately this is going to turn into a rant about the stupidity of secrecy over GPU internals.
You basically have two options on a BeagleBoard, you can either use Linux as an OS or you can code straight to the metal using something TI calls Starterware.
Now we want to write a motion controller, and that will not tolerate latency in response to interrupts, that makes Linux a less than ideal solution. Yes there are Linux kernels with realtime extensions but I doubt any of them could meet the latency requirements on a single core 700MHz Arm Cortex8.
So I start to take a loot at Starterware, the tools are horrible, but more in the "nobody at TI could be bothered making them work properly way" as opposed to the lack of functionality way, still not the worst development environment I've ever used. So looking at the samples, all seems straight forwards , I can bang pins, turn LED's on and off make ethernet connections, great....
But absolutely no access to the GPU.
Why do I care?
Well creating tool paths from a polygon model is computationally expensive, and my plan was to leverage the GPU to do most of the work, it's trivial to render a slice of the model using a variation of the classic shadow volume algorithm, I'd then convert that to spans and extract the paths.
OK then after much bitching and asking around to try and get docs on the PowerVR SGX included in the BeagleBone I give up and start looking at Linux as a solution.
The TI AM3359 has two onboard IO processors called PRU2's which I should be able to use to drive steppers, of course TI have never released the PRU2 version of the assembler for them, but the PRU1 assembler does produce usable code, I defer looking at the details until later.
OK onto Linux, and using the GPU to slice models!
After a lot of messing around.
Finding a version of Linux that works with the GPU drivers
Figuring out which bits of OpenGLES don't work in drivers
Figuring out what exact combination of color, depth and stencil surfaces actually work with FBO's
Figuring out how to get Linux to not boot into X
Ok I write a couple of hundred lines of code and I can render slices of the model, now to convert those slices into spans.
I do the obvious GLReadPixels, which I wouldn't expect to have great performance, but in practice it was hideous, the GLES2 driver doesn't support PBO's so I can't do the read asynchronously...
I think about it a bit more and realize that I can do the span conversion using OpenCL, at which point I only have to read the relatively small span buffer from the GPU rather than the entire 2Kx2K framebuffer.
After much web searching I discover that although Imagination Technologies (the IP developer of the SGX GPU) have in fact demonstrated an OpenCL driver and in fact claim that SGX supports compute, TI do not license the driver (as far as I can determine no one does).
And there we are, no way to proceed other than the hideously slow GLReadPixels.
The proprietary drivers and secrecy surrounding the documentation lock me into Linux, and then it doesn't provide enough functionality to do what I want....
I just don't get the secrecy surrounding the register/command stream level documentation for GPU's, I just can't imagine there is anything there that would expose the IP holder. Back in the NV2x days I reverse engineered the command stream so we could disassemble them and build them offline, and it was stunningly uninteresting. The only reason I can imagine the secrecy is that the IP companies are making money off licensing the drivers, and it removes any chance of competition.
Either way it makes the TI AM3359 much less useful for my purposes, and I'd immediately rule out anything using an Imagination Technologies part when looking at alternatives.
UGH!

Sunday, March 20, 2011

The holy trinity and MMORPG combat

Recently I was discussing the Cataclysm changes in WoW with a friend over lunch, he was complaining about the changes in healing and tanking in the new heroics. That coupled with the lack of tanks and healers available for random groups having drained the fun out of the game for him. In particular he was complaining that the new difficulty had created an environment where Tanks would quit any random group they considered even marginal, because they could instantly join another group.

One of the things he suggested was removing the Holy Trinity from MMORPG games. For those who don't know the Holy Trinity is the combination of DPS, Tank and Healer that's become the de-facto design for group based combat in MMORPG's. The first game I can remember using role based groups like this was Everquest (although it wasn't really a trinity at that point). Almost every game since has copied the basic mechanic. WoW did simplify it somewhat reducing it to 3 clear roles, and Blizzard has probably spent more time tailoring content to the pattern than anyone else. Asheron’s Call did eschew the class system all together, but it lead to cookie cutter builds, sure everyone could heal, DPS and take damage, but because there were a certain set of skills that had to be taken in any viable build everyone ended up with the same skills with only minor differences.

Getting back to my friends point which was that 2 of the 3 roles (Tanking and Healing) were more difficult to play or at least had dramatically more impact when performed poorly and almost everyone preferred to play the 3rd role anyway. Looking at WOW for a minute, even with 3 DPS to 1 Tank/Heal ratios, there still aren't enough Tanks or Healers to meet the demand in random dungeon queues, which tends to support his point.

It started me thinking, what would group combat without the Trinity look like? I’m fairly certain there are a number of different viable mechanics, but it’s an interesting exercise to try and devise one, at least at a very high level.

The requirements are relatively straight forwards.
  • We want to reward coordinated group play.
  • We don’t want it to become everyman for himself.
  • We don't want to excessively reward particular class combinations.
  • The classes still have to feel unique.

After a some though the basic idea I came up with is that combat becomes about handing off threat between the participants in a battle. In long battles multiple party members get to be "it" (the primary target of the mob). While you're “it”, you have several penalties that prevent you from retaining "it" status.

Let’s start with a simple system with one class.
Characters have two resources HP’s and Energy. In practice you could just have one, but it’s harder to sell through game “Lore”.
In addition they have 3 dynamic attributes
Threat Generation
DPS
Damage Mitigation
Imagine these attributes as spring systems with dampers.
These 3 attributes are effectively signed values starting in some neutral state (0) trying to return with some force to that state.

Character skills either directly or indirectly inject impulses or forces (positive or negative) to each of these 3 attributes and there is momentum associated with changes of the values.
The closer the attributes are to the neutral state the faster health and energy regenerate.

Depending on the skills a player uses, they can choose to generate extreme DPS or go with extreme damage mitigation, but will run out of energy and in the worst case gain or lose aggro with no energy to change there current focus.

That’s basically it, players have to coordinate their role changes with others in the party, changes aren’t instantaneous, so it requires a level of skill.

How do you differentiate classes in such a system? well you’ve got the obvious visual differences, Dodge vs Shield vs Magic etc. You can still use mechanics like the WoW rogue action points or the slight variation that Rift uses for Warriors. In addition if you look at what we are trying to do here it’s have the group manage a shared pool of energy/health throughout an encounter, so there is no reason that you can’t have skills that trade them between players. The 0 point of the attributes and the strength of forces could also be changed per class. I think that gives enough leeway for class uniqueness.

What about solo PVE? that pretty much amounts to DPS vs Damage Mitigation and the use of counters none of which are precluded by a change in core group mechanics.

And PVP? This is much harder because there is to way to manage threat with players, but it’s true of pretty much every other MMORPG game anyway, you kill the healers first, then it becomes a game of numbers. At least here the roles aren’t predefined and can change in battle. As to 1 on 1 PVP I think it’s close to impossible to balance a game for it with any substantial class variation.

There are almost certainly a lot of other core mechanics that could achieve compelling group play without the split by role mechanic. It requires designers to not start with the premise that MMORPG == Holy Trinity. Unfortunately I suspect that’s easier said than done.

One last thought, possibly the hardest part of all of this would be selling new mechanics to existing MMORPG players, there is a reason most new MMORPG’s follow in the WoW mold, and it’s because wondering too far from it alienates your player base.

Monday, January 18, 2010

3D- as in Stereo

I've been somewhat facinated with Stereo images for a long time, I owned one of the very first vomit inducing entertainment oriented VR headsets. Although I'll admit I didn't pay the $1000's the manufacturer originally asked for it.

With the sudden resurgence of 3D at CES, I started looking at NVidia's shutter glasses solution. NVidia came in and demo'd an early prototype of the Viewsonic monitor while I was working on Spore. I can go buy a 22 inch 120Hz Viewsonic monitor with the glasses for about $400, which doesn't seem unreasonable. I can buy the monitor alone for about $250 which is competitive with other 2 inch monitors. Then I looked at the price of a second set of glasses (just the glasses not the transmitter), $150 for an additional pair of shutter glasses seems obscene to me.

With HDMI 1.4 and the sudden popularity of 3D at CES, I suspect it won't be long before most panels are 120Hz and support input signals at that rate, so the cost of entry is going to be the cost of the N-Vision kit, NVidia needs to get the price down.

I'm a big fan of surround gaming, it really does add a lot more to games than you might first expect. I use a Matrox Tripple Head To Go (I wouldn't recomend it), and I've been considering "upgrading" (not sure it would actually be faster) to an ATI 5850 GPU hoping that eyefinity" resolves some of the setup pain. I must admit I'm intrigued by the 3D surround Demo NVidia did at CES, but I already own 3 24 inch monitors that I use for surround gaming, and the concept of replacing them with 3 new 22inch monitors and adding a second $300 video card is a little excessive even for me.

Stereo 3D really doesn't add much for the "hardcore" gamer, yes it's more immersive, but it usually makes it harder to play, and performance is reduced by Half because of the 2x rendering. So is it aimed at the less hard core player, if it is the cost of entry needs to drop, probably to less that $100.

Thursday, November 26, 2009

DX1 App Update - Macros should now work in more games

Download DX1 App

I've added support to use ScanCodes instead of VKey codes in macros. Macros that use ScanCodes will work in a wider variety of games. I've tested both timed and multikey macros in Dragon Age Origins where VKey macros do not work ScanCode macros do.

All your old macros should still work fine, you'll have to manually convert them to ScanCode macros if you want them to work in games that use DirectInput. By default all new macros are ScanCode macros.

This is a list of ScanCodes for most of the basic stuff - you'll need to convert them to decimal.

#define DIK_ESCAPE 0x01
#define DIK_1 0x02
#define DIK_2 0x03
#define DIK_3 0x04
#define DIK_4 0x05
#define DIK_5 0x06
#define DIK_6 0x07
#define DIK_7 0x08
#define DIK_8 0x09
#define DIK_9 0x0A
#define DIK_0 0x0B
#define DIK_MINUS 0x0C /* - on main keyboard */
#define DIK_EQUALS 0x0D
#define DIK_BACK 0x0E /* backspace */
#define DIK_TAB 0x0F
#define DIK_Q 0x10
#define DIK_W 0x11
#define DIK_E 0x12
#define DIK_R 0x13
#define DIK_T 0x14
#define DIK_Y 0x15
#define DIK_U 0x16
#define DIK_I 0x17
#define DIK_O 0x18
#define DIK_P 0x19
#define DIK_LBRACKET 0x1A
#define DIK_RBRACKET 0x1B
#define DIK_RETURN 0x1C /* Enter on main keyboard */
#define DIK_LCONTROL 0x1D
#define DIK_A 0x1E
#define DIK_S 0x1F
#define DIK_D 0x20
#define DIK_F 0x21
#define DIK_G 0x22
#define DIK_H 0x23
#define DIK_J 0x24
#define DIK_K 0x25
#define DIK_L 0x26
#define DIK_SEMICOLON 0x27
#define DIK_APOSTROPHE 0x28
#define DIK_GRAVE 0x29 /* accent grave */
#define DIK_LSHIFT 0x2A
#define DIK_BACKSLASH 0x2B
#define DIK_Z 0x2C
#define DIK_X 0x2D
#define DIK_C 0x2E
#define DIK_V 0x2F
#define DIK_B 0x30
#define DIK_N 0x31
#define DIK_M 0x32
#define DIK_COMMA 0x33
#define DIK_PERIOD 0x34 /* . on main keyboard */
#define DIK_SLASH 0x35 /* / on main keyboard */
#define DIK_RSHIFT 0x36
#define DIK_MULTIPLY 0x37 /* * on numeric keypad */
#define DIK_LMENU 0x38 /* left Alt */
#define DIK_SPACE 0x39
#define DIK_CAPITAL 0x3A
#define DIK_F1 0x3B
#define DIK_F2 0x3C
#define DIK_F3 0x3D
#define DIK_F4 0x3E
#define DIK_F5 0x3F
#define DIK_F6 0x40
#define DIK_F7 0x41
#define DIK_F8 0x42
#define DIK_F9 0x43
#define DIK_F10 0x44
#define DIK_NUMLOCK 0x45
#define DIK_SCROLL 0x46 /* Scroll Lock */
#define DIK_NUMPAD7 0x47
#define DIK_NUMPAD8 0x48
#define DIK_NUMPAD9 0x49
#define DIK_SUBTRACT 0x4A /* - on numeric keypad */
#define DIK_NUMPAD4 0x4B
#define DIK_NUMPAD5 0x4C
#define DIK_NUMPAD6 0x4D
#define DIK_ADD 0x4E /* + on numeric keypad */
#define DIK_NUMPAD1 0x4F
#define DIK_NUMPAD2 0x50
#define DIK_NUMPAD3 0x51
#define DIK_NUMPAD0 0x52
#define DIK_DECIMAL 0x53 /* . on numeric keypad */
#define DIK_F11 0x57
#define DIK_F12 0x58

#define DIK_F13 0x64 /* (NEC PC98) */
#define DIK_F14 0x65 /* (NEC PC98) */
#define DIK_F15 0x66 /* (NEC PC98) */

#define DIK_KANA 0x70 /* (Japanese keyboard) */
#define DIK_CONVERT 0x79 /* (Japanese keyboard) */
#define DIK_NOCONVERT 0x7B /* (Japanese keyboard) */
#define DIK_YEN 0x7D /* (Japanese keyboard) */
#define DIK_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */
#define DIK_CIRCUMFLEX 0x90 /* (Japanese keyboard) */
#define DIK_AT 0x91 /* (NEC PC98) */
#define DIK_COLON 0x92 /* (NEC PC98) */
#define DIK_UNDERLINE 0x93 /* (NEC PC98) */
#define DIK_KANJI 0x94 /* (Japanese keyboard) */
#define DIK_STOP 0x95 /* (NEC PC98) */
#define DIK_AX 0x96 /* (Japan AX) */
#define DIK_UNLABELED 0x97 /* (J3100) */
#define DIK_NUMPADENTER 0x9C /* Enter on numeric keypad */
#define DIK_RCONTROL 0x9D
#define DIK_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */
#define DIK_DIVIDE 0xB5 /* / on numeric keypad */
#define DIK_SYSRQ 0xB7
#define DIK_RMENU 0xB8 /* right Alt */
#define DIK_HOME 0xC7 /* Home on arrow keypad */
#define DIK_UP 0xC8 /* UpArrow on arrow keypad */
#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */
#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */
#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */
#define DIK_END 0xCF /* End on arrow keypad */
#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */
#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */
#define DIK_INSERT 0xD2 /* Insert on arrow keypad */
#define DIK_DELETE 0xD3 /* Delete on arrow keypad */
#define DIK_LWIN 0xDB /* Left Windows key */
#define DIK_RWIN 0xDC /* Right Windows key */
#define DIK_APPS 0xDD /* AppMenu key */

Tuesday, November 24, 2009

DX1 macro problems - Dragon Age Origins

I've been playing Dragon Age Origins and I noted that macros don't work in the app. They work fine in WOW and Torchlight. After a little research I think it's likely that DAO is using DirectInput to read the keyboard.
Apparently SendInput does do the right thing with DirectInput, but you have to use scan code instead of virtual keycodes. My guess would be sending Scan codes with Send Input inserts them earlier in the OS's input chain.
I've recieved email from a couple of people with similar problems in apps I don't run.
If I can get VS2008 installed on my new machine I'll try the change over the weekend and push out a fixed app.

Tuesday, July 21, 2009

Linux/Open and open source software...

About once every 12 months I take one of my machines and install various Linux/BSD distributions, mostly because I have a soft spot for UNIX like OS's. Pretty much every time I go through the same set of things that end up with me turning the machine off and leaving it off. It's usually a combination of hardware incompatibilities and poor development tools.

This time however I had an agenda, I wanted to re purpose the machine in question as a media player, the original plan was to install XBMC and be done with it.

OK so I go grab the latest Ubuntu disks, install it, which I have to say was extremely pain free. I install the xbmc package, and play a video, unfortunately it doesn't appear to respect the timer and plays the video very quickly with skipping audio. Hmmmmmm, so I dig around on various boards, the general consensus is it's a pulse audio issue, what's odd is that mplayer doesn't display the issue. OK I remove pulse from my system and try again, same thing. Hmmmmm, I decide to try it with the NULL sound driver to verify it's actually audio and the video plays at the correct speed.

I figure maybe it's a fixed issue, so I pull down the latest build via svn, rebuild XBMC, same issue.

In a fit of frustration I install Fedora and have more or less the same issues. I start looking at the video player inside XBMC, discover what a massive app it actually is. All I want is something basic that lets me browse videos from my server and play them.

So I decide screw it, I wonder what it actually takes to write a video player using some of the open source components all the others seem to leverage. the answer turns out to be not very much the ffmpeg libraries provide most of the infrastructure, and it's relatively easy to get something up and running in a day or so. I did have some issues with the libswscale library, it has a bug where by it incorrectly swaps pixels when it's doing a 1:1 scale and isn't using the MMX routines, but I could patch that locally (I'd submit a fix, but it looks to me like the original author very much intended it to do what it's doing, and I have no idea why).

OK so all's well that ends well?

Not really at some point I decided to take my basic video player and use OpenGL to put the pixels on the screen, all of a sudden I have this issue where I get repeating sound fragments, and since I'm syncing video to the audio clock choppy video.

My first thought was the audio thread starving, but for that to happen the app would have to be eating all the CPU and it's not.

I discover that as I make the target widow smaller it stops being an issue, I know it's not a rendering related issue though, because if I remove the clocksync and just let the video run, it runs faster, so I'm not limited by drawing pixels. So I waste a lot of time looking at various aspects of my code ruling them all out.

So I come up with a new theory, the audio driver is missing interrupts when the onboard video is busy for extended periods. To test my theory I try subdividing the single large polygon I'm using for display into 1024 small polygons and miraculously the issue goes away. Even doing a glClear is sufficient for the issue to return.

So now I'm at a loss, I can't easily establish if this is a hardware issue, or a driver issue, and if it's a driver issue, if it's a video driver or an audio driver problem, or even a chipset driver issue.

FWIW I believe it's an audio driver issue, I've tried the code with both an A2DP sound driver and I've put in an external sound card, and as long as I'm not using the internal sound card (NVidia MCP51) the issue doesn't present. I've tried setting various driver options with modprobe without success.

So I'm left with ignore the issue and just leave the sound card in there (which irritates me because it should work). Or start digging through the ALSA driver code which I really don't want to do.

Ugh!