# ProjectOrbiter MMU (oMMU) development thread

#### gattispilot

The best way I found to stop terrain eating the MMU was to set the touchdown points much larger than the physical footprint of the MMU, doing that avoided the terrain in most cases.

However my intention was / is to move away from touchdown points entirely, and update the vessel position directly through SetState - though that has enough problems on its own.
Oh. I can adjust the y axis so there is no space between the bottom and the top of the surface. I notice that some building at Brighton are actually above the surface also.

##### Scientist
Is there still the problem with missing runtimes, or is it fully late-binding now? I think the later would also be a "feature" to mention, given the middle-ware nature of WooMMU.
Yup- as Enjo said, it's fully late bound now. You have a single include into a client, to put, get, find things from MMExt. If MMExt is not installed, you get an error status on the put, but nothing crashes (i.e. no Error 126). How is this done? Embedded into the header implementation is the helper code to do a LoadLibrary (to find and load the MMExt2.dll), and the the GetProcAddress calls (to find and load each internal function call). All data transfers across the dynamic call interfaces are multi-version code safe for C++. (How? Generally by serializing to C buffers, with a large-buffer mode to malloc and free if the string is >64 chars (unlikely), and then the header code converts back into a std::string in the context of the client's version of VC++. This was from bitter experience between Enjo and me passing from old versions of VC++ to newer ones, and finding that the binary compatibility is absolutely not to be trusted!).

Oh and static links for the VC runtimes, so no 126's there either. It's a clean piece of code and heavily battle-tested.

#### gattispilot

The best way I found to stop terrain eating the MMU was to set the touchdown points much larger than the physical footprint of the MMU, doing that avoided the terrain in most cases.

However my intention was / is to move away from touchdown points entirely, and update the vessel position directly through SetState - though that has enough problems on its own.

Not familiar with SetState. So a larger touchdown area? I would think a smaller so that it is more precise?

Playing around with a guy that moves

#### Urwumpe

##### Not funny anymore
Donator
Hello, any news here?

#### Abloheet

Would it be possible to release a beta version of this project for the community to test?

#### Woo482

##### Moderator
Moderator
GFX Staff
Sorry, life got in the way - I'll see what condition things are in and see if I can get a release of some sort out.

#### Samuel Edwards

##### Clever title.
Moderator
Sorry, life got in the way - I'll see what condition things are in and see if I can get a release of some sort out.
Life has a nasty habit of doing that. Thanks for all the work you have done so far and are doing to bring back such a critical part of the Orbiter experience.

#### gattispilot

Any news? I can help if needed.

#### Woo482

##### Moderator
Moderator
GFX Staff
Sorry for the slow reply, there's two major blocking issues at the moment (I think, it's been a while since I worked on it properly :facepalm that have stopped any real progress

Firstly is implementing the EVA ground movement, I have a basic implementation using AddForce to get them to slide around on the ground but that really doesn't hold up very well, especially with time acceleration - Ideally movement would be implemented by setting the vessel status and updating the position on the surface but the math involved there for the vessel orientation matrix is apparently way over my head and I've not managed to get it working smoothly :lol:

Secondly is having a set of crew models to ship with the add-on, 3D modelling isn't my forte (You've all seen my mars rover!) if anyone would like to contribute a set of meshes that'd be a big help.

#### Urwumpe

##### Not funny anymore
Donator
Firstly is implementing the EVA ground movement, I have a basic implementation using AddForce to get them to slide around on the ground but that really doesn't hold up very well, especially with time acceleration - Ideally movement would be implemented by setting the vessel status and updating the position on the surface but the math involved there for the vessel orientation matrix is apparently way over my head and I've not managed to get it working smoothly :lol:
Well, I would say, you need a "middle-ware" library that does that kind of math for you, because I am VERY sure, you are not the only one who feels that way.

#### Woo482

##### Moderator
Moderator
GFX Staff
Well, if someone wants to make one you'll have a user in me :lol:

#### gattispilot

On the movement can you just change the lat and long of the guy. Change the heading....

Code:
if (FORWARDgear==1)//MOVING FORWARD
{
if (i3 < 0){//LEFT TURN
d_hdg = d_hdg + .00001;//rate of steering change of heading
vs2.surf_hdg -= d_hdg;
//sprintf(oapiDebugString(), "turn %d  SURFHDG %2.2f", i3,  vs2.surf_hdg);
if (vs2.surf_hdg<0){ vs2.surf_hdg += 2 * PI; }
rot += 0.005;//animation axle wheel turn rate
if (rot > .125) rot = .125;
}
if (i3 > 0){//RIGHT TURN
rot -= 0.005;//animation axle wheel turn rate
if (rot < -.125) rot = -.125;
d_hdg = d_hdg + .00001;//rate of steering change of heading
vs2.surf_hdg += d_hdg;
//sprintf(oapiDebugString(), "turn %d SURFHDG %2.2f", i3,  vs2.surf_hdg);
if (vs2.surf_hdg>2 * PI){ vs2.surf_hdg -= 2 * PI; }
}
if (i3 == 0) {// straight so straighten wheels
// sprintf (oapiDebugString (), "turn %2.2f cos %2.2f sin %2.2f", TURN_proc, cosTurn, sinTurn );
if (abs(rot) <= 0.005) rot = 0;
else if (rot < 0) rot += 0.005;
else if (rot > 0) rot -= 0.005;
d_hdg = 0;
}
if (TURN_proc == 0){//wheels are straight so move with heading
d_lat = (targetSpeed*oapiGetSimStep()*cos(vs2.surf_hdg) / each_deg);
d_lng = (targetSpeed*oapiGetSimStep()*sin(vs2.surf_hdg) / each_deg);
}
else {//wheels are not straight so move no matter the heading move to the left forward
d_lat = (targetSpeed*oapiGetSimStep()*(cosTurn*1) / each_deg);
d_lng = (targetSpeed*oapiGetSimStep()*(sinTurn*1) / each_deg);

}

//sprintf(oapiDebugString(), "turn %2.2f cos %2.2f sin %2.2f lat %2.2f lng %2.2f", TURN_proc, cosTurn, sinTurn, d_lat, d_lng);

}
My issue was trying to get the guy created in the airlock and not in the center of the vessel

#### Woo482

##### Moderator
Moderator
GFX Staff
I have tried that, it seems to result in the vessel just spinning on the ground:
The code used is:
Code:
oid oMMU_MMU::doGroundMovement(double deltaT)
{
VESSELSTATUS2 vs;
memset(&vs, 0, sizeof(vs));
vs.version = 2;
GetStatusEx(&vs);

double degrees = (planetRadius * 2 * PI) / 360;

// Calculate the new latitude of the vessel
double newLat = vs.surf_lat + ((yVelocity * deltaT) / planetRadius) * (180 / PI);
if (newLat > 90)
newLat = 90;
else if (newLat < -90)
newLat = -90;

// Calculate the new longitude of the vessel
double newLong = vs.surf_lng + ((xVelocity * deltaT) / planetRadius) * (180 / PI) / cos(vs.surf_lat * (PI / 180));
if (newLong > 179.9999)
newLong = -179.9999;
else if (newLong < -179.9999)
newLong = 179.9999;

/* Update the vessel status struct */
vs.surf_lat = newLat;
vs.surf_lng = newLong;
vs.surf_hdg = 0.0; // Fixed heading for testing
DefSetStateEx(&vs);
}
I'm sure I'm missing something insanely obvious, but I've not managed to spot what yet :facepalm:

#### gattispilot

Code:
void LER2016::MoveAround(){
memset(&vs2, 0, sizeof(vs2));
vs2.version = 2;
GetStatusEx(&vs2);
double sinTurn = sin(2 * PI * TURN_proc);
double cosTurn = cos(2 * PI * TURN_proc);
if (FORWARDgear==1)//MOVING FORWARD
{
if (i3 < 0){//LEFT TURN
d_hdg = d_hdg + .00001;//rate of steering change of heading
vs2.surf_hdg -= d_hdg;
//sprintf(oapiDebugString(), "turn %d  SURFHDG %2.2f", i3,  vs2.surf_hdg);
if (vs2.surf_hdg<0){ vs2.surf_hdg += 2 * PI; }
rot += 0.005;//animation axle wheel turn rate
if (rot > .125) rot = .125;
}
if (i3 > 0){//RIGHT TURN
rot -= 0.005;//animation axle wheel turn rate
if (rot < -.125) rot = -.125;
d_hdg = d_hdg + .00001;//rate of steering change of heading
vs2.surf_hdg += d_hdg;
//sprintf(oapiDebugString(), "turn %d SURFHDG %2.2f", i3,  vs2.surf_hdg);
if (vs2.surf_hdg>2 * PI){ vs2.surf_hdg -= 2 * PI; }
}
if (i3 == 0) {// straight so straighten wheels
// sprintf (oapiDebugString (), "turn %2.2f cos %2.2f sin %2.2f", TURN_proc, cosTurn, sinTurn );
if (abs(rot) <= 0.005) rot = 0;
else if (rot < 0) rot += 0.005;
else if (rot > 0) rot -= 0.005;
d_hdg = 0;
}
if (TURN_proc == 0){//wheels are straight so move with heading
d_lat = (targetSpeed*oapiGetSimStep()*cos(vs2.surf_hdg) / each_deg);
d_lng = (targetSpeed*oapiGetSimStep()*sin(vs2.surf_hdg) / each_deg);
}
else {//wheels are not straight so move no matter the heading move to the left forward
d_lat = (targetSpeed*oapiGetSimStep()*(cosTurn*1) / each_deg);
d_lng = (targetSpeed*oapiGetSimStep()*(sinTurn*1) / each_deg);

}

//sprintf(oapiDebugString(), "turn %2.2f cos %2.2f sin %2.2f lat %2.2f lng %2.2f", TURN_proc, cosTurn, sinTurn, d_lat, d_lng);

}

lng = vs2.surf_lng;
lat = vs2.surf_lat;
hdg = vs2.surf_hdg;

DefSetStateEx(&vs2);
return;
}
This is what I use to move the LER2016. You can ignore the TURN proc that was for moving at angle while not changing the heading.

Works. But not sure how to change the vessels altitude using vs2?

---------- Post added at 08:03 PM ---------- Previous post was at 05:14 PM ----------

Give this guy a try:

keypad 8 forward and 2 backward, 1/3 turns

Last edited:

#### gattispilot

Thanks. Yes I need it to change the heading separate from moving forward. I can move the guy my issue was creating and or deleting the guy in a certain area aka airlock

#### Woo482

##### Moderator
Moderator
GFX Staff
Looks like the rotation matrix stuff you have for setting the arot of the VESSELSTATUS2 struct is what I was missing. If you're wanting to I can probably get an alpha of oMMU to you to integrate with your LER in the next week or two - I've graduated now so I have some free time to catch up with things and finally get it finished :lol:

#### gattispilot

yes thanks. I need to tweak that code. Really not sure if that matrix is needed. But it worked. Some was needed to adjust the pitch and roll for a vehicle but a guy would always be straight up

---------- Post added 07-23-19 at 05:37 AM ---------- Previous post was 07-22-19 at 09:25 AM ----------

So I got the guy to turn smoothly. But only when not moving. Not sure why though. I think it is in here but it looks good
Code:
int NewUmmu::clbkConsumeDirectKey(char *kstate) {

FORWARDgear = 1;
REVERSEgear = 0;
neutralgear = 0;

return 0;
}

FORWARDgear = 0;
REVERSEgear = 1;
neutralgear = 0;

return 0;
}
turnvalue =  0.001;

return 0;
}
turnvalue =  - 0.001;

return 0;
}
FORWARDgear = 0;
REVERSEgear = 0;
neutralgear = 0;
turnvalue = 0;
return 0;
}
It is like when pressing one key the other keys don't register?

#### JMW

Sorry but still the same for me.
Only turns with NumPad 8 and 3 or 1 pressed together.
Still turns too fast....?