Talk about Head Mounted Displays (HMDs), augmented reality, wearable computing, controller hardware, haptic feedback, motion tracking, and related topics here!
Well since this is a IO software polling is a Necessity, the question is if we should abstract that with a Event model (All events are triggered from som kind of polling in every system )
I really dont see why we cant add this at any given point? This weekend i will write a little POC (Proof of concept) with Lua, that will give us a good idea whats possible with Lua and C#
Im done with the POC, LUa will work very well for our needs.
IT was very easy to work with, this little test took under 15 minutes to write, including reading the reference manual!
If you wanna try it out, see my attachment, please note that this is just a proof of concept.. the code will not be used for the real product
using System;
using System.Linq;
using System.Threading;
using LuaInterface;
namespace LuaInterfaceTest
{
class Program
{
public interface IOPlugin
{
string GlobalName { get; }
object CreateGlobal();
}
public class Mouse : IOPlugin
{
public string GlobalName
{
get { return "mouse"; }
}
public object CreateGlobal()
{
return new Global();
}
private class Global
{
private float x;
private float y;
private Random rand;
public Global()
{
rand = new Random();
}
public float getX()
{
x = x + rand.Next(-100, 100) / 100f;
return x;
}
public float getY()
{
y = y + rand.Next(-100, 100) / 100f;
return y;
}
public void setX(float x)
{
this.x = x;
}
public void setY(float y)
{
this.y = y;
}
}
}
public class Diagnostic
{
public void Debug(string debug)
{
Console.WriteLine(debug);
}
}
static void Main(string[] args)
{
using(var luaEngine = new Lua())
{
//The loading of the plugins will be somthing like this, but in this test i only load plugins in this assembly
var types = typeof (Program).Assembly.GetTypes().Where(t => t.IsClass && typeof (IOPlugin).IsAssignableFrom(t));
foreach(var type in types)
{
var plugin = Activator.CreateInstance(type) as IOPlugin;
luaEngine[plugin.GlobalName] = plugin.CreateGlobal();
}
luaEngine["diagnostic"] = new Diagnostic();
luaEngine["starting"] = true;
var script = @"
if (starting) then
--do stuff first loop
end
yaw = mouse:getX()
pitch = mouse:getY()
diagnostic:debug(""Yaw: ""..yaw.."" Pitch: ""..pitch);
";
var startup = true;
while (true)
{
luaEngine.DoString(script);
if(startup)
{
luaEngine["starting"] = false;
startup = false;
}
Thread.Sleep(5);
}
}
}
}
}
You do not have the required permissions to view the files attached to this post.
Thanks CyberVillain, I'll take a look at it a bit later. We should consider moving this to SourceForge (or similar). The forum guys are going to get bored pretty quickly if the code geeks start doing code reviews here.
Done even more googling and testing, Lua isnt threadsafe so if we choose a event model the events have to be triggered on the Lua thread (Each plugin can still have their own polling thread)
Well I kind of like Oliver, but if it were spelled: OliVR
Or .DIE (DOT DIE) since its a Device Input Emulator written with .NET
Also, can we just take over the OpenPIE project? Doesn't look like they are doing anything with it. All they did was make a sourceforge page like 5 years ago and never committed jack. I say we just use the name.
I think OliVR is clever but it doesn't really fit this product well. We should save that name for something more deserving.
I think stealing OpenPIE is a pretty good idea. It's not like they have a copyright. Can we just take administrative control of the SourceForge project or do we need to create a new project somewhere?
Edit: Just thought of OPIE (pronounced o-pee). Not sure if that's any better than OpenPIE. Tends to make me think of Ron Howard.
CyberVillain wrote:Im done with the POC, LUa will work very well for our needs.
IT was very easy to work with, this little test took under 15 minutes to write, including reading the reference manual!
If you wanna try it out, see my attachment, please note that this is just a proof of concept.. the code will not be used for the real product
That's pretty slick. I haven't looked at LUA but it does seem to fit nicely. I wonder if it can handle C# accessors instead of functions so you could have syntax like "yaw = mouse.X". My guess is "no", but that would make it easier to port GlovePie scripts. Maybe you could use just use member variables to get that syntax?
CyberVillain wrote:Done even more googling and testing, Lua isnt threadsafe so if we choose a event model the events have to be triggered on the Lua thread (Each plugin can still have their own polling thread)
Not really sure what you mean by this? It doesn't look like LUA runs in its own thread - just the thread that calls luaEngine.DoString()
CyberVillain wrote:Done more testing, a plugin can implement an event driven model
They have supplied a wrapper for C# events.. all yo have todo in Lua
That's not really what I had in mind anyway. I would think the event callbacks would go in the IOPlugin classes. Something sort-of like this...
public class MyDevice:IOPlugin, DeviceInterface {
Device D = new DeviceAPI();
int x = 0;
public int X {
get {
// the device and LUA parser must synchronize access to this value
lock(this) {
return x;
}
}
}
void OnDeviceChanged() {
// this function gets called by the device thread
lock(this) {
x = D.GetX();
}
}
}
//
// Maybe now the LUA script can use "x = device.X" to get the value in a thread-safe / event-driven way ?
//
CyberVillain wrote:Im done with the POC, LUa will work very well for our needs.
IT was very easy to work with, this little test took under 15 minutes to write, including reading the reference manual!
If you wanna try it out, see my attachment, please note that this is just a proof of concept.. the code will not be used for the real product
That's pretty slick. I haven't looked at LUA but it does seem to fit nicely. I wonder if it can handle C# accessors instead of functions so you could have syntax like "yaw = mouse.X". My guess is "no", but that would make it easier to port GlovePie scripts. Maybe you could use just use member variables to get that syntax?
If you prepend the LUA script with some LUA for .NET stuff i think you can have it access properties (Saw some examples for it somewhere)... Will have to look into it later..
brantlew wrote:
CyberVillain wrote:Done even more googling and testing, Lua isnt threadsafe so if we choose a event model the events have to be triggered on the Lua thread (Each plugin can still have their own polling thread)
Not really sure what you mean by this? It doesn't look like LUA runs in its own thread - just the thread that calls luaEngine.DoString()
Yeah, i mean the thread that LUA runs in the host program...
brantlew wrote:
CyberVillain wrote:Done more testing, a plugin can implement an event driven model
They have supplied a wrapper for C# events.. all yo have todo in Lua
That's not really what I had in mind anyway. I would think the event callbacks would go in the IOPlugin classes. Something sort-of like this...
public class MyDevice:IOPlugin, DeviceInterface {
Device D = new DeviceAPI();
int x = 0;
public int X {
get {
// the device and LUA parser must synchronize access to this value
lock(this) {
return x;
}
}
}
void OnDeviceChanged() {
// this function gets called by the device thread
lock(this) {
x = D.GetX();
}
}
}
//
// Maybe now the LUA script can use "x = device.X" to get the value in a thread-safe / event-driven way ?
//
Yeah, well, my original plan was pretty much exactly like that but it doesnt work. You have to lock everything that LUA can access (Because Luas state machine isnt thread safe)... Which i think is a too big trade off both in "clean code" and performance..
A big problem we need to solve is to detect which plugin dependencies a script has, we cant load them all because we dont want unnecessary background threads running collecting data we do not need..
Doesn't look like Lua supports it out of the box, the bruteforce way of doing it is to not add any plugins to the Lua engine, let the script crash, parse the error message for the name of the missing plugin, add it, run script again and so on.. This is ugly, plus if the scrip is complex with if-cases,switch-cases, while loops etc it will be hard to cover all execution paths...
edit: Maybe the easiest way if to just parse the script.. If we constraint our implemention to that globals has to be objects with methods and not just loose functions
example:
diagnostics:debug("foo")
instead of just debug("foo")
the first example is eeasilty parsed, a bit sad that we have to do it ourself though....
edit again: On a second thought.. its not very easyily parsed.. consider this..
you have two plugins, TrackIR and FreeTrackIR (Just an example)
if(FreeTrackIR:getX > 0) then
..code
end
a simple regex will return both above plugins.. Theres a bit of plumbing todo to get it right. But its not impossible... I whished the Lua engine fixed this instead
There are only 4 guys commenting at this point and we have 3 votes for FreePIE so that's a majority. FreePIE it is! Why don't we start an open source project somewhere and continue the low level discussions over there.
I've never worked on an open source project, so I don't really have any preferences or opinions about which service works best.
brantlew wrote:There are only 4 guys commenting at this point and we have 3 votes for FreePIE so that's a majority. FreePIE it is! Why don't we start an open source project somewhere and continue the low level discussions over there.
I've never worked on an open source project, so I don't really have any preferences or opinions about which service works best.
Me neither but I have used Github... I can upload a project with basic lineout...
That's fine with me. I don't know anything about GIT but I don't mind experimenting with it. I've heard that GitHUB is more friendly to work with (whatever that means).
A big problem we need to solve is to detect which plugin dependencies a script has, we cant load them all because we dont want unnecessary background threads running collecting data we do not need..
Just create a header section in the plugin that lists what dependencies it has, so that the engine can load them. Make it the problem of the script coder, not the engine.
I just setup my Git account, but I'm troubled by the lack of an important feature. They don't have a project forum - WTF??? That really seems like a huge oversight on their part. So where does a team like us in the infant design stage go to discuss design? Here? This doesn't seem like the right place to discuss code design. Do we have to start a google group or something? Seems dumb that we can't have our project discussion right there on the project page like SourceForge.
Well they sort of have forum-like features sprinkled through the "pull requests" and issue tracking where you can have active discussions. It just seems weird that we would have to open an issue like "Initial Design" just to talk about the project.
Is it ok for you guys if we skip the GUI for a while? Only use Unittesting as a "GUI"?
I like testdriven development and I think we should aim for a high code coverage..
I've soon done with a basic shell for the API, it has lots of holes that needs filling, but its a good start.. I actually implemented a woring example, Freetrack.. The GUI is going to be a challange.. But I can put up a basic shell with WPF and Caliburn micro so we have something to work on..
I think we should just use this thread as our discussion (for design, etc.). Any non-technical people would have been scared off many pages ago. When we have something working, we can make a new thread for user feedback and comments. This is a developer's thread for now.
In terms of using different device libraries, can't we just initialize only the ones we need. I mean, obviously we will have to include all the relevant libraries for each device, but we do not have to initialize and poll for every device constantly. We could have a script pre-processor that checks which devices are used and then only load and poll those devices. Or we could do a more generic approach where all compatible devices are enumerated and then attached to a generic VR device proxy controller, and the script only accesses these proxy controllers. There should be a way, of course, to enable or set preference to which devices you wish mapped to which proxy controllers. Of course, you can down-cast the proxy to a particular device if you need device specific features. This way the same script could work for any type of 3DOF device (or greater), could be a Wiimote, could be Razer Hydra, could be a Sparkfun IMU, etc.
Are you still going to open a GitHUB project CyberVillain? They support a limited kind of forum discussion. Personally I would rather discuss technical details over there to avoid monopolizing the board here with a flood of largely ignored posts. Also, if we pick up other participants along the way outside of our little VR group it would help to have the design history documented in-place. We can still give milestone updates over here.
I've been holding my comments, but since we don't have a project site yet I'll go ahead and add a couple of technical comments.
I think we should definitely skip the GUI until we have a solid architecture and most of the popular devices implemented. I have no problem with it being a command line utility and writing scripts in notepad, and much of our target audience (tech geeks) can handle that as well. The GUI is a polishing step, and adds little value to the app.
Also regarding this:
CyberVillain wrote:Yeah, well, my original plan was pretty much exactly like that but it doesnt work. You have to lock everything that LUA can access (Because Luas state machine isnt thread safe)... Which i think is a too big trade off both in "clean code" and performance..
Please explain this a bit more. The link you supplied seems to be discussing that LUA functions are not reentrant. That doesn't surprise me or trouble me, because that is not what my pseudo-code example was doing. I was not calling into LUA functions from a device I/O thread. Instead it was just protecting against when the LUA thread called our device functions. Perhaps I don't understand LUA thoroughly enough. Why doesn't my code sample work?
I've been sitting for the last FOUR hours and trying to create and access a git repo at sourceforge.
I gave up, did it with SVN instead.. The code us up, i need your sourceforge names so i can add you... Download the code, look around at the basic architecture of things.. My company has a Mumble server (VOIP) we can use to talk about everything done so far.. Please do not commit anything until coding standards etc are communicated..
brantlew wrote:I am now "brantlew" on SourceForge as well.
Ok, you should have read/write access now...
I also created a forum so we can discuss over there aswell.. but as Cyber pointed out I think the none developer guys have moved away from this thread
Nope, still here! Don't have much to add but still intresting to see whats going on.
"If you have a diabolical mind, the first thing that probably came to mind is that it will make an excellent trap: how do you get off a functional omni-directional treadmill?"
I have another plugin idea.. A plugin that can hook into nvidia sterovision and change convergence and seperation settings... In BF3 for example you can then trigger on mouse right (Put the scope up for aiming) change the converge so that the scope is rendered at z = 0 and then when you release the button the converge goes back to what ever is optimum for the game... I have no idea if its possible, but it would be very, very cool