OHM Axial Velocity HUD v1.0 RC1

OrbitHangar

Addon Comments
Joined
Apr 9, 2008
Messages
3,832
Reaction score
18
Points
0
Not an MFD, but a HUD, this addon draws 3 gauges for velocities over ship's principal axes.It doesn't replace any original or vessel-specific HUDs, but rather enhances them, providing more data feedback to the pilot.This is primarily a rendezvous/docking/VTOL aid, where seeing axial speeds is quite important. Although you'll find it useful in many other situations.Compatible with most (but not all) vessels.Works both with panel view and virtual cockpit view. The default layout is adjusted for DGIV and XR-familiy spacecrafts, although the layout can be edited via config file.To install, simply unpack the zip into orbiter root. The addon does not replace any files.Be sure to read the documentation located in add-on docs/Axial Velocity HUD.txtSome screenshots:1 2 3 4 5 6

[ame=http://www.orbithangar.com/searchid.php?ID=3595]More...[/ame]
 
Very nice idea, very well made. The one small suggestion I have would to be able to turn in on/off inside orbiter without going back to the launchpad and deactivating the module.
Keep up the good work!
 
Very nice idea
Thanks, but the idea isn't mine, i'm afraid. There was a space sim called "Homeplanet" (circa 2003), one of the very few that had newtonian physics. You may have played freeware Babylon 5: I've Found Her that uses Homeplanet's game engine. The speed gauges were in the original game and I thought it would be nice to have those in Orbiter.

I have would to be able to turn in on/off inside orbiter without going back to the launchpad and deactivating the module.
Well, what should I do: add a secret Ctrl+Alt+Shift+Win+[key] combination or a make Yet Another MFD with a single on/off button? :) Honestly, it indeed occured to me that someone might want a way to turn it off, but I couldn't decide how exactly. Please, share you thoughts.
 
Well, firstly, well done! I'm going to install this asap and have a bit of a fiddle with it. Especially like it how you've decided against making this a MFD, and for taking the step into the realm of fiddling around with the hud, I congratualate and thank you.

And as for turning it on and off, I highly recomend using a simple, easy shortkey. It's important for users to be able to easily turn HUD stuff on and off, especialy when using the VC as it is especialy cramped.
 
Great work! I installed it last night and used it getting to the ISS with the XR2. The gauges are easier ot use than trying to center the docking MFD, or the velocity vector on the docking HUD. About the only thing I wish is that I could use it independently of another HUD, but that's just a minor thing that isn't really even a problem. I posted a good review on OH for it!
 
Thank you, guys! :cheers: Your feedback is very much appreciated. Actually, I didn't really expect 132 downloads in just 24 hours.

About the only thing I wish is that I could use it independently of another HUD, but that's just a minor thing that isn't really even a problem.
Yes, that can be done. I've already decided to add a configurable hotkey for turning on/off, and I guess I can add a feature to suppress drawing the original HUD as well. But this'll bring a 50/50 probability of a problem with LaunchMFD: its launch compass HUD may also become suppressed, depending on the order, in which the addons are listed in orbiter.cfg.

So here's what I plan for RC2:
  • I've already made the NAV marker to stick the the HUD edge and blink if the target is out of view (shot).

  • Add a hotkey for on/off and an option to include suppressing the original HUD to the loop: on(overlay)/on(solo)/off(draw original). Or maybe a separate hotkey.

  • Add a separate hotkey to toggle the NAV receiver for the target marker.

The docking HUD btw, is pretty minimalistic, IMO overlaying it with gauges doesn't add significant clutter.

Edit: Just forgot to ask. Could a native English-speaker please proof-read the documentation file, esp. the grammar (I have to admit, English punctuation is a weak spot of mine) and style.
 
Whoa! Slow down! I haven't even had a chance to try out the RC1!

Moving on to the documentation. I speek english very goodly! :P I'll have a look over them.


-----Posted Added-----


For a non-native English speaker, you've done a fair good job! The only thing that I picked up wasn't even an error, just something to improve for readability issues:

Axial Velocity HUD.txt:

left shows velocity over vertical axis, upper - for lateral axis and right -
for longitudal axis.

Perhaps the "upper - for" and "right - for" should be reworded to be the same as the statement about the left gauge?
 
I may have found a little bug. In DGIV, safe mode, power and hud turned off. HUD refuses to turn on. If the mission is saved with HUD on, every thing works fine. Can someone confirm this.
 
Well, what should I do: add a secret Ctrl+Alt+Shift+Win+[key] combination or a make Yet Another MFD with a single on/off button? :) Honestly, it indeed occured to me that someone might want a way to turn it off, but I couldn't decide how exactly. Please, share you thoughts.

You could make a window of your plugin, like eg. Scenario Editor, accessible with Ctrl+F4 with "a single on/off button", but at least it won't take limited custom MFDs space.

And please tell me how you get on with Launch MFD - if its compass gets disabled.
 
Hey, James, thanks for looking into it!

MajorTom,
I may have found a little bug. In DGIV, safe mode, power and hud turned off. HUD refuses to turn on. If the mission is saved with HUD on, every thing works fine. Can someone confirm this.
I can :). Yes, that's a bug and I already know why it happens. Right now you can simply switch to another vessel, then switch back and it should reapeear.

Enjo,
And please tell me how you get on with Launch MFD - if its compass gets disabled.
The funniest part is that it's not a complete suppression but rather a 50/50 probability. And the explanation is quite long:

Back during development I came up to a conflict with LaunchMFD. Vel_hud appeared to work fine just until I switch focus to another vessel, and then switch back to the first one. The debugger pops up with a stack overflow exception inside launchmfd.dll. What the hell??

I realized, that apparently I'm not alone that clever, and LaunchMFD does the hijacking too in order to draw its launch compass on the HUD. And as far as I could guess (I didn't know that LaunchMFD sources were available up until recently), the LaunchMFD does exactly the same thing as my addon - patches a new focus vessel's VMT in opcFocusChanged() while returning back the original address for the vessel that loses the focus.

It appears, Orbiter manages its addons by putting them in a kind of a list. When a simulation event happens, like the user changes ships, Orbiter calls opcFocusChanged() sequentially for all addons in the list. And the order of the sequence doesn't change.

So here's what happens (let's assume that opcFocusChanged() for LaunchMFD was called first):

1. LaunchMFD hijacks vessel's clbkDrawHUD() and replaces it with an impostor, saving the original address somewhere.
2. vel_hud hijacks LaunchMFD's impostor from the vessels VMT (thinking it's the original functions) and replaces it with its own impostor, saving the old value somewhere.

2.5. Orbiter calls vessel->clbkDrawHUD(). It calls into the vel_hud's impostor who calls the LaunchMFD's impostor (thinking it's the original) and LaunchMFD calls the actual original clbkDrawHUD().

2.9. All's fine until
3. user changes ships.

4. LaunchMFD returns the original address of clbkDrawHUD() to the old vessel's VMT.
5. vel_hud returns the LaunchMFD's impostor to the old vessel's VMT, happily thinking that it patches back the original function address. (This is because the opcFocusChanged() is called for each addon every time in the same order.)

6-9. User plays with a new vessel then
10. switches back to the old vessel.

11. LaunchMFD hijacks clbkDrawHUD(), but it's not real clbkDrawHUD(), it's already an impostor. And if you recall p.5, it's no one other than LaunchMFD's impostor! So it saves the impostor's address as the original.
12. vel_hud hijacks LaunchMFD's impostor and replaces it with its own impostor.

12.5. Orbiter calls vessel->clbkDrawHUD(). It calls into the vel_hud's impostor which in turn calls the LaunchMFD's impostor (thinking it's the original) and LaunchMFD tries to call the original clbkDrawHUD() through previously saved pointer. Except that now the saved pointer points to LaunchMFD's own impostor saved in p.11. Oops, infinite recursion(tm).
12.9. Oribiter crashes and burns with a stack overflow in LaunchMFD.

I repeated the experiment, but this time I put vel_hud on top of the list in orbiter.cfg, and voila! I got a HUD to disappear completely, narrowly avoiding the stack overflow just because I already had a simple check in place that tested for the recursion before restoring the VMT pointer and calling original function.

I resolved the issue by adding more kludges, like constant patching in opcPostStep() and re-patching back in vel_hud's clbkDrawHUD(). As we can see, it's not 100% perfect. If the HUD isn't drawn this frame for some (legitimate) reason -- things happen exactly as MajorTom described: no more HUDs.

Oh, and that 50/50 comes from the order in which the addons' opcFocusChanged() functions are called: the last one to hijack the VMT entry 11 gets everything.

So right now I'm trying to invent another "clever" hack that could solve the compatibility problem with LaunchMFD.
 
@Wraith, thanks for the in depth explanation. Some nice insights into the internal workings. Keep up the good work.
 
I should probably think of something clever too, but actually I'm not the HUD feature's author, so this could take some time.
 
Legacy Reviews

Legacy Add-on Reviews from Orbit Hangar Mods


Review by zatnikitelman
Pros: Easy to see, easy to use, love the logarithmic scale
Cons: Overlaps standard huds
Review:
This a neat addon. I was docking the newly released XR2 to the ISS last night and this HUD made it easier than trying to 0 out velocity with the docking MFD and docking HUD. About the only thing I didn't like was it overlaid the standard HUDs. I don't know if this is an Orbiter API limitation on unique HUDs and it's just a minor thing. Overall, GREAT TOOL!


Review by astrocam
Pros: Great Tool for docking, rendevous, etc.
Cons: Crashes, Lines on HUD could be a bit thicker
Review:
Overall a good tool, however i got quite a few crashes when using the default deltaglider... Anyway, adding an option to the HUD that enables raw text velocities (Like in the UMMU) instead/in addition to the sliders would be awesome. Keep up the good work.
 
As you've stated, the problem lies in that both your MFD and LaunchMFD hack the VMT. Both are essentially screwing around with bits of memory they shouldn't be playing with and as such, you lose the guarantee that it's going to work. As you've stated, at stage 2 vel_hud tries to hook the VMT, but the value that it reads from the VMT is already 'wrong', so there's no way that it can work properly from that stage on as the onhook methods don't get called in a useful way. Also, you can't read it in at the start of orbiter and hold the 'known' value of the 'correct' VMT entry as when you unhook one MFD, it will unhook all the others and no MFD's imposter callback will get called.

The only way that I can see forward for this (unless the next version of orbiter allows the MFD to draw to the HUD) is to have all MFDs that want to draw to the HUD use a common system (common code) to draw to the HUD and to stick to it. Essentially, only one hook is done via some shared Hook class or function and each MFD registers/deregisters with this Hook class. The Hook class performs the one and only one hooking of the VMT and then calls each registered MFD's HUD_Draw function in turn. However, shared code etc is a whole new can of worms, and if another MFD doesn't use it and hooks the VMT again, you get back to the original problem.
 
As you've stated, the problem lies in that both your MFD and LaunchMFD hack the VMT. Both are essentially screwing around with bits of memory they shouldn't be playing with and as such, you lose the guarantee that it's going to work. As you've stated, at stage 2 vel_hud tries to hook the VMT, but the value that it reads from the VMT is already 'wrong', so there's no way that it can work properly from that stage on as the onhook methods don't get called in a useful way. Also, you can't read it in at the start of orbiter and hold the 'known' value of the 'correct' VMT entry as when you unhook one MFD, it will unhook all the others and no MFD's imposter callback will get called.

The only way that I can see forward for this (unless the next version of orbiter allows the MFD to draw to the HUD) is to have all MFDs that want to draw to the HUD use a common system (common code) to draw to the HUD and to stick to it. Essentially, only one hook is done via some shared Hook class or function and each MFD registers/deregisters with this Hook class. The Hook class performs the one and only one hooking of the VMT and then calls each registered MFD's HUD_Draw function in turn. However, shared code etc is a whole new can of worms, and if another MFD doesn't use it and hooks the VMT again, you get back to the original problem.

This is pretty much what my hooking class here (discussed here) does. In addition, I think hooking once and not repeatedly within PxxStep()-calls solves the problem of sequentially called "hookers".

regards,
Face
 
The only way that I can see forward for this (unless the next version of orbiter allows the MFD to draw to the HUD) is to have all MFDs that want to draw to the HUD use a common system (common code) to draw to the HUD and to stick to it. ...
Yes, yes, I was going to propose to form a "VMT Hijackers League" and virtualy force all HUD hackers to use some "Standard Hijacking API" but decided to wait for a while to see if Enjo comes up with anything less intrusive. But thanks for posting your insight anyway, as it's always good to see that I'm not alone thinking this kind of solution to be reasonable.

I think hooking once and not repeatedly within PxxStep()-calls solves the problem of sequentially called "hookers".
That using opcPostStep() to constantly patch the VMT was a desperate attempt to make vel_hud compatible. The original design was to use single patching during opcFocusChanged(). In RC2 I already dropped constant ptching.

Btw, my hooking code is a bit simpler and does not involve assembly.
 
That using opcPostStep() to constantly patch the VMT was a desperate attempt to make vel_hud compatible. The original design was to use single patching during opcFocusChanged(). In RC2 I already dropped constant ptching.

Btw, my hooking code is a bit simpler and does not involve assembly.

I see.

I used the assembly approach to ensure one single patch-access during runtime. Your method is always patching the VMT back and forth in order to call the original method. I had severe race-conditions while using such a method in a multithreaded Orbiter-addon (OMP), especially with addons directly modifying non-focus vessels, and especially with more than one "hooker" running. Of course I tried locking, but it didn't work out as stable as I wanted it to be. Hence the "patch-once/use-often" method in the class, naturally leading to assembly.

Anyway, since there are now 3 different hooking methods, I see the need for core-support, much like the now-obsolete oapi-callbacks.

regards,
Face
 
Back
Top