Skip to content
This repository has been archived by the owner on Mar 21, 2023. It is now read-only.

Commit

Permalink
wire fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Gliptal committed Feb 25, 2017
1 parent 5f0e6a2 commit afcfaf5
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 52 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@
#### 0.7.0

+ better usage flags

#### 0.8.0-beta2

+ wire angle fix
+ heading fix
+ declutter option
53 changes: 32 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,68 @@ TASER

**TA**cview **S**l**E**ds **R**enderer: dynamically generate `.xml` files to visually render SLED attack profiles in the Tacview 3D environment. This tool will generate the attack wire, and track, release, abort, and floor altitude blocks relative to a specific target in a specific NTTR conventional range.

INSTALL
======

[Download](https://github.com/Gliptal/taser/releases) the latest release.

Place `taser.exe` inside Tacview's `Data/Static Objects` folder:

![folder](http://i.imgur.com/UoaYtNk.jpg)

USAGE
======

Open an elevated (administrator) cmd window in the folder:

![admin](http://i.imgur.com/WdNJzux.jpg)

Execute the application by typing `taser.exe` and passing all required and any optional parameters:

![cmd](http://i.imgur.com/lK5lKhR.jpg)
![cmd](http://i.imgur.com/ifD7Y0Z.jpg)

If no errors occur the application will generate an `.xml` and exit:

![result](http://i.imgur.com/DPDaZKN.jpg)
![result](http://i.imgur.com/VuHqmKg.jpg)

Analyze your attack runs with Tacview:

![tacview](http://i.imgur.com/B4emnDk.jpg)
![tacview](http://i.imgur.com/fM73mBE.jpg)

USAGE
CLI
======

`taser.py [-h] [-o file] [-l ft] [-e °] -b nm -r ft -t ft -p ft -a ft -f ft range target`
`taser.py [-h] [-v] [-fn str] [-la ft] [-lh °] [-ah °] [-dc] -bd nm -ba ft -ta ft -ra ft -aa ft -ma ft range target`

`range` is the short name of the range containing the target (e.g. "64C")

`target` is the name of the target, with dashes "-" replacing spaces " " (e.g. "West-Bomb-Circle")

| required | flag | shorthand | purpose | unit | default |
| :---: | :---: | :---: | --- | :---: | :---: |
| YES | --base | -b | SLED's *base* distance | nm | |
| YES | --roll | -r | SLED's *roll-in* MSL altitude | ft | |
| YES | --track | -t | SLED's *track* MSL altitude | ft | |
| YES | --pickle | -p | SLED's *release* MSL altitude | ft | |
| YES | --abort | -a | SLED's *abort* MSL altitude | ft | |
| YES | --floor | -f | SLED's *mimimum* MSL altitude | ft | |
| | --out | -o | name of the generated `.xml` file | | "sled" |
| | --leeway | -l | available +/- leeway for the SLED's *roll-in*, *release*, and *track* altitudes | ft | 200ft |
| | --entry | -e | available +/- leeway for the range's attack heading at the SLED's *roll-in* altitude | ° | 10° |

Help is also available from the CLI itself by providing the `-h` (`--help`) flag.
| YES | --basedist | -bd | SLED's *base* distance | nm | |
| YES | --basealt | -ba | SLED's *base* MSL altitude | ft | |
| YES | --trackalt | -ta | SLED's *track* MSL altitude | ft | |
| YES | --releasealt | -ra | SLED's *release* MSL altitude | ft | |
| YES | --abortalt | -aa | SLED's *abort* MSL altitude | ft | |
| YES | --minalt | -ma | SLED's *mimimum* MSL altitude | ft | |
| | --filename | -fn | name of the generated `.xml` file | | "sled" |
| | --leewayalt | -la | available +/- leeway for the SLED's *base*, *track*, and *release* altitudes | ft | 200ft |
| | --leewayhdg | -lh | available +/- leeway for the range's attack heading at the SLED's *base* altitude | ° | 10° |
| | --attackhdg | -ah | required attack heading, overrides the range's default | ° | |
| | --declutter | -dc | declutter the target area by rendering the *abort* and *minimum* altitudes as planes | | |

Help and version number are also available from the CLI itself by providing the `-h` (`--help`) or the `-v` (`--version`) flag respectively.

FRAMEWORK
======

Development framework powered by [python](https://www.python.org/) and the following non-embedded plugins:

- [colorclass](https://pypi.python.org/pypi/colorclass)
- [dicttoxml](https://pypi.python.org/pypi/dicttoxml)
- [geopy](https://github.com/geopy/geopy)
- [PyYAML](http://pyyaml.org/)
+ [colorclass](https://pypi.python.org/pypi/colorclass)
+ [dicttoxml](https://pypi.python.org/pypi/dicttoxml)
+ [geopy](https://github.com/geopy/geopy)
+ [PyYAML](http://pyyaml.org/)

BUILD
======
Expand All @@ -64,7 +75,7 @@ BUILD

`.exe` versioning powered by [Simple Version Resource Tool](https://www.codeproject.com/articles/37133/simple-version-resource-tool-for-windows):

`verpatch.exe taser.exe /va /langid 0x0809 /high 0.6.0-beta1 /s desc "Generate Tacview .xml files to render SLED profiles." /s product "TAcview SlEds Renderer" /s (c) "CC Attribution-ShareAlike 4.0" /pv "0.6.0.0"`
`verpatch.exe taser.exe /va /langid 0x0809 /high x.x.x-x /s desc "Generate Tacview .xml files to render SLED profiles." /s product "TAcview SlEds Renderer" /s (c) "CC Attribution-ShareAlike 4.0" /pv "x.x.x.x"`

DATA
======
Expand Down
Binary file modified dist/taser.exe
Binary file not shown.
19 changes: 11 additions & 8 deletions source/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
TRACK_ALT = None
RELEASE_ALT = None
ABORT_ALT = None
FLOOR_ALT = None
MIN_ALT = None

def parse():
global RANGE
Expand All @@ -25,32 +25,34 @@ def parse():
global LEEWAY_ALT
global LEEWAY_HDG
global ATTACK_HDG
global DECLUTTER
global BASE_DIST
global BASE_ALT
global TRACK_ALT
global RELEASE_ALT
global ABORT_ALT
global FLOOR_ALT
global MIN_ALT

parser = argparse.ArgumentParser(description="generate .xml files to visually render SLED attack profiles in the Tacview 3D environment version: 0.6.0-beta1", formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=30))
parser.add_argument("-v", "--version", action="version", version="0.7.0")
parser.add_argument("-v", "--version", action="version", version="0.8.0-beta2")

parser.add_argument("range", type=str, help="the range containing the attacked target")
parser.add_argument("target", type=str, help="the attacked target")

optional_options = parser.add_argument_group("optional other parameters")
optional_options.add_argument("-fn", "--filename", type=str, help="name of the generated .xml file [default: \"sled\"]", metavar="str", default="sled")
optional_options.add_argument("-la", "--leewayalt", type=_positive_int, help="available +/- leeway for the SLED's base, release, and track altitudes (in feet) [default: 200ft]", metavar="ft", default=200)
optional_options.add_argument("-la", "--leewayalt", type=_positive_int, help="available +/- leeway for the SLED's base, track, and release altitudes (in feet) [default: 200ft]", metavar="ft", default=200)
optional_options.add_argument("-lh", "--leewayhdg", type=_angle, help="available +/- leeway for the range's attack heading at the SLED's base altitude (in degrees) [default: 10°]", metavar="°", default=10)
optional_options.add_argument("-ah", "--attackhdg", type=_heading, help="required attack heading, overrides the range's default (in degrees)", metavar="°", default=None)
optional_options.add_argument("-dc", "--declutter", action="store_true", help="declutter the target area by rendering the abort and minimum altitudes as planes")

required_options = parser.add_argument_group("required SLED parametes")
required_options.add_argument("-bd", "--basedist", type=_positive_int, help="base distance (in nautical miles)", metavar="nm", required=True)
required_options.add_argument("-ba", "--basealt", type=_positive_float, help="base altitude (in feet MSL)", metavar="ft", required=True)
required_options.add_argument("-ta", "--trackalt", type=_positive_float, help="track altitude (in feet MSL)", metavar="ft", required=True)
required_options.add_argument("-ra", "--releasealt", type=_positive_float, help="release altitude (in feet MSL)", metavar="ft", required=True)
required_options.add_argument("-aa", "--abortalt", type=_positive_float, help="abort altitude (in feet MSL)", metavar="ft", required=True)
required_options.add_argument("-fa", "--flooralt", type=_positive_float, help="minimum altitude (in feet MSL)", metavar="ft", required=True)
required_options.add_argument("-ma", "--minalt", type=_positive_float, help="minimum altitude (in feet MSL)", metavar="ft", required=True)

args = parser.parse_args()

Expand All @@ -60,12 +62,13 @@ def parse():
LEEWAY_ALT = args.leewayalt
LEEWAY_HDG = args.leewayhdg
ATTACK_HDG = args.attackhdg
DECLUTTER = args.declutter
BASE_DIST = args.basedist
BASE_ALT = args.basealt
TRACK_ALT = args.trackalt
RELEASE_ALT = args.releasealt
ABORT_ALT = args.abortalt
FLOOR_ALT = args.flooralt
MIN_ALT = args.minalt

def check_range():
global RANGE
Expand Down Expand Up @@ -107,7 +110,7 @@ def convert():
global TRACK_ALT
global RELEASE_ALT
global ABORT_ALT
global FLOOR_ALT
global MIN_ALT

LEEWAY_ALT = calc.ft_to_m(LEEWAY_ALT)
if ATTACK_HDG is not None:
Expand All @@ -117,7 +120,7 @@ def convert():
TRACK_ALT = calc.ft_to_m(TRACK_ALT)
RELEASE_ALT = calc.ft_to_m(RELEASE_ALT)
ABORT_ALT = calc.ft_to_m(ABORT_ALT)
FLOOR_ALT = calc.ft_to_m(FLOOR_ALT)
MIN_ALT = calc.ft_to_m(MIN_ALT)

def _positive_int(value):
number = int(value)
Expand Down
2 changes: 1 addition & 1 deletion source/calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def ft_to_m(ft):
return ft*0.3048

def thdg_to_mhdg(thdg):
return thdg
return thdg+19

def reverse_heading(hdg):
return (hdg+180) % 360
Expand Down
2 changes: 1 addition & 1 deletion source/data/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
- Name :
ShortName:
Shape : Cube
Color : "#ffa50010"
Color : "#ffa50060"
Position :
Latitude :
Longitude:
Expand Down
57 changes: 36 additions & 21 deletions source/tacview.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,75 +11,90 @@ def generate():
template = data.load("data/template.yaml")

target_altitude = calc.ft_to_m(args.TARGET["altitude"])
base_altitude = args.BASE_ALT-target_altitude
if args.ATTACK_HDG is None:
attack_heading = calc.reverse_heading(calc.thdg_to_mhdg(args.TARGET["heading"]))
else:
attack_heading = calc.reverse_heading(args.ATTACK_HDG)

wire_length = calc.hypotenuse_from_catheti(args.BASE_DIST, args.BASE_ALT-target_altitude)
wire_angle = calc.angle_from_catheti(args.BASE_ALT, args.BASE_DIST)
wire_length = calc.hypotenuse_from_catheti(args.BASE_DIST, base_altitude)
wire_angle = calc.angle_from_catheti(base_altitude, args.BASE_DIST)
wire_entry_width = calc.sin_cathetus_from_angle(wire_length, args.LEEWAY_HDG)
wire_height = args.LEEWAY_ALT*2

floor_lat, floor_lon = calc.shift_coords(args.TARGET["position"], args.BASE_DIST*0.3, -attack_heading)
abort_lat, abort_lon = floor_lat, floor_lon
min_lat, min_lon = calc.shift_coords(args.TARGET["position"], args.BASE_DIST*0.3, -attack_heading)
abort_lat, abort_lon = min_lat, min_lon
release_lat, release_lon = calc.shift_coords(args.TARGET["position"], calc.cos_cathetus_from_angle(args.RELEASE_ALT-target_altitude, wire_angle), -attack_heading)
track_lat, track_lon = calc.shift_coords(args.TARGET["position"], calc.cos_cathetus_from_angle(args.TRACK_ALT-target_altitude, wire_angle), -attack_heading)

floor_altitude = args.FLOOR_ALT/2
abort_altitude = args.FLOOR_ALT+((args.ABORT_ALT-args.FLOOR_ALT)/2)
if args.DECLUTTER:
min_altitude = args.MIN_ALT
abort_altitude = args.ABORT_ALT
else:
min_altitude = args.MIN_ALT/2
abort_altitude = args.MIN_ALT+((args.ABORT_ALT-args.MIN_ALT)/2)
release_altitude = args.RELEASE_ALT
track_altitude = args.TRACK_ALT

floor_width = wire_entry_width/2
abort_width = floor_width
release_width = wire_entry_width/1.5
min_width = wire_entry_width
abort_width = min_width
release_width = wire_entry_width
track_width = release_width

floor_length = args.BASE_DIST
abort_length = floor_length
min_length = args.BASE_DIST
abort_length = min_length
release_length = args.BASE_DIST*0.5
track_length = release_length

if args.DECLUTTER:
min_height = 1
abort_height = 1
else:
min_height = args.MIN_ALT
abort_height = args.ABORT_ALT-args.MIN_ALT
release_height = args.LEEWAY_ALT*2
track_height = args.LEEWAY_ALT*2

template[0]["Position"]["Latitude"] = args.TARGET["position"]["latitude"]
template[0]["Position"]["Longitude"] = args.TARGET["position"]["longitude"]
template[0]["Position"]["Altitude"] = target_altitude
template[0]["Orientation"]["Pitch"] = wire_angle
template[0]["Orientation"]["Yaw"] = attack_heading
template[0]["Size"]["Width"] = wire_entry_width
template[0]["Size"]["Length"] = wire_length
template[0]["Size"]["Height"] = args.LEEWAY_ALT*2
template[0]["Size"]["Height"] = wire_height

template[1]["Position"]["Latitude"] = floor_lat
template[1]["Position"]["Longitude"] = floor_lon
template[1]["Position"]["Altitude"] = floor_altitude
template[1]["Position"]["Latitude"] = min_lat
template[1]["Position"]["Longitude"] = min_lon
template[1]["Position"]["Altitude"] = min_altitude
template[1]["Orientation"]["Yaw"] = attack_heading
template[1]["Size"]["Width"] = floor_width
template[1]["Size"]["Length"] = floor_length
template[1]["Size"]["Height"] = args.FLOOR_ALT
template[1]["Size"]["Width"] = min_width
template[1]["Size"]["Length"] = min_length
template[1]["Size"]["Height"] = min_height

template[2]["Position"]["Latitude"] = abort_lat
template[2]["Position"]["Longitude"] = abort_lon
template[2]["Position"]["Altitude"] = abort_altitude
template[2]["Orientation"]["Yaw"] = attack_heading
template[2]["Size"]["Width"] = abort_width
template[2]["Size"]["Length"] = abort_length
template[2]["Size"]["Height"] = args.ABORT_ALT-args.FLOOR_ALT
template[2]["Size"]["Height"] = abort_height

template[3]["Position"]["Latitude"] = release_lat
template[3]["Position"]["Longitude"] = release_lon
template[3]["Position"]["Altitude"] = release_altitude
template[3]["Orientation"]["Yaw"] = attack_heading
template[3]["Size"]["Width"] = release_width
template[3]["Size"]["Length"] = release_length
template[3]["Size"]["Height"] = args.LEEWAY_ALT*2
template[3]["Size"]["Height"] = release_height

template[4]["Position"]["Latitude"] = track_lat
template[4]["Position"]["Longitude"] = track_lon
template[4]["Position"]["Altitude"] = track_altitude
template[4]["Orientation"]["Yaw"] = attack_heading
template[4]["Size"]["Width"] = track_width
template[4]["Size"]["Length"] = track_length
template[4]["Size"]["Height"] = args.LEEWAY_ALT*2
template[4]["Size"]["Height"] = track_height

_dict_to_file(template)

Expand Down

0 comments on commit afcfaf5

Please sign in to comment.