Jump to content

Analog To Digital - Analog Jump Jets / Variable Fire Rate (Gatling Gun Ac2)


15 replies to this topic

#1 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 14 July 2013 - 04:48 PM

Hi folks, it's about time for another one of my crazy macros using my ADHD library!

The basic idea of this one is to explore the idea of converting analogue inputs (ie a joystick axis) to digital outputs (ie a keyboard key) by spamming the key at a varying rate proportional to the amount you move the joystick axis.

Can be used for various things in MWO, for example:
  • Allow you to fire your jumpjets at a variable rate.
  • Allow you to fire a weapon at a variable rate. Great with Quad AC2s! Map to the analogue trigger of an XBOX controller for a variable rate fire trigger ; "Spin up" and "Spin down" like a Gatling Gun!
As always, update information will appear in the second post.



Download

GitHub Page

Posted Image



From the Readme:

ADHD-Analog-to-Digital
======================

An experiment in analog to digital - using a joystick axis to spam a key at varying rates.
Normally an easy thing to code, but compounded when a game only recognises presses of a certain minimum duration (eg 50ms between down and up)


Installation:
=============

Either
You either need Autohotkey and ADHD installed and run the ahk file (You may need to tweak the include statement at the end of the script)
Or
Run the EXE file

Usage:
======

Joystick ID - sets the ID of your physical stick

Joystick Axis - sets the axis number of the axis you wish to use

Use Half Axis - allows you to use only half the axis (ie from the mid-point to either end)

Invert Axis - allows you to invert the input (Probably useless in combination with Use Half Axis)

DeadZone - allows you to set a limit below which the axis will not register.

Fire Sequence - a comma separated list of AHK key names to hit
eg for just space, enter "Space", To hit 3,4,5,6 in sequence, enter "3,4,5,6" (Without the quotes)

Fire Rate
Min (Fastest Rate!) - The fastest rate (in ms) at which to fire - ie the rate to use when the axis is at 100%
Max (Slowest Rate!) - The slowest rate (in ms) at which to fire - ie the rate to use when the axis is at 1%

Useful readouts:
================

Current Axis Value - Shows you the input value of the selected axis. Usefel for finding the right setting for Joystick ID / Axis

Adjusted Axis value - Shows the amount (in percent) that it is trying to jump jet. Useful for debugging eg Use Half Axis and Invert Axis settings

Current Fire Rate - The current rate at which the macro will strobe the key (higher is faster). Useful for finding desired values Fire Rate Divider

Note:
Whilst there are no bindings in this ADHD macro, the "Limit Application" option in the bindings tab takes effect!


Settings for XBOX controller analogue trigger:
==============================================
Axis: 3
Use Half Axis: Low for Right trigger, High for Left trigger

Settings for Jumpjets:
======================
Rate Min: 0 Max: 200
Fire Sequence: Space

Settings for 500->125 ms fire rate (MWO 4xAC2):
==========================================
(Add a slack of 5ms to each for safety)
Rate Min: 130 Max: 500 (5ms above 125 for reliability)
Fire Sequence: 3,4,5,6

Edited by evilC, 15 July 2013 - 05:42 PM.


#2 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 14 July 2013 - 04:48 PM

Changelog:

Key:
! : Warning
* : Comment
= : Change / Fix
+ : Added feature

2.3 17th Jul 2013
= Script should be a bit more reliable. Sometimes when you went from 0 to full straight away, down would never get sent


2.2 16th Jul 2013
= Made labels for min and max make sense

2.1 16th Jul 2013
= Max and Min had got swapped, sorry...

2.0 16th Jul 2013
+ Completely new timing routine
+ Min and Max rate options
+ Deadzone setting
= UI cleanup, lots of tooltips added
= Readouts (Current Fire Rate etc) now make sense

1.3 15th Jul 2013
= Removed the "Send key up when at 100% rate" option.
This is now calculated automatically. If the key is due to be held 100% of the time, a key up is not sent if only sending a single key.
If sending a sequence of keys, then it sends a keyup for one key and a keydown for the next at the same point in time.

1.2 15th Jul 2013
+ Added homepage link

1.1 14th Jul 2013
= Initial public release

Edited by evilC, 17 July 2013 - 02:51 AM.


#3 Loc Nar

    Member

  • PipPipPipPipPipPipPipPip
  • 1,132 posts

Posted 14 July 2013 - 06:58 PM

Good work, totally worth pursuing! I got my PWM turning scheme to work properly -about a week before real analog turning debuted.

#4 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 15 July 2013 - 06:08 AM

I would definitely be interested in hearing of your experiences in this area Loc (or anyone else!), the technique I use at the moment is as follows:

(Talking about it in terms of a jump jet, but technique remains the same)

The pulse width (Time a key is held) is constant at 50ms, the period varies.

10% thrust = "on 10% of the time", so 1000ms * 0.1 = on for 100ms in 1 second

100ms / 50 = 2x 50ms pulses per second.

1000 / 2 = 500 = 50ms pulse every 500ms

So 90% is:
1000 * 0.9 = 900
900 / 50 = 18
1000 / 18 = 55.55
one pulse every 55.55ms

When it hits 100%, obviously you have 20x 50ms pulses = 1000ms of pulse = no time between falling and rising clock rate.
Hence the "Send key up on 100%" option - if you are only ever hitting one key, there will be no point in sending a down/up.

I am thinking I could eliminate this confusing option though by checking if only one key is used and if all the time is "used up", then dont send a key up.

I am sure a lot of the maths and logic could be heavily optimised also, I just wanted to get something in and working as a testbed before trying to improve upon it.

#5 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 15 July 2013 - 07:12 AM

New version up

1.3 15th Jul 2013
= Removed the "Send key up when at 100% rate" option.
This is now calculated automatically. If the key is due to be held 100% of the time, a key up is not sent if only sending a single key.
If sending a sequence of keys, then it sends a keyup for one key and a keydown for the next at the same point in time.

#6 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 15 July 2013 - 07:26 AM

Hmm, I have been having a look at the code and it seems sleep deprivation got the better of me.
The figures are out, the "Current fire rate" output is displaying a rather nonsensical value - do not trust the figures if trying to time weapons.
Gonna have a look at it now.

#7 Loc Nar

    Member

  • PipPipPipPipPipPipPipPip
  • 1,132 posts

Posted 15 July 2013 - 12:43 PM

Quote

I would definitely be interested in hearing of your experiences in this area Loc (or anyone else!), the technique I use at the moment is as follows:
</p>

Actually you have hit the nail pretty squarely with your approach, and there's not much I need to add for you to make this work. For my turning scheme, the only unexpected problem I encountered was the need for a minimum time-on for each pulse event to properly register and convert to turning action, which left me with a very small window between not enough, and the screen would ratchet through it's range movement, or too much, in which case it just turned at full speed. I was only able to come up with 2 pulse rates that were appreciably unique (in addition to full speed turning), so my turning system effectively has 3 speeds. I could have made more to smooth the in-between rates, but there was little point since the slowest I could make it turn was still ~2/3 the speed of the full rate.

A week later there was analog turning available(!) and made my scheme obsolete so it has sat dormant but I still have the TARGET lines handy and adapting them will be straightforward. Somehow I hadn't considered applying them to JJ till you mentioned it here, but I suspect they will work a lot better than the turning did. Even the actual analog turning doesn't allow a very high degree of rate change between minimum and maximum, but feathered JJ operation can be smoothly finessed at lower-than-full rates than the digital turning can.

Going to do some experimenting with JJ now, since TARGET will allow me to assign them to an analog axis to generate the variable rates based on displacement! :)

edit: markup anomalies

Edited by Loc Nar, 15 July 2013 - 02:00 PM.


#8 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 15 July 2013 - 05:15 PM

New version up, 2.0

Vastly improved technique, way easier to understand the logic.

Now the method is this:
the analogue axis controls a variable, which dynamically sets an amount of time you need to wait between pulses.

A loop runs constantly that checks to see if the time since the last pulse is greater than the amount set by the state of the axis, and if is, fires a down.

Ups are only fired 50ms after downs

All downs after the first one and all ups are excluded if the axis is at the max rate, except when sending a sequence.
(This allows the button to be held at max rate and not released at all)

There is also a min and max setting, combined with deadzone support.
This way, when you start to move the axis, it does not have to start at a really slow rate, it can kick in at a decent rate. Plus you can limit the max rate.

Edited by evilC, 15 July 2013 - 05:15 PM.


#9 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 15 July 2013 - 05:27 PM

New version up, 2.1
Fixed a bug with max and min rate being swapped.

Edited by evilC, 15 July 2013 - 05:40 PM.


#10 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 15 July 2013 - 05:41 PM

D'oh sorry
2.2 up. Labels fixed for Min and Max. Should finally make sense now.

#11 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 17 July 2013 - 02:53 AM

New version up, 2.3

I got my Logitech G13 today - this script works perfectly with it. It is particularly comfortable using the analog stick for jump jets.

#12 Loc Nar

    Member

  • PipPipPipPipPipPipPipPip
  • 1,132 posts

Posted 17 July 2013 - 01:45 PM

Been a while since I've played with PWM, and forgot that once you get ~50% time on/off it essentially counts as a fully held keypress, so the workable range is closer to being from 0-50% for time on/off if any modulation is to be found. I found 50ms to be too short for the JJ to do anything besides make noise and kill momentum and began increasing burn times but can't seem to find a happy medium that successfully averages the effect without negative impact.

I've spent some time playing around with this in TARGET, but have yet to find any usable timing ratios and find my trajectories more easily controlled with normal binary on/off commands since it needs to be mostly. If moving forward at full speed, even letting off the jets for a split second (in an otherwise full burn) yields basically a flat trajectory.

I have found that while running along the ground, pulsing them at less than full burn doesn't get the mech off the ground and instead quickly whittles away your momentum with each event. I will explore this more, and am curious what time on/off ratios you are having luck with.

#13 evilC

    Member

  • PipPipPipPipPipPipPipPip
  • Legendary Founder
  • Legendary Founder
  • 1,298 posts
  • LocationLondon, UK

Posted 17 July 2013 - 02:06 PM

I use pulse rate modulation, but keep the pulse duration constant @ 50ms, and can see the difference right down to 50ms pulse frequency.
Keep the press duration short, so you can strobe it on/off as fast as possible was my line of thinking.
By doing a long press, it is very difficult to maintain a hover. You want lots of short presses instead.
Also, with my code, as the pulse frequency hits the pulse duration (ie 50ms), it stops trying to strobe and just presses.

My technique will not be possible in TARGET - you need a proper programming language with flow of control and the ability to know the current time.

#14 Loc Nar

    Member

  • PipPipPipPipPipPipPipPip
  • 1,132 posts

Posted 17 July 2013 - 03:52 PM

TARGET gives me control over pulse length and delay in addition to the ability to assign an analog axis into zones with different events, allowing me to create a gradient of events, which I already successfully pulled off with turning in the recent past and don't see how it is any different than the technique you describe so I must be missing something.

What other parameters are there to manipulate?

My first attempts were using 50ms pulses, and just changing the rate as well. As you notice too, anything less than a 50ms delay between pulses counts as a held keypress (or more accurately whenever 50% or better time on/off is achieved) in TARGET too, which I'm pretty sure is a Windows function.

So far I've found short keypresses to be too short to have any inertial thrust effect on a mech so I kept bumping up pulse event length until it started doing something other than reducing my forward momentum or making noise, but only played around with it for a short while.

My mech will hover if I have full JJ, stop for a split second and then continue with full JJ. Once even a single tiny pause interrupts the thrust though, even holding full burn is just hovering. I've been testing this with a Jenner that has 4/5 JJ. I can make scripts that successfully generate spacebar presses at different frequency rates and test them in notepad etc, but in-game they behave poorly, including all the rates I tested so far using 50ms pulses.

Going back in for another look, starting with 50ms pulses again.

#15 Loc Nar

    Member

  • PipPipPipPipPipPipPipPip
  • 1,132 posts

Posted 19 July 2013 - 02:39 PM

I think I replied to this thread in one of your other posts, but after having a little better luck with 50ms pulses and thinking about your pressure sensitive xbox shoulder buttons I am likely going to modify my mech stick accordingly. I found the perfect plug-n-play pressure sensitive button to mod it with in order to turn the pinky paddle lever (my preferred JJ actuator ) into a ratiometric pressure sensitive analog output.

That way I can make the best use of these variably feathering JJs. I think if I remove it from it's mounting board it will fit right into the microswitch housing with minimal modding to the stick itself. I will have to reroute the Vref/Gnd/Vout from an unused pot on my throttle, but that's not a problem and other than that this thing hooks up just like a pot or a Hall.

http://www.phidgets....oduct_id=1106_0
Posted Image

#16 CyBerkut

    Member

  • PipPipPipPipPipPipPip
  • 609 posts
  • LocationSomewhere north of St. Petersburg

Posted 20 July 2013 - 08:37 AM

Interesting find / thought there, Loc Nar!





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users