• Welcome to PiBoSo Official Forum. Please login or sign up.
 

The Lumberbar/MCCC/M300/M301

Started by Chris_Beeves, May 06, 2019, 09:07:40 pm

Previous topic - Next topic

Chris_Beeves

The second prototype I made was made for DS1 mode (torque). It is all explained in my first post here I think. No ffb was planned for that one, only adjustable resistance from the GPBikes plugin depending on a number of factors.

After seeing Marcel's video (and his advice) I switched to ffb and DS2.  Now I just use the load cells for brakes.

With a better implementation of DS1 in the game I think prototype 2 would have worked fine though. :)
I had to try..

Chris_Beeves

Found out that I have access to Visual Studio Enterprise, so today I started looking at writing the example .dlo for my knee rumblers.

The function I want from the .dlo is receiving the lean angle and sending it to an Arduino via serial port.
Receiving the lean angle seems simple enough (just copy the example code), but everything with the serial port handling makes it a bit complicated.
Especially since I have never seen Visual Studio until today  ;D

I have no idea what I am doing so far, but with enough trials and errors I guess I will get there in time..
This is what I have come up with so far. In my naive mind I just need to figure out the magic word that makes the .dlo spit out telemetry data through the (hopefully) opened serial port:


#include<windows.h>
#include <stdio.h>

/*
If compiled as C++, extern "C" must be added to declaration of functions to export

X+ is right, Y+ is top and Z+ is forward.
*/


extern "C" __declspec(dllexport) char* GetModID()
{
return "gpbikes";
}

extern "C" __declspec(dllexport) int GetModDataVersion()
{
return 8;
}

extern "C" __declspec(dllexport) int GetInterfaceVersion()
{
return 9;
}

/******************************************************************************
structures and functions to receive data from the simulated bike
******************************************************************************/
extern "C" typedef struct
{
int m_iRPM; /* engine rpm */
float m_fEngineTemperature; /* degrees Celsius */
float m_fWaterTemperature; /* degrees Celsius */
int m_iGear; /* 0 = Neutral */
float m_fFuel; /* liters */
float m_fSpeedometer; /* meters/second */
float m_fPosX, m_fPosY, m_fPosZ; /* world position of a reference point attached to chassis ( not CG ) */
float m_fVelocityX, m_fVelocityY, m_fVelocityZ; /* velocity of CG in world coordinates. meters/second */
float m_fAccelerationX, m_fAccelerationY, m_fAccelerationZ; /* acceleration of CG local to chassis rotation, expressed in G ( 9.81 m/s2 ) and averaged over the latest 10ms */
float m_aafRot[3][3]; /* rotation matrix of the chassis. It incorporates lean and wheeling */
float m_fYaw, m_fPitch, m_fRoll; /* degrees, -180 to 180 */
float m_fYawVelocity, m_fPitchVelocity, m_fRollVelocity; /* degress / second */
float m_afSuspLength[2]; /* shocks length. meters. 0 = front; 1 = rear. */
float m_afSuspVelocity[2]; /* shocks velocity. meters/second. 0 = front; 1 = rear */
int m_iCrashed; /* 1 = rider is detached from bike */
float m_fSteer; /* degrees. Negative = right  */
float m_fThrottle; /* 0 to 1 */
float m_fFrontBrake; /* 0 to 1 */
float m_fRearBrake; /* 0 to 1 */
float m_fClutch; /* 0 to 1. 0 = Fully engaged */
float m_afWheelSpeed[2]; /* meters/second. 0 = front; 1 = rear */
int m_aiWheelMaterial[2]; /* material index. 0 = not in contact */
float m_fSteerTorque; /* Nm */
int m_iPitLimiter; /* 1 = pit limiter is activated */
int m_iECUMode; /* 0 = engine mapping; 1 = traction control; 2 = engine braking */
char m_szEngineMapping[3];
int m_iTractionControl;
int m_iEngineBraking;
int m_iAntiWheeling;
int m_iECUState; /* bit field. Bit 1 = TC active; bit 2 = engine braking active; bit 3 = antiwheeling active */
} SPluginsBikeData_t;

/* called when software is started */

extern "C" __declspec(dllexport) int Startup(char* _szSavePath)
{
/*
return value is requested rate
0 = 100hz; 1 = 50hz; 2 = 20hz; 3 = 10hz; -1 = disable
*/
return 3;

int main()
{
HANDLE hComm;
hComm = CreateFile("\\\\.\\COM24", //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write   
0, // No Sharing                               
NULL, // No Security                             
OPEN_EXISTING, // Open existing port only                     
0, // Non Overlapped I/O                           
NULL); // Null for Comm Devices

if (hComm == INVALID_HANDLE_VALUE)
printf("Error in opening Serial port");
else
printf("\nopening serial port successful\n");

DCB dcbSerialParams = { 0 }; // Initializing DCB structure
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

Status = GetCommState(hComm, &dcbSerialParams);

dcbSerialParams.BaudRate = CBR_9600; // Setting BaudRate = 9600
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT; // Setting StopBits = 1
dcbSerialParams.Parity = NOPARITY; // Setting Parity = None

SetCommState(hComm, &dcbSerialParams);

COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50; // in milliseconds
timeouts.ReadTotalTimeoutConstant = 50; // in milliseconds
timeouts.ReadTotalTimeoutMultiplier = 10; // in milliseconds
timeouts.WriteTotalTimeoutConstant = 50; // in milliseconds
timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
}
}

/* called when software is closed */
extern "C" __declspec(dllexport) void Shutdown()
{
int main()
{
HANDLE hComm;

CloseHandle(hComm); //Closing the Serial Port
return 0;
}
}


Any input on this would be very much appreciated!

Until next time..  :o
I had to try..

HornetMaX

Try to look at existing libraries for low-level stuff like handling of serial ports, it's always easier.
For a past project, I used this: https://www.teuniz.net/RS-232/

Chris_Beeves

Great tip! Thanks!

Looks a fair bit simpler than the standard windows stuff.
I had to try..

Chris_Beeves

Still waiting for the motor driver board to make the first prototype.. Somebody is probably swimming the package over to Sweden from the UK.
I have a holiday coming up in two weeks so hopefully I'll get some time to get it running.
Can't wait to have a working rig so I can play again soon!
I had to try..

Chris_Beeves

Well, some good news is that I got my motor drivers! :D
Bad news, they were damaged..
Good news, I fixed them!

Bad news, I can't seem to get the encoder working on the Arduino Leonardo.. On the Uno it works perfect, but the Leo, no..
So I'm kind of stuck trying to find out what the problem might be..
The different FFB programs I have tried for the Arduino Leonardo won't recognize it either.

Probably a good thing since I need to be focusing on my studies at the moment! Hard though, when this is so much more interesting..
I had to try..

Chris_Beeves

VOILA!!

Ran the encoder through my new 5€ Arduino oscilloscope and saw that the signals made much more sense when running the board on 3,3V instead of 5V.


So now it seems like I have almost all the components I need in order to build a working prototype! :D
All I need now is some connection from the motor to the steering axle.
I'm thinking belt drive, but with the ratio I want (something like 1:15) it would require quite a large pulley on the steering axle..
I had to try..

TimboC137

very nice. can't wait to see it in action.

maybe you could use a few pulleys to step up the ratio instead of one large pulley. something like this maybe....

https://www.aliexpress.com/item/32341085661.html?spm=2114.search0104.3.22.12e1641dkza1ww&ws_ab_test=searchweb0_0%2Csearchweb201602_4_10065_10068_10130_10547_319_10059_10884_317_10887_10696_321_322_10084_453_10083_454_10103_10618_10307_10301_10821_537_536%2Csearchweb201603_52%2CppcSwitch_0&algo_expid=6ee7440b-41c9-4bd8-93ca-e5b7cd338d45-3&algo_pvid=6ee7440b-41c9-4bd8-93ca-e5b7cd338d45&transAbTest=ae803_5

Chris_Beeves

Quote from: TimboC137 on May 31, 2019, 06:18:12 pmvery nice. can't wait to see it in action.

maybe you could use a few pulleys to step up the ratio instead of one large pulley. something like this maybe....


I know! Me neither!! ;D
(Damn you, lack of time)

I thought about that too, and probably it is the only choice I have.
I wanted to avoid it, since it doesn't only add cost but also takes space and makes the FFB less "direct"..

Since using a BLDC or stepper motor (super expensive drivers) is out of the question, I'm going to have to use a high gear
ratio to get high torque. Even a large 350W e-bike motor is 3000rpm, and since I will only be using 50 degrees of movement, I won't have the need for that kind of speed. A 1:30 ratio on that kind of a motor would probably be fast enough and that would give me about 30Nm of stall torque :O
If I don't gear it I think I'm just going to burn motors.
I had to try..

Chris_Beeves

I have been experimenting a bit with The Arduinos and decided to rip out the internals of the Logitech wheel and try to replace them.

Bought an Arduino Pro Micro, which is pretty much a tiny Leonardo, off eBay and I already had motor driver boards.
The wheel has an optical encoder, similar to the one I already tested, so I wanted to see if I could get it working with the Arduino.
It worked like a charm, so I decided to try switching out the "motherboard".

I wanted to see how the resolution and force feedback feeling would be. It was a huge step up! Feels like the original hard/software is on power save mode, not doing much work unless it really has to. The new brain has much less of a weak center, and reacts much quicker! Plus, I can tweak the ffb effects a bit.
All this I managed to do without cutting a single wire, so it is fully restorable.



After using the Pro Micro,  replacing the little breadboard with a smaller soldered version and resoldering the capacitor and all connectors of the motor driver to the bottom of the PCB, I could even get the cover on! This is so much fun..

Now I have to reassemble the handlebar controls again, I want to try this with GPB!
I had to try..

Chris_Beeves

Redesigning the clutch and throttle at the moment. I now use a hall sensor inside the clutch handle instead. The wire was a pain. :)
I'm also trying to convert the throttle from potentiometer to hall sensor. My first 3D-printed prototype had some issues, so I'm designing v2 now..

Will be testing a brushless setup for ffb soon as well , but I'm not too confident it will work. A fun experiment though :)

I had to try..

Gav

Quote from: Chris_Beeves on October 26, 2019, 12:53:57 pmRedesigning the clutch and throttle at the moment. I now use a hall sensor inside the clutch handle instead. The wire was a pain. :)
I'm also trying to convert the throttle from potentiometer to hall sensor. My first 3D-printed prototype had some issues, so I'm designing v2 now..

Will be testing a brushless setup for ffb soon as well , but I'm not too confident it will work. A fun experiment though :)



You can use an ebike throttle if you want a ready made solution for the throttle as these use a hall effect sensor and work perfectly. They are also very cheap.

Chris_Beeves

Quote from: Gav on November 08, 2019, 08:43:20 amYou can use an ebike throttle if you want a ready made solution for the throttle as these use a hall effect sensor and work perfectly. They are also very cheap.

Yeah, that would absolutely work. I'm having fun making my own though, so that is plan b.
I had to try..

Chris_Beeves

Actually got an e-bike throttle for free, so I guess I'll use that one for now.. :)

I have had some time lately, so a little progress has been made. Bought some bearings and a motor. I need to 3D-print som bearing holders and the big pulley to be able to build a first real prototype.
Sketched it up:
I had to try..