Phidgets – Using Phidgets in UDK

By | 06/09/2010

Using Phidgets in Unreal Development Kit

Introduction

This tutorial will show you how to use Phidgets within UDK. Phidgets are low cost USB sensor and control units for the PC. They allow your game to control objects in the real world such as servo motors and LCD screens, and also allow the real world to control your game through sensors such as vibration sensors and Radio Fequency ID tags (RFID Tags). For a full list of the sensors see the phidgets website www.phidgets.com.

Phidgets can be easily used with a range of languages including C++. C# Flash, Flex, MATLAB and Java, have a look at the programming resources here.

Be warned. This tutorial is fairly detailed and only takes you through setting up one type of phidget, the 3-axis accelerometer. Although the code for most phidgets follows roughly the same pattern in terms of defining handlers, opening and closing, there are variations across the phidgets, so I’ve tried to explain the logic, rather than just tell you what to copy and past, as you will need to understand the logic of the API if you want to use other phidgets in UDK.

A Problem & Solution 

The Phidget drivers do provide you with a DLL file (32bit and 64bit), created in standard C, which allows access to the phidgets from any language which can link to a C based DLL. UnrealScript provides the DLLBind command, which in theory should be able to link directly to this DLL and provide direct access to the phidgets from within UnrealScript. Unfortunately, I had all sorts of problems trying get this DLL to work with UnrealScript, so I decided to created my own DLL based on C++ which works fine in UnrealScript. This also gave me more control over how the phidgets communicate with UnrealScript. For example, RFID tags output their ID number as an array of bytes (unsigned chars) which are not as easy to remember so I find it easier to work with my own unique integers. I found it a lot easier to convert the array of bytes into integers within the DLL, rather than passing the byte data from the DLL to UnrealScript and then processing the byte data it in UnrealScript.

So, you could try using the phidget21.dll supplied with the phidget drivers, and DLLBind() within UnrealScript, but this tutorial will show you the DIY approach, which will give you more flexibility in the long run. I also learned a heck of a lot going through this process, which will hopefully save you a lot of time. 

The Tutorial 

This tutorial will walk you through how to create your own C++ DLL for UnrealScript and how to access the phidgets from within UnrealScript. 

You Will Need

  • UDK
  • Latest phidget drivers from here: http://www.phidgets.com/drivers.php
  • Make sure you download the correct version for your system (32bit or 64bit). If using the 64bit version, this also comes with 32bit versions of the phidget library, which you will need later. This tutorial will assume you are using the 64bit version.
  • Visual Studio 2008 Professional (I am still using 2008 as I know it works, I’m sure the express edition will work as well).
  • An accelerometer phidget (the phidget code follows a similar logic for many of the phidget’s, so you will be able to adjust the following tutorial for most phidget’s)

 

A – Phidget Setup

Download and install the latest drivers, link is provided above.

You should now see the phidget manager icon  in the Windows Taskbar. This is the Phidget Manager application which allows you to communicate with the phidgets. This application must be running whenever you want to use a phidget. If you do not see this icon, select the Phidget Control Panel shortcut in the Phidget group in the Start menu.
Double click the manager icon to open the application. You will see a list of phidgets currentl attached to the PC.

 

 

 

Double clicking on a phidget entry will start up a test application so you can check out the features of the phidget.
Using windows explorer, have a look in C:\Program Files\Phidgets. Some important file to be aware of are:
 
  1. Phidget21Manager.exe – This is the Phidget Control Panel application.
  2. Phidget21.h – This header file will provide your C or C++ application with phidget functionality.
  3. Phidget21.lib – Also required when we create the DLL project.
  4. Phidget21.dll – the standard C based DLL which I could not get working in UnrealScript. If you do get it working let me know!
Now have a look in the C:\Program Files\Phidgets\Examples folder. Here you will find a set of example applications which you can use to test each phidget, these can also be accessed by double clicking a phidgets entry in the manager application, see step 2 above.
That’s it for setting up the phidgets. The next step is creating a C++ DLL so we can.
 

B – Download the C/C++ Code

Go to the following link http://www.phidgets.com/programming_resources.php and from the C/C++ section download the “Code Sample”. You may also want to download the API Refence and the “Getting Started Guide”.
This will provide you with a series of .c files which we will copy and past into our new DLL.

C – Prepareing the C++ DLL

This part will assume you are using Visual Studio 2008 Professional, although I’m sure visual Studio Express will work as well.

In Visual Studio select FILE | NEW | PROJECT  

Select “Visual C++” as the Project Type then select “Win32 Console Application” in the Templates section, see below.
 

Enter a name for the DLL, for example “UDKphidgets”. Then select a location to save the project. Click OK

  • Click NEXT in the project wizard
  • Select DLL in the APPLICATION TYPE
  • Uncheck all the other options and click FINISH, as below

 

d

 

The new project will open up and you will have a project structure like this:

 

We will only be working in the UDKPhidgets.cpp file, we don’t need to touch anything else. The main aim is to copy the code from one of the example files we downloaded in section B above, for the required phidget, into our new UDKPhidgets.cpp file and make a few small changes in order to allow the code to work with UnrealScript.
Next we need to add in the Phidget21.h which we looked at back in step A3, into our project, so we have access to all the phidget functionality. In Windows Explorer, navigate to C:\Program Files\Phidgets copy Phidget21.h then paste it into your project directory, in the same location as UDKphidgets.cpp.
This next step assumes you are using the 64bit version of the drivers. Navigate to C:\Program Files\Phidgets\x86 and copy phidget21.lib and paste this into your project directory, in the same location as UDKphidgets.cpp. Do not copy the version of this file which is in C:\Program Files\Phidgets, we need the x86 version.
 
In the Solution Explorer window in Visual Studio, expand the HEADER FILES folder to view the contents. Right click on the folder name and select ADD | EXISTING ITEM. Navigate to the project folder and select the Phidget21.h. Now right click on the REOURCE FILES folder and select Phidget21.lib. A custom build windows will appear, just click NO. Your project structure should look like this:

 

Now add a reference to this header file and another header. In UDKphidgets.cpp add the following lines if the are not already present: underneath:

1
#include "stdafx.h" #include "phidget21.h" #include <stdexcept>

To save a bit of typing use the std namespace. This will allow us to call functions in the std library without having to type std:: every time. It will also be more flexible if you decide to use other libraries inside the DLL. Read this if you are not familiar with namespaces. Add the following after the header files:

1
using namespace std;

 

D – The Sample Code

First I would recommend reading through the Phdiget Programming Manual, especially the section on Phidget API Copncepts, page 8 to 10. I will not repeat that section here, so I will assume you have read it through and understand the main concepts behind opening and closing phidgets, as well as event handlers.Lets have a look at the sample code you download in step B1. This tutorial is based on the accelerometer phidget, so we will look at the example Accelerometer-simple.c

The main structure of the this code is:

  • AttachHandler() – To react to the accelerometer being attached to the PC
  • DetachHandler() – To react to the accelerometer being detached from the PC
  • ErrorHandler() – To react to an error in the acceleromoeter
  • accel_AccelChangeHandler() – To react to a change in the acceleromoter data which is greater than a specified threshold
  • display_properties() – Prints the properties of the acceleromoeter to the command line
  • accelerometer_simple() – This is the main code which opens, processes and closes the phidgetmain() – this is the main entry point for the DLL, we are not interested in this.

 

If you browse through the other samples you will see that the code follows a very similar structure in each example. We are going to copy this code into our DLL, and only make a few slight changes, so if you are trying this with another phidget, use the sample code for that phidget in your DLL.

First we need to define the event handlers, as above. In the sample file, the attach event handler looks like this:

1
//callback that will run if the Accelerometer is attached to the computer   int AttachHandler(CPhidgetHandle IFK, void *userptr) {     int serialNo;       CPhidget_getSerialNumber(IFK, &serialNo);       printf("Accelerometer %10d attached!", serialNo);       return 0; }

In our DLL we need that function to look like this, exactly the same, but with the __stdcall convetion added and a accel_ prefix to the function name:

1
//callback that will run if the Accelerometer is attached to the computer, Note the __STDCALL convetion int __stdcall accel_AttachHandler(CPhidgetHandle IFK,  void  *userptr)   {     int serialNo;     CPhidget_getSerialNumber(IFK, &serialNo);     printf("Accelerometer %10d attached!  \n", serialNo);          return 0; }

__stdcall ensures that the standard calling convention for the Microsoft Win32 API is used, without this convention, the DLL will not compile. See this artcile on calling conventions. The accel_ prefix just distinguishes this attach handler from other attach handlers for other phidgets if you add them later.

For each of the four event handlers in Accelerometer-simple.c, copy the function into your DLL, and add the __stdcall convention before the function name and the accel_ prefix to the function name.

Now copy the following variable from the sample file and place it after the namespace line:

1
double past_samples[3];
Compile the project to check there are no errors.
If you receive a LNK2019 error, check you are using the phidget21.lib file from the C:\Program Files\Phidgets\x86  folder, and NOT the same file from C:\Program Files\Phidgets\.
We now need to declare a handle for the accelerometer. This is declared in the open() function in the sample file but we will declare it it at the top of our code so the handle is available to the three functions we will create which will read the acceleration data. Paste the following line after the past_samples line:
1
CPhidgetAccelerometerHandle accel = 0;

Next copy and paste the display_properties() function into your code, place it after accel_AccelChangeHandler. No changes are required to this function. This will simply output properties to the command line from Unreal, so we can see that the phidget is working.

Our DLL is going to expose five functions to the outside world:

  1. Open the accelerometer
  2. Get data from the X axis of the accelerometer
  3. Get data from the Y axis of the accelerometer
  4. Get data from the Z axis of the accelerometer
  5. Close the Acceleromoeter

 

The functions to define the event handlers in step 3 above do not need to be exposed outside the DLL.

To start, we need to define the names of any external functions so UnrealScript will be able to hook into the DLL. Copy the following code into UDKphidgets.cpp after the declaration of the accelerometer handle:

1
extern "C" __declspec( dllexport ) int accel_Open(void); extern "C" __declspec( dllexport ) double accel_GetX();  extern "C" __declspec( dllexport ) double accel_GetY();  extern "C" __declspec( dllexport ) double accel_GetZ(); extern "C" __declspec( dllexport ) int accel_Close();

First, create the open() function. Add the following code after the display_properties() function:

1
int accel_Open() {   }

This method will be available from outside the DLL as we have defined it as an extern, in the previous step.

Copy all the code between the curly brackets in the open() method in the sample file, and paste it into the above empty method. We now need to make a few adjustments.

From the code you have just pasted in, remove the following, as we have already declared this handler higher up in the code:
1
//create the accelerometer object CPhidgetAccelerometer_create(&accel);

I removed the following lines, but you can keep them. 

1
//read accelerometer event data printf("Reading.....\n");

Remove the following. We do not want the player pressing a key in Unreal in order to get the accelerometer working. We will place the closing statements in their own method, so we can call a separate close event from within UnrealScript.

1
//wait until user input is read printf("Press any key to end\n"); getchar();   //since user input has been read, this is a signal to terminate the program so we will close the phidget and delete the object we created  printf("Closing...\n"); CPhidget_close((CPhidgetHandle)accel); CPhidget_delete((CPhidgetHandle)accel);

Add the accel_ prefix to event handlers within the new open() method, so

  • AttachHandler becomes accel_AttachHandler
  • DetachHandler becomes accel_DetachHandler
  • ErrorHandler becomes accel_ErrorHandler
  • AccelChangeHandler becomes accel_AccelChangeHandler

 

We will now create a method to read the acceleration data on the x axis of the acceleromoeter. Add the following code after the open() method:

1
double accel_GetX() {     //Define a temp variable to hold the acceleration       double cur_accel;          //Set acceleration to 0 in case the following call fails     cur_accel = 0;          //Find the acceleration of the x axis (2nd parameter) of the current accelerometer     CPhidgetAccelerometer_getAcceleration(accel, 0, &cur_accel);          // Print a debug line     printf("ACCELERATION IN X AXIS FROM DLL : %lf\n", cur_accel);          //Return the x axis acceleration     return cur_accel; }

The above code is using the CPhidgetAccelerometer_getAcceleration() method, this is not in the sample file, but more info on this and other methods for each specific phidget can be found in the documentation on the phidget’s website. The second parameter of this method is the axis number where:

0 = x axis

1 = y axis

2 = z axis

When called this method will return the current acceleration data on the x axis. This method will be available from outside the DLL as we have defined it as an extern, in the step 8 above.

Now copy and paste this code to create similar methods for the Y and Z axis. Remember to change the 2nd parameter of CPhidgetAccelerometer_getAcceleration() and use the same method names as declared in step 8 with the accel_ prefix. Also change the comment line which acts as a debug statement. You can remove this later.

Using the same closing statements as in the sample file, create a method to close the phidget’s, paste this code to the bottom of the page.:

 

1
int accel_Close() {     printf("ACCELEROMETER Closing\n");          CPhidget_close((CPhidgetHandle)accel);     CPhidget_delete((CPhidgetHandle)accel);          //all done, exit     return 0; }

Finally, compile the code and check for errors.  If all is well, you will find the DLL in the debug folder in the project folder.

 

Over to UDK

Now that we have out DLL,we need to copy it across to UDK. Place the DLL in the following folder inside the UDK installation: \Binaries\Win32\UserCode

we need to setup Unreal Script to call these methods. In this example, we will control a rolling sphere with the accelerometer. I will assume you are using the Unreal Frontend application to compile and run your scripts.

I will assume you are familiar with setting up UnrealScript and a suitable IDE, as well as the language itself.  I will assume you know how to do this and are ready to add the code into your own custom classes. Please make sure you understand the above tutorials, otherwise the following steps will just not work.

In your custom package in the Development\Src folder create a new .uc file called accel_KActorSphere.uc and add the following code into it, the comments in the code will explain whats happening:

1
// Create a subclass of KActorSpawnable so the actor can be influenced by phisics // ie the force we will apply from the accelerometer // NOTE the DLLBind directive, this links to our new DLL class PhidgetKActorSphere extends KActorSpawnable placeable DLLBind(UDKphidget);   // Declare all the imported phidget dll functions dllimport final function int accel_Open(); dllimport final function float accel_GetX(); dllimport final function float accel_GetY(); dllimport final function float accel_GetZ(); dllimport final function int accel_Close();   // Before Playe begins, open the acceleromoeter simulated function PreBeginPlay() {     //Declare local variables     local int result;           //Call parent method     super.PreBeginPlay();          // Open the accelerometer using the new phidget DLL     result = accelOpen();          // Define the time period between each call to the timer method     // Data from the accelerometer will be retrieved each     // time the timer method is called     SetTimer(0.1, true);          // Turn on the physics     StaticMeshComponent.WakeRigidBody(); }   // Close the accelerometer when the object is destroyed simulated function Destroyed()  {     local int result;          // Close the acceleromoter     result = accelClose(); }   function Timer()  {     // Declare local variables     local float xAccel;     local float yAccel;     local float zAccel;  // We will not use the Z axis, but defined here in case you need it     local Vector vectForce;          // Get the acceleration from each axis (from the new Phidget DLL) and mulitply each         // value by 100 so that it is high enough value to affect the sphere     xAccel = accelGetX();     xAccel = 100.0 * xAccel;     yAccel = accelGetY();     yAccel = 100.0 * yAccel;     zAccel = accelGetZ();         zAccel = 100.0 * zAccel;               // Add the acceleration forces into a vector variable         vectForce.x = xAccel;         vectForce.y = yAccel;         vectForce.z = 0;    // Do not use the z axis as we just want the ball to roll around the floor              // Apply the vector force to the sphere        StaticMeshComponent.AddForce(vectForce); }   // These are the Default properties of the sphere defaultproperties {     Begin Object Class=StaticMeshComponent Name=StaticMeshComponent01              StaticMesh=StaticMesh'SH_Package.TestObjects.SH_Mesh'         bNotifyRigidBodyCollision=true         HiddenGame=TRUE         ScriptRigidBodyCollisionThreshold=0.001                 LightingChannels=(Dynamic=TRUE)                 DepthPriorityGroup=SDPG_Foreground       End Object          Components.Add(StaticMeshComponent01)          Begin Object Class=StaticMeshComponent Name=StaticMeshComponent02              StaticMesh=StaticMesh'SH_Package.TestObjects.SH_Mesh'                 HiddenGame=TRUE                CollideActors=TRUE                 BlockActors=FALSE                 AlwaysCheckCollision=TRUE                 RBCollideWithChannels=(Default=TRUE, BlockingVolume=TRUE, GameplayPhysics=TRUE, EffectPhysics=TRUE, FracturedMeshPart=FALSE)              End Object            Components.Add(StaticMeshComponent02) }

Save the scripts and use the Unreal Frontend to compile and check for errors

Lets move over to the editor now. In the Unreal Editor add the sphere to the level by selecting the Generic Browser, then Actor Classes tab, select Actor | DynamicSMActor | KActor | KActorSpawnable | PhidgetKActorSphere. Then right click on the map somewhere and select Add PhidgetKActorSphere here.

Download my test sphere object in its own package here. Place this in the UDKGame\Content\TestPackages folder. Load up the Generic Browser and select the Content Browser Tab, navigate to the SH_Package | TestObjects package and select the SH_Mesh object in the Content Browser. This is the sphere which we willadd to the level and control with the accelerometer.

In the editor window, select the new sphere and press F4 to view the properties and expand DynamicSMActor | Static Mesh Component | Static Mesh Component | Static Mesh entry. Click the Use Selected Object in Content Browser icon . This will paste a link to the SH_Mesh sphere into this property. The sphere is ready to go !

Close the editor and use the Unreal Frontend to launch the game. You should see the sphere in the level, small rotations of the accelerometer will move the sphere.

If you are having problems, you can debug with the ‘log() statement in UnrealScript and with the printf() statement in the DLL. Both will output to the log window which you can switch on in the UnrealFrontend (the ‘Show Log’ option in the PC pane of the game tab.

Leave a Reply

Your email address will not be published.