Xbox rumble test (Please be gentle ;) )

Post anything about MX Simulator here. Please. I'm begging you.
cpt_Slow
Posts: 683
Joined: Sat Dec 15, 2007 5:58 pm
Team: Privateer
Contact:

Xbox rumble test (Please be gentle ;) )

Post by cpt_Slow »

Thought I might as well show my horrible coding skills :P Basically I wanted to try and implement proper force feedback to try and simulate riding a real bike, but figured coding that would be far too complex considering I have never programmed in C++ before :oops: and of course I'd have to build a compatible controller first. So I decided to try a simple rumble at first, to try and find my feet. So a few video tutorials later, some reading up and some nice advice from JLV, I came up with a VERY rough rumble, which when the source code is analysed will probably be deemed unsuitable for human consumption so to speak. :P Anyway, basically it takes three samples from the streaming output, compares the x,y,z positions of the camera at each snapshot of time and approximates an acceleration. I really didn't like my method of approximating acceleration but couldn't think of another simple way....it's open to suggestions ;) Then finds the magnitude of the overall acceleration, and sort of roughly translates this to a rumble value for the motors on the controller. One of the motors is the tingly vibration and the other is the cluncky vibration. I wanted to make it so that forward acceleration was tingly, and any other acceleration and deceleration was clunky, but I'd need to use the angles etc for that and I wanted to make sure I was on the right lines first so for now it feels kind of random.

Anyway this is the code

Code: Select all

#include "CXBOXController.h"
  #include <iostream>
#include <stdio.h>
#include <cmath>

using namespace std;
CXBOXController* Player1;
int main()
{
    char one[500];
	char two[500];
	char three[500];
	
	int i = 0;
    
	double x1 ;
	double x2 ;
    double x3 ;
	double y1 ;
	double y2 ;
	double y3 ;
	double z1 ;
	double z2 ;
	double z3 ;
	double t1;
	double t2;
	double t3;

	double a;
	double ax;
	double ay;
	double az;
	double number;
	
	int v1 = 0;
	int v2 = 0;
  Player1 = new CXBOXController(1);


  do
 {  
fgets(one, 500, stdin);
 sscanf (one,"%*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG ", &t1, &x1, &y1, &z1);

 fgets(two, 500, stdin);
 sscanf (two,"%*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG  ", &t2, &x2, &y2, &z2);
 
 fgets(three, 500, stdin);
 sscanf (three,"%*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG  ", &t3, &x3, &y3, &z3);

 

ax = (((x2-x3)/(t3-t2))-((x1-x2)/(t2-t1)))/(t3-t1)*10;
ay = (((y2-y3)/(t3-t2))-((y1-y2)/(t2-t1)))/(t3-t1)*10;
az = (((z2-z3)/(t3-t2))-((z1-z2)/(t2-t1)))/(t3-t1)*10;
number=pow(ax,2)+pow(ay,2)+pow(az,2);
a= sqrt(number);


	if(ax<0)
	{ v1=a*20;
	}
	else
	{ v2=a*20;
	}
 Player1->Vibrate(v1,v2);
  ;
 }
 
while (i==0) ;
 cin.get();
  return( 0 );
}

The controller class was shamelessly copied from this tutorial: http://www.codeproject.com/KB/directx/x ... input.aspx

Feedback is what I'm after really (excuse the pun :P) as I know this is probably terrible coding, and is it worth continuing? I'm not going to post the executable until somebody has verified that it won't crash somebody's system. :P
cpt_Slow
Posts: 683
Joined: Sat Dec 15, 2007 5:58 pm
Team: Privateer
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by cpt_Slow »

Just updated a bit, I've toned down the effect and put a failsafe if the final integer exceeds the maximum acceptable value of the controller. I noticed that sometimes it missed a couple of big landings which obviously should give the greatest shock, even after this failsafe...so I tried to get it to pick them up by adding a few do nothing loops...I assume this is bad practice? Is there a preferable way to make a short delay? Anyway, here's the updated code if anyone's interested..oh yeah I also got rid of my infinite loop I forgot ( I was just using it for testing) about and so now it closes when mxsim stops, or when you change to third person view.

Code: Select all

#include "CXBOXController.h"
  #include <iostream>
#include <stdio.h>
#include <cmath>



using namespace std;
CXBOXController* Player1;
int main()
{
    char one[500];
	char two[500];
	char three[500];
	
	
    int i = 500;
	double x1 ;
	double x2 ;
    double x3 ;
	double y1 ;
	double y2 ;
	double y3 ;
	double z1 ;
	double z2 ;
	double z3 ;
	double t1;
	double t2;
	double t3;

	double a;
	double ax;
	double ay;
	double az;
	double number;
	
	int v1 = 0;
	int v2 = 0;
  Player1 = new CXBOXController(1);


  do
 {  
fgets(one, 500, stdin);
 sscanf (one,"%*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG ", &t1, &x1, &y1, &z1);
 do 
 {i--;
 }
 while (i!=0);
 fgets(two, 500, stdin);
 sscanf (two,"%*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG  ", &t2, &x2, &y2, &z2);
  i=500;
 do 
 {i--;
 }
 while (i!=0);
 fgets(three, 500, stdin);
 sscanf (three,"%*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG %*c %*c %*c %LG  ", &t3, &x3, &y3, &z3);

 

ax = (((x2-x3)/(t3-t2))-((x1-x2)/(t2-t1)))/(t3-t1)*10;
ay = (((y2-y3)/(t3-t2))-((y1-y2)/(t2-t1)))/(t3-t1)*10;
az = (((z2-z3)/(t3-t2))-((z1-z2)/(t2-t1)))/(t3-t1)*10;
number=pow(ax,2)+pow(ay,2)+pow(az,2);
a= sqrt(number);


	if((a*15)>65536)
	{  v1=65536;
		v2=65536;
	}
	else if (az<0)
	{ v2=a*10;
	}
	else
	{
		v1=a*15;
		
	}
 Player1->Vibrate(v1,v2);
   i=1000;
 do 
 {i--;
 }
 while (i!=0);
  
 }
 
while (t3-t1>0) ;

v1=0;
	v2=0;
   
      
  return( 0 );
}
VMX_SKYmx99
Posts: 836
Joined: Sat Feb 09, 2008 9:51 pm
Team: BOMR
Location: San Francisco, CA

Re: Xbox rumble test (Please be gentle ;) )

Post by VMX_SKYmx99 »

Where do we put this?
Image
cpt_Slow
Posts: 683
Joined: Sat Dec 15, 2007 5:58 pm
Team: Privateer
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by cpt_Slow »

Sorry, this is just the source code for the main section of the application, you would need to compile it and run from a pipe using the command window for it to work. I didn't really want to post the executable until somebody had verified my source in case I got cries of viruses etc. I can send you the .exe with further details of how to use it in a pm if you like? Bearing in mind it only works for xbox 360 controllers and is FAR from perfect. :oops:
cpt_Slow
Posts: 683
Joined: Sat Dec 15, 2007 5:58 pm
Team: Privateer
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by cpt_Slow »

Actually I figure I might as well post it for those who want to use it, it's changed a bit since that last code (loops taken out, numbers adjusted) . This program goes into your mxsim INSTALL folder not the personal folder. Then in windows explorer navigate to your mxsim install folder and whilst holding shift...right click on any blank space inside the folder. Click "Open Command Window Here" when the window pops up type in "mx.exe --print-orientation | xboxtest.exe" start a race or time trial and you should have some form of rumble on your 360 controller. This only works in first person view and if you change to third person view it will actually stop working in first person until you restart. Also, pausing or navigating the menu will stop it working for now (it was either that, or having to end process every time sorry). I know it's a bit of a faff for a not so great outcome but I'd really appreciate it if somebody could test it out. I'm not sure why it still doesn't register some of the big landings, I'm thinking maybe it's a timing issue maybe :(

Anyway, here's a link of anyone feels like trying it out. http://www.mediafire.com/?wfyexy4cithsssq
Thanks :)
jlv
Site Admin
Posts: 14913
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by jlv »

I'd go with a structure more like this:

Code: Select all

struct position p[3];
double accel[3];
int i;

i = 0;

read_position(&p[i++ % 3]);
read_position(&p[i++ % 3]);

while (read_position(&p[i++ % 3])) {
   get_acceleration(accel, &p[(i - 3) % 3], &p[(i - 2) % 3], &p[(i - 1) % 3]);
   set_vibrate(accel);
}
The little 3 entry ring buffer would let you reuse the old positions so you can get an acceleration value for every position instead of 1 acceleration value for every 3 positions. Probably not a big deal since with 128 updates per second you're still updating 42 times per second, but it seems a little cleaner to me.

Here are a couple of other nitpicks:

Why not a simpler scanf format string like this?
sscanf(two,"t=%lf p0=%lf p1=%lf p2=%lf", &t, &x, &y, &z);

It looks like you have some time delay loops in there. Even if that works, which is unlikely, it will waste CPU time. If you're trying to delay, use Sleep(milliseconds). You shouldn't need to delay though since the input will control the timing.
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
cpt_Slow
Posts: 683
Joined: Sat Dec 15, 2007 5:58 pm
Team: Privateer
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by cpt_Slow »

jlv wrote:
The little 3 entry ring buffer would let you reuse the old positions so you can get an acceleration value for every position instead of 1 acceleration value for every 3 positions. Probably not a big deal since with 128 updates per second you're still updating 42 times per second, but it seems a little cleaner to me.
I understand the concept you're suggesting, but I don't really understand the code you've posted, sorry. :oops: I tried to do something similar myself, albeit in a more long winded and less elegant way than yourself. But if I have three elements in an array p[3] and I am doing calculations using p, p[i-1], p[i-2]...how would I get it so that when i was 0 or 1...the negative values referred to the corresponding positive elements....if that makes sense? :P

eg: I want p[2]-p[1] when i = 2 and p[0]-p[2] when i=0
so p-p[i-1] would work if I could get the numbers to loop somehow?

jlv wrote: Why not a simpler scanf format string like this?
sscanf(two,"t=%lf p0=%lf p1=%lf p2=%lf", &t, &x, &y, &z);


I was searching for ages to find something like that, I honestly didn't know you could do that with sscanf.....thanks. I knew it was pretty clumsy the way I was doing it haha.
jlv wrote: It looks like you have some time delay loops in there. Even if that works, which is unlikely, it will waste CPU time. If you're trying to delay, use Sleep(milliseconds). You shouldn't need to delay though since the input will control the timing.

Yeah I got rid of those pretty quickly, they didn't seem to do anything like you said. I thought maybe taking less samples would help the issue with missing some of the big landings. I actually tried Sleep first, but it seemed to lag mxsim pretty badly for some reason.
I've also fixed the fact I put 65536 instead of 65535 now.
Anyway, I realise this forum isn't a C++ class with me as a student, so I'l keep on trying to read up and try and work out what you've written. :P

Thanks for looking at it though, I really appreciate it.
Sandhapper
Posts: 1267
Joined: Sat Jul 10, 2010 9:21 am
Team: MotoRAD
Location: The Nederlands

Re: Xbox rumble test (Please be gentle ;) )

Post by Sandhapper »

I would like to test it for you. I have try your mediafire link, but when i type in mx.exe --print-orientation | xboxtest.exe in the Command Window but then the game strats up, i get an error that it cant find the dll (I dont know wich dll, have to do it all again). Do i something wrong?
I realy like this idea!;)

Sand.
2013 EMF outdoors 2nd place overall
2013 MxSCentral outdoors 2nd place overall
2012 EMF outdoors 2nd overall
2012 SMA sx 2nd overall
2011 SMA outdoors champion

Image
cpt_Slow
Posts: 683
Joined: Sat Dec 15, 2007 5:58 pm
Team: Privateer
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by cpt_Slow »

Thanks for the interest. Not sure what could be causing that problem as I don't think this app relies on any dlls. I'll link you to the latest version anyway...this time I included a batch file so you should be able to extract xboxtest.exe to your mxsim install folder and put mx.bat on your desktop...double clicking mx.bat should load up mxsim with the rumble. (Although this depends on your operating system, if it doesn't you can either open up the .bat file with notepad and edit the directory path, or use the command line again.) Anyway, hope this one works and thanks again for trying it out.
http://www.mediafire.com/?v6ar4dd74aouk0j
yzmxer608
Posts: 15352
Joined: Mon Dec 29, 2008 4:30 am
Team: SYS
Location: Wisconsin, U.S.A

Re: Xbox rumble test (Please be gentle ;) )

Post by yzmxer608 »

Tried it, it didn't work for me but when I close mxs my controller started vibrating and wouldn't stop until I closed the cmd :lol:.
TeamHavocRacing wrote:If I had a nickel for every time someone asked for this, I would have a whole shitload of nickels.
yzmxer608
Posts: 15352
Joined: Mon Dec 29, 2008 4:30 am
Team: SYS
Location: Wisconsin, U.S.A

Re: Xbox rumble test (Please be gentle ;) )

Post by yzmxer608 »

Never mind, I tried it a few more times and it worked properly. Some of the big hits (like overjumping a jump) don't feel like it vibrates hard enough, but other places feel like it vibrates too much. It might just be because it's something you're not used to, you normally play this game with no feedback, but now when you do you're not sure how it's going to react. It's cool but I don't think you'll be able to use it for long periods of time otherwise your hands might go numb.
TeamHavocRacing wrote:If I had a nickel for every time someone asked for this, I would have a whole shitload of nickels.
jlv
Site Admin
Posts: 14913
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by jlv »

cpt_Slow wrote:I understand the concept you're suggesting, but I don't really understand the code you've posted, sorry. :oops: I tried to do something similar myself, albeit in a more long winded and less elegant way than yourself. But if I have three elements in an array p[3] and I am doing calculations using p, p[i-1], p[i-2]...how would I get it so that when i was 0 or 1...the negative values referred to the corresponding positive elements....if that makes sense? :P

eg: I want p[2]-p[1] when i = 2 and p[0]-p[2] when i=0
so p-p[i-1] would work if I could get the numbers to loop somehow?

That's why you use the modulus operator % to limit the index to 0-2. In the example I posted, after the first 3 reads "i" will be 3. So on the first loop it will call get_acceleration() with these array indices:
(3-3)%3 = 0, (3-2)%3 = 1, (3-1)%3 = 2


On the next loop, with "i" == 4, it will be this:
(4-3)%3 = 1, (4-2)%3 = 2, (4-1)%3 = 0

On the next loop, with "i" == 5, it will be this:
(5-3)%3 = 2, (5-2)%3 = 0, (5-1)%3 = 1

As you can see, it will continue to circle around the buffer with the last three positions in (i-3)%3, (i-2)%3 and (i-3)%3. (Actually it will overflow after running for about 6 months. You could do "i=(i%3)+3;" every once in a while if you wanted to run forever.)
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
cpt_Slow
Posts: 683
Joined: Sat Dec 15, 2007 5:58 pm
Team: Privateer
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by cpt_Slow »

No I know exactly what you mean, I thought the same thing but no I definitely think it need to react more to the big hits. I've been playing around with the numbers and tried to give more weighting tovertical accleration but it didn't really help that much. I'm not sure if it's because it's pulling the values from the actual camera position or if it's the program's fault but it's definitely not right. :( As for it not working initially I'm not sure what that would be sorry, always started up fine for me. The vibration could sometimes stick on even after closing the app when I was first testing it but it shouldn't happen now....if it does though try opening xboxtest.exe on it's own and hit return a few times until it stops. Thanks for the feedback though yzed I'll try and work on it, maybe start by toning everything down.

To JLV, I actually tried it with the modulus operator in place, but it made no difference, when referring to what would be element -1 it gave a value of 1.06e-306 or something similar. :S I'm on my phone right now but when I get back on my pc I'll have another look at what you've posted and hopefully I can improve what I've got. Again, thanks for taking the time to explain to an eager if slightly useless listner haha.
jlv
Site Admin
Posts: 14913
Joined: Fri Nov 02, 2007 5:39 am
Team: No Frills Racing
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by jlv »

On most C/C++ platforms (might be all, I'm not sure what the standard says) a negative number divided by a positive number will truncate towards 0 and have a negative remainder. So -1 % 3 is -1. You need to make sure it doesn't go negative. In my example it never subtracts enough from "i" to make it go negative.
Josh Vanderhoof
Sole Proprietor
jlv@mxsimulator.com
If you email, put "MX Simulator" in the subject to make sure it gets through my spam filter.
JB323
Posts: 1967
Joined: Sat Sep 12, 2009 9:26 pm
Team: Privateer Life
Location: Arizona
Contact:

Re: Xbox rumble test (Please be gentle ;) )

Post by JB323 »

id like to see this tweak and set along the compression of the suspension along with the strength of vibration. It would be nice to mirror every pump of the forks with a small kick in the rumble instead of a full cycle of it if that make sense.
Image

Privateer Life # 323 Support from Motosport | Race Tech | 180 Decals

http://instagram.com/jbolen323/
Post Reply