Oooo! Maybe a save!
File saved from the depths of copy-&-paste!!!
A Dip Into Programming!My previous flowchart contained a box asking "is
targetBearing within
turret training range?". There should be an image of this simple question below.
Hmmm. Well, that's an easy question for us, eyeballing a solution, but in programming terms it needs to be defined more completely. There's a flowchart below which details
precisely how to answer this question, producing the results which are either "not in range" or "in range", for any turret. How cool is that? (Answer, not very: all questions and queries in a flowchart should result in 'answerable', logical questions.)
Off to the basics. I'm measuring all angles from the bow, clockwise (if you want to think in degrees, that's fine - though the program will gulp up stepper counts instead, still measured from zero).
What's (vaguely) interesting here is that the second flowchart
doesn't care what units are being used, it's only interested in the relationship
between numbers, where these numbers are measured from the bow, clockwise.
The anticlockwise limit to a training arc is defined as a variable. I'm using (the cunningly named)
turretMin[ x ] for this, where 'x' is the turret number (for programmers, you'll notice that the
turretMin variable is actually an array: "what's an array, Andy?" Ok. Think of a horizontal row of pigeon holes, one box for each turret, where each one is numbered by another variable called 'x'). That means
turretMin[ 2 ], for example, will be the leftmost position allowed by the turret numbered 2 in our initial declaration of these variables. (Incidentally, good programming practice dictates that turret 2 will be the
third turret, since we can - and should - number arrays from 0 upwards.)
Similarly,
turretMax[ x ] is the clockwise limit. This is ('I see the square brackets!')
another array. Finally,
targetBearing is the singular angle, measured from the bow, of the target we wish to point at.
So what's happening in the expanded flowchart?
Turrets, any turrets, have
two mathematical formats. Type
one have a training arc
which crosses the '0 degrees' boundary. That is, the left limit (
turretMin) might be 220 degrees, while the right limit (
turretMax) might be 140 degrees. This is the situation for turret A in the Dreadnought, and (maybe different limits, but same result) for turrets A & B in Warspite, for example.
Type
two turrets have training arcs which
do not cross the '0 degrees' boundary. Think of turrets P, Q, X & Y in Dreadnought. X & Y in Warspite. P, Q and X in Invincible. Their training arcs are completely outwith the 0 degrees boundary...incidentally, we can include Dreadnought's P turret as a type
two, if we set a
turretMax of 360 degrees.
The flowchart, in its first query, differentiates between these two formats.
Type
two is forced to the right,
one is to the left.
On the right side of this flowchart, we first ask "is
targetBearing >=
turretMin[ x ]?" and then asks "is
targetBearing <=
turretMax[ x ]?". If (and only if!) the answer to
both these questions is 'yes', then the
targetBearing lies within the training arc: it's "in range". Simple! It's a question of "Are you bigger than
that AND less than
that?"
To the left, the answer's a little more devious. "is
targetBearing >=
turretMin[ x ]?" will scope any bearing angles "above" the minimum angle to 360 degrees, and then (should this fail) will ask a further question "well then, is
targetBearing <=
turretMax[ x ]?", to fill in the other options. Our question now is "Are you bigger than
that OR less than
that?"
If (and only if!) the answer to
either these last two questions is 'yes', then the
targetBearing lies within the training arc: we once again get the result "in range".
The good news - while it's easy to pick our slow wetware through a flowchart, step-by-step, it actually makes it more complicated than the program. Here's how we could write the above for an Arduino, which uses a (close!) dialect of the language known as C.
targetOpportunity = FALSE; // we set a targetOpportunity variable = FALSEif(turretMax[ x }>turretMin[ x ]){ // this is first query in flowchart if(targetBearing>=turretMin[ x ]{ // this is the right-side 'YES' route if(targetBearing<=turretMax[ x ]{ // targetOpportunity = TRUE; // if 'YES' AND 'YES', therefore the target is in arc } }} else { // a 'NO' to first query in flowchart: we'll go down the left-side if(targetBearing>=turretMin[ x ]{ // targetOpportunity = TRUE; // Above minimum? Good! } else { if(targetBearing<=turretMax[ x ]{ targetOpportunity = TRUE; // OR below maximum? Just as good. } }}The outcome is a TRUE of FALSE flag set for any turret.
Incidentally, "//" marks the start of any comment, and is disregarded by the microprocessor.
The above works really well, and
extremely quickly.
But we could even speed it up. (... Can you see how? (Advanced Question Paper! Not obligatory!))
More soon!
Andy