地对地导弹测试

This commit is contained in:
2025-10-15 11:23:32 +08:00
parent 9163fad251
commit a236fcde15
365 changed files with 380521 additions and 261 deletions

44
base_types/README.md Normal file
View File

@@ -0,0 +1,44 @@
**CUI**
# base_types model library
## CUI Designation Indicator
* Controlled by: Air Force Research Laboratory
* Controlled by: Aerospace Systems Directorate
* CUI Categories: CTI, EXPT
* LDC/Distribution Statement: DIST-C
* POC: afrl.rq.afsim@us.af.mil
## Notices and Warnings
### DISTRIBUTION STATEMENT C
Distribution authorized to US Government agencies and their contractors;
Critical Technology, Export Controlled; (2021 Mar 10). Other requests for this
information shall be referred to AFRL Aerospace Systems Directorate.
### NOTICE TO ACCOMPANY FOREIGN DISCLOSURE
This content is furnished on the condition that it will not be released to
another nation without specific authority of the Department of the Air Force of
the United States, that it will be used for military purposes only, that
individual or corporate rights originating in the information, whether patented
or not, will be respected, that the recipient will report promptly to the
United States any known or suspected compromise, and that the information will
be provided substantially the same degree of security afforded it by the
Department of Defense of the United States. Also, regardless of any other
markings on the document, it will not be downgraded or declassified without
written approval from the originating U.S. agency.
### WARNING - EXPORT CONTROLLED
This content contains technical data whose export is restricted by the Arms
Export Control Act (Title 22, U.S.C. Sec 2751 et seq.) or the Export
Administration Act of 1979, as amended, Title 50 U.S.C., App. 2401 et seq.
Violations of these export laws are subject to severe criminal penalties.
Disseminate in accordance with provisions of DoD Directive 5230.25.
### HANDLING AND DESTRUCTION NOTICE
Handle this information in accordance with DoDI 5200.48. Destroy by any
approved method that will prevent unauthorized disclosure or reconstruction of
this information in accordance with NIST SP 800-88 and 32 C.F.R 2002.14
(Safeguarding Controlled Unclassified Information).
**CUI**

View File

@@ -0,0 +1,523 @@
UNCLASSIFIED
Converted from file radar1.pat
0.00 30.00 -30.00 DB 2D
0.00 1801 0.00 0.10
0.00 1801 0.00 0.10
AZCUT
0.00 -0.20 -0.81 -1.87 -3.46 -5.72 -8.97
-14.01 -24.72 -24.61 -16.76 -14.07 -13.27 -13.72
-15.36 -18.55 -24.85 -30.00 -24.78 -20.14 -18.25
-17.85 -18.66 -20.81 -25.07 -30.00 -30.00 -25.07
-22.04 -20.88 -21.01 -22.38 -25.38 -30.00 -30.00
-30.00 -25.48 -23.50 -22.99 -23.70 -25.79 -30.00
-30.00 -30.00 -29.00 -26.02 -24.84 -24.94 -26.30
-29.34 -30.00 -30.00 -30.00 -28.63 -26.69 -26.20
-26.92 -29.05 -30.00 -30.00 -30.00 -30.00 -28.66
-27.53 -27.66 -29.06 -30.00 -30.00 -30.00 -30.00
-30.00 -28.99 -28.54 -29.30 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -29.56 -29.75 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00
ELCUT
0.00 -0.20 -0.81 -1.87 -3.46 -5.72 -8.97
-14.01 -24.72 -24.61 -16.76 -14.07 -13.27 -13.72
-15.36 -18.55 -24.85 -30.00 -24.78 -20.14 -18.25
-17.85 -18.66 -20.81 -25.07 -30.00 -30.00 -25.07
-22.04 -20.88 -21.01 -22.38 -25.38 -30.00 -30.00
-30.00 -25.48 -23.50 -22.99 -23.70 -25.79 -30.00
-30.00 -30.00 -29.00 -26.02 -24.84 -24.94 -26.30
-29.34 -30.00 -30.00 -30.00 -28.63 -26.69 -26.20
-26.92 -29.05 -30.00 -30.00 -30.00 -30.00 -28.66
-27.53 -27.66 -29.06 -30.00 -30.00 -30.00 -30.00
-30.00 -28.99 -28.54 -29.30 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -29.56 -29.75 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -29.75 -29.56 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -29.30 -28.54
-28.99 -30.00 -30.00 -30.00 -30.00 -30.00 -29.06
-27.66 -27.53 -28.66 -30.00 -30.00 -30.00 -30.00
-29.05 -26.92 -26.20 -26.69 -28.63 -30.00 -30.00
-30.00 -29.34 -26.30 -24.94 -24.84 -26.02 -29.00
-30.00 -30.00 -30.00 -25.79 -23.70 -22.99 -23.50
-25.48 -30.00 -30.00 -30.00 -25.38 -22.38 -21.01
-20.88 -22.04 -25.07 -30.00 -30.00 -25.07 -20.81
-18.66 -17.85 -18.25 -20.14 -24.78 -30.00 -24.85
-18.55 -15.36 -13.72 -13.27 -14.07 -16.76 -24.61
-24.72 -14.01 -8.97 -5.72 -3.46 -1.87 -0.81
-0.20 0.00

View File

@@ -0,0 +1,523 @@
UNCLASSIFIED
Converted from file radar2.pat
0.00 30.00 -30.00 DB 2D
0.00 1801 0.00 0.10
0.00 1801 0.00 0.10
AZCUT
0.00 -0.20 -0.81 -1.87 -3.46 -5.72 -8.97
-14.01 -24.72 -24.61 -16.76 -14.07 -13.27 -13.72
-15.36 -18.55 -24.85 -30.00 -24.78 -20.14 -18.25
-17.85 -18.66 -20.81 -25.07 -30.00 -30.00 -25.07
-22.04 -20.88 -21.01 -22.38 -25.38 -30.00 -30.00
-30.00 -25.48 -23.50 -22.99 -23.70 -25.79 -30.00
-30.00 -30.00 -29.00 -26.02 -24.84 -24.94 -26.30
-29.34 -30.00 -30.00 -30.00 -28.63 -26.69 -26.20
-26.92 -29.05 -30.00 -30.00 -30.00 -30.00 -28.66
-27.53 -27.66 -29.06 -30.00 -30.00 -30.00 -30.00
-30.00 -28.99 -28.54 -29.30 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -29.56 -29.75 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00
ELCUT
0.00 -0.20 -0.81 -1.87 -3.46 -5.72 -8.97
-14.01 -24.72 -24.61 -16.76 -14.07 -13.27 -13.72
-15.36 -18.55 -24.85 -30.00 -24.78 -20.14 -18.25
-17.85 -18.66 -20.81 -25.07 -30.00 -30.00 -25.07
-22.04 -20.88 -21.01 -22.38 -25.38 -30.00 -30.00
-30.00 -25.48 -23.50 -22.99 -23.70 -25.79 -30.00
-30.00 -30.00 -29.00 -26.02 -24.84 -24.94 -26.30
-29.34 -30.00 -30.00 -30.00 -28.63 -26.69 -26.20
-26.92 -29.05 -30.00 -30.00 -30.00 -30.00 -28.66
-27.53 -27.66 -29.06 -30.00 -30.00 -30.00 -30.00
-30.00 -28.99 -28.54 -29.30 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -29.56 -29.75 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -30.00 -30.00
-30.00 -30.00 -30.00 -30.00 -29.75 -29.56 -30.00
-30.00 -30.00 -30.00 -30.00 -30.00 -29.30 -28.54
-28.99 -30.00 -30.00 -30.00 -30.00 -30.00 -29.06
-27.66 -27.53 -28.66 -30.00 -30.00 -30.00 -30.00
-29.05 -26.92 -26.20 -26.69 -28.63 -30.00 -30.00
-30.00 -29.34 -26.30 -24.94 -24.84 -26.02 -29.00
-30.00 -30.00 -30.00 -25.79 -23.70 -22.99 -23.50
-25.48 -30.00 -30.00 -30.00 -25.38 -22.38 -21.01
-20.88 -22.04 -25.07 -30.00 -30.00 -25.07 -20.81
-18.66 -17.85 -18.25 -20.14 -24.78 -30.00 -24.85
-18.55 -15.36 -13.72 -13.27 -14.07 -16.76 -24.61
-24.72 -14.01 -8.97 -5.72 -3.46 -1.87 -0.81
-0.20 0.00

View File

@@ -0,0 +1,265 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#!/usr/bin/perl -w
# convert a suppressor antenna pattern to a tabular pattern
#
sub ReadAndTrim
{
# Read a single line from the input file, checking for EOF.
$eof = !($line = <ANT_IN>);
# Trim leading and trailing whitespace.
$line =~ s/^\s+|\s+$//g;
};
if (@ARGV != 2)
{
die("Wrong number of arguments.\nUsage: convert <in_file> <out_file>\n");
}
$file_name = $ARGV[0];
$out_file_name = $ARGV[1];
if (! open(ANT_IN, "+<", $file_name))
{
die("** ERROR: File $file_name could not be opened\n");
}
if (! open ANT_OUT, ">", $out_file_name)
{
die("** ERROR: File $out_file_name could not be opened\n");
}
$el_array_index = 0;
$data_value_set_index = 0;
$az_array_length = 0;
$max_el_values_size = 0;
$max_el_values_index = 0;
$el_array_length = 0;
my @el_array;
#Read first line;
ReadAndTrim();
while (!eof)
{
#print $line, "\n";
# first character in the line should not be "$"
# if DIMENSION 1 AZ found
if (index($line , "DIMENSION 1 AZ")!= -1)
{
$firstChar = index($line, "(") + 1;
$lastChar = index($line, ")") - 1;
$az_units = lc(substr $line, $firstChar, ($lastChar - $firstChar + 1));
ReadAndTrim();
while (index($line, "\$") != 0)
{
# push all whitespace delimited values into the array.
push (@az_array, split(/\s+/, $line));
ReadAndTrim();
}
$az_array_length = @az_array;
# get ready for next block
$index = 0;
while ($index != $az_array_length)
{
$offset = 0.0; # may change
push(@az_array_padded, $az_array[$index]);
if (($index != 0) &&
($index != ($az_array_length - 1)))
{
push(@az_array_padded, $az_array[$index] + 0.0001);
}
$index = $index + 1;
}
}
# convert to array with staggered edge values (e.g. -0.00001 and 0.00001)
# else if DIMENSION 2 EL found
elsif (index($line, "DIMENSION 2 EL") != -1)
{
# check the value in parentheses
# these are the units
$firstChar = index($line, "(") + 1;
$lastChar = index($line, ")") - 1;
$el_units[$data_value_set_index] = lc(substr $line, $firstChar, ($lastChar - $firstChar + 1));
#print {STDOUT} "el units: ", $el_units[data_value_set_index], "\n";
# read next line
ReadAndTrim();
# Clear the el values
@el_values = ();
# read in el values until we get to the actual data
while (index($line, "GAIN") == -1)
{
# push all whitespace delimited values into the array.
push (@el_values, split(/\s+/, $line));
ReadAndTrim();
}
# these need to be saved for later evaluation
$el_values_size = @el_values;
for($i=0; $i<$el_values_size; $i=$i+1)
{
$el_array[$data_value_set_index][$i] = $el_values[$i];
}
$el_array_length[$data_value_set_index] = $el_values_size;
# Need to determine which set of el values has the most elements
# as all other el arrays will be expanded to fit this one.
if ($el_values_size > $max_el_values_size)
{
$max_el_values_index = $data_value_set_index;
$max_el_values_size = $el_values_size;
}
# read data values
# this is tricky because we read either until we encounter another
# header or comment line, or we reach eof :(
# for now, we will REQUIRE a comment break "$"; although this does not
# appear to be required, the files I've seen follow the rule.
# Clear the data values.
@data_values = ();
# Keep reading data until we encounter the "$" char (comment) at the first position of a line.
do
{
ReadAndTrim();
if (! $eof)
{
$char1 = substr $line, 0, 1; #check for valid data
# read el values;
push (@data_values, split(/\s+/, $line));
}
else
{
print "End of file.\n";
}
}
while ((!$eof) && (!($char1 =~ /\$/)));
# these need to be saved for later evaluation
$data_values_size = @data_values;
for($i=0; $i<$data_values_size; $i=$i+1)
{
$data_array[$data_value_set_index][$i] = $data_values[$i];
}
$data_array_length[$data_value_set_index] = $data_values_size;
# increment the data value set index
#print "Data Values: ", @data_values, "end_data_values\n";
$data_value_set_index = $data_value_set_index + 1;
# Find max set of el values. The entire table will have
# to be expanded and padded to include all elevation values.
}
else
{
#comment line; read next
ReadAndTrim();
}
}
# Done reading input
print "Done reading input.";
$el_array_padded[0] = $el_array[$max_el_values_index][0];
$index = 1;
while ($index != $max_el_values_size)
{
$offset = 0.0; # may change
push(@el_array_padded, $el_array[$max_el_values_index][$index]);
if ($index != ($max_el_values_size - 1))
{
push(@el_array_padded, $el_array[$max_el_values_index][$index]);
}
$index = $index + 1;
}
#now ready to write out data
$num_padded_el_values = @el_array_padded;
$num_padded_az_values = @az_array_padded;
#$num_padded_values = $num_padded_az_values * $num_padded_el_values;
# Three comment lines
print {ANT_OUT} "# Generated from Suppressor\n";
print {ANT_OUT} "# \n";
print {ANT_OUT} "# \n";
print {ANT_OUT} $num_padded_az_values, " ", $num_padded_el_values, "\n ";
$prevElValue = 500;
for ($i=0; $i<$num_padded_el_values; ++$i)
{
if ($el_array_padded[$i] == $prevElValue)
{
print {ANT_OUT} $el_array_padded[$i]+0.01, " ";
}
else
{
print {ANT_OUT} $el_array_padded[$i], " ";
}
$prevElValue = $el_array_padded[$i];
}
print {ANT_OUT} "\n";
#print el index
# All data for the first az bin (first and second indices) are available in the first el set.
# Just need to expand values into all el bins
$az_index = 0;
for ($az = 0; $az < $num_padded_az_values; ++$az)
{
$el_index = 0;
#print $az, " ", $az_array[$az_index], " ", $az_array_padded[$az],"\n";
for ($el = 0; $el < $num_padded_el_values; ++$el)
{
#print $az, " ", $el, " ", $az_index, " ", $el_index, " ", $el_array[$az_index][$el_index], " ", $el_array_padded[$el], " ", $data_array[$az_index][$el_index], "\n";
$pattern[$az][$el] = $data_array[$az_index][$el_index];
if ($el_array[$az_index][$el_index] < $el_array_padded[$el])
{
if ($el_array[$az_index][$el_index+1] <= $el_array_padded[$el])
{
$el_index += 1;
}
}
}
if ($az_array[$az_index] < ($az_array_padded[$az] - 0.0001))
{
$az_index += 1;
}
}
$prevAzValue = 500;
for ($az = 0; $az < $num_padded_az_values; ++$az)
{
if ($az_array_padded[$az] == $prevAzValue)
{
print {ANT_OUT} $az_array_padded[$az]+0.01, " ";
}
else
{
print {ANT_OUT} $az_array_padded[$az], " ";
}
$prevAzValue = $az_array_padded[$az];
for ($el = 0; $el < $num_padded_el_values; ++$el)
{
print {ANT_OUT} $pattern[$az][$el], " ";
}
print {ANT_OUT} "\n";
}
#print $az_array_padded;
# Close input and output files
close(ANT_IN);
close(ANT_OUT);
select(STDOUT);

View File

@@ -0,0 +1,44 @@
# ****************************************************************************
# UNCLASSIFIED//FOUO
# See AAA_ITAR.txt for distribution and usage.
# ****************************************************************************
DATA-TABLE
$ --UNCLASSIFIED
$ ...
$ ...
DIMENSION 1 AZ (DEG)
-180 -90 -30 0 30 90 180
$ EL DATA FOR AZ Interval: -180 to -90
DIMENSION 2 EL (DEG)
-90 -30 30 90
GAIN (DB)
-10 -8 -10
$ EL DATA FOR AZ Interval: -90 to -30
DIMENSION 2 EL (DEG)
-90 -30 0 30 90
GAIN (DB)
-9 -7 -7 -9
$ EL DATA FOR AZ Interval: -30 to 0
DIMENSION 2 EL (DEG)
-90 -30 -10 10 30 90
GAIN (DB)
-3 -2 0 -2 -3
$ EL DATA FOR AZ Interval: 0 to 30
DIMENSION 2 EL (DEG)
-90 -30 30 90
GAIN (DB)
-3 0 -3
$ EL DATA FOR AZ Interval: 30 to 90
DIMENSION 2 EL (DEG)
-90 -30 30 90
GAIN (DB)
-9 -7 -9
$ EL DATA FOR AZ Interval: 90 to 180
DIMENSION 2 EL (DEG)
-90 -30 30 90
GAIN (DB)
-10 -8 -10

View File

@@ -0,0 +1,85 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
###############################################################################
# simple AWACS Platform (Airborne CAOC)
###############################################################################
optical_signature awacs_optical_signature
constant 1000 m^2
end_optical_signature
radar_signature awacs_radar_signature
constant 1000 m^2
end_radar_signature
platform_type AWACS WSF_PLATFORM
icon KC-10
side blue
mover WSF_AIR_MOVER
default_linear_acceleration 1.0 g
default_radial_acceleration 1.0 g
end_mover
optical_signature awacs_optical_signature
radar_signature awacs_radar_signature
# command_chain sat-ops self // satellites
# command_chain uavs self // UAVs
# command_chain strike self // Strike assets
// --- * --- * ---
// Comm
// --- * --- * ---
# comm constellation-xmtr WSF_RADIO_XMTR
# frequency 900.0 mhz
# end_comm
# comm constellation-rcvr WSF_RADIO_RCVR
# frequency 1000.0 mhz
# internal_link track-proc
# end_comm
// --- * --- * ---
// Sensors
// --- * --- * ---
// N/A
sensor geo_sensor WSF_GEOMETRIC_SENSOR
azimuth_field_of_view -180.0 degrees 180.0 degrees
elevation_field_of_view -90.0 degrees 90.0 degrees
minimum_range 0 m
# 300 nm
maximum_range 555600 m
on
frame_time 0.5 sec
reports_location
reports_velocity
reports_iff
reports_bearing
#do not report weapons quality tracks
track_quality 0.75
ignore_same_side
internal_link track-proc
end_sensor
// --- * --- * ---
// Processors
// --- * --- * ---
processor track-proc WSF_TRACK_PROCESSOR
# purge_interval 5 min
purge_interval 120.0 sec
update_interval 10.0 sec
end_processor
end_platform_type

View File

@@ -0,0 +1,55 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
include_once ../weapons/aam/simple_a2a_missile.txt
platform_type BLUE_ADV_FIGHTER_1_BASE WSF_PLATFORM
icon F-22
category fighter
mover WSF_AIR_MOVER
roll_rate_limit 1 rad/sec
default_linear_acceleration 1.0 g
default_radial_acceleration 6.5 g
default_climb_rate 400 fps
# Mach 1.7 (1095.3 kts) at 30K feet, with afterburner, Janes Reference
maximum_speed 1095.3 knots
# Ceiling, Janes Reference
maximum_altitude 50000 ft
minimum_altitude 50 ft
# g limit, Janes Reference
maximum_linear_acceleration 9 g
#no_pitch
at_end_of_path extrapolate
end_mover
fuel WSF_VARIABLE_RATE_FUEL
rate 7.0 lb/s
initial_quantity 14000 lb
maximum_quantity 14000 lb
end_fuel
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 sec
update_interval 1 sec
end_processor
weapon int_missile SIMPLE_A2A_MISSILE_WEAPON end_weapon
end_platform_type

View File

@@ -0,0 +1,16 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for BLUE_ADV_FIGHTER_1
include_once blue_adv_fighter_1_base.txt
platform_type blue_adv_fighter_1 BLUE_ADV_FIGHTER_1_BASE
//nothing new for now
end_platform_type

View File

@@ -0,0 +1,120 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for BLUE_ADV_FIGHTER_1
include_once platforms/blue_adv_fighter_1_base.txt
#for AIAI-thinker
include_once processors/ripr_agents/aiai/aiai_processor.txt
include_once weapons/aam/simple_short_range_missile.txt
include_once weapons/aam/super_long_range_missile.txt
include_once weapons/aam/blue_lr_a2a_rf_missile.txt
platform_type blue_adv_fighter_1 BLUE_ADV_FIGHTER_1_BASE
//use a longer range missile for this type
//adjust missile ranges in int-thinker below to accomodate
delete weapon int_missile
#weapon int_missile SUPER_LONG_RANGE_MISSILE end_weapon
#weapon int_missile SIMPLE_LONG_RANGE_MISSILE end_weapon
#weapon aim9 SIMPLE_SHORT_RANGE_MISSILE end_weapon
#weapon jdradm SUPER_LONG_RANGE_MISSILE end_weapon
weapon blue_lr_a2a_rf_missile SIMPLE_BLUE_LR_A2A_RF_MISSILE
quantity 8
end_weapon
# edit weapon blue_sr_a2a_ir_missile
# quantity 2
# end_weapon
# edit weapon jdradm
# quantity 6
# end_weapon
//This is the code that lets the interceptor intercept
processor int-thinker AIAI-thinker
script_variables
#mWeaponArray[0] = Map<string, Object>();
#mWeaponArray[0].Set("name", "blue_sr_a2a_ir_missile");
#mWeaponArray[0].Set("weapon", PLATFORM.Weapon("blue_sr_a2a_ir_missile"));
#mWeaponArray[0].Set("rangeMin", 1000);
#mWeaponArray[0].Set("rangeMax", 65000); // ~35 miles
mWeaponArray[0] = Map<string, Object>();
mWeaponArray[0].Set("name", "blue_lr_a2a_rf_missile");
mWeaponArray[0].Set("weapon", PLATFORM.Weapon("blue_lr_a2a_rf_missile"));
mWeaponArray[0].Set("rangeMin", 1000);
mWeaponArray[0].Set("rangeMax", 111120); // ~60 miles
mWeaponArray[0].Set("numActiveMax", 2); // how many weapons of this type can be in play simultaneously
mWeaponArray[0].Set("AIR", 1); // DOMAIN CAPABLE, yes, this weapon can hit air (default true)
mWeaponArray[0].Set("LAND", 0); // DOMAIN CAPABLE, no, this weapon can NOT hit land (default false)
/*
mWeaponArray[1] = Map<string, Object>();
#mWeaponArray[1].Set("name", "blue_lr_a2a_rf_missile");
#mWeaponArray[1].Set("weapon", PLATFORM.Weapon("blue_lr_a2a_rf_missile"));
mWeaponArray[1].Set("name", "jdradm");
mWeaponArray[1].Set("weapon", PLATFORM.Weapon("jdradm"));
mWeaponArray[1].Set("rangeMin", 9260);
#mWeaponArray[1].Set("rangeMax", 111120); // ~60 miles
mWeaponArray[1].Set("rangeMax", 296320); // ~160 miles
mWeaponArray[1].Set("numActiveMax", 1); // how many weapons of this type can be in play simultaneously
*/
end_script_variables
end_processor
sensor geo_sensor WSF_GEOMETRIC_SENSOR
azimuth_field_of_view -180.0 degrees 180.0 degrees
elevation_field_of_view -90.0 degrees 90.0 degrees
//azimuth_field_of_view -60.0 degrees 60.0 degrees
//elevation_field_of_view -30.0 degrees 30.0 degrees
minimum_range 0 m
#maximum_range 100000 m
#maximum_range 138900 m #about 75 nm, 75% of missile range
maximum_range 185200 m #about 100 nm
on
frame_time 0.5 sec
reports_location
reports_velocity
reports_iff
track_quality 1.0
ignore_same_side
internal_link track_manager
end_sensor
processor incoming_threats WSF_THREAT_PROCESSOR
update_interval 0.1 sec
#update_interval 2.0 sec
#1300 knots
threat_velocity 668.7778 m/s
threat_angle_spread 20.0 deg
script void identified_new_threat(WsfTrack aTrack)
writeln("!!! me: ", PLATFORM.Name(), ", new threat: ", aTrack.TargetName(), ", speed: ", aTrack.Speed());
end_script
script void dropped_threat(WsfTrack aTrack)
if (aTrack.IsValid())
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat: ", aTrack.TargetName());
}
else
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat");
}
end_script
end_processor
end_platform_type

View File

@@ -0,0 +1,155 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
//include_once ../sensors/blue_esm.txt
//include_once ../weapons/blue_lr_a2a_rf_missile.txt
//include_once ../weapons/blue_sr_a2a_ir_missile.txt
//include_once ../weapons/harm2.txt
//include_once ../weapons/jsow.txt
//include_once aiai_weapon.txt
include_once ../sensors/radar/blue_a2a_radar.txt
include_once ../weapons/aam/simple_a2a_missile.txt
include_once ../signatures/blue_multirole_fighter_3_radar_signature.txt
platform_type BLUE_MULTIROLE_FIGHTER_1 WSF_PLATFORM
icon F-18E
category fighter
fuel WSF_VARIABLE_RATE_FUEL
rate 7.0 lb/s
initial_quantity 14000 lb
maximum_quantity 14000 lb
end_fuel
mover WSF_AIR_MOVER
roll_rate_limit 1 rad/sec
default_linear_acceleration 1.0 g
default_radial_acceleration 6.5 g
default_climb_rate 400 fps
//old value
//maximum_speed 600.0 knots
// Janes Reference, Max level speed: more than M1.8 (1160 kts)
maximum_speed 1160.0 knots
//old value
//maximum_altitude 55000 ft
//Combat Ceiling, Janes Reference
maximum_altitude 50000 ft
minimum_altitude 50 ft
maximum_linear_acceleration 8 g
#no_pitch
at_end_of_path extrapolate
end_mover
radar_signature blue_multirole_fighter_3_radar_signature
sensor blue_a2a_radar BLUE_A2A_RADAR
//debug
on
internal_link track_manager
ignore_same_side
end_sensor
sensor esm-1 BLUE_ESM
//debug
off
internal_link track_manager
end_sensor
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 sec
update_interval 1 sec
end_processor
weapon int_missile SIMPLE_A2A_MISSILE_WEAPON end_weapon
// weapon blue_lr_a2a_rf_missile BLUE_LR_A2A_RF_MISSILE
// quantity 10
// end_weapon
// weapon blue_sr_a2a_ir_missile BLUE_SR_A2A_IR_MISSILE
// quantity 2
// end_weapon
// weapon HARM2 HARM2_WEAPON
// quantity 2
// end_weapon
// weapon JSOW JSOW_WEAPON
// quantity 2
// end_weapon
end_platform_type
#xobject BLUE_MULTIROLE_FIGHTER_1 {
#x name "BLUE_MULTIROLE_FIGHTER_1 %d"
#x icon "f_18"
# opponent_icon "f_18"
#x team blue
# extern_attribute body_type_id 12
# sensors (
#x BLUE_A2A_RADAR
#x BLUE_ESM
# IFF )
#x tactics military_tactics
#x dynamics powered_dynamics
#x aero_model (
#x linear_accel 1.0 G
#x radial_accel 6.5 G
#x climb_rate 400.0 fps
#x max_speed 850.0 knots
#x max_alt 55000 ft
#x min_alt 50 ft
# fuel_table ( 76 (115 1.37 pps
# 150 1.59 pps
# 301 6.76 pps
# 321 23.4 pps)
# 5473 (143 1.24 pps
# 187 1.44 pps
# 293 4.65 pps
# 318 16.50 pps)
# 10671 (206 1.20 pps
# 236 1.27 pps
# 271 2.13 pps
# 295 7.37 pps))
# max_speed_table ( 76 321
# 4573 318
# 10671 295)
# fuel 14000 lb
# )
# launch_to_alt 32000 ft
# launch_to_speed 500 knots
#x stores (
#x blue_lr_a2a_rf_missile BLUE_LR_A2A_RF_MISSILE
#x HARM2 HARM2
#x JSOW
#x blue_sr_a2a_ir_missile BLUE_SR_A2A_IR_MISSILE)
# //nonsense accuracy values for testing
# tgt_err_attributes target_range_err 10.0 ft
# tgt_err_attributes target_az_err 0.01 deg
# tgt_err_attributes target_el_err 0.02 deg
# tgt_err_attributes target_rdot_err 1.0 ft
# tgt_err_attributes target_azdot_err 0.03 deg
# tgt_err_attributes target_eldot_err 0.04 deg
# tgt_err_attributes launch_azalign_err 0.05 deg
# tgt_err_attributes launch_elalign_err 0.06 deg
# tgt_err_attributes launch_rollalign_err 0.07 deg
# tgt_err_attributes launch_msl_align_err 0.08 deg
#x ir_signature (1.0 1.6 2.1 2.4 2.6 2.6 2.6 2.6 2.6 2.6 2.5 2.1
#x 1.6 2.1 2.5 2.6 2.6 2.6 2.6 2.6 2.6 2.4 2.1 1.6)
#x rcs3d F15CRCS
#x}
#

View File

@@ -0,0 +1,16 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for BLUE_MULTIROLE_FIGHTER_1
include_once blue_multirole_fighter_1_base.txt
platform_type blue_multirole_fighter_1 BLUE_MULTIROLE_FIGHTER_1
//nothing new for now
end_platform_type

View File

@@ -0,0 +1,73 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for BLUE_MULTIROLE_FIGHTER_1
include_once platforms/blue_multirole_fighter_1_base.txt
#for AIAI-thinker
include_once processors/ripr_agents/aiai/aiai_processor.txt
platform_type blue_multirole_fighter_1 BLUE_MULTIROLE_FIGHTER_1
//This is the code that lets the interceptor intercept
processor int-thinker AIAI-thinker
script_variables
mWeaponArray[0] = Map<string, Object>();
mWeaponArray[0].Set("name", "int_missile");
mWeaponArray[0].Set("weapon", PLATFORM.Weapon("int_missile"));
mWeaponArray[0].Set("rangeMin", 1000);
mWeaponArray[0].Set("rangeMax", 65000); // ~35 miles
mWeaponArray[0].Set("numActiveMax", 1); // how many weapons of this type can be in play simultaneously
end_script_variables
end_processor
//don't mess around with crappy radars, use a simple geometric sensor
delete sensor blue_a2a_radar
delete sensor esm-1
sensor geo_sensor WSF_GEOMETRIC_SENSOR
azimuth_field_of_view -180.0 degrees 180.0 degrees
elevation_field_of_view -90.0 degrees 90.0 degrees
minimum_range 0 m
maximum_range 100000 m
on
frame_time 0.5 sec
reports_location
reports_velocity
reports_iff
track_quality 1.0
ignore_same_side
internal_link track_manager
end_sensor
processor incoming_threats WSF_THREAT_PROCESSOR
update_interval 0.1 sec
#update_interval 2.0 sec
#1300 knots
threat_velocity 668.7778 m/s
script void identified_new_threat(WsfTrack aTrack)
writeln("!!! me: ", PLATFORM.Name(), ", new threat: ", aTrack.TargetName());
end_script
script void dropped_threat(WsfTrack aTrack)
if (aTrack.IsValid())
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat: ", aTrack.TargetName());
}
else
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat");
}
end_script
end_processor
end_platform_type

View File

@@ -0,0 +1,58 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
platform_type BOMBER WSF_PLATFORM
# icon EA-6B
icon B-52
mover WSF_AIR_MOVER
# WAGs - Luke Miklos
roll_rate_limit 0.7 rad/sec
default_linear_acceleration 0.7 g
default_radial_acceleration 2.5 g
default_climb_rate 300 fps
# Mach 0.9 (516.0 kts) at altitude, Janes Reference
maximum_speed 516.0 knots
# Ceiling, Janes Reference
maximum_altitude 55000 ft
minimum_altitude 1000 ft
# WAG - Luke Miklos
maximum_linear_acceleration 7 g
#no_pitch
at_end_of_path extrapolate
end_mover
fuel WSF_VARIABLE_RATE_FUEL
#rough calculation for fuel rate: based on max range, cruising speed, & max fuel
rate 4.0 lb/s
# Janes Reference, max fuel
# 46000 gallons internal, plus two 700 gallon underwing drop tanks
# jet fuel is 6 lb per gallon
initial_quantity 284400 lb
maximum_quantity 284400 lb
end_fuel
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 sec
update_interval 2 sec
end_processor
end_platform_type

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
AGE1 2.
CHISIG 6.
TCORR 10. 10. 10. !OBSERVATION CORRELATION TIMES
44444444444444444444444444400000000000000000000000 VALKEY 1-50
00000000000000000000000000000000000000000000000000 VALKEY 51-100
AGEMOD 5.0 20.0
0.5 5.0
0.25 1.0
5.0 20.0
5.0 60.0
5.0 60.0
0.1 1.0
VALSIG 0.001
VCUTF 0.6
MALTS 5
STKPN 5.0
TMUSUP 5.0
TRCH 20.0
TRCHW 5.0
WTVMSL 0.5
TPROJ 3.0
AGFOLO 20.0
AGERAD 10.0
CLIMBM 10000.0
GMAXM 4.0
RFXDLY 0.2 !REFLEX_DELAY - FOR MANEUVER IMPLEMENTATION AFTER DECISION IS
WRFORM 0.1
WRRFRM 0.5
RNGWPN 25000. 30000. 85000. 3000. 40000. !SRM,MRM,LRM,GUN,DEW
TVPOLD 15.
DETR0 0.02
TEARLY 4.99
HDSPRD 2.0
HDPKLO 0.05
HDPKHI 0.10
HDRKMX 0.5
HDPSMN 0.8
SPLITA 45.0
REQDLY 15.0
ORDDLY 20.1
CHSWLS .3
CHSWLO .2
10. NEARBY UPDATE INTERVAL
DTUDES 5.0
DELFAC 0.3
CWIDTH 5.0
MAXAC_LOW 3
MAXAC_MED 5
MAXAC_HI 10
SLOGEE 3.
SL_G_LEEWAY 2.
TNL_ALPHA 0.3
TNL_BETA_LOW 0.6
TNL_BETA_MED 0.75
TNL_BETA_HI 0.9
TNL_TAU_LOW 60.0
TNL_TAU_MED 30.0
TNL_TAU_HI 0.001
TNL_CNTRST 2.
HOTMIN 1000. !minimum height over terrain
FT_REJECT_T 0.02 !Time (per false tgt) to reject false targets (sec)
TAU_ESTAB 30. Establishment value time constant
ESTABLISH 20. Threshold for establishment
DIS-ESTABLISH 10. Threshold for disestablishment (currently unused)
PURGE 1. Threshold for purging (currently unused)
VISUAL 40. Value added for a visual observation
RADAR Values added for radar obs
SCAN 13.2 => roughly 2 hits in 20 seconds will establish
STT 40.
TWS 40.
SPOT 40.
ACTIVE 40.
MESSAGE 40.
INFERRED 40.
JAMMED_RADAR
SCAN 13.2
STT 40.
TWS 40.
SPOT 40.
ACTIVE 40.
JAMMED_MESSAGE 40.
IFF 40.
RHAW 40.
IRST 40.
MW 40.
MAW 40.
RWR 40.
SAN 40.
TTT 40.
SSS 40.
XAV 40.
TOC 40.
ESM 40.
EXT 40.
OTD 40.
DLD 40.

View File

@@ -0,0 +1,335 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#no other easy way in WSF to get relative NED position
#here we calculate a rough approximation ourselves
script Vec3 RelativePositionNED(WsfGeoPoint from, WsfGeoPoint to)
double deg2ft = 364812.76313;
Vec3 vec = Vec3.Construct( (to.Latitude() -from.Latitude() )*deg2ft,
(to.Longitude()-from.Longitude())*deg2ft*MATH.Cos(from.Latitude()*MATH.RAD_PER_DEG()),
-(to.Altitude() -from.Altitude() )*MATH.FT_PER_M());
return vec;
end_script
#replicates subroutine makecs(bxin,bzin,b)
script Array<double> makecs(Vec3 bxin, Vec3 bzin)
Array<double> b = Array<double>();
Vec3 bx;
Vec3 by;
Vec3 bz;
// Normalize bxin, store in bx
bx = bxin.Normal();
// Cross product of bzin and Normalized bxin, stored in by
by = Vec3.Cross(bzin, bx);
// Normalize by and evaluate the magnitude of original by
if (by.Normalize() == 0.0)
{
// If the magnitude of by is zero, replace by with cross of bx and unit Z vector
Vec3 unitZ = Vec3.Construct(0.0, 0.0, 1.0);
by = Vec3.Cross(unitZ, bx);
by.Normalize();
}
//cross product of bx and by stored in bz
bz = Vec3.Cross(bx, by);
b[0] = bx.Get(0); // b(1,1) = bx(1)
b[3] = bx.Get(1); // b(1,2) = bx(2)
b[6] = bx.Get(2); // b(1,3) = bx(3)
b[1] = by.Get(0); // b(2,1) = by(1)
b[4] = by.Get(1); // b(2,2) = by(2)
b[7] = by.Get(2); // b(2,3) = by(3)
b[2] = bz.Get(0); // b(3,1) = bz(1)
b[5] = bz.Get(1); // b(3,2) = bz(2)
b[8] = bz.Get(2); // b(3,3) = bz(3)
return b;
end_script
#replicates subroutine makex(cxin,[return c])
# EQUIVALENT TO MAKECS WHEN ARGUMENT BZIN = (0,0,1)
script Array<double> makex(Vec3 cxin)
Array<double> c = Array<double>();
Vec3 unitZ = Vec3.Construct(0.0, 0.0, 1.0);
c = makecs(cxin, unitZ);
return c;
end_script
#replicates subroutine makeh([return matrix], dir)
#returns an array (rot) that represents a 3x3 rotation matrix
#where rot[0] = matrix(1,1) and rot[1] == matrix(1,2)
script Array<double> makeh(Vec3 dir)
Array<double> rot = Array<double>();
double temp = MATH.Sqrt(dir[0]*dir[0] + dir[1]*dir[1]);
rot[0] = dir[0]/temp; #c(1,1) = cxin(1)/sngl(temp)
rot[1] = dir[1]/temp; #c(1,2) = cxin(2)/sngl(temp)
rot[2] = 0.0; #c(1,3) = 0.
rot[3] = -rot[1]; #c(2,1) = -c(1,2)
rot[4] = rot[0]; #c(2,2) = c(1,1)
rot[5] = 0.0; #c(2,3) = 0.
rot[6] = 0.0; #c(3,1) = 0.
rot[7] = 0.0; #c(3,2) = 0.
rot[8] = 1.0; #c(3,3) = 1.
return rot;
end_script
# replicates: subroutine vxfrmc(b,v, [return Vec3 vt],1)
# "b" represents a 3x3 rotation matrix
# where b[0] = matrix(1,1) and b[1] == matrix(1,2)
script Vec3 vxfrmc1(Array<double> b, Vec3 v)
#b = 3x3 rotation matrix where [0] = (1,1) and [1] == (1,2)
double x = v[0]*b[0]+v[1]*b[1]+v[2]*b[2];
double y = v[0]*b[3]+v[1]*b[4]+v[2]*b[5];
double z = v[0]*b[6]+v[1]*b[7]+v[2]*b[8];
Vec3 vt = Vec3.Construct(x,y,z);
return vt;
end_script
# replicates: subroutine vxfrmc(b,[return Vec3],vt,2)
# "b" represents a 3x3 rotation matrix
# where b[0] = matrix(1,1) and b[1] == matrix(1,2)
script Vec3 vxfrmc2(Array<double> b, Vec3 vt)
#b = 3x3 rotation matrix where [0] = (1,1) and [1] == (1,2)
double x = vt[0]*b[0]+vt[1]*b[3]+vt[2]*b[6];
double y = vt[0]*b[1]+vt[1]*b[4]+vt[2]*b[7];
double z = vt[0]*b[2]+vt[1]*b[5]+vt[2]*b[8];
Vec3 v = Vec3.Construct(x,y,z);
return v;
end_script
# replicates: subroutine rotx(chi,vin,[return vout])
# FINDS VECTOR IN A FRAME ROTATED BY CHI ABOUT X-AXIS
script Vec3 rotx(double chi, Vec3 vin)
double cchi = (Math.Cos(chi * Math.DEG_PER_RAD())) * Math.RAD_PER_DEG();
double schi = (Math.Sin(chi * Math.DEG_PER_RAD())) * Math.RAD_PER_DEG();
Vec3 vout = Vec3.Construct(vin[0], (cchi*vin[1]+schi*vin[2]), (-schi*vin[1]+cchi*vin[2]));
return vout;
end_script
# replicates: subroutine rotv(chi,vaxis,vin,[return vout])
# ROTATE VECTOR BY ANGLE ABOUT SPECIFIED AXIS
#CIN CHI REAL - DESIRED ANGLE OF ROTATION (radians)
#CIN VAXIS 3-VEC - AXIS OF ROTATION
#CIN VIN 3-VEC - UNROTATED VECTOR
#COUT VOUT 3-VEC - RESULT OF ROTATING VIN BY CHI ABOUT VAXIS
script Vec3 rotv(double chi, Vec3 vaxis, Vec3 vin)
Array<double> rot = Array<double>();
if (vaxis[0]*vaxis[0] + vaxis[1]*vaxis[1] == 0.0)
{
Vec3 unitX = Vec3.Construct(1,0,0);
rot = makecs(vaxis, unitX);
}
else
{
rot = makex(vaxis);
}
Vec3 vout = vxfrmc1(rot,vin);
vout = rotx(-chi,vout);
vout = vxfrmc2(rot,vout);
return vout;
end_script
# replicates: vmake(a,vin,vout)
# a - desired vector norm
# vector - vector to rescale
script Vec3 vmake(double a, Vec3 vin)
double b = a / vin.Magnitude();
// TODO prevent div by zero?
// b = a/sqrt(1.e-35 + vin(1)*vin(1) + vin(2)*vin(2) + vin(3)*vin(3))
Vec3 vout = Vec3.Construct(b*vin.X(), b*vin.Y(), b*vin.Z());
return vout;
end_script
# replicates: subroutine ramp(xlo,xval,xhi)
script double ramp(double xlo, double xval, double xhi)
double rampVal = (xval-xlo) / (xhi-xlo);
if(rampVal <= 0.0)
{
rampVal = 0.0;
}
if(rampVal >= 1.0)
{
rampVal = 1.0;
}
return rampVal;
end_script
# replicates: subroutine border(z, z0)
script double border(double z, double z0)
double border = 0;
if (z <= 0)
{
double t = (z / z0 - 1.0);
border = 1.0 / (1.0 + (t * t));
}
else
{
double u = (z / z0 + 1.0) * (z / z0 + 1.0);
border = u / (1 + u);
}
return border;
end_script
# replicates: subroutine cauchy(z, z0)
script double cauchy(double z, double z0)
double t = (z / z0);
return 1.0 / (1.0 + (t * t));
end_script
script Vec3 vorth(Vec3 a, Vec3 b)
double x = (a[0]*b[0]+a[1]*b[1]+a[2]*b[2])/(b[0]*b[0]+b[1]*b[1]+b[2]*b[2]);
Vec3 temp = b;
temp.Scale(x);
Vec3 c = Vec3.Subtract(a,temp);
return c;
end_script
script bool HaveWeapon(WsfPlatform plat)
for(int i=0; i<plat.WeaponCount(); i+=1)
{
if (plat.WeaponEntry(i).QuantityRemaining() >= 1)
{
return true;
}
}
return false;
end_script
script Vec3 unitv2(Vec3 a)
double mag = MATH.Sqrt(a.X()*a.X() + a.Y()*a.Y());
Vec3 val = Vec3.Construct(a.X()/mag, a.Y()/mag, 0.0);
return val;
end_script
#replicates portion of desvvi that calculates "vuse" and "spduse"
#function arguments:
# vdes = normalized direction vector
# spddes = speed in ft/sec
#returns a vec in ft/sec
script Vec3 desvvi(WsfBrawlerPlatform plat, Vec3 vdes, double spddes)
bool lngtrn;
Vec3 vuse = Vec3();
double spduse;
double cornrv = plat.CorneringVelocity(); //fps
double grav = 32.17405; //fps
double gmxsut = plat.MaxSustainedGs();
//C --external declarations
# integer rspace
# realdot,ramp,xlimit
# real arccos
//C --local declarations
//real h(2),hdes(2);
Vec3 h = Vec3();
Vec3 hdes = Vec3();
double d10 = 0.174533; //radians (10 deg)
double s30 = 0.5;
double s45 = 0.707107;
double s15 = 0.258819;
double dsemax,hnorm,csenow,senow;
//real arcsin
//C*ENDDEC
vuse = unitv2(vdes);
h = unitv2(plat.VelocityNED());
//C CURRENT HEADING COORDINATES:
//C X = [ H(1),H(2)]
//C Y = [-H(2),H(1)]
//hdes(1) = vuse(1)*h(1)+vuse(2)*h(2)
hdes.SetX(vuse.X()*h.X()+vuse.Y()*h.Y());
//C TO AVOID MESSING UP LATER ARCCOS(HDES(1)):
if(MATH.Fabs(hdes.X()) > 1.0)
{
if(MATH.Fabs(hdes.X()) > 1.000001)
{
//call nabort('HDES(1) NORM');
writeln("ABORT!!!! hdes(1) > 1.000001");
return Vec3();
}
hdes.SetX(1.0);
if (hdes.X() < 0)
{
hdes.SetX(-1.0);
}
}
hdes.SetY(-vuse.X()*h.Y()+vuse.Y()*h.X());
csenow = plat.Speed()*MATH.FT_PER_M()+0.01;
csenow = Vec3.Dot(vdes,plat.VelocityNED())/csenow;
senow = MATH.ACos(csenow);
double tproj3 = plat.ProjectedTimeDelta();
dsemax = tproj3*(gmxsut*grav/cornrv);
//C LNGTRN REQUIRES LARGE ERRORS IN BOTH MAGNITUDE AND HEADING
lngtrn = MATH.ACos(hdes.X()) > dsemax && senow > 1.5*dsemax;
if (!lngtrn)
{
//C
//C SHORTER TURN:
//C
vuse = vdes;
spduse = spddes;
//goto 9999
}
else
{
//C
//C LONGER TURN:
//C
if((plat.Speed()*MATH.FT_PER_M()) > 0.9*cornrv)
{
if((plat.Speed()*MATH.FT_PER_M()) < 1.1*cornrv)
{
//C HERE SPEED NEAR CORNER - MAINTAIN MODEST DIVE TO HELP MAINTAIN SPD
vuse.SetZ(s15);
}
else
{
//C TOO FAST - PULL UP WHILE TURNING
//format('DESVVI... TOO FAST, CORNER = ',f8.2,' MACH ',f5.1)
vuse.SetZ(-s45*ramp(1.1*cornrv,plat.Speed()*MATH.FT_PER_M(),1.2*cornrv));
}
}
else
{
//C TOO SLOW - SET 30 DEG DIVE
vuse.SetZ(s30);
}
hnorm = MATH.Sqrt(1.0-vuse.Z()*vuse.Z());
if(hdes.X() > 0.0)
{
//C RENORMALIZE HORIZONTAL FOR LESS THAN 90 DEG HEADING CHANGES
vuse.SetX(vuse.X()*hnorm);
vuse.SetY(vuse.Y()*hnorm);
}
else
{
//C SET UP 90 DEG HEADING CHANGE AND DO ROTATION BACK TO EARTH COORDINATES
//C IMPLICIT IS HDES(1) = 0
hdes.SetY(hnorm);
if (hdes.Y() < 0)
{
hdes.SetY(-hnorm);
}
vuse.SetX(-h.Y()*hdes.Y());
vuse.SetY(h.X()*hdes.Y());
}
spduse = cornrv;
//goto 9999
}
//C
//9999
vuse.Normalize();
vuse.Scale(spduse);
return vuse;
end_script

View File

@@ -0,0 +1,23 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior alt1514_point
precondition
return 1.0;
end_precondition
execute
extern int kturn;
kturn = 0; //go straight at target
end_execute
end_behavior

View File

@@ -0,0 +1,26 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior alt1516_bvr_end_run_left
script_variables
end_script_variables
precondition
return 1.0;
end_precondition
execute
extern int kturn;
kturn = -1; //go left around target
writeln_d("executed alt1516_bvr_end_run_left");
end_execute
end_behavior

View File

@@ -0,0 +1,22 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior alt1517_bvr_end_run_right
precondition
return 1.0;
end_precondition
execute
extern int kturn;
kturn = 1; //go right around target
end_execute
end_behavior

View File

@@ -0,0 +1,112 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt31.f
// Replicates the straight and level at max speed 3,1,1,1 alternative behavior
behavior alt3111_straight_level_max_speed
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3111Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 1;
int icall = 1;
int lcall = 1;
Vec3 mDir0 = Vec3();
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3111_straight_level_max_speed, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3111Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
# C STRAIGHT AND LEVEL AT MAX SPEED
#10 iactn = 4
# lenalt = lactn(iactn)
# altdsc = indpk(3,1,1,1)
# call xmit(2,vp(1,me),dir0)
# dir0(3) = 0.
# call vnorm(dir0,dir0)
# gmx = gmxsu
# spdmod = thrttl
# spd0 = 3.
# go to 800
mDir0 = PLATFORM.VelocityNED();
mDir0.SetZ(0.0);
mDir0.Normalize();
mGMX = brawlerPlatform.MaxSustainedGs();
mSpd0 = 3.0;
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,117 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt31.f
// Replicates the straight and level (current speed) 3,1,2,1 alternative behavior
behavior alt3121_straight_level
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3121Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 1;
int icall = 2;
int lcall = 1;
Vec3 mDir0;
double mGMX = 1.0;
double mSpd0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3121_straight_levelt, T=", TIME_NOW);
#writeln_d("T = ", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3121Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
# C STRAIGHT-AND-LEVEL
#20 iactn = 4
# lenalt = lactn(iactn)
# altdsc=indpk(3,1,2,1)
# call xmit(2,vp(1,me),dir0)
# dir0(3) = 0.
# call vnorm(dir0,dir0)
# gmx = gmxsu
# spd0 = spdnow(me)
# spdmod = desspd
mDir0 = PLATFORM.VelocityNED();
mDir0.SetZ(0.0);
mDir0.Normalize();
mGMX = brawlerPlatform.MaxSustainedGs();
mSpd0 = PLATFORM.Speed();
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithSpeed(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
writeln_d("T=", TIME_NOW, ", alt3121_straight_level = ", score);
return score;
end_precondition
execute
writeln_d("3121_straight_level, dir0 = ", mDir0.ToString());
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithSpeed(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,103 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt32.f and captrn.f
// Replicates the route maneuver 3,2,1,1 and cap turn 3,2,2,1 alternative behavior
// This behavior will just fly the WSF platform route
behavior alt3211_route_maneuver
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3211Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 2;
int icall = 1;
int lcall = 1;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3411_straight_flight, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3211Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() > 0)
{
// Fail if we should be pursuing a weapon task
return Failure("pursuing WEAPON task");
}
WsfRoute route = PLATFORM.Route();
if (!route.IsValid() || route.Size() < 2)
{
// Fail if we do not have a valid route
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " invalid route");
writeln_d(msg);
return Failure(msg);
}
// Otherwise return a high score for this alternative
// so it is picked and we just follow our route
double score = 10.0;
return score;
end_precondition
execute
PLATFORM.ReturnToRoute();
end_execute
end_behavior

View File

@@ -0,0 +1,169 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f
// Replicates the 1v1 Offensive Maneuver 3,4,1,1 alternative behavior
// Straight Flight
//
// Operates on nearest perceived threat to generate maneuver alternative
behavior alt3411_straight_flight
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
WsfLocalTrack targetTrack;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3411Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 1;
int lcall = 1;
double mLongRange = 5.0 * Math.M_PER_NM();
Vec3 dir0;
double mGMX = 1.0;
double mSpd0 = 3.0;
// ALSO NEED:
// randomization to simulate imperfect decision making, valsig, read from MIND file, typically ~0.01
// Production rule bias, used in scoring of alternative
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3411_straight_flight, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3411Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (target) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
targetTrack = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!targetTrack.IsValid())
{
return Failure("no target track!");
}
// Get nearest hostile and check that range is less than max
// alt34.f line 114
WsfTrack nearestHostile = perception.NearestThreat();
double rangeToNearest = 999999999; # default large value, in meters
if (nearestHostile.IsValid() &&
nearestHostile.LocationValid())
{
rangeToNearest = nearestHostile.SlantRangeTo(PLATFORM);
}
if (!nearestHostile.IsValid())
{
writeln_d("nearest hostile not valid!");
return Failure("no vaild hostiles closer than 5 nautical miles");
}
if (rangeToNearest > mLongRange)
{
writeln_d("nearest hostile too far away! (", rangeToNearest," m)");
return Failure("no vaild hostiles closer than 5 nautical miles");
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
# alt34.f line 115 - 121
# iactn = 4
# call vnorm(vp(1,me),dir0) - get a unit vector (dir0) of my current velocity vector
# gmx = amin1(3.,gmxsu) - take the smaller of 3.0 and Maximum load possible at maximum thrust
# spd0 = 3.
# spdmod = thrttl (desspd = 1, thrttl = 2, desacc = 3)
int iactn = 4;
dir0 = PLATFORM.VelocityNED().Normal();
mGMX = Math.Min(3.0, brawlerPlatform.MaxSustainedGs());
mSpd0 = 3.0;
int spdmod = 2; // thrttl
### Project and Evaluate (Score) Maneuver Alternative
// Alternative is only projected tproj sec and then evaluated
double alternativeScore = brawlerPlatform.EvaluateVectorWithThrottle(dir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
writeln_d(PLATFORM.Name(), " behavior_alt3411_straight_flight score = ", alternativeScore, ", T=", TIME_NOW);
### Return Maneuver Alternative Score
return alternativeScore;
end_precondition
execute
#writeln_d(PLATFORM.Name(), " executing behavior_alt3411_straight_flight, T=", TIME_NOW);
brawlerPlatform.FlyVectorWithThrottle(dir0, mGMX, mSpd0);
# if (mDrawSteering == true)
# {
# mDraw.SetLayer("behavior_pursue_target");
# mDraw.SetDuration(processor.UpdateInterval());
# mDraw.SetColor(1.0, 0.5, 0.0);
# mDraw.SetLineSize(1);
# mDraw.BeginLines();
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(mTargetPoint);
# mDraw.End();
# }
#
# string msg = write_str("pursue-target: ", targetTrack.TargetName(), " at speed ", (string)mTargetSpeed);
# writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
# FlyTarget( PLATFORM, mTargetPoint, mTargetSpeed);
end_execute
end_behavior

View File

@@ -0,0 +1,145 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt342.f
// Replicates the 3,4,2,1 alternative behavior
// alt3421_roll_+15_pull
include_once BrawlerScriptUtil.txt
behavior alt3421_roll_15_pull
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3421Enabled = true;
double mLongRange = 5.0 * Math.M_PER_NM();
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 2;
int lcall = 1;
Vec3 a0; # maneuver plane
Vec3 dir0; # direction vector
double gmx; # max Gs
double spd0; # throttle setting
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3421 roll_+15_pull, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3421Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
## alt 34.f line 97, & 140
#lrange = rhst*ftnmi .gt. 5.0
#if(lrange)goto 15
WsfTrack nearestHostile = perception.NearestThreat();
double rangeToNearest = 999999999; # default large value, in meters
if (nearestHostile.IsValid() &&
nearestHostile.LocationValid())
{
rangeToNearest = nearestHostile.SlantRangeTo(PLATFORM);
}
if (!nearestHostile.IsValid())
{
writeln_d("nearest hostile not valid!");
return Failure("no vaild hostiles closer than 5 nautical miles");
}
if (rangeToNearest > mLongRange)
{
writeln_d("nearest hostile too far away! (", rangeToNearest," m)");
return Failure("no vaild hostiles closer than 5 nautical miles");
}
##alt342.f line 99-112
## GENERATE MAX TURNS IN MANEUVER PLANES ADJACENT TO PRESENT PLANE
## ROLL +15 & PULL
#iactn = 4
#dir0(1) = 0.
#dir0(2) = sd15
#dir0(3) = -cd15
#call vxfrmc(rwep,dir0,dir0,2)
## DIR0 IS UNIT ACCELERATION VECTOR IN DESIRED MANEUVER PLANE
#call manpln(dir0,gmxsu)
double sd15 = 0.2588190;
double cd15 = 0.9659258;
dir0 = Vec3.Construct(0.0, sd15, -cd15);
dir0 = brawlerPlatform.ConvertWindtoNED(dir0);
double gmxsu = brawlerPlatform.MaxTacticalGs();
#call manpln(dir0,gmxsu)
#manpln() - maneuver in plane: replicated in 6 lines below
dir0 = vorth(dir0, PLATFORM.VelocityNED());
dir0.Normalize();
int iactn = 4;
gmx = gmxsu;
spd0 = 3.0;
int spdmod = 2; //thrttl
### Project and Evaluate (Score) Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
PLATFORM.FlyVectorWithThrottle(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,140 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt343.f
// Replicates the 3,4,3,1 alternative behavior
// alt3431_roll-15_pull
behavior alt3431_roll-15_pull
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3431Enabled = true;
double mLongRange = 5.0 * Math.M_PER_NM();
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 3;
int lcall = 1;
Vec3 a0; # maneuver plane
Vec3 dir0; # direction vector
double gmx; # max Gs
double spd0; # throttle setting
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3431 roll-15_pull, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3431Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
## alt 34.f line 97, & 140
#lrange = rhst*ftnmi .gt. 5.0
#if(lrange)goto 15
WsfTrack nearestHostile = perception.NearestThreat();
double rangeToNearest = 999999999; # default large value, in meters
if (nearestHostile.IsValid() &&
nearestHostile.LocationValid())
{
rangeToNearest = nearestHostile.SlantRangeTo(PLATFORM);
}
if (!nearestHostile.IsValid())
{
writeln_d("nearest hostile not valid!");
return Failure("no vaild hostiles closer than 5 nautical miles");
}
if (rangeToNearest > mLongRange)
{
writeln_d("nearest hostile too far away! (", rangeToNearest," m)");
return Failure("no vaild hostiles closer than 5 nautical miles");
}
##alt343.f line 99-109
## ROLL -15 & PULL
#dir0(1) = 0.
#dir0(2) = -sd15
#dir0(3) = -cd15
#call vxfrmc(rwep,dir0,dir0,2)
## DIR0 IS UNIT ACCELERATION VECTOR IN DESIRED MANEUVER PLANE
#call manpln(dir0,gmxsu)
double sd15 = 0.2588190;
double cd15 = 0.9659258;
dir0 = Vec3.Construct(0.0, -sd15, -cd15);
dir0 = brawlerPlatform.ConvertWindtoNED(dir0);
double gmxsu = brawlerPlatform.MaxTacticalGs();
#call manpln(dir0,gmxsu)
#manpln() - maneuver in plane: replicated in 6 lines below
dir0 = vorth(dir0, PLATFORM.VelocityNED());
dir0.Normalize();
int iactn = 4;
gmx = gmxsu;
spd0 = 3.0;
int spdmod = 2; //thrttl
### Project and Evaluate (Score) Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
PLATFORM.FlyVectorWithThrottle(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,331 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt344.f
// Replicates the 3,4,4,1 alternative behavior
// alt3441_tail_attack
include_once BrawlerScriptUtil.txt
behavior alt3441_tail_attack
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
WsfLocalTrack targetTrack;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3441Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 4;
int lcall = 1;
Vec3 a0; # maneuver plane
Vec3 dir0; # direction vector
double gmx; # max Gs
double spd0; # speed or throttle setting (depending on spdmod)
int spdmod;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
#when talatk() is done:
# dir0 is normalized
# spd0 is in units of ft/sec (or set to 3.0 for throttle mode)
script void talatk()
writeln_d("alt3441 tail attack: talatk");
# # local declarations
# integer jacid
# real t,pres,dens,vs,pr,dr,xcarot(3),vcarot(3)
# real xprj(3),vprj(3),rhprj(3,3),dlag,dlagn,dlagun,vtemp(3)
# real dxtail(3),aprj(3),ause(3),dt,spdwtd,x_tgt(3)
# data dlagn/5000./,dlagun/1000./
# # ENDDEC
# # SET TARGET POSITION BEHIND TARGET A/C A DISTANCE DLAG
# jacid = iacidt(iac)
# dlag=dlagn
# if(.not.noaim) dlag= (ppmrmn+ppmrmx)/2.
# if(mslpp.eq.nummis+1) dlag= dlagun
# # GET POSITION OF AC 5 SECONDS IN FUTURE:
# dt = 5.
# #if (xp(3,iac).ge.trkr_neg_alt) call nabort('talatk...tgt more than /par/trkr_neg_alt feet below ground')
# call xmit3(xp(1,iac),x_tgt)
# if (x_tgt(3).ge.0.) x_tgt(3) = -1.0
# call atmos(-x_tgt(3),t,pres,dens,vs,pr,dr)
# call a_lim(x_tgt,vp(1,iac),ap(1,iac),dt,casmin(iac)/sqrt(dr),ause)
# call projw(x_tgt,vp(1,iac),ause,dt,xprj,vprj,aprj,rhprj)
# call vmake(-dlag,vprj,vtemp)
# call vsum(x_tgt,vtemp,dxtail)
# call vsub(dxtail,xp(1,me),dxtail)
# call vecinc(vp(1,iac),0.5/tproj3,dxtail,dir0)
# spd0 = xmag(dir0)
# spdmod = desspd
# spdwtd = spdnow(me)+almax*tproj3*1.1
# if (spd0 .gt. spdwtd)
# {
# spd0 = 3.
# spdmod = thrttl
# }
# call vnorm(dir0,dir0)
double dlagn = 5000.0;
double dlagun = 1000.0;
double dlag = dlagn;
## check if we have a weapon task - it shouldn't reach this point if we didn't
#if(.not.noaim) dlag= (ppmrmn+ppmrmx)/2.
## check if we have a weapon, otherwise close at gun range
#if(mslpp.eq.nummis+1) dlag= dlagun
if (!HaveWeapon(PLATFORM))
{
dlag = dlagun;
}
# GET POSITION OF AC 5 SECONDS IN FUTURE:
double dt = 5.0;
#if (xp(3,iac).ge.trkr_neg_alt) call nabort('talatk...tgt more than /par/trkr_neg_alt feet below ground')
# call xmit3(xp(1,iac),x_tgt)
# ##LBM - dont do projection for now
# if (x_tgt(3).ge.0.) x_tgt(3) = -1.0
# call atmos(-x_tgt(3),t,pres,dens,vs,pr,dr)
# call a_lim(x_tgt,vp(1,iac),ap(1,iac),dt,casmin(iac)/sqrt(dr),ause)
# call projw(x_tgt,vp(1,iac),ause,dt,xprj,vprj,aprj,rhprj)
//LBM - not able to perceive target's acceleration
//assume target's velocity after dt is same as now
//LBM - convert everything to feet when calculating against BRAWLER constants
// convert back to meters to call WSF commands
Vec3 vprj = targetTrack.VelocityNED();
Vec3 vtemp = vprj.Normal();
vtemp.Scale(-dlag);
# Vec3 x_tgt; //target position
# Vec3 xp; //my position
# Vec3 dxtail = Vec3.Add(x_tgt,vtemp); #adding vtemp is not accounted for in the line below
# dxtail = Vec3.Subtract(dxtail,xp);
Vec3 dx = RelativePositionNED(PLATFORM.Location(), targetTrack.CurrentLocation());
dx.Scale(MATH.FT_PER_M());
Vec3 dxtail = Vec3.Add(dx,vtemp);
Vec3 vpt = targetTrack.VelocityNED();
vpt.Scale(MATH.FT_PER_M());
dxtail.Scale(0.5/brawlerPlatform.ProjectedTimeDelta());
dir0 = Vec3.Add(vpt,dxtail);
spd0 = dir0.Magnitude(); #ft/sec
spdmod = 1; //(desspd = 1, thrttl = 2, desacc = 3)
#double almax = brawlerPlatform.MaxForwardAccelWithGravity() * MATH.M_PER_FT();
double almax = brawlerPlatform.MaxForwardAccelWithGravity(); #ft/sec^2
double spdwtd = PLATFORM.Speed()*MATH.FT_PER_M() + almax * brawlerPlatform.ProjectedTimeDelta() * 1.1;
if (spd0 > spdwtd)
{
spd0 = 3.0;
spdmod = 2; //(desspd = 1, thrttl = 2, desacc = 3)
}
dir0.Normalize();
end_script
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3441 tail_attack, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3441Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
writeln_d("no weapon (target) tasks!");
return Failure("no weapon (target) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
targetTrack = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!targetTrack.IsValid())
{
writeln_d("no target track!");
return Failure("no target track!");
}
if (!targetTrack.VelocityValid())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " target track does not have valid velocity!");
writeln_d(msg);
return Failure(msg);
}
##alt344.f line 172 - 224
int iactn = 4;
# GENERATE TURNS IN MANEUVER PLANE CONTAINING LOS TO OPPONENT
Vec3 dxpme = RelativePositionNED(PLATFORM.Location(),targetTrack.CurrentLocation());
Vec3 vp = PLATFORM.VelocityNED();
Vec3 vp_iac = targetTrack.VelocityNED();
bool bhndme = (Vec3.Dot(dxpme,vp) < 0.0);
bool bhndhm = (Vec3.Dot(dxpme,vp_iac) > 0.0);
if (bhndme && bhndhm)
{
# BEHIND EACH OTHER: WANT COURSE REVERSAL
# USE TAIL ATTACK FOR NOW
talatk();
}
else if (bhndme && !bhndhm)
{
# HE'S ON MY TAIL!: NO TAIL ATTACK ALTERNATIVE GENERATED
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " HE IS ON MY TAIL! NO TAIL ATTACK!");
writeln_d(msg);
return Failure(msg);
}
else if (!bhndme && bhndhm)
{
# I'M ON HIS TAIL!: GENERATE TAIL ATTACK
talatk();
}
else if (!bhndme && !bhndhm)
{
# NOSE TO NOSE: PLAN INTERCEPT
#call aimpt(xp(1,me),spdnow(me),xp(1,iac),vp(1,iac),spdnow(iac),daimpt,lsoln);
WsfWaypoint aimptWP = WsfWaypoint();
double intTime = PLATFORM.InterceptLocation3D(targetTrack, aimptWP);
#if (lsoln)
if (intTime > 0)
{
WsfGeoPoint daimpt = aimptWP.Location();
#call vsub(daimpt,xp(1,me),dxaim);
Vec3 dxaim = RelativePositionNED(PLATFORM.Location(), daimpt); #NED coordinates
dir0 = dxaim.Normal();
spd0 = 3.0;
spdmod = 2; //(desspd = 1, thrttl = 2, desacc = 3)
}
else
{
//return Failure("ERROR: intercept somehow not possible, even though head to head with target!");
# ASSUME OVERSHOOT, SO TRY A TAIL ATTACK
talatk();
}
}
else
{
//call nabort('AL344...UNKNOWN GEOMETRY');
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " ...UNKNOWN GEOMETRY");
writeln_d(msg);
return Failure(msg);
}
//lmore = .true.
double gmxsu = brawlerPlatform.MaxTacticalGs();
gmx = gmxsu;
### Project and Evaluate (Score) Maneuver Alternative
double score = 0;
if (spdmod == 2)
{
score = brawlerPlatform.EvaluateVectorWithThrottle(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
}
else
{
score = brawlerPlatform.EvaluateVectorWithSpeed(dir0, gmx, spd0 * MATH.M_PER_FT(), ilevel, kalt, icall, lcall);
}
writeln_d("T=", TIME_NOW, ", 3441_tail_attack = ", score);
writeln_d("raw = ", brawlerPlatform.RawManeuverValueComponent("offensive"),
", ", brawlerPlatform.RawManeuverValueComponent("low speed recovery"),
", ", brawlerPlatform.RawManeuverValueComponent("defensive"),
", ", brawlerPlatform.RawManeuverValueComponent("illumination"),
", ", brawlerPlatform.RawManeuverValueComponent("missile evasion"),
", ", brawlerPlatform.RawManeuverValueComponent("missile aiming"));
writeln_d("component = ", brawlerPlatform.ManeuverValueComponent("offensive"),
", ", brawlerPlatform.ManeuverValueComponent("low speed recovery"),
", ", brawlerPlatform.ManeuverValueComponent("defensive"),
", ", brawlerPlatform.ManeuverValueComponent("illumination"),
", ", brawlerPlatform.ManeuverValueComponent("missile evasion"),
", ", brawlerPlatform.ManeuverValueComponent("missile aiming"));
writeln_d("tunnel = ", brawlerPlatform.TunnelVisionMultiplier("offensive"),
", ", brawlerPlatform.TunnelVisionMultiplier("low speed recovery"),
", ", brawlerPlatform.TunnelVisionMultiplier("defensive"),
", ", brawlerPlatform.TunnelVisionMultiplier("illumination"),
", ", brawlerPlatform.TunnelVisionMultiplier("missile evasion"),
", ", brawlerPlatform.TunnelVisionMultiplier("missile aiming"));
writeln_d("bias = ", brawlerPlatform.InherentBiasFaults("aggressiveness"),
", ", brawlerPlatform.InherentBiasFaults("mutual support"),
", ", brawlerPlatform.InherentBiasFaults("airspeed maintenance"));
writeln_d("mult = ", brawlerPlatform.OffensiveMultiplier(),
", ", brawlerPlatform.DefensiveMultiplier());
if (targetTrack.Target().IsValid())
{
writeln_d("engage = ", brawlerPlatform.LastEngagementValue(targetTrack.Target()));
}
return score;
end_precondition
execute
writeln_d("3441_tail_attack");
## what was evaluated should be actually performed now
if (spdmod == 2)
{
PLATFORM.FlyVectorWithThrottle(dir0, gmx, spd0);
}
else
{
PLATFORM.FlyVectorWithSpeed(dir0, gmx, spd0 * MATH.M_PER_FT());
}
end_execute
end_behavior

View File

@@ -0,0 +1,129 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt345.f
// Replicates the 3,4,5,1 alternative behavior
// alt3451_pull_gmax_sust
include_once BrawlerScriptUtil.txt
behavior alt3451_pull_gmax_sust
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3451Enabled = true;
bool mCheckRollOverTopValue = true; #this alternative assumes a different one has already evaluated and flown (to set the roll over the top value)
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 5;
int lcall = 1;
Vec3 a0; # maneuver plane
Vec3 dir0; # direction vector
double gmx; # max Gs
double spd0; # throttle setting
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3451 pull_gmax_sust, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3451Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
##alt34.f line 160 //filter out this alternative?
double valrot = brawlerPlatform.RollOverTopValue();
if(mCheckRollOverTopValue == true && valrot == 0.0)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " valrot == 0");
writeln_d(msg);
return Failure(msg);
}
##alt345.f line 104 - 119
#iactn = 4
#call makeh(vp(1,me),rot)
#dir0(1) = 0.001
#dir0(2) = 0.0
#dir0(3) = -1.000
#call vxfrmc(rot,dir0,dir0,2)
#call vnorm(dir0,dir0)
#gmx = gmxsu
#spd0 = 3.
#spdmod = thrttl
int iactn = 4;
Vec3 vp = PLATFORM.VelocityNED();
Array<double> rot = makeh(vp);
dir0 = Vec3.Construct(0.001, 0.0, -1.0);
dir0 = vxfrmc2(rot, dir0);
dir0.Normalize();
double gmxsu = brawlerPlatform.MaxTacticalGs();
gmx = gmxsu;
spd0 = 3.0;
int spdmod = 2; //thrttl // spdmod = thrttl (desspd = 1, thrttl = 2, desacc = 3)
### Project and Evaluate (Score) Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
PLATFORM.FlyVectorWithThrottle(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,113 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt347.f
// Replicates the 3,4,7,1 alternative behavior
// alt3471_slow_current_dir
behavior alt3471_slow_current_dir
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3471Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 7;
int lcall = 1;
Vec3 a0; # maneuver plane
Vec3 dir0; # direction vector
double gmx; # max Gs
double spd0; # throttle setting
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3471 slow_current_dir, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3471Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
##alt347.f line 108 //initialize value
#call vnorm(vp(1,me),myvdir)
##alt347.f line 124 - 134
#iactn=4
#call xmit(3,myvdir,dir0)
#gmx=amin1(3.,gmxsu)
#spd0=spdnow(me)+almin*tproj3*1.1
#spd0 = amax1(200.,spd0)
#spdmod = desspd
Vec3 myvdir = PLATFORM.VelocityNED().Normal();
int iactn = 4;
dir0 = myvdir;
double gmxsu = brawlerPlatform.MaxTacticalGs();
gmx = MATH.Min(3.0,gmxsu);
double almin = brawlerPlatform.MinForwardAccelWithGravity(); #ft/sec^2
spd0 = PLATFORM.Speed() * MATH.FT_PER_M() + almin * brawlerPlatform.ProjectedTimeDelta() * 1.1;
spd0 = MATH.Max(200.0, spd0);
spd0 *= MATH.M_PER_FT();
int spdmod = 1; //desspd // spdmod = thrttl (desspd = 1, thrttl = 2, desacc = 3)
### Project and Evaluate (Score) Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithSpeed(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
PLATFORM.FlyVectorWithSpeed(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,119 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt347.f
// Replicates the 3,4,7,2 alternative behavior
// alt3472_slow_pull_right
behavior alt3472_slow_pull_right
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3472Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 7;
int lcall = 2;
Vec3 a0; # maneuver plane
Vec3 dir0; # direction vector
double gmx; # max Gs
double spd0; # throttle setting
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3472 slow_pull_right, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3472Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
##alt347.f line 108 //initialize value
#call vnorm(vp(1,me),myvdir)
##alt347.f line 135 - 148
#iactn=4
#acc0(1)=0.
#acc0(2)=sroll
#acc0(3)=-croll
#call vxfrmc(rwep,dir0,acc0,2)
#gmx=gmxsu
#spd0=spdnow(me)+almin*tproj3*1.1
#spd0 = amax1(200.,spd0)
#spdmod = desspd
Vec3 myvdir = PLATFORM.VelocityNED().Normal();
int iactn = 4;
double sroll = 0.2588190; //sin of roll angle (15 deg)
double croll = 0.9659258; //cos of roll angle (15 deg)
Vec3 acc0 = Vec3.Construct(0.0, sroll, -croll);
dir0 = brawlerPlatform.ConvertWindtoNED(acc0);
double gmxsu = brawlerPlatform.MaxTacticalGs();
gmx = gmxsu;
double almin = brawlerPlatform.MinForwardAccelWithGravity();
spd0 = PLATFORM.Speed() * MATH.FT_PER_M() + almin * brawlerPlatform.ProjectedTimeDelta() * 1.1;
spd0 = MATH.Max(200.0, spd0);
spd0 *= MATH.M_PER_FT();
int spdmod = 1; //desspd // spdmod = thrttl (desspd = 1, thrttl = 2, desacc = 3)
### Project and Evaluate (Score) Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithSpeed(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
PLATFORM.FlyVectorWithSpeed(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,119 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt347.f
// Replicates the 3,4,7,3 alternative behavior
// alt3473_slow_pull_left
behavior alt3473_slow_pull_left
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3473Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 7;
int lcall = 3;
Vec3 a0; # maneuver plane
Vec3 dir0; # direction vector
double gmx; # max Gs
double spd0; # throttle setting
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3473 slow_pull_left, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3473Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
##alt347.f line 108 //initialize value
#call vnorm(vp(1,me),myvdir)
##alt347.f line 150 - 163
#iactn=4
#acc0(1)=0.
#acc0(2)=-sroll
#acc0(3)=-croll
#call vxfrmc(rwep,dir0,acc0,2)
#gmx=gmxsu
#spd0=spdnow(me)+almin*tproj3*1.1
#spd0 = amax1(200.,spd0)
#spdmod = desspd
Vec3 myvdir = PLATFORM.VelocityNED().Normal();
int iactn = 4;
double sroll = 0.2588190; //sin of roll angle (15 deg)
double croll = 0.9659258; //cos of roll angle (15 deg)
Vec3 acc0 = Vec3.Construct(0.0, -sroll, -croll);
dir0 = brawlerPlatform.ConvertWindtoNED(acc0);
double gmxsu = brawlerPlatform.MaxTacticalGs();
gmx = gmxsu;
double almin = brawlerPlatform.MinForwardAccelWithGravity();
spd0 = PLATFORM.Speed() * MATH.FT_PER_M() + almin * brawlerPlatform.ProjectedTimeDelta() * 1.1;
spd0 = MATH.Max(200.0, spd0);
spd0 *= MATH.M_PER_FT();
int spdmod = 1; //desspd // spdmod = thrttl (desspd = 1, thrttl = 2, desacc = 3)
### Project and Evaluate (Score) Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithSpeed(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
PLATFORM.FlyVectorWithSpeed(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,121 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt34.f -> alt347.f
// Replicates the 3,4,7,4 alternative behavior
// alt3474_slow_pull_current_plane
behavior alt3474_slow_pull_current_plane
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3474Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 4;
int icall = 7;
int lcall = 4;
Vec3 a0; # maneuver plane
double gmx; # max Gs
double spd0; # throttle setting
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
double grav = 32.17405;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition alt3474 slow_pull_current_plane, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3474Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
##alt347.f line 108 //initialize value
#call vnorm(vp(1,me),myvdir)
##alt347.f line 165 - 183
#if(xmag(ap(1,me)).lt.0.1)then
# //FAIL
#endif
#iactn=3
#call cross(myvdir,ap(1,me),a0)
#call vnorm(a0,a0)
#gmx = gmxsu*grav
#--spd0 is a throttle setting under the NEW iactn=3 format
#spd0 = -1.0
Vec3 myvdir = PLATFORM.VelocityNED().Normal();
Vec3 ap = PLATFORM.AccelerationNED(); //meters/sec^2
ap.Scale(Math.FT_PER_M()); //convert to feet/sec^2
if(ap.Magnitude() < 0.1)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " acceleration not high enough to clearly define a maneuever plane!");
writeln_d(msg);
return Failure(msg);
}
int iactn = 3;
a0 = Vec3.Cross(myvdir, ap).Normal();
double gmxsu = brawlerPlatform.MaxTacticalGs();
gmx = gmxsu*grav;
#--spd0 is a throttle setting under the NEW iactn=3 format
#spd0 = -1.0; //this means 100% thrust reversal setting
spd0 = 1.0; //NO thrust reversal in brawler -> -1 gets converted to 1 (mil power)
### Project and Evaluate (Score) Maneuver Alternative
double score = brawlerPlatform.EvaluateTurnInPlaneWithThrottle(a0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
PLATFORM.PullGsInPlaneWithThrottle(a0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,207 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt35.f
// Replicates the 1v1 Defensive Maneuver 3,5,1,1 alternative behavior
// Defensive right break turn
// Operates on nearest perceived threat to generate maneuver alternative
include_once BrawlerScriptUtil.txt
behavior alt3511_break_right
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3511Enabled = true;
bool mCheckRange = true;
bool mCheckBoresight = true;
bool mCheckClosingSpeed = true;
// Alternative ID
int ilevel = 3;
int kalt = 5;
int icall = 1;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0;
double mGMX = 1.0;
double mSpd0 = 3.0;
// ALSO NEED:
// randomization to simulate imperfect desision making, valsig, read from MIND file, typically ~0.01
// Production rule bias, used in socring of alternative
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3511_break_right, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3511Enabled)
{
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (hostile) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
WsfLocalTrack hostile = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!hostile.IsValid())
{
return Failure("no hostile track!");
}
//TODO - change this script so it doesn't use a truth method?
if (hostile.TargetKilled())
{
return Failure("hostile was destroyed!");
}
// alt35.f line 136 - 140
//if the predicted range (rngun) between me and threat greater then 2 nautical miles, skip
double projectionTime = TIME_NOW + brawlerPlatform.ProjectedTimeDelta();
WsfGeoPoint projectedHostileLocation = hostile.LocationAtTime(projectionTime);
double rangeToHostile = PLATFORM.SlantRangeTo(projectedHostileLocation);
if (mCheckRange == true && rangeToHostile > 2.0 * Math.M_PER_NM())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " nearest hostile further than 2 nautical miles");
writeln_d(msg);
return Failure(msg);
}
//if the off-bore angle between threat and me is greater than pi/2, skip
if (mCheckBoresight == true && brawlerPlatform.OffBoresightAngle(hostile.Target(), PLATFORM) > Math.PI_OVER_2())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Boresight angle between hostile and me greater than Pi/2");
writeln_d(msg);
return Failure(msg);
}
//if the off-bore angle between me and the threat is less than pi/2 check more conditions
if (mCheckBoresight == true && brawlerPlatform.OffBoresightAngle(PLATFORM, hostile.Target()) < Math.PI_OVER_2())
{
//if the predicted range rate (rngrun) of the threat is greater then zero, skip
if (mCheckClosingSpeed == true && PLATFORM.ClosingSpeedOf(hostile) > 0)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Hostile is not closing");
writeln_d(msg);
return Failure(msg);
}
//if the predicted range minus the range rate * 2 is greater than 3000, skip
if (mCheckRange == true && rangeToHostile * Math.FT_PER_M() - (PLATFORM.ClosingSpeedOf(hostile) * 3.28084 * 2.0) > 3000.0)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Hostile further than 3000 ft within 2 seconds");
writeln_d(msg);
return Failure(msg);
}
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
// alt35.f line 141 - 153
# fill dir0 with values from dxpme(1,iac)
# vxfrmc(rwep,dir0,dir0,1) - transforms vectors as specified by an orientation matrix
# dir0(1) = 0
# vxfrmc(rwep,dir0,dir0,2)
# if(-xp(3,me).lt.5000.) dir0(3) = amin1(0.,dir0(3))
# vnorm(dir0,dir0)
# gmx = gmxin+(2.-gmxin)*ramp(1.,rngun(iac)*ftnmi,2.)
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,5,icall,1,iacidt(iac),0)
# spd0 = 3.
# spdmod = thrttl
mDir0 = RelativePositionNED(PLATFORM.Location(), projectedHostileLocation);
mDir0 = brawlerPlatform.ConvertNEDtoWind(mDir0);
mDir0.SetX(0.0);
mDir0 = brawlerPlatform.ConvertWindtoNED(mDir0);
if (PLATFORM.Altitude() < 5000.0 * Math.M_PER_FT())
{
mDir0.SetZ( Math.Min(0.0, mDir0.Z()) );
}
mDir0.Normalize();
mGMX = brawlerPlatform.MaxAvailableGs() + (2.0 - brawlerPlatform.MaxAvailableGs()) *
ramp(1.0, rangeToHostile * Math.M_PER_NM(), 2.0);
mSpd0 = 3.0;
### Evaluate (Score) Maneuver Alternative
double alternativeScore = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
### Return Maneuver Alternative Score
return alternativeScore;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing behavior_alt3511_break_right, T=", TIME_NOW);
// Fly this alternative
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
# if (mDrawSteering == true)
# {
# mDraw.SetLayer("behavior_pursue_target");
# mDraw.SetDuration(processor.UpdateInterval());
# mDraw.SetColor(1.0, 0.5, 0.0);
# mDraw.SetLineSize(1);
# mDraw.BeginLines();
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(mTargetPoint);
# mDraw.End();
# }
#
# string msg = write_str("pursue-target: ", targetTrack.TargetName(), " at speed ", (string)mTargetSpeed);
# writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
# FlyTarget( PLATFORM, mTargetPoint, mTargetSpeed);
end_execute
end_behavior

View File

@@ -0,0 +1,210 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt35.f
// Replicates the 1v1 Defensive Maneuver 3,5,3,1 alternative behavior
// Defensive left break turn
// Operates on nearest perceived threat to generate maneuver alternative
include_once BrawlerScriptUtil.txt
behavior alt3531_break_left
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3531Enabled = true;
bool mCheckRange = true;
bool mCheckBoresight = true;
bool mCheckClosingSpeed = true;
// Alternative ID
int ilevel = 3;
int kalt = 5;
int icall = 3;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0;
double mGMX = 1.0;
double mSpd0 = 3.0;
// ALSO NEED:
// randomization to simulate imperfect desision making, valsig, read from MIND file, typically ~0.01
// Production rule bias, used in socring of alternative
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3531_break_left, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3531Enabled)
{
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (hostile) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
WsfLocalTrack hostile = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!hostile.IsValid())
{
return Failure("no hostile track!");
}
//TODO - change this script so it doesn't use a truth method?
if (hostile.TargetKilled())
{
return Failure("hostile was destroyed!");
}
// alt35.f line 184 - 188
# if(rngun(iac)*ftnmi .gt. 2.) go to 205
# if(obang(iac,me) .gt. hafpi) go to 205
# if(obang(me,iac).gt.hafpi) go to 232
# if(rngrun(iac) .gt. 0.) go to 205
# if(rngun(iac)-rngrun(iac)*2. .gt. 3000.) go to 205
//if the predicted range (rngun) between me and threat greater then 2 nautical miles, skip
double projectionTime = TIME_NOW + brawlerPlatform.ProjectedTimeDelta();
WsfGeoPoint projectedHostileLocation = hostile.LocationAtTime(projectionTime);
double rangeToHostile = PLATFORM.SlantRangeTo(projectedHostileLocation);
if (mCheckRange == true && rangeToHostile > 2.0 * Math.M_PER_NM())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " nearest hostile further than 2 nautical miles");
writeln_d(msg);
return Failure(msg);
}
//if the off-bore angle between threat and me is greater than pi/2, skip
if (mCheckBoresight == true && brawlerPlatform.OffBoresightAngle(hostile.Target(), PLATFORM) > Math.PI_OVER_2())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Boresight angle between hostile and me greater than Pi/2");
writeln_d(msg);
return Failure(msg);
}
//if the off-bore angle between me and the threat is less than pi/2 check more conditions
if (mCheckBoresight == true && brawlerPlatform.OffBoresightAngle(PLATFORM, hostile.Target()) < Math.PI_OVER_2())
{
//if the predicted range rate (rngrun) of the threat is greater then zero, skip
if (mCheckClosingSpeed == true && PLATFORM.ClosingSpeedOf(hostile) > 0)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Hostile is not closing");
writeln_d(msg);
return Failure(msg);
}
//if the predicted range minus the range rate * 2 is greater than 3000, skip
if (mCheckRange == true && rangeToHostile * Math.FT_PER_M() - (PLATFORM.ClosingSpeedOf(hostile) * 3.28084 * 2.0) > 3000.0)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " Hostile further than 3000 ft within 2 seconds");
writeln_d(msg);
return Failure(msg);
}
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
// alt35.f line 189 - 201
#232 continue
# call xmit(3,dxp(1,me,iac),dir0)
# call vxfrmc(rwep,dir0,dir0,1)
# dir0(1) = 0.
# call vxfrmc(rwep,dir0,dir0,2)
# if(-xp(3,me).lt.5000.) dir0(3) = amin1(0.,dir0(3))
# call vnorm(dir0,dir0)
# gmx = gmxin+(2.-gmxin)*ramp(1.,rngun(iac)*ftnmi,2.)
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,5,icall,1,iacidt(iac),0)
# spd0 = 3.
# spdmod = thrttl
mDir0 = RelativePositionNED(PLATFORM.Location(), projectedHostileLocation);
mDir0 = brawlerPlatform.ConvertNEDtoWind(mDir0);
mDir0.SetX(0.0);
mDir0 = brawlerPlatform.ConvertWindtoNED(mDir0);
if (PLATFORM.Altitude() < 5000.0 * Math.M_PER_FT())
{
mDir0.SetZ( Math.Min(0.0, mDir0.Z()) );
}
mDir0.Normalize();
mGMX = brawlerPlatform.MaxAvailableGs() + (2.0 - brawlerPlatform.MaxAvailableGs()) *
ramp(1.0, rangeToHostile * Math.M_PER_NM(), 2.0);
mSpd0 = 3.0;
### Evaluate (Score) Maneuver Alternative
double alternativeScore = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
### Return Maneuver Alternative Score
return alternativeScore;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing behavior_alt3531_break_left, T=", TIME_NOW);
// Fly this alternative
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
# if (mDrawSteering == true)
# {
# mDraw.SetLayer("behavior_pursue_target");
# mDraw.SetDuration(processor.UpdateInterval());
# mDraw.SetColor(1.0, 0.5, 0.0);
# mDraw.SetLineSize(1);
# mDraw.BeginLines();
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(mTargetPoint);
# mDraw.End();
# }
#
# string msg = write_str("pursue-target: ", targetTrack.TargetName(), " at speed ", (string)mTargetSpeed);
# writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
# FlyTarget( PLATFORM, mTargetPoint, mTargetSpeed);
end_execute
end_behavior

View File

@@ -0,0 +1,156 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt35.f
// Replicates the 1v1 Defensive Maneuver 3,5,5,1 alternative behavior
// RUN AWAY!
include_once BrawlerScriptUtil.txt
behavior alt3551_run_away
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3551Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 5;
int icall = 5;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0 = Vec3();
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3551_run_away, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3551Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
writeln_d("no weapon (hostile) tasks!");
return Failure("no weapon (hostile) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
WsfLocalTrack hostile = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!hostile.IsValid())
{
writeln_d("no hostile track!");
return Failure("no hostile track!");
}
//TODO - change this script so it doesn't use a truth method?
if (hostile.TargetKilled())
{
writeln_d("hostile was destroyed!");
return Failure("hostile was destroyed!");
}
// alt35.f line 233 - 234
# rrunmn = 5.*ramp(twopi,obang(iac,me)+obang(me,iac),0.)
# if(rngun(iac)*ftnmi .lt. rrunmn) go to 205
double obang_hostile_me = brawlerPlatform.OffBoresightAngle(hostile.Target(), PLATFORM);
double obang_me_hostile = brawlerPlatform.OffBoresightAngle(PLATFORM, hostile.Target());
double rrunmn = 5.0 * ramp(Math.TWO_PI(), obang_hostile_me + obang_me_hostile, 0.0);
double projectionTime = TIME_NOW + brawlerPlatform.ProjectedTimeDelta();
WsfGeoPoint projectedHostileLocation = hostile.LocationAtTime(projectionTime);
double rangeToHostile = PLATFORM.SlantRangeTo(projectedHostileLocation);
if (rangeToHostile * Math.M_PER_NM() < rrunmn)
{
// Hostile too far
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " range to hostile < minimum range to run");
writeln_d(msg);
return Failure(msg);
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
// alt35.f line 235 - 243
#245 continue
# iactn = 4
# call vmult(-1.,dxeuan(1,iac),dir0)
# lenalt = lactn(iactn)
# altdsc = altpk(3,5,icall,1,iacidt(iac),0)
# dir0(3) = 0.
# gmx = gmxsu
# spd0 = 3.
# spdmod = thrttl
Vec3 dxeuan = RelativePositionNED(PLATFORM.Location(), projectedHostileLocation);
mDir0.SetX(dxeuan.X() * -1.0);
mDir0.SetY(dxeuan.Y() * -1.0);
mDir0.SetZ(0.0);
mGMX = brawlerPlatform.MaxSustainedGs();
mSpd0 = 3.0;
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
writeln_d("mDir0 = ", mDir0.ToString(), ", mGMX = ", mGMX, ", mSpd0 = ", mSpd0, ", score = ", score, ", my speed = ", PLATFORM.Speed());
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,143 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt35.f
// Replicates the force overshoot 3,5,6,1 alternative behavior
behavior alt3561_force_overshoot
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3561Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 5;
int icall = 6;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0;
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3561_force_overshoot, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3561Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (hostile) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
WsfLocalTrack hostile = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!hostile.IsValid())
{
return Failure("no hostile track!");
//TODO also validate location / veloctiy
}
// alt35.f line 247
# if(rngun(iac).gt.3000.) go to 205
double projectionTime = TIME_NOW + brawlerPlatform.ProjectedTimeDelta();
WsfGeoPoint projectedHostileLocation = hostile.LocationAtTime(projectionTime);
double rangeToHostile = PLATFORM.SlantRangeTo(projectedHostileLocation);
if (rangeToHostile > 3000 * Math.FT_PER_M())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " hostile range greater than 3000 ft");
writeln_d(msg);
return Failure(msg);
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
// alt35.f line 249 - 256
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,5,icall,1,iacidt(iac),0)
# call cros1(vp(1,me),vp(1,iac),dir0)
# if(dir0(3).gt.0.) call vmult(-1.,dir0,dir0)
# gmx = amin1(5.,gmxin)
# spd0 = spdnow(me)+almin*tproj3*1.1
# spdmod = desspd
Vec3 myVdir = PLATFORM.VelocityNED();
Vec3 tgtVdir = hostile.VelocityNED();
mDir0 = Vec3.Cross(myVdir, tgtVdir);
mDir0.Normalize();
if (mDir0.Z() > 0)
{
mDir0.Scale(-1.0);
}
mGMX = Math.Min(5.0, brawlerPlatform.MaxAvailableGs());
double almin = brawlerPlatform.MinForwardAccelWithGravity();
mSpd0 = PLATFORM.Speed() * MATH.FT_PER_M() + almin * brawlerPlatform.ProjectedTimeDelta() * 1.1;
mSpd0 *= MATH.M_PER_FT();
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithSpeed(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
writeln_d("T=", TIME_NOW, ", 3561_force_overshoot = ", score);
return score;
end_precondition
execute
writeln_d("3561_force_overshoot");
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithSpeed(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,165 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt35.f
// Replicates the negative velocity 3,5,8,1 alternative behavior
include_once BrawlerScriptUtil.txt
behavior alt3581_negative_velocity
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3581Enabled = true;
bool mCheckBoresight = true;
bool mCheckRange = true;
// Alternative ID
int ilevel = 3;
int kalt = 5;
int icall = 8;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0;
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3581_negative_velocity, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3581Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (hostile) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
WsfLocalTrack hostile = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!hostile.IsValid())
{
return Failure("no hostile track!");
}
//TODO - change this script so it doesn't use a truth method?
if (hostile.TargetKilled())
{
return Failure("hostile was destroyed!");
}
// alt35.f line 282 - 285
# if(spdut(iac).eq.0.0)goto 205
# if(obang(iac,me).gt.hafpi) go to 205
# rrunmn = 5.*ramp(twopi,obang(iac,me)+obang(me,iac),0.) <- same as 3551
# if(rngun(iac)*ftnmi .gt. rrunmn+1.) go to 205
if (!hostile.VelocityValid() || (hostile.Speed()*MATH.FT_PER_M()) < 1)
{
// If we don't have valid velocity or spoed is effectively zero
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " hostile has invalid or no speed");
writeln_d(msg);
return Failure(msg);
}
double obang_hostile_me = brawlerPlatform.OffBoresightAngle(hostile.Target(), PLATFORM);
double obang_me_hostile = brawlerPlatform.OffBoresightAngle(PLATFORM, hostile.Target());
if (mCheckBoresight == true && obang_hostile_me > Math.PI_OVER_2())
{
// Not ahead of hostile
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " off boresight angle hostile to me > Pi/2");
writeln_d(msg);
return Failure(msg);
}
double rrunmn = 5.0 * ramp(Math.TWO_PI(), obang_hostile_me + obang_me_hostile, 0.0);
double projectionTime = TIME_NOW + brawlerPlatform.ProjectedTimeDelta();
WsfGeoPoint projectedHostileLocation = hostile.LocationAtTime(projectionTime);
double rangeToHostile = PLATFORM.SlantRangeTo(projectedHostileLocation);
if (mCheckRange == true && rangeToHostile * Math.M_PER_NM() < rrunmn + 1.0)
{
// Hostile too far
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " range to hostile < minimum range to run");
writeln_d(msg);
return Failure(msg);
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
// alt35.f line 286 - 292
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,5,icall,1,iacidt(iac),0)
# call vmake(-1.,veut(1,iac),dir0)
# gmx = gmxsu
# spd0 = 3.
# spdmod = thrttl
mDir0 = vmake(-1.0, hostile.VelocityNED());
mGMX = brawlerPlatform.MaxSustainedGs();
mSpd0 = 3.0;
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,153 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted from BRAWLER v7.5 alt36.f
// Replicates the blah blah 3,6,1,1 alternative behavior
// blah blah
// alt3611_fly_vector
behavior alt3611_fly_vector
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
WsfLocalTrack targetTrack;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3611Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 6;
int icall = 1;
int lcall = 1;
double mMaxSustainedG = 2.0;
double mLongRange = 5.0 * Math.M_PER_NM();
Vec3 dir0;
double gmx = 1.0;
double spd0 = 3.0;
// ALSO NEED:
// randomization to simulate imperfect decision making, valsig, read from MIND file, typically ~0.01
// Production rule bias, used in scoring of alternative
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt33841_aim_missile_typ4, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
### check if alternative should even be considered?
if (!mAlternative3611Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (target) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
targetTrack = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!targetTrack.IsValid())
{
return Failure("no target track!");
}
extern Vec3 vecfpp;
extern double valfpp;
extern double sflypp;
#alt36()
#iactn = 4
#set_gmx()
Vec3 vv = vecfpp.Normal();
dir0 = desvvi(brawlerPlatform, vv, sflypp);
spd0 = dir0.Magnitude();
dir0.Normalize();
//spdmod = desspd;
//call indupk(altd1,tac_ilevel,tac_kalt,tac_icall,tac_lcall);
//if (tac_kalt.ne.8 .or. tac_icall.ne.2) then
if ((PLATFORM.Speed()*MATH.FT_PER_M()) <= spd0+100.0)
{
double gmxsut = brawlerPlatform.MaxSustainedGs();
double gmxsu = brawlerPlatform.MaxTacticalGs();
double wt = ramp(spd0 - 100.0, PLATFORM.Speed()*MATH.FT_PER_M(),spd0+100.0);
gmx = wt*MATH.Max(2.0,MATH.Max(gmxsut,gmxsu)) + (1.0-wt)*MATH.Min(gmxsut,gmxsu);
gmx = MATH.Max(gmx,2.0);
}
else
{
gmx = brawlerPlatform.MaxAvailableGs(); #gmxin;
}
//else
#LBM - not doing GCI drag tactic (1,8,2,1) right now
//...
//endif
spd0 *= MATH.M_PER_FT();
double score = brawlerPlatform.EvaluateVectorWithSpeed(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
writeln_d("alt3611_fly_vector score = ", score);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithSpeed(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,201 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt38.f
// Replicates the blah blah 3,8,4,1 alternative behavior
// blah blah
//alt3841_aim_missile_typ4
//LBM - NOTE: using typ4 because it uses maneuver type 4 (instead of type 9)
// according to notes in BRAWLER, this is the replacement for typ1
// especially for certain sims because of stability problems
behavior alt3841_aim_missile_typ4
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
WsfLocalTrack targetTrack;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3841Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 8;
int icall = 4;
int lcall = 1;
double mMaxSustainedG = 2.0;
double mLongRange = 5.0 * Math.M_PER_NM();
Vec3 dir0;
double gmx = 1.0;
double spd0 = 3.0;
// ALSO NEED:
// randomization to simulate imperfect decision making, valsig, read from MIND file, typically ~0.01
// Production rule bias, used in scoring of alternative
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt33841_aim_missile_typ4, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
### check if alternative should even be considered?
if (!mAlternative3841Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (target) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
targetTrack = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!targetTrack.IsValid())
{
return Failure("no target track!");
}
bool alt_ctrl = false; //see ali38()
bool msl_loft = false; //see line 147 (no productions rules right now)
## alt38.f : lines 136 - 150
#if (noaim) go to 980
#if (mslpp .ge. nummis+1) then
if (!HaveWeapon(PLATFORM))
{
# SKIP ALT_CTRL DETERMINATION IF SELECTED WEAPON IS A GUN
alt_ctrl = false;
msl_loft = false;
//go to 900
}
else
{
#call gmisld(ppmptr,1) #TODO
# Call special handler to see if desire missile loft
#call pcode(23) #TODO
# Loft missile if ready and pr_loft is set
#msl_loft = (ready && pr_loft); #TODO
}
## alt38.f : lines 227 - 253
# generate aim_missile_typ4 unless alt_ctrl = T.
if (alt_ctrl)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " alt_ctrl is true, do not do aim_missile_typ4 behavior");
writeln_d(msg);
return Failure(msg);
}
# generate aim_missile_typ1 if pointing in direction of aimpoint
#LBM - not doing vectored flight right now
# if (valfpp > 0.0)
# {
# double theta = sepa(dxeuan(1,ppmiac),vecfpp);
# if (theta > 0.8*zeta_lim)
# {
# return Failure("not pointing in right direction, do not do aim_missile_typ4 behavior");
# }
# }
#LBM - not a manned sim, dont even check, right now
#if (simltr != mansim) goto 900
# This is a replacement for icall=1 maneuver, for manned simulators
# Use a type 4 maneuver to avoid stability problems with type
# 9 maneuver at WSSC:
int iactn = 4;
Vec3 ppmapt; //calculated from mlsenv() -> envgeo() -> aimpt()
WsfWaypoint aimptWP = WsfWaypoint();
double weaponSpeedFtSec = 3349.35; //(mach 3) ft/sec
double intTime = PLATFORM.InterceptLocation3D(targetTrack, aimptWP, weaponSpeedFtSec, 5.0);
if (intTime < 0)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " missile intercept not possible!");
writeln_d(msg);
return Failure(msg);
}
#call vdir(xp(1,me),ppmapt,desdir);
Vec3 desdir = RelativePositionNED(PLATFORM.Location(), aimptWP.Location());
desdir.Normalize();
double spddes = PLATFORM.Speed()*MATH.FT_PER_M(); //from ali38() -> slow_aim is never set, so use current speed
#call des1v1(desdir,spddes,dir0,spd0,lngtrn,semin,sewid);
spd0 = spddes; //from des1v1 (direct copy, duh)
dir0 = desdir; //from des1v1 (direct copy, duh)
int spdmod = 1; //(desspd = 1, thrttl = 2, desacc = 3)
if ((PLATFORM.Speed()*MATH.FT_PER_M()) <= spd0+100.0)
{
double gmxsut = brawlerPlatform.MaxSustainedGs();
double gmxsu = brawlerPlatform.MaxTacticalGs();
double wt = ramp(spd0-100.0, PLATFORM.Speed()*MATH.FT_PER_M(), spd0+100.0);
gmx = wt*MATH.Max(2.0,MATH.Max(gmxsut,gmxsu)) + (1.0-wt)*MATH.Min(gmxsut,gmxsu);
gmx = MATH.Max(gmx,2.0);
}
else
{
gmx = brawlerPlatform.MaxAvailableGs(); #gmxin
}
spd0 *= MATH.M_PER_FT();
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithSpeed(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithSpeed(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,119 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt39.f
// Replicates the evade missile 3,9,1,1 alternative behavior
// GENERATES MISSILE EVASION MANEUVER
behavior alt3911_evade_missile
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfThreatProcessor threatProc;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3911Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 9;
int icall = 1;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0 = Vec3();
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
threatProc = (WsfThreatProcessor)PLATFORM.Processor("incoming_threats");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3911_straight_flight, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3911Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTrack threat = threatProc.NearestThreat();
if (!threat.IsValid())
{
// This check equivalent to noneed in alt39.f
writeln_d("no incoming missiles");
return Failure("no incoming missiles");
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,9,1,1,0,0)
# call xmit(3,direv,dir0)
# gmx = gmxin
# spd0 = throtm(iacid) <- limits throttle to 2 if there are IR missiles coming at me
# spdmod = thrttl
// Get stored evasion direction vector
//Vec3 direvd = brawlerPlatform.EvasionDirection();
Vec3 direvd = brawlerPlatform.EvasionDirection();
mDir0 = direvd;
mGMX = brawlerPlatform.MaxAvailableGs();
mSpd0 = 2; // Always 2 for now
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,140 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt3a.f
// Replicates the low speed recover 3,A,1,1 alternative behavior
include_once BrawlerScriptUtil.txt
behavior alt3A11_low_speed_recover
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3A11Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 10;
int icall = 1;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0 = Vec3();
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3411_straight_flight, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3A11Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
if (!brawlerPlatform.SlowFlight())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " not in slow flight");
writeln_d(msg);
return Failure(msg);
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
# C ALTERNATIVE 1: "ALMOST" STRAIGHT DOWN
#20 continue
#C --SET DIR0 ALMOST STRAIGHT DOWN, BUT SLIGHLY IN THE DIRECTION
#C --OF MY CURRENT VELOCITY
# call xmit3(unitz,dir0)
# call vcross(vp(1,me),unitz,vtemp)
# call rotv(2.0*rad,vtemp,dir0,dir0)
# go to 990
#990 submor = .true.
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,10,icall,1,0,0)
#C --SET TO HIGHEST THROTTLE SETTING FOR MAX SPEED
# spd0 = 3.
# spdmod = thrttl
# call srch(dragvl,ndatbl,acmasp*grav,index,xx) <- search drag versus lift table for aircraft mass * gravity
# if(index.ne.0) go to 995
# index = ndatbl
# xx = 0.0
#995 continue
# gmx = gmxin*(index-xx-1.0)/(ndatbl-1.0)
# gmx = amax1(gmx,1.5)
# gmx = 1.5+(gmx-1.5)*ramp(.5,vp(3,me)/spdnow(me),0.)
mDir0 = Vec3.Construct(0, 0, 1);
Vec3 vtemp = Vec3.Cross(PLATFORM.VelocityNED(), mDir0);
double rad = Math.PI()/180.0;
mDir0 = rotv(2.0*rad, vtemp, mDir0);
mSpd0 = 3;
mGMX = brawlerPlatform.MaxAvailableGs(); // TODO add drag v lift
mGMX = Math.Max(mGMX, 1.5);
Vec3 vp = PLATFORM.VelocityNED();
double speed = PLATFORM.Speed() * Math.FT_PER_M(); // Speed in f/sec
mGMX = 1.5 + (mGMX - 1.5) * ramp(0.5, (vp[2] * Math.FT_PER_M()/speed), 0.0);
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,139 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt3a.f
// Replicates the low speed recover right 45 deg 3,A,2,1 alternative behavior
behavior alt3A21_low_speed_recover_right45
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3A21Enabled = false;
// Alternative ID
int ilevel = 3;
int kalt = 10;
int icall = 2;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0 = Vec3();
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
// Magic numbers from alt3a.f
double sd45 = 0.7071068;
double cd45 = 0.7071068;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3411_straight_flight, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3A21Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
if (!brawlerPlatform.SlowFlight())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " not in slow flight");
writeln_d(msg);
return Failure(msg);
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
#C ALTERNATIVE 2: ROLL +45 DEGREES
#40 continue
# dir0(1) = 0.
# dir0(2) = sd45
# dir0(3) = -cd45
# call vxfrmc(rbep,dir0,dir0,2)
# go to 990
#990 submor = .true.
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,10,icall,1,0,0)
#C --SET TO HIGHEST THROTTLE SETTING FOR MAX SPEED
# spd0 = 3.
# spdmod = thrttl
# call srch(dragvl,ndatbl,acmasp*grav,index,xx)
# if(index.ne.0) go to 995
# index = ndatbl
# xx = 0.0
#995 continue
# gmx = gmxin*(index-xx-1.0)/(ndatbl-1.0)
# gmx = amax1(gmx,1.5)
# gmx = 1.5+(gmx-1.5)*ramp(.5,vp(3,me)/spdnow(me),0.)
mDir0 = Vec3.Construct(0.0, sd45, -cd45);
//TODO convert from earth to body coordinates
mSpd0 = 3;
mGMX = brawlerPlatform.MaxAvailableGs(); // TODO add drag v lift
mGMX = Math.Max(mGMX, 1.5);
Vec3 vp = PLATFORM.VelocityNED();
double speed = PLATFORM.Speed() * Math.FT_PER_M(); // Speed in f/sec
mGMX = 1.5 + (mGMX - 1.5) * ramp(0.5, (vp[2] * Math.FT_PER_M()/speed), 0.0);
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,139 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt3a.f
// Replicates the low speed recover left 45 deg 3,A,3,1 alternative behavior
behavior alt3A31_low_speed_recover_left45
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3A31Enabled = false;
// Alternative ID
int ilevel = 3;
int kalt = 10;
int icall = 3;
int lcall = 1;
// Maneuver Alternative flight values
Vec3 mDir0 = Vec3();
double mGMX = 1.0;
double mSpd0 = 3.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
// Magic numbers from alt3a.f
double sd45 = 0.7071068;
double cd45 = 0.7071068;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3411_straight_flight, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3A31Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
if (!brawlerPlatform.SlowFlight())
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " not in slow flight");
writeln_d(msg);
return Failure(msg);
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
# C ALTERNATIVE 3: ROLL -45 DEGREES
#60 continue
# dir0(1) = 0.
# dir0(2) = -sd45
# dir0(3) = -cd45
# call vxfrmc(rbep,dir0,dir0,2)
# go to 990
#990 submor = .true.
# iactn = 4
# lenalt = lactn(iactn)
# altdsc = altpk(3,10,icall,1,0,0)
#C --SET TO HIGHEST THROTTLE SETTING FOR MAX SPEED
# spd0 = 3.
# spdmod = thrttl
# call srch(dragvl,ndatbl,acmasp*grav,index,xx)
# if(index.ne.0) go to 995
# index = ndatbl
# xx = 0.0
#995 continue
# gmx = gmxin*(index-xx-1.0)/(ndatbl-1.0)
# gmx = amax1(gmx,1.5)
# gmx = 1.5+(gmx-1.5)*ramp(.5,vp(3,me)/spdnow(me),0.)
mDir0 = Vec3.Construct(0.0, -sd45, -cd45);
//TODO convert from earth to body coordinates
mSpd0 = 3;
mGMX = brawlerPlatform.MaxAvailableGs(); // TODO add drag v lift
mGMX = Math.Max(mGMX, 1.5);
Vec3 vp = PLATFORM.VelocityNED();
double speed = PLATFORM.Speed() * Math.FT_PER_M(); // Speed in f/sec
mGMX = 1.5 + (mGMX - 1.5) * ramp(0.5, (vp[2] * Math.FT_PER_M()/speed), 0.0);
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithThrottle(mDir0, mGMX, mSpd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithThrottle(mDir0, mGMX, mSpd0);
end_execute
end_behavior

View File

@@ -0,0 +1,188 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt3b.f
// Replicates the illuminate 3,B,1,1 alternative behavior
// GENERATES ILLUMINATION MANEUVER
//
behavior alt3B11_illuminate
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfPerceptionProcessor perception;
WsfBrawlerPlatform brawlerPlatform;
WsfLocalTrack targetTrack;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
bool mAlternative3B11Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 11;
int icall = 1;
int lcall = 1;
double mMaxSustainedG = 2.0;
double mLongRange = 5.0 * Math.M_PER_NM();
Vec3 dir0;
double gmx = 1.0;
double spd0;
// ALSO NEED:
// randomization to simulate imperfect decision making, valsig, read from MIND file, typically ~0.01
// Production rule bias, used in scoring of alternative
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
double mLastTime = 0.0;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
perception = (WsfPerceptionProcessor)PLATFORM.Processor("perception");
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3B11_illuminate, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
### check if alternative should even be considered?
if (!mAlternative3B11Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no weapon (target) tasks!");
}
WsfTask targetTask = tasks.Entry(0);
targetTrack = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!targetTrack.IsValid())
{
return Failure("no target track!");
}
## alt3b.f : lines 84 - 127
# if(!lillum)
# {
# return Failure("lillum == false");
# }
#
dir0 = Vec3.Construct(0,0,0);
#if(nbvr == 0) call nabort('ALT3B...NBVR=0')
# #LBM - only fly against targetTrack, not all things
# do 50 ibvr=1,nbvr
# if (jtgbvr(ibvr).lt.0) call nabort('ALT3B...JTGBVR IS ZERO')
# if (jtgbvr(ibvr).eq.0) goto 50
# iac = mmindt(jtgbvr(ibvr))
# if (iac.eq.0) goto 50
#call vdir(xp(1,me),xp(1,iac),dx)
Vec3 dx = RelativePositionNED(PLATFORM.Location(), targetTrack.CurrentLocation());
dx.Normalize();
Vec3 vp = PLATFORM.VelocityNED();
Vec3 dir0i = vorth(vp,dx);
#call veclin(0.5/xmag(dir0i),dir0i,root3*0.5,dx,dir0i)
//missile phases:
//pinfr=1, psema=2, pactr=3, pcomg=4, pguns=5, phor=6, p_act_ir_1=7, p_inertial=8, pnewg=9
int kndbvr; //TODO? = pcomg if command guided launch
int psema = 2; //semi active
int pcomg = 4; //command guided
if (kndbvr == psema)
{
# SEMI-ACTIVE MISSILE, GIVE FULL WEIGHT
#call vsum(dir0,dir0i,dir0);
}
else if (kndbvr == pcomg)
{
# ACTIVE RADAR MISSILE, PRESUMABLY PRE-ACQUISITION
# GIVE 50% WEIGHT TO ITS ILLUM VECTOR
#call vecinc(dir0,0.5,dir0i,dir0)
}
else
{
#call nabort('ALT3B...unknown/illegal kndbvr')
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " unknown/illegal kndbvr");
writeln_d(msg);
return Failure(msg);
}
# If BVR target is not to be considered in high detail do not
# illuminate
if (dir0.Magnitude() == 0.0)
{
string msg = write_str("T=",TIME_NOW,", alt ", ilevel, kalt, icall, lcall, " dir0 == zero");
writeln_d(msg);
return Failure(msg);
}
#call unitv(dir0,dir0)
int iactn = 4;
gmx = 2.0;
double bvrmch = 1.0; //TODO - find for real
double fmachp = 1.0; //TODO - find for real
spd0 = PLATFORM.Speed() * MATH.Max(1.0,bvrmch/fmachp); #spd0 in meter/seconds units here
int spdmod = 1; //(desspd = 1, thrttl = 2, desacc = 3)
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateVectorWithSpeed(dir0, gmx, spd0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyVectorWithSpeed(dir0, gmx, spd0);
end_execute
end_behavior

View File

@@ -0,0 +1,123 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 alt3g.f and brlrol.f
// Replicates the barrel roll 3,16,1,1 alternative behavior
// DO A BARREL ROLL! - Peppy
behavior alt3G11_barrel_roll
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
// Takes the place of 'brlflg'
bool mAlternative3G11Enabled = true;
// Alternative ID
int ilevel = 3;
int kalt = 16;
int icall = 1;
int lcall = 1;
// Barrel Roll Generation Parameters (formerly from rules file)
// See Brawler Production Rule Handbook 2.1.2.4 Barrel Roll - brlrol
double rolrat = 15; // Desired roll rate in degrees/sec
double ptchrt = 30; // Desired pitch rate in degrees/sec
double lgees = 0; // Desired longitudinal acceleration in units of gees.
// Maneuver Alternative flight values
Vec3 mA0 = Vec3();
Vec3 mAl0 = Vec3();
double mAccmod = 0.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
double grav = 32.17405; // From pcon.fi
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
#writeln_d(PLATFORM.Name(), " precondition behavior_alt3G11_barrel_roll, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
if (!mAlternative3G11Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
// ALL CONDITIONS PASS
### Generate Maneuver Alternative
# brlrol.f
#--NEXT LINE ALLOWS ALT3G TO GENERATE ALTERNATIVE
#brlflg=.true.
#if(lprnt) write(ioutp,1000) rolrat,ptchrt,lgees
#--SET DESIRED RATES
#w0(1)=rolrat*rad
#w0(2)=ptchrt*rad
#w0(3)=0.0
#al0 = grav*lgees
#accmod = desacc
#call xmit(5,althld(5),baralt)
mA0.SetX(rolrat * Math.RAD_PER_DEG());
mA0.SetY(ptchrt * Math.RAD_PER_DEG());
mA0.SetZ(0.0);
mAl0.SetX(grav * lgees); // Note al0 is actually a singe value, it is set to vector accreq(1) in command.f
//mAccmod = ??; where do we get desacc?
# alt3g.f
#iactn = 1
#lenalt=lactn(iactn)
#altdsc = indpk(3,16,1,1)
#call xmit(5,baralt,althld(5)) <- copy predefined barrel roll maneuver into alternative storage
### Evaluate [Projected] Maneuver Alternative
double score = brawlerPlatform.EvaluateRates(mA0, mAl0, ilevel, kalt, icall, lcall);
return score;
end_precondition
execute
## what was evaluated should be actually performed now
brawlerPlatform.FlyRates(mA0, mAl0);
end_execute
end_behavior

View File

@@ -0,0 +1,264 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior pilot_posture
script_debug_writes off
script_variables
WsfTask targetTask;
WsfLocalTrack targetTrack;
WsfQuantumTaskerProcessor processor;
WsfBrawlerPlatform brawlerPlatform;
double root3 = 1.732050808; # pcon.fi
double splita = 45.0; # MIND file, TODO - use read in value
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
precondition
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
string err = write_str("no weapon (target) tasks!");
writeln_d(err);
return Failure(err);
}
targetTask = tasks.Entry(0);
targetTrack = PLATFORM.MasterTrackList().Find(targetTask.LocalTrackId());
if (!targetTrack.IsValid() || targetTrack.TargetKilled())
{
string err = write_str("no target track!");
writeln_d(err);
return Failure(err);
}
return true;
end_precondition
execute
writeln_d("executing pilot_posture");
Vec3 xp = brawlerPlatform.LocationNED();
Vec3 vp = PLATFORM.VelocityNED();
double spdnow = PLATFORM.Speed()*MATH.FT_PER_M();
Vec3 xp_iac = brawlerPlatform.LocationNED(targetTrack);
Vec3 vp_iac = targetTrack.VelocityNED();
#aslct2()
#spcial()
#spbvri()
// "iac" is target index, get target track from WEAPON task, for now
Vec3 hlvec = Vec3();
double hlspd = 0.0;
double hlval = 0.0;
extern int kturn;
//C --GET KTURN VALUE
//call ckrngi(myturn,-2,2,'~KTURN(IACID)~')
double sgn = 1.0;
if (kturn<0)
{
sgn = -1.0;
}
#double vsme = 0.0; #TODO - speed of sound
#double bvrmch = 0.0; #TODO - mach to use BVR (MIND2)
#double bvrmch = PLATFORM.Speed()*MATH.FT_PER_M() / vsme;
#double sa = vsme*bvrmch;
double sa = brawlerPlatform.Speed()*MATH.FT_PER_M();
//call asstgt(iacord,jacidord,virtl,nassign)
//if(nassign.eq.0) goto 900
//iac = iacord(1);
if (kturn != 0)
{
writeln_d("kturn != 0");
//C --THIS CODE NOT NEEDED FOR POINT TACTIC:
//C --COMPUTE INTERCEPT PT AIMP, BASED ON MAX OF MACH 1 OR PRESENT MACH
//C --USE THE FIRST MEMBER OF THE ASSIGNED TARGET GROUP.
#st = xmag(vp(1,iac));
double st = vp_iac.Magnitude();
//LBM - TODO - verify units used in WsfBrawlerPlatform AimPoint and Intercept() methods!!!
#call aimpt(xp(1,me),amax1(sa,vsme),xp(1,iac),vp_iac,st,aimp,lsoln);
#Vec3 aimp = brawlerPlatform.AimPoint(xp, MATH.Max(sa, vsme), xp_iac, vp_iac, st);
Vec3 aimp = brawlerPlatform.AimPoint(xp, sa, xp_iac, vp_iac, st);
#Vec3 dxpme = Vec3.Subtract(xp_iac, xp);
#Vec3 dxt = dxpme;
Vec3 dxt = Vec3.Subtract(xp_iac, xp);
dxt.SetZ(0.0);
dxt.Normalize();
if(aimp.Magnitude() > 0)
{
#call vsub(aimp,xp(1,me),dxi);
Vec3 dxi = Vec3.Subtract(aimp, xp);
dxi.SetZ(0.0);
dxi.Normalize();
}
}
# if (kturn == 0) //C --POINT AT TGT
# {
# hdes = -xp(3,me);
# if (lbit(pp_skrs,saskr) || pp_comg)
# {
# if (!ppmtrk)
# {
# hdes = amin1(hdes,-xp(3,iac));
# }
# }
## //LBM - dont worry about rules right now
## //C --CHANGED RULFLG VALUE 18 NOV 87 DICKERSON
## if (rulflg == 1510)
## {
## call pcode(-rulflg);
## hdes = prdalt;
## }
#
# Vec3 aimpt = ((WsfBrawlerPlatform)PLATFORM).AimPoint(Vec3, double, Vec3, Vec3, double);
#
# #call intcpt(xp(1,me),spdnow(me),xp(1,iac),vp(1,iac),root3/2.0,0.0,hdes,hlvec,hlspd);
# hlvec = ((WsfBrawlerPlatform)PLATFORM).Intercept(Vec3, PLATFORM.Speed()*MATH.FT_PER_M(), Vec3, Vec3, double, double, double);
# hlspd = hlvec.Magnitude();
# hlvec.Normalize();
#
# //goto 965;
# }
# //else
if (kturn == 1 || kturn == -1) //C --END-RUN TGT
{
writeln_d("end run");
double closmn = root3/2.0;
double angint = splita*sgn;
double hdes = PLATFORM.Altitude();
//hdes = -xp(3,me);
//LBM - dont worry about lower targets or flying lower, for now
# if (lbit(pp_skrs,saskr) || pp_comg)
# {
# if (!ppmtrk)
# {
# hdes = amin1(hdes,-xp(3,iac));
# }
# }
//LBM - dont worry about rules right now
# //C --CHANGED RULFLG VALUE 18 NOV 87 DICKERSON
# if (rulflg == 1510)
# {
# call pcode(-rulflg);
# hdes = prdalt;
# }
//LBM - TODO - verify units used in WsfBrawlerPlatform AimPoint and Intercept() methods!!!
//call intcpt(xp(1,me),spdnow(me),xp(1,iac),vp(1,iac),root3/2.0,splita*sgn,hdes,hlvec,hlspd);
Vec3 desVec = brawlerPlatform.Intercept(xp, spdnow, xp_iac, vp_iac, closmn, angint, hdes);
hlvec = desVec.Normal();
hlspd = desVec.Magnitude();
//brawlerPlatform.InterceptLocation3D(
//goto 965;
}
# else if (kturn == 2 || kturn == -2) //C --LOOP
# {
# if (lsoln) then
# call xmit3(dxi,temp)
# else
# call xmit3(dxt,temp)
# endif
# call makex(vp(1,me),r)
# call vxfrmc(r,temp,temp,1)
# loopha = loopha .or. temp(1).lt.0.
# loopnf = loopnf .or. (loopha .and. temp(1).gt.0. .and. (sign(1.,temp(2)).eq.sgn) )
# if (loopnf) then
# //C --HERE NO LONGER LOOP - POINT
# goto 100
# endif
# temp(1) = 0.
# temp(2) = sgn
# temp(3) = 0.
# call vxfrmc(r,hlvec,temp,2)
# hlval = valme*1.5
# hlspd = bvrmch*spdnow(me)/fmachp
# //C --TURN OFF FORMATION VALUES DURING LOOP:
# mdskpp = iand(mdskpp,6)
# stkppp = stkppp*0.25
# goto 970
# }
# //C
#//900 continue
# //C --HERE NO TGT - PRESUMABLY DEAD
# hlval = 0.
# goto 970
# //C
//965 continue
//C --FINISH SETTING UP HIGH LEVEL STEERING VALUES
#hlval = valeff(iac);
hlval = brawlerPlatform.LastEngagementValue(targetTrack.Target());
#writeln_d("hlvec = ", hlvec.ToString(), ", hlval = ", hlval, ", hlspd = ", hlspd);
//970 continue
//call steer
#steer()
# if (dirspc.ne.0) then
# //C --SUPPRESS VECTORED FLIGHT VALUES - DIRECT HAS PRECEDENCE
# valfpp= 0.0
# elseif (vfspc.eq.0) then
//C --USE NORMAL HIGH_LEVEL VALUES FOR VECTORED_FLIGHT
//call xmit(3,hlvec,vecfpp)
extern Vec3 vecfpp;
extern double valfpp;
extern double sflypp;
vecfpp = hlvec;
valfpp = hlval;
sflypp = hlspd;
writeln_d("vecfpp = ", vecfpp.ToString(), ", valfpp = ", valfpp, ", sflypp = ", sflypp);
brawlerPlatform.SuggestVectoredFlight(vecfpp, valfpp, sflypp);
# else
# //C --USE FORCE_V VECTOR INSTEAD OF HL... VALUES
# //C --THESE MAY BE SET BY EITHER PRODUCTION RULES OR IP
# call xmit(3,hlvfor,vecfpp)
# valfpp = hlvalf
# sflypp = hlspdf
# endif
//call sepset(10.0) //LBM - not doing separation yet
//9999
return;
end_execute
end_behavior

View File

@@ -0,0 +1,329 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 aslct7.f and akshn7.f
// Replicates the gun fire 7,3,7,x alternative behavior
include_once BrawlerScriptUtil.txt
behavior weapon_decision_gun
script_debug_writes off
script_variables
double RNGWPN = 3000.0; #feet (from MIND file)
WsfQuantumTaskerProcessor processor;
WsfBrawlerPlatform brawlerPlatform;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawGuns = true;
WsfDraw mDraw = WsfDraw();
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
// Takes the place of production rules
bool mAlternative7371Enabled = true;
// Alternative ID
int ilevel = 7;
int kalt = 3;
int icall = 7; // Always 7 for gun
int lcall = 1;
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
// Needed?
brawlerPlatform = (WsfBrawlerPlatform)PLATFORM;
end_on_init
// Replicates the checks done in canfirg.f
// Return true if the gun can be fired ("hard" checks)
// Sets the string to the fail reason
script bool canfirg(string failMsg)
/*
cnfire = .false.
C --NOTE THAT WE ARE RECALCULATING PILOT POSTURE VARIABLES HERE
C --ppmrmx WILL BE NEEDED IN shldfrg, SO PERFORM THIS CALCULATION
C --UNCONDITIONALLY.
call gunenv(xp(1,me),vp(1,me),xp(1,ppmiac),vp(1,ppmiac),
1 ppmptr,ppmrmn,ppmrmx,ppmapt,ppmse,ppmaof,ppmenv,ppmtrk,ppmohr,
2 rbep )
C --If temp midway in a 0.5 second burst exceeds maximum (1.0 by
C --definition) then you can't shoot. Rate of temperature rise
C --is 1.0/t_to_heat, so that firing for t_to_heat seconds reaches
C --the limit.
overheat = (gun_temp+0.25/t_to_heat .gt. 1.0)
if (overheat) then
rsfail = 'GUN OVERHEAT'
return
endif
C
C --CHECK IF TARGET IS IN ENVELOPE
if (.not.ppmenv) then
rsfail = 'NOT IN ENVELOPE '
return
endif
C
C --CHECK ON PROBABILITY IN RANGE
pinrng = prmax2(ppmiac,ppmrmx,1.0,0.2)
pbinrg = pinrng.ge.pr2lim
if (.not.pbinrg) then
rsfail = 'LOW PROB IN RANGE'
return
endif
C
visacq = inform(ppmiac).eq.1 .and. time.le.seet(ppmiac)+0.5
C --If pilot has not had a recent visual (or does not have a
C --radar lock if rdrgun is set), then gun can't be fired.
if(.not.rdrgun) then
C --DO I HAVE A RECENT VISUAL?
if(.not.visacq) then
rsfail = 'NO RECENT VISUAL'
return
endif
else
C --AN ESTABLISHED RADAR TRACK MAY SUBSTITUTE FOR A VISUAL
C --IF RDRGUN=.TRUE.
call lockid(iacid,ppmjid,locked)
gunacq = visacq .or. locked.eq.2
if(.not.gunacq) then
rsfail = 'NO RECENT VISUAL OR LOCK'
return
endif
endif
C
cnfire = .true.
*/
#bool canFire = false;
bool canFire = true; #LBM - temporary
return canFire;
end_script
// Replicates the checks done in shldfrg.f
// Return true if the should should be fired ("soft" checks)
// Sets the string to the fail reason if any
script bool shldfrg(string failMsg)
/*
C --If target is inside Rmax2, don't need the following
C --tests(target is inside no-escape range).
C --CHECK THAT PILOT BELIEVES RANGE IS OK FOR TARGETING
pinrng = prmax2(ppmiac,ppmrmx,ppm_rpeak,0.2)
pbinrg = pinrng.ge.pr2lim
call pdset('PROB_IN_RANGE',pbinrg)
C
C --CALCULATE CURRENT ENVELOPE LEVEL; ppmrmx WAS RECALCULATED IN canfirg
elevnow = envlvg(rngnow(me,ppmiac),rdotme(ppmiac),ppmse,ppmrmx,
1 'SHOOT')
C --CALCULATE PROJECTED ENVELOPE, CONSTANT VELOCITY PROJECTION FOR
C --ME AND CURRENT ACCELERATION PROJECTION FOR TARGET.
C --call vecinc(xp(1,me),tproj3,vp(1,me),xme)
C --Full projection for target, fixed velocity projection
C --for attacker.
C --call gunenv(xme,vp(1,me),xeut(1,ppmiac),veut(1,ppmiac),
call gunenv(xeuan,veuan,xeut(1,ppmiac),veut(1,ppmiac),
1 ppmptr,rmin,rmax,aimp,se,aof,inenvp,trkbl,ovrhoz,rbep)
elevprj = envlvg(rngun(ppmiac),rngrun(ppmiac),se,rmax,'SHOOT')
if(lprnt) write(ioutp,2000) rmin,rmax,rng(ppmiac),aimp,se,aof,
1 elevprj
C
C --CHECK PROJECTION -- IS LEVEL DECREASING?
worse = (elevnow.ge.elevprj)
call pdset('SHOT_WORSENING',worse)
C
needid = (irel(ppmiac).eq.0) .and. (id_mode.ne.bvr_id_md)
call pdset('SURE_BAD_GUY',.not.needid)
C
if (needid)then
lfire = .false.
rsfail = 'NEED ID'
elseif(.not.(pbinrg.or.worse))then
rsfail = '!(IN RPEAK OR WORSE)'
lfire = .false.
else
lfire = .true.
endif
*/
# bool lfire = false;
bool lfire = true; #LBM - temporary
return lfire;
end_script
precondition
#writeln_d(PLATFORM.Name(), " precondition weapon_decision_gun, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
// aslct7.f line 123 - 132
# --CHECK IF TARGET SELECTED
# if (ppmiac .eq. 0 .and. .not.dewvmsl)then
# rsfail = 'NO TARGET SELECTED'
# goto 800
# endif
# --CHECK IF WEAPON SELECTED
# if (ppmptr .eq. 0)then
# rsfail = 'NO WEAPON SELECTED'
# goto 800
# endif
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no target selected");
}
WsfTrack targetTrack = PLATFORM.MasterTrackList().FindTrack(tasks.Entry(0).LocalTrackId());
if (!targetTrack.IsValid())
{
return Failure("no valid target track");
}
#LBM - temporary
# // Weapon selection done in selwpn.f (called from aslct2.f)
# // checks weapon inventory. Use a similar check here as a replacement
# if (!HaveWeapon(PLATFORM))
# {
# // TODO Account for weapon type gun/missile
# return Failure("no weapon selected");
# }
if (!PLATFORM.Weapon("gun").IsValid() || PLATFORM.Weapon("gun").QuantityRemaining() <= 0)
{
writeln_d(" ", PLATFORM.Name(), " no weapon selected at time: ", TIME_NOW);
return Failure("no weapon selected");
}
# // aslct7() calls canfir().
# // canfir.f checks production rules and GCI inhibit
# // just doing a simple flag for now
# if (!mAlternative7371Enabled)
# {
# writeln_d("behavior not enabled!");
# return Failure("behavior alternative not enabled");
# }
#
# //canfir.f calls canfirg()
# string msg = "";
# if (!canfirg(msg))
# {
# return Failure(msg);
# }
#
# // aslct7 line 199 - 205
# // if undamaged calls shldfr().
# // if we are damaged skip checks and fire now
# if (PLATFORM.DamageFactor() <= 0.0)
# {
# // shldfr.f just calls the specific weapon type
# if (!shldfrg(msg))
# {
# return Failure(msg);
# }
# }
#
# // aslct7 creates and alternative to evaluate.
# // The alternative has no projection and always
# // evaluates to 1, so skip that processing
WsfWeapon gun = PLATFORM.Weapon("gun");
if (gun.LaunchComputer().CanIntercept(targetTrack, 0.1)) #see "firing_delay" for BULLET weapon
{
WsfGeoPoint pt = gun.LaunchComputer().InterceptPoint();
#TODO - move slant range check to gun's launch computer???
if (PLATFORM.SlantRangeTo(pt) <= (RNGWPN * MATH.M_PER_FT()))
{
# #draw line to intercept point
# if (mDrawGuns)
# {
# double delta = ((WsfBrawlerPlatform)PLATFORM).ProjectedTimeDelta();
# mDraw.SetLayer("behavior_weapon_decision_gun");
# mDraw.SetDuration(delta);
# mDraw.SetColor(0.5, 0.5, 0.5); #gray
# mDraw.SetLineSize(1);
# mDraw.SetLineStyle("solid");
# mDraw.BeginLines();
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(pt);
# mDraw.End();
# }
return true;
}
else
{
writeln_d("no gun fire, too far away");
return Failure("no gun fire, too far away");
}
}
else
{
writeln_d("gun cannot intercept target yet");
return Failure("gun cannot intercept target yet");
}
// All conditions pass, weapon can fire
return true;
end_precondition
execute
// Replicates akshn7.f
// We don't need to do all the bookeeping that BRAWLER
// does. Just launch the weapon.
// TODO Fill in gun fire
#LBM - temporary
WsfTrack targetTrack = PLATFORM.MasterTrackList().FindTrack(processor.TasksReceivedOfType("WEAPON").Entry(0).LocalTrackId());
WsfWeapon weapon = PLATFORM.Weapon("gun");
bool launched = weapon.FireSalvo(targetTrack, 1); // Always firing one for now
if (!launched)
{
writeln_d(" ", PLATFORM.Name(), " could NOT fire at track: ", targetTrack.TargetName(), " at time: ", TIME_NOW);
}
else if (mDrawGuns)
{
double delta = ((WsfBrawlerPlatform)PLATFORM).ProjectedTimeDelta();
mDraw.SetLayer("behavior_weapon_decision_gun");
mDraw.SetDuration(delta);
mDraw.SetColor(1.0, 1.0, 1.0); #white
mDraw.SetLineSize(2);
mDraw.SetLineStyle("dotted2");
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(targetTrack.CurrentLocation());
mDraw.End();
}
end_execute
end_behavior

View File

@@ -0,0 +1,510 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
// converted BRAWLER v7.5 aslct7.f and akshn7.f
// Replicates the missile fire 7,3,1,x alternative behavior
include_once BrawlerScriptUtil.txt
behavior weapon_decision_missile
script_debug_writes off
script_variables
WsfQuantumTaskerProcessor processor;
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** alternative parameters **//
//**********************************************************************//
// Flag used to enable/disable this alternative
// Takes the place of production rules
bool mAlternative7311Enabled = true;
// Alternative ID
int ilevel = 7;
int kalt = 3;
int icall = 1; // Weapon number, for missiles 1 - 6
int lcall = 1;
// Max/Min range for a SRM (meters)
double mMaxRange = 25000 * Math.M_PER_FT();
double mMinRange = 4000 * Math.M_PER_FT();
// Maximum angle a shot can be taken at (degrees)
double mMaxFiringAngle = 15.0;
// Percent range is reduced by for simple envelope
double mPercentRange = 0.2;
// Maximum number of missiles on a target
int mTargetSaturation = 1;
// Required track quality for a shot
double mRequiredTrackQuality = 0.8;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
double grav = 32.17405; // From pcon.fi
end_script_variables
on_init
if (PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
processor = (WsfQuantumTaskerProcessor)PROCESSOR;
}
end_on_init
// Replicates the checks done in canfirm.f
// Return true if the missile can be fired
// Sets the string to the fail reason
script bool canfirm(WsfLocalTrack target, string failMsg)
/*
cnfire = .false.
--MISSILE COMING OFF RAIL
if (lnchng) then
rsfail = 'MISL COMING OFF RAIL'
return
endif
--SWITCHOLOGY DELAYS
pswtch = (time .ge. timemf)
if (.not. pswtch)then
rsfail = 'SWITCHOLOGY'
return
endif
--CHECK IF TARGET IS IN ENVELOPE
--NOTE THAT SOME PPM... VARIABLES ARE RECALCULATED.
call mslenv_typ_mm(ppmiac,renv_typ)
call mslenv(iacid,xp(1,me),vp(1,me),ap(1,me),
1 alphap,xp(1,ppmiac),vp(1,ppmiac),ap(1,ppmiac),
2 ppmptr, rbep, rwep, ext_mle, .true., renv_typ, ppmrmn, ppmrmx,
3 ppmapt, ppmse, ppmaof, ppmenv, ppmtrk, ppmohr,l_config)
if (.not. ppmenv)then
rsfail = 'TGT NOT IN ENV'
return
endif
--Does pilot beleive that target is within max range (R<Rmax1)?
pinrng = prmax2(ppmiac,ppmrmx,1.,0.2)
pbinrg = (pinrng .gt. pr2lim)
if (.not.pbinrg)then
rsfail = 'LOW PROB. TGT IN RNG'
return
endif
if(lnchma.eq.0)then
rsfail = 'FAIL ALL FIRE MODES'
return
endif
cnfire = .true.
*/
// Not currently checking for another missile coming off the rail
// Not currently checking for switchology delays
// CHECK IF TARGET IS IN ENVELOPE
// Using a very simplified replacement of mslenv()
// that take a percentage of ange and a simple angle check
double range = PLATFORM.SlantRangeTo(target);
double absRelativeBearing = MATH.Fabs(PLATFORM.RelativeBearingTo(target));
if (range < (mMinRange + mMinRange * mPercentRange) ||
range > (mMaxRange - mMaxRange * mPercentRange) ||
absRelativeBearing >= mMaxFiringAngle )
{
#writeln("absRelativeBearing = ", absRelativeBearing, ", range = ", range);
#failMsg = "TGT NOT IN ENV";
target.SetAuxData("msg", "TGT NOT IN ENV");
return false;
}
// Does pilot beleive that target is within max range (R<Rmax1)?
// Using simplified version of prmax2
// and assuming short range missile with rmax = 25000 ft
double drng = (mMaxRange - PLATFORM.SlantRangeTo(target));
if (drng < 0.0)
{
#failMsg = "LOW PROB. TGT IN RNG";
target.SetAuxData("msg", "LOW PROB. TGT IN RNG");
return false;
}
// Not currently checking launch modes
// lnchma set if fctest() passes checks
return true;
end_script
// Replicates the checks done in shldfrm.f
// Return true if the missile should be fired
// Sets the string to the fail reason if any
script bool shldfrm(WsfLocalTrack target, string failMsg)
/*
C --CHECK THAT PILOT BELIEVES RANGE IS OK FOR TARGETING
pinrng = prmax2(ppmiac,ppmrmx,ppm_rpeak,0.2)
pbinrg = pinrng.ge.pr2lim
call pdset('PROB_IN_RANGE',pbinrg)
call mslenv_typ_mm(ppmiac,renv_typ)
C
C --CALCULATE tgleav
C --POSSIBLE PROJECTIONS
C -- ATTACKER TARGET
C --(1) CONSTANT VELOCITY XEUAN CONSTANT VELOCITY vecinc
C --(2) CURRENT MANEUVER XEUA CURRENT MANEUVER XEUT
C --(3) CURRENT MANEUVER XEUA CONSTANT VELOCITY vecinc
C --(4) CONSTANT VELOCITY XEUAN CURRENT MANEUVER XEUT
C --LOGIC IS AS FOLLOWS:
C --IF CASE (1) (neither maneuver) IS IN ENVELOPE THEN
C -- IF CASE (2) (both maneuver) IS OUT OF ENVELOPE
C -- IF CASE (3) (atkr maneuvers) IS IN ENVELOPE
C -- IF CASE(4) (tgt maneuvers) IS OUT OF ENVELOPE
C -- ASSERT: TARGET AT FAULT
C
C CASE 1: CALCULATE INENVP_CC
if (ient.eq.sament) then
call xmit3(xp(1,me),xme)
call xmit3(vp(1,me),vme)
call xmit(9,rbep,rbeme)
call xmit(9,rwep,rweme)
else
call xmit3(xeuan,xme)
call xmit3(veuan,vme)
call xmit(9,rbeuan,rbeme)
call xmit(9,rweuan,rweme)
endif
call vecinc(xp(1,ppmiac),tproj3,vp(1,ppmiac),xtgt)
call xmit3(vp(1,ppmiac),vtgt)
call zero3(azero)
xtgt(3) = amin1(xtgt(3),-50.)
call mslenv(iacid,xme,vme,azero,alphap,xtgt,vtgt,azero,
1 misl(mslpp),rbeme,rweme,.false.,.true.,renv_typ,rmin_mm,
2 rmax_mm,aimp,se_mm,aof_mm,inenvp_cc,trkbl,ovrhoz,l_config)
C --"target leaving" CANNOT BE TRUE IF NOT IN ENVELOPE WHEN NEITHER
C --MANEUVERING
if(.not.inenvp_cc)then
tgleav = .false.
goto 200
endif
C
C --CASE 2: CALCULATE INENVP_MM
if (ient.eq.sament) then
C --USE SAME AS CASE 1 SINCE I CAN'T MANEUVER
continue
else
call xmit3(xeua,xme)
call xmit3(veua,vme)
call xmit(9,rbeua,rbeme)
call xmit(9,rweua,rweme)
endif
call xmit3(xeut(1,ppmiac),xtgt)
call xmit3(veut(1,ppmiac),vtgt)
call mslenv(iacid,xme,vme,azero,alphap,xtgt,vtgt,azero,
1 misl(mslpp),rbeme,rweme,.false.,.true.,renv_typ,rmin,rmax,
2 aimp,se,aof,inenvp_mm,trkbl,ovrhoz,l_config)
C --"target leaving" CANNOT BE TRUE IF STILL IN ENV. WHEN BOTH MANEUVER
if(inenvp_mm)then
tgleav = .false.
goto 200
endif
C
C --CASE 3: CALCULATE INENVP_MC
if (ient.eq.sament) then
C --USE SAME AS CASE 1 SINCE I CAN'T MANEUVER
continue
else
call xmit3(xeua,xme)
call xmit3(veua,vme)
call xmit(9,rbeua,rbeme)
call xmit(9,rweua,rweme)
endif
call vecinc(xp(1,ppmiac),tproj3,vp(1,ppmiac),xtgt)
call xmit3(vp(1,ppmiac),vtgt)
xtgt(3) = amin1(xtgt(3),-50.)
call mslenv(iacid,xme,vme,azero,alphap,xtgt,vtgt,azero,
1 misl(mslpp),rbeme,rweme,.false.,.true.,renv_typ,rmin,rmax,
2 aimp,se,aof,inenvp_mc,trkbl,ovrhoz,l_config)
if(.not.inenvp_mc)then
tgleav = .false.
goto 200
endif
C
C --CASE 4: CALCULATE INENVP_CM
if (ient.eq.sament) then
C --USE SAME AS CASE 1 SINCE I CAN'T MANEUVER
continue
else
call xmit3(xeuan,xme)
call xmit3(veuan,vme)
call xmit(9,rbeuan,rbeme)
call xmit(9,rweuan,rweme)
endif
call xmit3(xeut(1,ppmiac),xtgt)
call xmit3(veut(1,ppmiac),vtgt)
call mslenv(iacid,xme,vme,azero,alphap,xtgt,vtgt,azero,
1 misl(mslpp),rbeme,rweme,.false.,.true.,renv_typ,rmin,rmax,aimp,
2 se,aof,inenvp_cm,trkbl,ovrhoz,l_config)
tgleav = .not.inenvp_cm
C
200 continue
call pdset('TGT_LEAVING_ENV',tgleav)
C
C --Calculate current envelope level (WORSE)
elevnow= envlvl(rngnow(me,ppmiac),rdotme(ppmiac),ppmse,
1 ppmaof,ppmrmn,ppmrmx,ppm_rpeak,ppm_semax,aoffmx,
2 ppmtrk,ppmohr,'SHOOT ')
C
if (ient.ne.sament) then
elevprj= envlvl(rng(ppmiac),rngr(ppmiac),se_mm,aof_mm,rmin_mm,
1 rmax_mm,ppm_rpeak,ppm_semax,aoffmx,trkbl,ovrhoz,'SHOOT ')
if(lprnt) write(ioutp,2000) rmin_mm,rmax_mm,
1 rng(ppmiac),aimp,se_mm,aof_mm,elevprj
else
C --rng, rngr NOT SET FOR SAM, USE rngun, rngrun
elevprj= envlvl(rngun(ppmiac),rngrun(ppmiac),se_mm,aof_mm,
1 rmin_mm,rmax_mm,ppm_rpeak,ppm_semax,aoffmx,trkbl,ovrhoz,
2 'SHOOT ')
if(lprnt) write(ioutp,2000) rmin_mm,rmax_mm,
1 rngun(ppmiac),aimp,se_mm,aof_mm,elevprj
endif
C --CHECK PROJECTION -- IS LEVEL DECREASING?
worse = (elevnow.ge.elevprj)
call pdset('SHOT_WORSENING',worse)
10 continue
C
C --Check if target is too near beam for successful semi-active
C -- missile shot
lbeam = beamsht()
call pdset('SA_BEAM_SHOT',lbeam)
C
C --If positive target ID required to fire, has ID been
C --established?
needid = (irel(ppmiac).eq.0) .and. (id_mode.ne.bvr_id_md)
call pdset('SURE_BAD_GUY',.not.needid)
C
C --check for fratricide risk
call set_hldcod(mslpp,ppmiac,hldcode,pp_skrs,pp_undes,lfrshot)
lfrat = lbit(hldcode,2)
call pdset('FRAT_RISK',lfrat)
C
C --CHECK IF FRIEND HAS A BETTER SHOT
lfrnd = lbit(hldcode,1)
call pdset('FRND_BETTER_SHOT',lfrnd)
C
C --Is target already engaged with max number of missiles/target?
other_tgtd = 0
do 100 igg=1,ngg
iacf = listf(igg)
acidf = iacidt(iacf)
if (iacid .eq. acidf)goto 100
C --Don't count another's selection if you have a much better
C --shot, since he will wait for you to shoot
if (.not.lfrshot(iacf)) goto 100
C --Don't count another's selection if you have selected the
C --same target earlier! RMK 9 Apr 92
C --(Cant use others_tgt(iacid) here since not set until akshn7)
if (others_tgt(acidf).eq.ppmiac)then
C --However, we do need to use others_tgt(iacid) here, since
C --we need to use others_msgtim(iacid), which is only correct
C --if others_tgt(iacid) .eq. ppmiac
if(others_tgt(iacid).eq.ppmiac) then
C --I have selected this tgt previously
if (others_msgtim(acidf).lt.others_msgtim(iacid)) then
C --He selected this target earlier than I, so count him
other_tgtd = other_tgtd + 1
endif
else
C --I just changed to this target, so if anybody else has
C --sent me a message selecting him, they must have gotten
C --there first
other_tgtd = other_tgtd + 1
endif
endif
100 continue
110 continue
satur = ((nmhutl(ppmiac)+other_tgtd).ge.mxtgt_ac(ppmjid))
call pdset('TARGET_SATURATED',satur)
skr_lock = .false.
do 300 iseek = 1, mx_skr
if (skr_acquired(iseek)) then
skr_lock = .true.
goto 305
endif
300 continue
305 continue
call pdset('SEEKER_LOCK',skr_lock)
C
C --CHECK WEAPON QUALITY TRACK
C --no_trk indicates track not needed for this launch mode
no_trk = (lnchma .eq. ppsli) .or.
1 (lnchma .eq. ppslr) .or.
2 (lnchma .eq. pcguv) .or.
3 (lnchma .eq. pvtnhms)
if (.not.usewqt(iflite)) then
C --Flight does not require WQT
needwqt = .false.
elseif (no_trk) then
C --Using a luanch mode that is not cued from a track
needwqt = .false.
else
needwqt = .not.wpnqual
endif
400 continue
C
C --FIRING LOGIC:
lfire =
1 .not.(needid.or.satur.or.lfrat.or.lfrnd.or.lbeam.or.needwqt)
2 .and.(pbinrg.or.(worse.and..not.tgleav))
if(lfire)then
rsfail = ' '
else
if(needid)then
rsfail = 'NEED ID'
elseif(satur)then
rsfail = 'MXTGT_AC LIMIT'
elseif(lfrat)then
rsfail = 'FRATRICIDE RISK'
elseif(lfrnd)then
rsfail = 'FRND HAS BETTER SHOT'
elseif(lbeam)then
rsfail = 'TGT TOO NEAR BEAM'
elseif(.not.(pbinrg.or.(worse.and..not.tgleav)))then
rsfail = 'FAILED ENV LOGIC'
elseif (needwqt) then
rsfail = 'NO WEAPON QUAL TRK'
else
call nabort('SHLDFRM..unknown failure reason')
endif
endif
*/
// ONLY Checking target stauration and track quality for now
if (PLATFORM.WeaponsActiveFor(target.TrackId()) >= mTargetSaturation)
{
//lfire = true;
writeln_d(" ", PLATFORM.Name(), " shouldn't fire ", target.TargetName(), " saturated");
failMsg = "MXTGT_AC LIMIT";
return false;
}
if (target.TrackQuality() < mRequiredTrackQuality)
{
failMsg = "NO WEAPON QUAL TRK";
return false;
}
return true;
end_script
precondition
#writeln_d(PLATFORM.Name(), " precondition weapon_decision_missile, T=", TIME_NOW);
### Evaluate conditions that would prevent behavior alternative from running
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
writeln_d("not a quantum tasker!");
return Failure("behavior not attached to a WSF_QUANTUM_TASKER_PROCESSOR");
}
// aslct7.f line 123 - 132
# --CHECK IF TARGET SELECTED
# if (ppmiac .eq. 0 .and. .not.dewvmsl)then
# rsfail = 'NO TARGET SELECTED'
# goto 800
# endif
# --CHECK IF WEAPON SELECTED
# if (ppmptr .eq. 0)then
# rsfail = 'NO WEAPON SELECTED'
# goto 800
# endif
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
if(tasks.Count() <= 0)
{
return Failure("no tasks");
}
// Assuming 1v1 and first and only task is the one we want
WsfLocalTrack targetTrack = PLATFORM.MasterTrackList().FindTrack(tasks.Entry(0).LocalTrackId());
if(tasks.Count() <= 0 || targetTrack.IsNull() || !targetTrack.IsValid())
{
writeln_d(" ", PLATFORM.Name(), " no target selected at time: ", TIME_NOW);
return Failure("no target selected");
}
// Weapon selection done in selwpn.f (called from aslct2.f)
// checks weapon inventory. Use a similar check here as a replacement
if (!PLATFORM.Weapon("srm").IsValid() || PLATFORM.Weapon("srm").QuantityRemaining() <= 0)
{
writeln_d(" ", PLATFORM.Name(), " no weapon selected at time: ", TIME_NOW);
return Failure("no weapon selected");
}
// aslct7() calls canfir().
// canfir.f checks production rules and GCI inhibit
// just doing a simple flag for now
if (!mAlternative7311Enabled)
{
writeln_d("behavior not enabled!");
return Failure("behavior alternative not enabled");
}
//canfir.f calls canfirm()
string msg = "";
if (!canfirm(targetTrack, msg))
{
msg = targetTrack.AuxDataString("msg");
writeln_d(" ", PLATFORM.Name(), " couldn't fire at time: ", TIME_NOW, " ", msg);
return Failure(msg);
}
// aslct7 line 199 - 205
// if undamaged calls shldfr().
// if we are damaged skip checks and fire now
if (PLATFORM.DamageFactor() <= 0.0)
{
// shldfr.f just calls the specific weapon type
if (!shldfrm(targetTrack, msg))
{
writeln_d(" ", PLATFORM.Name(), " shouldn't fire at time: ", TIME_NOW, " ", msg);
return Failure(msg);
}
}
// aslct7 creates and alternative to evaluate.
// The alternative has no projection and always
// evaluates to 1, so skip that processing
// All conditions pass, weapon can fire
return true;
end_precondition
execute
// Replicates akshn7.f
// We don't need to do all the bookeeping that BRAWLER
// does. Just launch the weapon.
WsfTaskList tasks = processor.TasksReceivedOfType("WEAPON");
// Assuming 1v1 and first and only task is the one we want
WsfLocalTrack targetTrack = PLATFORM.MasterTrackList().FindTrack(tasks.Entry(0).LocalTrackId());
//Assuming weapon name, checked in precondition
WsfWeapon weapon = PLATFORM.Weapon("srm");
bool launched = weapon.FireSalvo(targetTrack, 1); // Always firing one for now
if (!launched)
{
writeln_d(" ", PLATFORM.Name(), " could NOT fire at track: ", targetTrack.TargetName(), " at time: ", TIME_NOW);
}
end_execute
end_behavior

View File

@@ -0,0 +1,72 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
platform_type BRAWLER_FLIGHT_LEAD WSF_PLATFORM
comm datalink WSF_COMM_TRANSCEIVER
network_name brawler_net
internal_link data_mgr
internal_link task_mgr
internal_link perception
end_comm
processor data_mgr WSF_TRACK_PROCESSOR
master_track_processor
end_processor
track_manager
retain_raw_tracks
retain_track_history
uncorrelated_track_drops disable
end_track_manager
processor perception WSF_PERCEPTION_PROCESSOR
asset_perception status_messages
end_processor
processor task_mgr WSF_QUANTUM_TASKER_PROCESSOR
script_variables
## for evaluating weapon tasks
Map<string,int> mKnownTargetTypes = Map<string,int>();
mKnownTargetTypes["BRAWLER_PLATFORM"] = 1;
end_script_variables
script Array<WsfTask> FlightLeadTaskGeneration (Array<WsfLocalTrack> TRACKS, Array<WsfAssetPerception> ASSETS )
Array<WsfTask> tasks = Array<WsfTask>();
//if its us, then create weapon tasks for enemy tracks
writeln_d("TRACKS.Size() = ", TRACKS.Size(), ", ASSETS.Size() = ", ASSETS.Size());
for (int i=0; i<TRACKS.Size(); i=i+1)
{
WsfLocalTrack lt = TRACKS.Get(i);
if (lt.IsValid() && (!lt.SideValid() || lt.Side() != PLATFORM.Side()))
{
if (mKnownTargetTypes.Size() <= 0 || mKnownTargetTypes.Exists(lt.TargetType()))
{
WsfTask task = WsfTask.Construct(1.0, "WEAPON", lt);
task.SetTaskType("WEAPON");
tasks.PushBack(task);
writeln_d("weapon task generated for: ", lt.TargetName(), ", updated time: ", lt.UpdateTime());
}
}
}
return tasks;
end_script
on_initialize
end_on_initialize
#debug
#script_debug_writes on
#show_task_messages
reallocation_strategy dynamic
generator custom FlightLeadTaskGeneration
evaluator distance
#allocator greedy_isolated
allocator optimal_profit
allocator_extra_assets optimal_profit #assigns tasks to extra blue guys
update_interval 0.3 sec
end_processor
end_platform_type

View File

@@ -0,0 +1,208 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#TODO - give blue_sr_a2a_ir_missile limited IR seekers, not perfect trackers
include_once ../../weapons/aam/blue_sr_a2a_ir_missile.txt
include_once ../../../site_types/weapons/other/gun.txt
# BRAWLER Behaviors
# "CONTEXT-FREE" Maneuvers
include_once alternatives/behavior_alt3111_straight_level_max_speed.txt
include_once alternatives/behavior_alt3121_straight_level.txt
include_once alternatives/behavior_alt3211_route_maneuver.txt
# Offensive 1v1 Maneuvers
include_once alternatives/behavior_alt3411_straight_flight.txt
include_once alternatives/behavior_alt3421_roll_+15_pull.txt
include_once alternatives/behavior_alt3431_roll-15_pull.txt
include_once alternatives/behavior_alt3441_tail_attack.txt
include_once alternatives/behavior_alt3451_pull_gmax_sust.txt
include_once alternatives/behavior_alt3471_slow_current_dir.txt
include_once alternatives/behavior_alt3472_slow_pull_right.txt
include_once alternatives/behavior_alt3473_slow_pull_left.txt
include_once alternatives/behavior_alt3474_slow_pull_current_plane.txt
# Defensive 1v1 Maneuvers
include_once alternatives/behavior_alt3511_break_right.txt
include_once alternatives/behavior_alt3531_break_left.txt
include_once alternatives/behavior_alt3551_run_away.txt
include_once alternatives/behavior_alt3561_force_overshoot.txt
include_once alternatives/behavior_alt3581_negative_velocity.txt
#missile aiming maneuever
include_once alternatives/behavior_alt3841_aim_missile_typ4.txt
include_once alternatives/behavior_alt3911_evade_missile.txt
include_once alternatives/behavior_alt3A11_low_speed_recover.txt
include_once alternatives/behavior_alt3A21_low_speed_recover_right45.txt
include_once alternatives/behavior_alt3A31_low_speed_recover_left45.txt
#include_once alternatives/behavior_alt3B11_illuminate.txt
include_once alternatives/behavior_alt3G11_barrel_roll.txt
# Weapon employment decision alternatives
include_once alternatives/behavior_weapon_decision_gun.txt
include_once alternatives/behavior_weapon_decision_missile.txt
#include_once alternatives/behavior_alt1514_point.txt
#include_once alternatives/behavior_alt1516_bvr_end_run_left.txt
#include_once alternatives/behavior_alt1517_bvr_end_run_right.txt
#include_once alternatives/behavior_pilot_posture.txt
#
##direct maneuver
##
##fly vector
#include_once alternatives/behavior_alt3611_fly_vector.txt
#include_once alternatives/behavior_debug_data.txt
# A WSF_BRAWLER_PLATFORM must have the following defined:
# 1. A WSF_BRAWLER_MOVER or WSF_P6DOF_MOVER
# 2. A WSF_QUANTUM_TASKER_PROCESSOR (typically named task_mgr)
# 3. A WSF_PERCEPTION_PROCESSOR (typically named perception)
# 4. A WSF_THREAT_PROCESSOR (typically named incoming_threats)
platform_type BRAWLER_PLATFORM WSF_BRAWLER_PLATFORM
icon F-15
mover WSF_BRAWLER_MOVER
aero_file ACFT_BD.FXW
#draw_projection
end_mover
mind_file MIND
#draw_alternatives
#draw_nominal_states
#debug
weapon srm BLUE_SR_A2A_IR_MISSILE
quantity 2
end_weapon
weapon gun BULLET
quantity 12 #each "bullet" represents a 1-sec burst of gunfire
end_weapon
comm datalink WSF_COMM_TRANSCEIVER
network_name brawler_net
internal_link data_mgr
internal_link task_mgr
internal_link perception
end_comm
sensor simple_sensor WSF_GEOMETRIC_SENSOR
on
#azimuth_field_of_view -45.0 degrees 45.0 degrees
#elevation_field_of_view -20.0 degrees 20.0 degrees
azimuth_field_of_view -180.0 degrees 180.0 degrees
elevation_field_of_view -90.0 degrees 90.0 degrees
maximum_range 150 km
frame_time 0.5 sec
reports_location
reports_velocity
reports_range
reports_iff
track_quality 1.0
internal_link data_mgr
ignore_same_side
end_sensor
processor data_mgr WSF_TRACK_PROCESSOR
purge_interval 60 sec
report_interval 1.0 sec
report_to commander via datalink
fused_track_reporting on
raw_track_reporting off
end_processor
processor perception WSF_PERCEPTION_PROCESSOR
threat_update_interval 2 sec
max_threat_load 5
reports_self on
report_interval 1.0 sec
report_to commander via datalink
end_processor
processor incoming_threats WSF_THREAT_PROCESSOR
threat_time_to_intercept 120 sec #default: 60 sec
end_processor
processor task_mgr WSF_QUANTUM_TASKER_PROCESSOR
#debug
#show_task_messages
# script_variables
# int kturn = 0; //turn type for BVR flight tactics
# Vec3 vecfpp = Vec3(); //vectored flight, direction
# double valfpp = 0.0; //vectored flight, value
# double sflypp = 0.0; //vectored flight, speed
# end_script_variables
behavior_tree
#behavior_node debug_data
# #FLIGHT TACTIC DECISION
# priority_selector
# behavior_node alt1516_bvr_end_run_left
# behavior_node alt1517_bvr_end_run_right
# behavior_node alt1514_point
# end_priority_selector
# #FLIGHT POSTURE DECISION
# selector
# #behavior_node altWXYZ_blah_blah
# end_selector
# #PILOT POSTURE DECISION
# selector
# behavior_node pilot_posture
# end_selector
#PILOT MANEUVERING DECISION
priority_selector
#when debug: prints precondition score of each selector child behavior
#debug
behavior_node alt3111_straight_level_max_speed
behavior_node alt3121_straight_level
behavior_node alt3411_straight_flight
behavior_node alt3421_roll_15_pull
behavior_node alt3431_roll-15_pull
behavior_node alt3441_tail_attack
behavior_node alt3451_pull_gmax_sust
behavior_node alt3471_slow_current_dir
behavior_node alt3472_slow_pull_right
behavior_node alt3473_slow_pull_left
behavior_node alt3474_slow_pull_current_plane
behavior_node alt3511_break_right
behavior_node alt3531_break_left
behavior_node alt3551_run_away
behavior_node alt3561_force_overshoot
behavior_node alt3581_negative_velocity
#behavior_node alt3611_fly_vector
behavior_node alt3841_aim_missile_typ4
#behavior_node alt3211_route_maneuver
behavior_node alt3911_evade_missile
#behavior_node alt3A11_low_speed_recover
#behavior_node alt3A21_low_speed_recover_right45
#behavior_node alt3A31_low_speed_recover_left45
#behavior_node alt3B11_illuminate
behavior_node alt3G11_barrel_roll
end_priority_selector
#WEAPON EMPLOYMENT DECISION
selector
behavior_node weapon_decision_gun
behavior_node weapon_decision_missile
end_selector
end_behavior_tree
end_processor
end_platform_type

View File

@@ -0,0 +1,42 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
platform_type FLIGHT_LEAD_BASE WSF_PLATFORM
//these definitions go in scenario specific platform type derivatives
// comm cmdr_net DATALINK_TYPE
// network_name <local:slave>
// internal_link data_mgr
// end_comm
// comm sub_net DATALINK_TYPE
// network_name <local:master>
// internal_link data_mgr
// end_comm
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 seconds
#report_to commander via cmdr_net
report_to subordinates via sub_net
//Only report fused tracks to entities that won't transmit tracks back.
//report_interval 20 sec
report_interval 4 sec
fused_track_reporting off
raw_track_reporting on
end_processor
end_platform_type

View File

@@ -0,0 +1,16 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for flight lead base
include_once flight_lead_base.txt
platform_type FLIGHT_LEAD FLIGHT_LEAD_BASE
end_platform_type

View File

@@ -0,0 +1,28 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for AIFL-thinker
include_once processors/ripr_agents/aifl/aifl_processor.txt
#for flight lead base
include_once platforms/flight_lead_base.txt
platform_type FLIGHT_LEAD FLIGHT_LEAD_BASE
processor lead-thinker AIFL-thinker
#debug
script_variables
###mEscortNames[0] = "some platform name";
end_script_variables
#auto_exclusive_mode true
#job_window_open_length 5 sec
#bid_window_open_length 5 sec
end_processor
end_platform_type

View File

@@ -0,0 +1,31 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
platform_type GCI_BASE WSF_PLATFORM
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 seconds
//report_to commander via cmdr_net
report_to subordinates via sub_net
//Only report fused tracks to entities that won't transmit tracks back.
//report_interval 20 sec
report_interval 4 sec
fused_track_reporting off
raw_track_reporting on
end_processor
end_platform_type

View File

@@ -0,0 +1,17 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for gci base
include_once gci_base.txt
platform_type GCI GCI_BASE
end_platform_type

View File

@@ -0,0 +1,22 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for AIGCI-thinker
include_once processors/ripr_agents/aigci/aigci_processor.txt
#for gci base
include_once platforms/gci_base.txt
platform_type GCI GCI_BASE
processor gci-thinker AIGCI-thinker
end_processor
end_platform_type

View File

@@ -0,0 +1,61 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
include_once ../weapons/aam/simple_a2a_missile.txt
#all guesses in this platform type definition are simply scaled up values from other known jets
platform_type RED_ADV_FIGHTER_1_BASE WSF_PLATFORM
icon F-22
category fighter
mover WSF_AIR_MOVER
# WAGs - Luke Miklos
roll_rate_limit 1.4 rad/sec
default_linear_acceleration 1.2 g
default_radial_acceleration 7.0 g
default_climb_rate 500 fps
# Mach 2.0 at altitude, WAG - Luke Miklos
maximum_speed 1288.6 knots
# Ceiling, WAG - Luke Miklos
maximum_altitude 60000 ft
minimum_altitude 50 ft
# g limit, WAG - Luke Miklos
maximum_linear_acceleration 10 g
#no_pitch
at_end_of_path extrapolate
end_mover
fuel WSF_VARIABLE_RATE_FUEL
rate 7.0 lb/s
initial_quantity 14000 lb
maximum_quantity 14000 lb
end_fuel
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 sec
update_interval 1 sec
end_processor
weapon int_missile SIMPLE_A2A_MISSILE_WEAPON end_weapon
end_platform_type

View File

@@ -0,0 +1,16 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for RED_ADV_FIGHTER_1
include_once red_adv_fighter_1_base.txt
platform_type RED_ADV_FIGHTER_1 RED_ADV_FIGHTER_1_BASE
//nothing new for now
end_platform_type

View File

@@ -0,0 +1,106 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for RED_ADV_FIGHTER_1
include_once red_adv_fighter_1_base.txt
#for AIAI-thinker
include_once processors/ripr_agents/aiai/aiai_processor.txt
#for red_mr_a2a_rf_missile
include_once weapons/aam/red_mr_a2a_rf_missile.txt
include_once weapons/aam/simple_blue_lr_a2a_rf_missile.txt
platform_type RED_ADV_FIGHTER_1 RED_ADV_FIGHTER_1_BASE
//use a different missile for this type
//adjust missile ranges in int-thinker below to accomodate
delete weapon int_missile
#weapon int_missile RED_MR_A2A_RF_MISSILE end_weapon # ~45 nm range
weapon blue_lr_a2a_rf_missile SIMPLE_BLUE_LR_A2A_RF_MISSILE end_weapon # ~60 nm range
edit weapon blue_lr_a2a_rf_missile
quantity 8
end_weapon
//This is the code that lets the interceptor intercept
processor int-thinker AIAI-thinker
script_variables
#agentProductions must be relative to working directory of application
#this file usually sits in scenario_name/platforms folder
#working directory is typically the scenario folder
#agentProductions = "../ripr/agents/aiai/RIPR-AIAI.soar";
#mWeaponArray[0] = Map<string, Object>();
#mWeaponArray[0].Set("name", "int_missile");
#mWeaponArray[0].Set("weapon", PLATFORM.Weapon("int_missile"));
#mWeaponArray[0].Set("rangeMin", 5556);
#mWeaponArray[0].Set("rangeMax", 83340);
#mWeaponArray[0].Set("numActiveMax", 2); // how many weapons of this type can be in play simultaneously
mWeaponArray[0] = Map<string, Object>();
mWeaponArray[0].Set("name", "blue_lr_a2a_rf_missile");
mWeaponArray[0].Set("weapon", PLATFORM.Weapon("blue_lr_a2a_rf_missile"));
mWeaponArray[0].Set("rangeMin", 1000);
mWeaponArray[0].Set("rangeMax", 111120); // ~60 miles
mWeaponArray[0].Set("numActiveMax", 2); // how many weapons of this type can be in play simultaneously
end_script_variables
end_processor
sensor geo_sensor WSF_GEOMETRIC_SENSOR
//azimuth_field_of_view -180.0 degrees 180.0 degrees
//elevation_field_of_view -90.0 degrees 90.0 degrees
azimuth_field_of_view -60.0 degrees 60.0 degrees
elevation_field_of_view -30.0 degrees 30.0 degrees
minimum_range 0 m
# maximum_range 100000 m
maximum_range 63000 m
on
frame_time 0.5 sec
reports_location
reports_velocity
reports_iff
track_quality 1.0
ignore_same_side
internal_link track_manager
end_sensor
processor incoming_threats WSF_THREAT_PROCESSOR
update_interval 0.1 sec
#update_interval 2.0 sec
#1300 knots
threat_velocity 668.7778 m/s
threat_angle_spread 15.0 deg
threat_time_to_intercept 240 sec
script void identified_new_threat(WsfTrack aTrack)
writeln("!!! me: ", PLATFORM.Name(), ", new threat: ", aTrack.TargetName());
end_script
script void dropped_threat(WsfTrack aTrack)
if (aTrack.IsValid())
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat: ", aTrack.TargetName());
}
else
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat");
}
end_script
end_processor
end_platform_type

View File

@@ -0,0 +1,58 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
include_once ../weapons/aam/simple_a2a_missile.txt
platform_type RED_FIGHTER_1_BASE WSF_PLATFORM
icon SU-27
category fighter
mover WSF_AIR_MOVER
roll_rate_limit 1 rad/sec
default_linear_acceleration 1.0 g
default_radial_acceleration 6.5 g
default_climb_rate 400 fps
# Mach 1.85 (1192.0 kts) at altitude, Janes Reference
maximum_speed 1192.0 knots
# Ceiling, Janes Reference
maximum_altitude 59000 ft
minimum_altitude 50 ft
# g limit, Janes Reference
maximum_linear_acceleration 9 g
#no_pitch
at_end_of_path extrapolate
end_mover
fuel WSF_VARIABLE_RATE_FUEL
rate 7.0 lb/s
initial_quantity 19842 lb
#max internal fuel + max external stores load, Janes reference
#(4500 internal + 4500 external = 9000 kg)
maximum_quantity 19842 lb
end_fuel
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 sec
update_interval 1 sec
end_processor
weapon int_missile SIMPLE_A2A_MISSILE_WEAPON end_weapon
end_platform_type

View File

@@ -0,0 +1,16 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for RED_FIGHTER_1
include_once red_fighter_1_base.txt
platform_type RED_FIGHTER_1 RED_FIGHTER_1_BASE
//nothing new for now
end_platform_type

View File

@@ -0,0 +1,82 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for RED_FIGHTER_1
include_once red_fighter_1_base.txt
#for AIAI-thinker
include_once processors/ripr_agents/aiai/aiai_processor.txt
#for red_mr_a2a_rf_missile
include_once weapons/aam/red_mr_a2a_rf_missile.txt
platform_type RED_FIGHTER_1 RED_FIGHTER_1_BASE
//use a different missile for this type
//adjust missile ranges in int-thinker below to accomodate
delete weapon int_missile
weapon int_missile RED_MR_A2A_RF_MISSILE end_weapon
//This is the code that lets the interceptor intercept
processor int-thinker AIAI-thinker
script_variables
mWeaponArray[0] = Map<string, Object>();
mWeaponArray[0].Set("name", "int_missile");
mWeaponArray[0].Set("weapon", PLATFORM.Weapon("int_missile"));
mWeaponArray[0].Set("rangeMin", 5556);
mWeaponArray[0].Set("rangeMax", 83340);
mWeaponArray[0].Set("numActiveMax", 2); // how many weapons of this type can be in play simultaneously
end_script_variables
end_processor
sensor geo_sensor WSF_GEOMETRIC_SENSOR
//azimuth_field_of_view -180.0 degrees 180.0 degrees
//elevation_field_of_view -90.0 degrees 90.0 degrees
azimuth_field_of_view -60.0 degrees 60.0 degrees
elevation_field_of_view -30.0 degrees 30.0 degrees
minimum_range 0 m
# maximum_range 100000 m
maximum_range 63000 m
on
frame_time 0.5 sec
reports_location
reports_velocity
reports_iff
track_quality 1.0
ignore_same_side
internal_link track_manager
end_sensor
processor incoming_threats WSF_THREAT_PROCESSOR
update_interval 0.1 sec
#update_interval 2.0 sec
#1300 knots
threat_velocity 668.7778 m/s
threat_angle_spread 13.0 deg
threat_time_to_intercept 240 sec
script void identified_new_threat(WsfTrack aTrack)
writeln("!!! me: ", PLATFORM.Name(), ", new threat: ", aTrack.TargetName());
end_script
script void dropped_threat(WsfTrack aTrack)
if (aTrack.IsValid())
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat: ", aTrack.TargetName());
}
else
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat");
}
end_script
end_processor
end_platform_type

View File

@@ -0,0 +1,129 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
//include_once ../sensors/red_esm.txt
//include_once ../sensors/rwr_esm.txt
//include_once ../weapons/x_jammer_red.txt
include_once ../sensors/radar/red_a2a_radar.txt
include_once ../weapons/aam/simple_a2a_missile.txt
platform_type RED_MULTIROLE_FIGHTER_2_BASE WSF_PLATFORM
icon SU-27
category fighter
mover WSF_AIR_MOVER
roll_rate_limit 1 rad/sec
default_linear_acceleration 1.0 g
default_radial_acceleration 6.0 g
default_climb_rate 400 fps
maximum_speed 850.0 knots
maximum_altitude 50000 ft
minimum_altitude 50 ft
maximum_linear_acceleration 8 g
at_end_of_path extrapolate
end_mover
processor track_manager WSF_TRACK_PROCESSOR
//debug
purge_interval 60 sec
update_interval 1 sec
end_processor
sensor red_multirole_fighter_2_radar RED_A2A_RADAR
on
processor track_manager
ignore_same_side
end_sensor
// sensor red_esm RED_ESM
// processor track_manager
// end_sensor
// sensor rwr_esm RWR_ESM
// processor track_manager
// end_sensor
weapon int_missile SIMPLE_A2A_MISSILE_WEAPON end_weapon
// weapon disrupt1 X_JAMMER_RED
// on
// end_weapon
fuel WSF_FUEL
//maximum_quantity 6531 kg
//10,000 lbs is about 4536 kg
maximum_quantity 4536 kg
//initial_quantity 6000 kg
initial_quantity 4500 kg
consumption_rate 1 kg/sec
bingo_quantity 1500 kg
on_bingo
writeln_d ("!!! ", PLATFORM.Name(), " on_bingo fuel");
end_on_bingo
on_empty
writeln_d ("!!! ", PLATFORM.Name(), " on_empty fuel");
end_on_empty
end_fuel
end_platform_type
#object RED_MULTIROLE_FIGHTER_2 {
# name "RED_MULTIROLE_FIGHTER_2 %d"
# team red
# icon "su_27"
# opponent_icon "su_27"
# //opponent_icon "CH_53"
# sensors (RED_A2A_RADAR RED_ESM RWR_ESM)
# tactics military_tactics
# dynamics powered_dynamics
# aero_model (
# linear_accel 1.0 G
# radial_accel 6.0 G
# climb_rate 400.0 fps
# max_speed 850.0 knots
# max_alt 50000 ft
# min_alt 50 ft
# fuel_table ( 76 (115 1.37 pps
# 150 1.59 pps
# 301 6.76 pps
# 321 23.4 pps)
# 5473 (143 1.24 pps
# 187 1.44 pps
# 293 4.65 pps
# 318 16.50 pps)
# 10671 (206 1.20 pps
# 236 1.27 pps
# 271 2.13 pps
# 295 7.37 pps))
# max_speed_table ( 76 321
# 4573 318
# 10671 295)
# fuel 10000 lb
# )
# launch_to_alt 32000 ft
# launch_to_speed 500 knots
# net off
#x ir_signature (1.0 1.2 1.6 1.8 2.0 2.0 2.0 2.0 2.0 2.0 1.9 1.8
#x 1.7 1.9 2.0 2.0 2.0 2.0 2.0 2.0 2.0 1.8 1.6 1.2)
# rcs3d FTR_RCS
#}
#
#

View File

@@ -0,0 +1,16 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for RED_MULTIROLE_FIGHTER_2
include_once red_multirole_fighter_2_base.txt
platform_type RED_MULTIROLE_FIGHTER_2 RED_MULTIROLE_FIGHTER_2_BASE
//nothing new for now
end_platform_type

View File

@@ -0,0 +1,99 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#for RED_MULTIROLE_FIGHTER_2
include_once red_multirole_fighter_2_base.txt
#for AIAI-thinker
include_once processors/ripr_agents/aiai/aiai_processor.txt
#for red_mr_a2a_rf_missile
include_once weapons/aam/red_mr_a2a_rf_missile.txt
script_interface
//debug
end_script_interface
// This is a ripr interceptor, based on red_multirole_fighter_2.
platform_type RED_MULTIROLE_FIGHTER_2 RED_MULTIROLE_FIGHTER_2_BASE
//use a different missile for this type
//adjust missile ranges in int-thinker below to accomodate
delete weapon int_missile
weapon int_missile RED_MR_A2A_RF_MISSILE end_weapon
//This is the code that lets the interceptor intercept
processor int-thinker AIAI-thinker
script_variables
#agentProductions must be relative to working directory of application
#this file usually sits in scenario_name/platforms folder
#working directory is typically the scenario folder
#agentProductions = "../ripr/agents/aiai/RIPR-AIAI.soar";
mWeaponArray[0] = Map<string, Object>();
mWeaponArray[0].Set("name", "int_missile");
mWeaponArray[0].Set("weapon", PLATFORM.Weapon("int_missile"));
mWeaponArray[0].Set("rangeMin", 5556);
mWeaponArray[0].Set("rangeMax", 83340);
mWeaponArray[0].Set("numActiveMax", 2); // how many weapons of this type can be in play simultaneously
end_script_variables
end_processor
//don't mess around with crappy radars, just use a simple geometric sensor
delete sensor red_a2a_radar
sensor geo_sensor WSF_GEOMETRIC_SENSOR
//azimuth_field_of_view -180.0 degrees 180.0 degrees
//elevation_field_of_view -90.0 degrees 90.0 degrees
azimuth_field_of_view -60.0 degrees 60.0 degrees
elevation_field_of_view -30.0 degrees 30.0 degrees
minimum_range 0 m
# maximum_range 100000 m
maximum_range 63000 m
on
frame_time 0.5 sec
reports_location
reports_velocity
reports_iff
track_quality 1.0
ignore_same_side
internal_link track_manager
end_sensor
processor incoming_threats WSF_THREAT_PROCESSOR
update_interval 0.1 sec
#update_interval 2.0 sec
#1300 knots
threat_velocity 668.7778 m/s
threat_angle_spread 10.0 deg
threat_time_to_intercept 240 sec
script void identified_new_threat(WsfTrack aTrack)
writeln("!!! me: ", PLATFORM.Name(), ", new threat: ", aTrack.TargetName());
end_script
script void dropped_threat(WsfTrack aTrack)
if (aTrack.IsValid())
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat: ", aTrack.TargetName());
}
else
{
writeln("!!! ", PLATFORM.Name(), " dropped a threat");
}
end_script
end_processor
end_platform_type

View File

@@ -0,0 +1,131 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
# CLASSIFICATION: UNCLASSIFIED
#
# This script is for controlling the mutually exclusive aspect of the
# SLB and SLC operations currently.
#
# The sensor name and technique names may be changed on the instantiation
# of the processor on the platform definition.
#
# Also note that the update_interval is set to 10.0 sec as the default and
# may need changed if it needs updated at a different interval (e.g. scan
# rate of the radar).
# --------------------------------------------------------------------------
processor EP_OPERATIONS WSF_SCRIPT_PROCESSOR
#script_call_trace off
#script_debug_writes off
update_interval 10.0 sec // default, need to update once per scan of the radar
script_variables
Array<string> mSensorNameList = Array<string>();
string mSLB_TechName = "sidelobe_blanking";
string mSLC_TechName = "sidelobe_canceling";
bool mStateChange = false;
string mPerceptionString = "";
end_script_variables
on_initialize
if (mSensorNameList.Empty())
{
int sensorCount = PLATFORM.SensorCount();
for (int i = 0; i < sensorCount; i = i + 1)
{
mSensorNameList.PushBack(PLATFORM.SensorEntry(i).Name());
writeln_d("EP_OPERATIONS script auto added platform:sensor ", PLATFORM.Name(),
":", PLATFORM.SensorEntry(i).Name(), " to control list.");
}
}
else
{
foreach (string sensorName in mSensorNameList)
{
writeln_d("EP_OPERATIONS script manually added platform:sensor ", PLATFORM.Name(),
":", sensorName, " to control list.");
}
}
if (mSensorNameList.Empty())
{
writeln("****WARNING: EP_OPERATIONS script has empty sensor list on ", PLATFORM.Name());
}
end_on_initialize
on_update
// Loop the sensor list and get each sensor in list to update
foreach (string sensorName in mSensorNameList)
{
// Get the sensor
WsfSensor sensor = PLATFORM.Sensor(sensorName);
// Update the operating status of the techniques
bool mSLB_Operating = sensor.IsEP_TechniqueActive(mSLB_TechName);
bool mSLC_Operating = sensor.IsEP_TechniqueActive(mSLC_TechName);
if (sensor.ContinuousJammingPerceived())
{
if (! mSLC_Operating)
{
mSLC_Operating = sensor.SelectEP_Technique(mSLC_TechName);
mPerceptionString = "Continuous jamming perceived";
mStateChange = true;
}
if (mSLB_Operating && mSLC_Operating)
{
mSLB_Operating = (! sensor.DeselectEP_Technique(mSLB_TechName));
}
}
else if (sensor.PulseJammingPerceived())
{
writeln_d("Perceived pulse jamming");
if (! mSLB_Operating)
{
mSLB_Operating = sensor.SelectEP_Technique(mSLB_TechName);
mPerceptionString = "Pulse jamming perceived";
mStateChange = true;
}
if (mSLB_Operating && mSLC_Operating)
{
mSLC_Operating = (! sensor.DeselectEP_Technique(mSLC_TechName));
}
}
else
{
if (mSLC_Operating)
{
mSLC_Operating = (! sensor.DeselectEP_Technique(mSLC_TechName));
mPerceptionString = "Jamming not perceived";
mStateChange = true;
}
if (mSLB_Operating)
{
mSLB_Operating = (! sensor.DeselectEP_Technique(mSLB_TechName));
mPerceptionString = "Jamming not perceived";
mStateChange = true;
}
}
if (mStateChange)
{
mStateChange = false; // reset the state change flag
writeln_d("T=", TIME_NOW, " ", PLATFORM.Name(), ":", sensorName, " ", mPerceptionString);
writeln_d(" SLB=", mSLB_Operating);
writeln_d(" SLC=", mSLC_Operating);
}
}
end_on_update
end_processor

View File

@@ -0,0 +1,75 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#include_once ../common/common_platform_script.txt
include_once ../common/weapon_defs.txt
include_once behavior_planned_route.txt
include_once behavior_pursue_weapon_task_target.txt
include_once behavior_engage_weapon_task_target.txt
#only define things in this type definition that can be overwritten later
# ie: only the behavior_tree, not the on_update or on_initialize blocks
processor AI_QUANTUM_TASKER WSF_QUANTUM_TASKER_PROCESSOR
update_interval 2.0 sec
script_debug_writes off
#show_task_messages
script_variables
// agent constants
double cDEFAULT_ALTITUDE = 9144; // ~30,000 feet
// the interceptor uses these threat priority pairs to determine who is the most important threat of concern
Map<string, double> ThreatTypePriority = Map<string, double>();
ThreatTypePriority["unknown"] = 0.0;
ThreatTypePriority["uav"] = 2.0;
ThreatTypePriority["sam"] = 4.0;
ThreatTypePriority["ship"] = 4.0;
ThreatTypePriority["awacs"] = -500.0;
ThreatTypePriority["bomber"] = 2.0;
ThreatTypePriority["jammer"] = 0.0;
ThreatTypePriority["fighter"] = 10.0;
ThreatTypePriority["missile"] = 9.0;
ThreatTypePriority["missile_fast"] = 9.0; // try new category for cmd
double mEngagementAggressiveness = 0.4; // value in range [0, 1]. 1 is suicidal, 0 is very cautious.
// used by behavior_in_danger, behavior_evade, & behavior_disengage.
bool mAllowCoopEngage = false;
string mUplinkSensorName = "geo_sensor"; //name of sensor object
end_script_variables
behavior_tree
# selector
# behavior_node evade
# behavior_node go_home
# behavior_node escort
# behavior_node cap-route
# behavior_node pincer
# sequence
selector
behavior_node pursue_weapon_task_target
# behavior_node sar_job
# behavior_node pursue-point
behavior_node planned_route
end_selector
# behavior_node guide_weapons
# end_sequence
# end_selector
behavior_node engage_weapon_task_target
# behavior_node radar-control
# behavior_node weapon-uplink
end_behavior_tree
end_processor

View File

@@ -0,0 +1,68 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior anti-radiation_shot
script_variables
bool tempVariable;
end_script_variables
precondition
writeln("precondition anti-radiation_shot");
extern Array<string> ttrs;
foreach(string ttr in ttrs)
{
if (PLATFORM.AuxDataBool(ttr)) #is this guy painting us with his radar?
{
return true;
}
}
return false;
end_precondition
execute
writeln("executing anti-radiation_shot.");
PLATFORM.Comment("anti-radiation_shot");
########################################################################
### shoot on any target tracking radards that are painting us
########################################################################
extern Array<string> ttrs;
foreach(string ttr in ttrs)
{
if (PLATFORM.AuxDataBool(ttr)) #shoot at this guy if we can, he's tracking us
{
writeln_d(PLATFORM.Name(), " trying to shoot at ttr: ", ttr);
WsfPlatform ttrPlatform = WsfSimulation.FindPlatform(ttr);
if (ttrPlatform.IsValid()) #take a shot
{
WsfTrack ttrTrack = ttrPlatform.MakeTrack();
ttrTrack.SetAuxData("notlocal", "true");
extern bool CheckAndFire(WsfTrack);
if (CheckAndFire(ttrTrack))
{
writeln_d(PLATFORM.Name(), " shot at the ttr: ", ttr);
PLATFORM.SetAuxData(ttr, false);
}
}
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,151 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior avoid_overshoot
script_variables
double mLagPursuitTime = 5.0; #when flying lag pursuit, fly to where the target was this many seconds ago
double mTurnRadius = -1.0;
WsfGeoPoint mTurnPost = WsfGeoPoint();
bool mDrawPost = false;
bool mDrawLag = false;
WsfDraw mDraw = WsfDraw();
double cGRAVITY_ACCEL = 9.80665; # 1 G
double cDEFAULT_ACCEL = (cGRAVITY_ACCEL * 7.5); # m/s^2 ~7.5 Gs
end_script_variables
precondition
writeln("precondition avoid_overshoot");
//check relative position and rates against target
WsfTrack targetTrack = PROCESSOR.GetTarget();
WsfMover mover = PLATFORM.Mover();
if (targetTrack.IsNull() || !targetTrack.IsValid() || mover.IsNull() || !mover.IsValid())
{
writeln("target or mover not valid for executing avoid_overshoot");
return false;
}
//check if target is turning & I'm in pursuit
//check if I'm in danger of overshooting the target
//if inside the turn circle: fly lag
//if outside the turn circle, check closing speed and range: fly to post
WsfPlatform tPlatform = targetTrack.Target();
Vec3 tAccel = tPlatform.AccelerationWCS();
mTurnRadius = tPlatform.VelocityWCS().MagnitudeSquared() / tAccel.Magnitude(); //equation of circular motion
Vec3 tTurnPost = tAccel.Normal();
tTurnPost . Scale(mTurnRadius); //turning post is center of turning circle
tTurnPost = Vec3.Add(tPlatform.Location().LocationWCS(), tTurnPost); //(one radius in the direction of acceleration)
mTurnPost . Set(tTurnPost);
if (!mTurnPost.IsValid() || mTurnPost.Altitude() < 0 || mTurnPost.Altitude() != mTurnPost.Altitude())
{
writeln("mTurnPost is NOT VALID!");
return false;
}
if (PLATFORM.SlantRangeTo(mTurnPost) > mTurnRadius)
{
//we are outside the target's turning circle
double tCloseSpeed = PLATFORM.ClosingSpeedOf(tPlatform);
//don't want to swing it too wide
}
else
{
//we are inside the target's turning circle
return true;
}
return false;
end_precondition
execute
WsfTrack targetTrack = PROCESSOR.GetTarget();
if (targetTrack.IsNull() || !targetTrack.IsValid())
{
writeln("target track not valid for executing avoid_overshoot");
return;
}
writeln("executing avoid_overshoot");
PLATFORM.Comment("avoid_overshoot");
//fly lag &/or climb
double maxLagDist = 0.40 * PLATFORM.SlantRangeTo(targetTrack);
double maxLagTime = maxLagDist / targetTrack.Speed();
double lagTime = mLagPursuitTime;
if (lagTime > maxLagTime)
{
lagTime = maxLagTime;
}
WsfGeoPoint targetLagPos = targetTrack.LocationAtTime(TIME_NOW - lagTime);
//use track's old position (just extrapolated with velocity, backwards)
double tAlt = targetTrack.Altitude();
if (PLATFORM.Altitude() > tAlt)
{
tAlt = PLATFORM.Altitude();
}
PLATFORM.GoToAltitude(tAlt, 100);
PLATFORM.TurnToHeading(PLATFORM.TrueBearingTo(targetLagPos), cDEFAULT_ACCEL);
if (mDrawPost)
{
mDraw.SetLineSize(2);
mDraw.SetColor(0.2, 1.0, 0.2); //greenish
mDraw.SetDuration(PROCESSOR.UpdateInterval());
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(mTurnPost);
mDraw.End();
}
if (mDrawLag)
{
mDraw.SetLineSize(2);
mDraw.SetColor(0.8, 1.0, 0.2); //yellow-ish
mDraw.SetDuration(PROCESSOR.UpdateInterval());
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(targetLagPos);
mDraw.End();
}
double tSpeed = targetTrack.Speed();
//double percentSpeed = 1.0 + (PLATFORM.SlantRangeTo(mTurnPost) / (mTurnRadius * 100)); //vary speed based on distance from from post
double percentSpeed = 0.95; //match the targets speed for now
//writeln("tSpeed=", tSpeed, ", mTurnPost=", mTurnPost.ToString(), ", SlantRangeTo(mTurnPost)=", PLATFORM.SlantRangeTo(mTurnPost), ", mTurnRadius=", mTurnRadius, ", percentSpeed=", percentSpeed);
PLATFORM.GoToSpeed(tSpeed*percentSpeed, cDEFAULT_ACCEL, true);
//use out of plan manuevers if necessary to slow down & preserve energy (climb)
###PLATFORM.GoToAltitude(mBiggestThreat.Altitude(), cDEFAULT_ACCEL, true);
end_execute
end_behavior

View File

@@ -0,0 +1,122 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior bid_on_jobs
script_debug_writes off
script_variables
bool mBidOnOwnJobs = false;
end_script_variables
precondition
writeln_d(PLATFORM.Name(), " precondition bid_on_jobs, T=", TIME_NOW);
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
} // ((WsfRIPRProcessor)PROCESSOR)
if (mBidOnOwnJobs == false)
{
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
if (!commander.IsValid())
{
writeln_d("does not have a valid commander");
return Failure("does not have a valid commander");
}
else if (commander.GetJobs().Size() <= 0)
{
writeln_d("commander does not have any jobs");
return Failure("commander does not have any jobs");
}
else
{
return true;
}
}
else
{
if (((WsfRIPRProcessor)PROCESSOR).GetJobs().Size() <= 0)
{
writeln_d("agent does not have any jobs on its own job board");
return Failure("agent does not have any jobs on its own job board");
}
else
{
return true;
}
}
end_precondition
#on_init
#end_on_init
execute
writeln_d(PLATFORM.Name(), " executing bid_on_jobs, T=", TIME_NOW);
Array<WsfRIPRJob> jobs;
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
if (mBidOnOwnJobs == false)
{
if (commander.IsBidWindowOpen())
{
jobs = commander.GetJobs();
}
else
{
writeln_d("commanders bidding window not open");
return;
}
}
else
{
if (((WsfRIPRProcessor)PROCESSOR).IsBidWindowOpen())
{
jobs = ((WsfRIPRProcessor)PROCESSOR).GetJobs();
}
else
{
writeln_d("my bidding window not open");
return;
}
}
foreach (WsfRIPRJob job in jobs)
{
double bid = ((WsfRIPRProcessor)PROCESSOR).QueryBid(job);
if ((bid < 0) && (job.GetProgress(((WsfRIPRProcessor)PROCESSOR)) < 1))
{
writeln_d("bid_on_jobs: job.UnbidJob() for job: ", job.GetDescription());
job.UnbidJob( ((WsfRIPRProcessor)PROCESSOR) );
}
else
{
job.BidJob(((WsfRIPRProcessor)PROCESSOR), bid);
writeln_d(PLATFORM.Name(), " bid for ", job.GetDescription(), " = ", bid, ", priority = ", job.GetPriority());
for (int channel = 1; channel < ((WsfRIPRProcessor)PROCESSOR).GetNumJobChannels(); channel = channel + 1)
{
double scaledBid = bid * 0.25;
if (bid < 0.0)
{
scaledBid = bid * 2.5;
}
job.BidJob( ((WsfRIPRProcessor)PROCESSOR), channel, scaledBid, 0.0 );
}
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,167 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior cap-route
script_debug_writes off
script_variables
bool mDrawRoute = true;
WsfDraw mDraw = WsfDraw();
string mOldRouteStr = "no route";
bool mNewRoute = false;
WsfGeoPoint mPoint;
double mHeading;
string mRouteName;
WsfRoute mRoute;
WsfRIPRJob mCurrentJob = null;
end_script_variables
precondition
writeln_d("precondition cap-route");
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
}
string anOldRouteStr = mOldRouteStr;
mOldRouteStr = "no route";
mNewRoute = false;
extern WsfTrack GetTrackByName (WsfPlatform, string);
extern bool TestTrackCategory (WsfTrack, string);
if (((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().IsValid() &&
((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().IsJobWindowOpen())
{
mCurrentJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
}
if (mCurrentJob.IsNull() ||
!mCurrentJob.IsValid() ||
mCurrentJob.Name() != "cap-route")
{
writeln_d("cap-route -> job not a valid cap-route job");
return Failure("job is not a valid cap-route job");
}
mPoint = (WsfGeoPoint)mCurrentJob.GetData("location");
mHeading = (double)mCurrentJob.GetData("heading");
mRouteName = (string)mCurrentJob.GetData("route name");
WsfRoute route = WsfRoute.FindGlobal(mRouteName);
if (!mPoint.IsValid())
{
writeln("!!! Invalid point for cap-route job: ", mCurrentJob.GetDescription() );
return Failure("cap-route job does not have valid point");
}
if (!route.IsValid())
{
writeln("!!! Invalid route for cap-route job: ", mCurrentJob.GetDescription() );
return Failure("cap-route job does not have route named");
}
mHeading = MATH.NormalizeAngleMinus180_180(mHeading);
########################################################################
### print output / comments for any tartet change
########################################################################
mOldRouteStr = "Job: " + ", " + mCurrentJob.GetDescription();
writeln_d(" - ", mOldRouteStr);
if (mOldRouteStr != anOldRouteStr)
{
PLATFORM.Comment(mOldRouteStr);
mNewRoute = true;
mRoute = WsfRoute.CopyGlobal(mRouteName);
mRoute.Transform(mPoint.Latitude(), mPoint.Longitude(), mHeading);
}
mDraw.SetDuration(((WsfRIPRProcessor)PROCESSOR).UpdateInterval());
return true;
end_precondition
#on_init
#end_on_init
execute
writeln_d(PLATFORM.Name(), " executing cap-route, T=", TIME_NOW);
//PLATFORM.Comment("cap-route");
bool onCap = false;
# WsfRoute myRoute = PLATFORM.Route();
# if(myRoute.IsValid() && myRoute.Name() == "cap_route")
# {
# int routeIndex = PLATFORM.RoutePointIndex();
# if (routeIndex < 0 || routeIndex >= myRoute.Size())
# {
# routeIndex = 0;
# }
#
# double distThreshold = 4.0*185.2; ## 4/10th nm
# if (myRoute.Waypoint(routeIndex).Location().GroundRangeTo(PLATFORM.Location()) < distThreshold)
# {
# routeIndex = routeIndex + 1;
# if (routeIndex >= myRoute.Size())
# {
# routeIndex = 0;
# }
# }
# //onCap = PLATFORM.FollowRoute(myRoute, routeIndex);
#
# WsfWaypoint wpt = myRoute.Waypoint(routeIndex);
# extern bool FlyTarget(WsfPlatform, WsfGeoPoint, double);
# onCap = FlyTarget(PLATFORM, wpt.Location(), wpt.Speed());
# }
onCap = ( ! PLATFORM.Mover().IsExtrapolating() );
if (!onCap || mNewRoute)
{
WsfRoute capRoute = WsfRoute.Create("cap_route");
WsfRoute givenRoute = WsfRoute.CopyGlobal(mRouteName);
givenRoute.Transform(mPoint.Latitude(), mPoint.Longitude(), mHeading);
capRoute.Append(givenRoute);
PLATFORM.FollowRoute(capRoute);
}
if (mDrawRoute == true)
{
WsfRoute currRoute = PLATFORM.Route();
if (currRoute.IsValid())
{
mDraw.SetLayer("behavior_cap-route");
mDraw.Erase(PLATFORM.Name());
mDraw.SetId(PLATFORM.Name());
mDraw.SetColor(1,0,1);
mDraw.SetLineSize(1);
mDraw.SetLineStyle("dashed");
mDraw.BeginPolyline();
for (int i=0; i<currRoute.Size(); i=i+1)
mDraw.Vertex(currRoute.Waypoint(i).Location());
mDraw.End();
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,160 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior debug_job_board
script_variables
Array<WsfRIPRProcessor> mSubs = Array<WsfRIPRProcessor>();
Array<WsfRIPRJob> mJobs = Array<WsfRIPRJob>();
bool mHideMinBids = true;
double mMinBid = -MATH.DOUBLE_MAX();
end_script_variables
on_init
end_on_init
precondition
writeln_d("precondition debug_job_board");
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
} // ((WsfRIPRProcessor)PROCESSOR)
mSubs = ((WsfRIPRProcessor)PROCESSOR).GetRIPRSubordinateProcessors();
mSubs.PushBack(((WsfRIPRProcessor)PROCESSOR));
mJobs = ((WsfRIPRProcessor)PROCESSOR).GetJobs();
if( (mSubs.Size() > 0) && (mJobs.Size() > 0))
{
return true;
}
return false;
end_precondition
execute
writeln_d("executing debug_job_board");
writeln("Job Board for ", PLATFORM.Name(), " at Time = ", TIME_NOW);
#write top row (bidder names)
string topRow = " job name, priority, ";
foreach (WsfRIPRProcessor sub in mSubs)
{
string subName = sub.Platform().Name();
while (subName.Length() < 16)
{
subName = " " + subName;
}
if (subName.Length() > 16)
{
subName = subName.Substring(-16);
}
topRow = topRow + subName + ", "; #each column is 18 spaces wide
}
###topRow = topRow.Substring(0,-2); #clip off the last comma & space
topRow = topRow + " winner";
string lines = "-";
while (lines.Length() < topRow.Length())
{
lines = lines + "-";
}
writeln(lines);
writeln(topRow);
foreach (WsfRIPRJob job in mJobs)
{
string jobDesc = job.GetDescription();
while (jobDesc.Length() < 32)
{
jobDesc = " " + jobDesc;
}
if (jobDesc.Length() > 32)
{
jobDesc = jobDesc.Substring(-32);
}
string row = jobDesc + " "; #this should be 33 spaces, at this point
string pString = (string)job.Priority();
while( pString.Contains(".") && pString.Substring(-1)=="0") #take off all trailing zeros
{
pString = pString.Substring(0,-1);
}
if (pString.Length() > 16)
{
pString = pString.Substring(0,15);
}
pString = pString + ", ";
while (pString.Length() < 18)
{
pString = " " + pString;
}
row = row + pString;
foreach (WsfRIPRProcessor sub in mSubs)
{
double bidValue = job.GetBid(sub);
string bidValStr = (string)bidValue;
if (mHideMinBids == true && bidValue <= mMinBid)
{
bidValStr = "-";
}
while( bidValStr.Contains(".") && bidValStr.Substring(-1)=="0") #take off all trailing zeros
{
bidValStr = bidValStr.Substring(0,-1);
}
if (bidValStr.Length() > 16)
{
bidValStr = bidValStr.Substring(0,15);
}
bidValStr = bidValStr + ", ";
while (bidValStr.Length() < 18)
{
bidValStr = " " + bidValStr;
}
row = row + bidValStr;
}
###row = row.Substring(0,-2); #clip off the last comma & space
Array<WsfPlatform> winners = job.Winners();
string winner;
if (winners.Empty())
{
winner = "-";
}
else if (winners.Size() > 1)
{
winner = (string)winners.Size() + " winners";
}
else
{
winner = winners[0].Name();
}
while (winner.Length() < 16)
{
winner = " " + winner;
}
if (winner.Length() > 16)
{
winner = winner.Substring(-16);
}
row = row + winner;
writeln(row);
}
writeln(lines);
writeln("");
end_execute
end_behavior

View File

@@ -0,0 +1,94 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior default-flight
script_debug_writes off
script_variables
bool mDrawRoute = false;
WsfDraw mDraw = WsfDraw();
bool mResumeDefaultRoute = true;
double cDEFAULT_SPEED = 450.0 * MATH.MPS_PER_NMPH();
double cDEFAULT_ACCEL = 7.5 * Earth.ACCEL_OF_GRAVITY(); // 7.5 G (m/s^2)
double cLARGE_UPDATE_INTERVAL = 3.0; // update once every 3 seconds
end_script_variables
script void DrawRoute()
WsfRoute currRoute = PLATFORM.Route();
if (currRoute.IsValid())
{
//PLATFORM.Comment("draw current route");
mDraw.SetLayer("behavior default=flight");
mDraw.Erase(PLATFORM.Name());
mDraw.SetId(PLATFORM.Name());
mDraw.SetColor(0,1,1);
mDraw.SetLineSize(2);
mDraw.SetLineStyle("dash_dot2");
mDraw.BeginPolyline();
for (int i=0; i<currRoute.Size(); i=i+1)
{
mDraw.Vertex(currRoute.Waypoint(i).Location());
}
mDraw.End();
}
end_script
precondition
writeln_d("precondition default-flight");
return true;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing default-flight, T=", TIME_NOW);
//PLATFORM.Comment("default-flight");
if (mResumeDefaultRoute)
{
bool success = false;
//go at default speed; this gets overwritten if route waypoint has defined a speed
success = PLATFORM.GoToSpeed(cDEFAULT_SPEED, cDEFAULT_ACCEL, true);
//return to route, at the last target route point as re-entry
#success = success && PLATFORM.ReturnToRoute();
extern bool ReEnterRoute(WsfPlatform);
success = success && ReEnterRoute(PLATFORM);
if (!success)
{
string msg = "ERROR: transition to default flight, could not return to route!";
PLATFORM.Comment(msg);
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
}
else
{
string msg = write_str("returning to route: ", PLATFORM.Route().Name());
//PLATFORM.Comment(msg);
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
}
}
else
{
extern double cDEFAULT_ALTITUDE;
extern bool FlyHold (WsfPlatform, double, double, double);
FlyHold( PLATFORM, PLATFORM.Heading(), cDEFAULT_ALTITUDE, cDEFAULT_SPEED);
}
#PROCESSOR.SetUpdateInterval(cLARGE_UPDATE_INTERVAL);
if (mDrawRoute)
{
DrawRoute();
}
end_execute
end_behavior

View File

@@ -0,0 +1,177 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior disengage
script_debug_writes off
script_variables
double cDIVE_ALTITUDE = 304.8; # 1000 feet
double cDEFAULT_SPEED = 200.0; # m/s
double cMAX_SPEED = 9999999999.99; # m/s
double cGRAVITY_ACCEL = 9.80665; # 1 G
double cDEFAULT_ACCEL = (cGRAVITY_ACCEL * 7.5); # m/s^2 ~7.5 Gs
double cANGLE_TOLERANCE = 45.0; # degrees
bool drawEscape = false;
WsfDraw draw = WsfDraw();
end_script_variables
on_init
draw.SetLineSize(2);
draw.SetColor(1.0, 0.0, 1.0); //purple
end_on_init
script bool IsFlightAsset(WsfPlatform aPlat)
if (aPlat.Mover().IsA_TypeOf("WSF_AIR_MOVER" ) ||
aPlat.Mover().IsA_TypeOf("WSF_6DOF_MOVER") )
{
return true;
}
else if (aPlat.MakeTrack().AirDomain())
{
return true;
}
else if((aPlat.Altitude() > 152.4) && (aPlat.Speed() > 51.44) ) // ~500 feet alt, ~100 knots speed
{
return true;
}
return false;
end_script
script bool IsWeapon(WsfTrack aTrack)
if (aTrack.Target().IsValid() && aTrack.Target().WeaponEngagement().IsValid())
{
return true;
}
return false;
end_script
precondition
writeln("precondition disengage");
//check track list or threat processor for any threats
extern double mVisualRange;
double totalThreatsWVR = 0.0;
foreach (WsfLocalTrack t in PLATFORM.MasterTrackList())
{
if (!t.SideValid() || t.Side() != PLATFORM.Side())
{
if ((!IsWeapon(t)) && (PLATFORM.SlantRangeTo(t) < mVisualRange))
{
writeln_d(" is threat: ", t.TargetName());
totalThreatsWVR = totalThreatsWVR + 1.0;
}
}
}
double assetCount = 0.0;
WsfRIPRProcessor cmdr = PROCESSOR.GetRIPRCommanderProcessor(); # get the flight lead
if (cmdr.IsValid())
{
WsfRIPRProcessor cmdr2 = cmdr.GetRIPRCommanderProcessor(); # check for gci
if (cmdr2.IsValid())
{
foreach (WsfPlatform aifl in cmdr2.Platform().Subordinates())
{
foreach (WsfPlatform aiai in aifl.Subordinates())
{
if (IsFlightAsset(aiai) && PLATFORM.SlantRangeTo(aiai) < mVisualRange)
{
writeln_d(" is asset: ", aiai.Name());
assetCount = assetCount + 1.0;
}
}
}
}
else
{
foreach (WsfPlatform aiai in cmdr.Platform().Subordinates())
{
if (IsFlightAsset(aiai) && PLATFORM.SlantRangeTo(aiai) < mVisualRange)
{
writeln_d(" is asset: ", aiai.Name());
assetCount = assetCount + 1.0;
}
}
}
}
extern double mEngagementAggressiveness;
double requiredAggressiveness = totalThreatsWVR / (totalThreatsWVR + assetCount);
writeln_d(" required aggress for disengage: ", requiredAggressiveness, " mine: ", mEngagementAggressiveness);
if (mEngagementAggressiveness < requiredAggressiveness)
{
draw.SetDuration(PROCESSOR.UpdateInterval());
return true; //disengage
}
//check if there are any threats that I need to evade
//if there are & I have an energy advantage (altitude &/or speed), then extend the escape & unload
//???
//???
//???
return false;
end_precondition
execute
writeln("executing disengage.");
PLATFORM.Comment("disengage");
#double bestheading = 0.0; //compute this as away from all threats
#PLATFORM.TurnToHeading(bestheading);
//calculate an average heading to incoming platforms weighted by distance
double y = 0;
double x = 0;
foreach (WsfLocalTrack t in PLATFORM.MasterTrackList())
{
if (t.IsValid() && (!t.SideValid() || t.Side() != PLATFORM.Side()))
{
double distMod = 1 / PLATFORM.SlantRangeTo(t);
double bearingMod = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(t));
x = x + MATH.Sin(bearingMod) * distMod;
y = y + MATH.Cos(bearingMod) * distMod;
writeln_d(" Incoming ", t.TargetName(), " at distance: ", 1 / distMod, ", bearing: ", bearingMod);
}
}
if (x!=0 || y!=0) //if there is something to run from
{
double evadeHeading = MATH.NormalizeAngle0_360(MATH.ATan2(x, y) - 180);
writeln_d(" x: ", x, ", y: ", y, ", evade at: ", evadeHeading);
extern bool FlyHold (WsfPlatform, double, double, double);
FlyHold( PLATFORM, evadeHeading, cDIVE_ALTITUDE, cMAX_SPEED);
if (drawEscape == true)
{
WsfGeoPoint pt = PLATFORM.Location();
pt.Extrapolate(evadeHeading, 1852 * 10); //draw line in direction of egress, for 10 nautical miles
draw.BeginLines();
draw.Vertex(PLATFORM.Location());
draw.Vertex(pt);
draw.End();
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,63 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior draw_master_track_list
script_variables
WsfDraw draw = WsfDraw();
end_script_variables
on_init
end_on_init
precondition
writeln_d("precondition draw_master_track_list");
if (PLATFORM.MasterTrackList().Count() <= 0)
{
return false;
}
draw.SetDuration(PROCESSOR.UpdateInterval());
return true;
end_precondition
execute
writeln_d("executing draw_master_track_list");
draw.SetLineSize(2);
draw.BeginLines();
foreach(WsfLocalTrack t in PLATFORM.MasterTrackList())
{
draw.SetColor(1.0, 1.0, 0.0); //yellowish
draw.Vertex(PLATFORM.Location());
draw.Vertex(t.CurrentLocation());
for(int i=0; i<t.RawTrackCount(); i=i+1)
{
WsfTrack x = t.RawTrack(i);
if (x.LocationValid())
{
draw.SetColor(0.0, 1.0, 0.0); //green
draw.Vertex(x.CurrentLocation());
draw.Vertex(t.CurrentLocation());
}
}
if (t.Target().IsValid())
{
draw.SetColor(0.0, 0.0, 1.0); //blue
draw.Vertex(t.CurrentLocation());
draw.Vertex(t.Target().Location());
}
}
draw.End();
end_execute
end_behavior

View File

@@ -0,0 +1,47 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior draw_target
script_variables
WsfDraw draw = WsfDraw();
end_script_variables
on_init
draw.SetLineSize(2);
draw.SetColor(1.0, 0.0, 1.0); //purple
end_on_init
precondition
writeln("precondition draw_target");
WsfTrack targetTrack = PROCESSOR.GetTarget();
if (targetTrack.IsNull() || !targetTrack.IsValid())
{
writeln_d("target not valid for executing draw_target");
return false;
}
draw.SetDuration(PROCESSOR.UpdateInterval());
return true;
end_precondition
execute
writeln("executing draw_target");
WsfTrack targetTrack = PROCESSOR.GetTarget();
draw.BeginLines();
draw.Vertex(PLATFORM.Location());
draw.Vertex(targetTrack.CurrentLocation());
draw.End();
end_execute
end_behavior

View File

@@ -0,0 +1,629 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
##############################################################################
### assumes exists: extern string GetWeaponForThreat(WsfPlatform, WsfTrack);
##############################################################################
behavior engage-target
script_debug_writes off
script_variables
//**********************************************************************//
//** platform / agent specific shooting parameters **//
//**********************************************************************//
bool mCoopEngageOne = false;
bool mCoopEngageOneFlightOnly = false;
//specify any targets here that you will always shoot at...
//even disregarding other targets to do so. (use types or names)
Array<string> mMustShootAtCategories = Array<string>();
mMustShootAtCategories[0] = "sam";
mMustShootAtCategories[1] = "FIRE_CONTROL";
double mDegradedFiringAngle = 55.0; //negative if not valid
double mDegradedPercentRange = 0.50; //range constraint if past degraded firing angle
//specify orientation limits for shooting
double mMaxFiringRollAngle = 10.0; //dont shoot if rolled more/less than this
double mMaxFiringPitchAngle = 15.0; //dont shoot if pitched more than this
double mMinFiringPitchAngle = -10.0; //dont shoot if pitched less than this
//**********************************************************************//
//** threat specific shooting parameters **//
//**********************************************************************//
//require different track qualities to fire on different kinds of threats
double DefaultRequiredTrackQuality = 0.49;
Map<string, double> ThreatTypeRequiredTrackQuality = Map<string, double>();
ThreatTypeRequiredTrackQuality["bomber"] = 0.49;
ThreatTypeRequiredTrackQuality["fighter"] = 0.49;
//fire off different salvos at different types of threats
int DefaultAirSalvo = 1;
int DefaultGndSalvo = 1;
Map<string, int> ThreatTypeSalvo = Map<string, int>();
ThreatTypeSalvo["sam"] = 2;
ThreatTypeSalvo["ship"] = 2;
ThreatTypeSalvo["bomber"] = 2;
ThreatTypeSalvo["fighter"] = 1;
ThreatTypeSalvo["FIRE_CONTROL"] = 1;
ThreatTypeSalvo["primary_target"] = 2;
ThreatTypeSalvo["secondary_target"] = 2;
//force a specific weapon for use against given threat type
Map<string, string> ThreatTypeWeapon = Map<string, string>();
//ThreatTypeWeapon["uav"] = "srm";
//ThreatTypeWeapon["fighter"] = "lrm";
//**********************************************************************//
//** weapon + threat specific shooting parameters **//
//**********************************************************************//
//specify an Rmax based on which weapon used and which threat engaged
double DefaultPercentRangeMax = 0.80; // don't launch unless within this percent of Rmax
double DefaultPercentRangeMin = 1.20; // don't launch unless beyond this percent of Rmin
Map<string, Map<string, double>> WeaponThreatRmaxMap = Map<string, Map<string, double>>();
WeaponThreatRmaxMap["base_weapon"] = Map<string, double>();
WeaponThreatRmaxMap["base_weapon"].Set("fighter", 0.80);
//specify max firing angles based on weapon used and threat engaged
double DefaultMaxFiringAngle = 45.0;
Map<string, Map<string, double>> WeaponThreatAngleMap = Map<string, Map<string, double>>();
WeaponThreatAngleMap["base_weapon"] = Map<string, double>();
WeaponThreatAngleMap["base_weapon"].Set("fighter", 45.0);
WeaponThreatAngleMap["base_weapon"].Set("missile", 30.0);
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
double mInactiveLaunchDelay = 1.0; // wait 1 seconds after your last missile detonated.
// hacky, useful for weapons that dont show active
Map<string,double> mTrackWeaponActiveMap = Map<string,double>();
Map<WsfTrack, double> mRoundsFiredAtMap = Map<WsfTrack, double>(); //useful when weapons don't show as active
end_script_variables
script bool MustShootAt(WsfTrack track)
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory in mMustShootAtCategories )
{
if( plat.CategoryMemberOf( aCategory ) )
{
return true;
}
}
}
return false;
end_script
script int GetSalvoForThreat(WsfTrack track)
#writeln_d("checking salvo size for category: ", category);
#WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetIndex() );
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : int salvo in ThreatTypeSalvo )
{
if( plat.CategoryMemberOf( aCategory ) )
{
writeln_d("salvo for type ", aCategory, " = ", salvo);
return salvo;
}
}
}
extern string GetTargetDomain(WsfTrack);
string sTargetDomain = GetTargetDomain(track);
if ( (sTargetDomain == "LAND") || (sTargetDomain == "SURFACE") )
{
return DefaultGndSalvo;
}
return DefaultAirSalvo;
end_script
script double GetRequiredTrackQualityForThreat(WsfTrack threat)
writeln_d("checking required TQ for track: ", threat.TargetName());
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : double quality in ThreatTypeRequiredTrackQuality )
{
if( plat.CategoryMemberOf( aCategory ) )
{
writeln_d("TQ for type ", aCategory, " = ", quality);
return quality;
}
}
}
return DefaultRequiredTrackQuality;
end_script
script double GetLaunchPercentRangeMaxOnThreat(string weaponName, WsfTrack threat)
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
if (WeaponThreatRmaxMap.Exists(weaponName))
{
Map<string, double> categoryRangeMap = WeaponThreatRmaxMap.Get(weaponName);
foreach (string aCategory : double percent in categoryRangeMap)
{
if( plat.CategoryMemberOf( aCategory ) )
{
return percent;
}
}
}
}
return DefaultPercentRangeMax;
end_script
script double GetMaxFiringAngleForWeapon(string weaponName, WsfTrack threat)
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
if (WeaponThreatAngleMap.Exists(weaponName))
{
Map<string, double> threatAngleMap = WeaponThreatAngleMap.Get(weaponName);
foreach (string aCategory : double angle in threatAngleMap)
{
if( plat.CategoryMemberOf( aCategory ) )
{
return angle;
}
}
}
}
return DefaultMaxFiringAngle;
end_script
script string GetWeaponForThreat(WsfPlatform platform, WsfTrack track)
bool checkName = false;
string name = "";
extern bool IsWeaponDomainCapable(WsfTrack, Map<string, Object>);
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : string wpnStr in ThreatTypeWeapon )
{
writeln_d("checking if ", plat.Name(), " is category: ", aCategory);
if( wpnStr.Length()>0 && plat.CategoryMemberOf( aCategory ) )
{
checkName = true;
name = wpnStr;
writeln_d(" Time= ", TIME_NOW, " ", PLATFORM.Name(), " searching only for weapon category: ", name, " (for use against ", plat.Name(), ")");
break;
}
}
}
else
{
writeln_d("platform for target ", track.TargetName()," is not valid!");
}
extern Array<Map<string, Object>> mWeaponArray;
foreach (Map<string, Object> curWeapon in mWeaponArray)
{
string weaponName = (string)curWeapon["name"];
WsfWeapon weapon = (WsfWeapon)curWeapon["weapon"];
writeln_d(" checking weapon ", weaponName, " valid=", weapon.IsValid());
if (checkName && weaponName != name)
{
continue;
}
if (weapon.QuantityRemaining() <= 0)
{
continue;
}
if (!IsWeaponDomainCapable(track,curWeapon))
{
continue;
}
WsfLaunchComputer lcPtr = weapon.LaunchComputer();
if (lcPtr.IsValid() &&
lcPtr.IsA_TypeOf("WSF_AIR_TO_AIR_LAUNCH_COMPUTER"))
{
writeln_d(" using air-to-air launch computer");
// The returned array contains: Rmax, RmaxTOF, Rne, RneTOF, Rmin, RminTOF
// in that order. -1.0 means "not valid".
Array<double> returnedValues = lcPtr.LookupResult(track);
// Now have to consider whether we have enough information to continue with a weapon shot:
double theRmax = returnedValues[0]; //"Rmax";
double theRmaxTOF = returnedValues[1]; //"RmaxTOF";
double theRne = returnedValues[2]; //"Rne";
double theRneTOF = returnedValues[3]; //"RneTOF";
double theRmin = returnedValues[4]; //"Rmin";
double theRminTOF = returnedValues[5]; //"RminTOF";
double range = 0.0;
if (track.RangeValid())
{
range = track.Range(); #is this the range from you to the track, or the range from the sensor to the track?
}
else
{
range = track.GroundRangeTo(PLATFORM);
}
// Check for track range less than Rmin * scaleFactor, if not, return.
// But do not check for min range constraint at all unless we are likely to be needing it.
if (range < 5000)
{
if (theRmin == -1.0)
{
writeln_d(" Engagement did not shoot since Rmin was not valid.");
continue;
#return;
}
double RminConstraint = theRmin * DefaultPercentRangeMin;
if (range < RminConstraint)
{
writeln_d(" Engagement did not shoot since inside the k * Rmin constraint distance.");
writeln_d(" Range versus Rmin constraint = ", range, ", ", RminConstraint);
continue;
#return;
}
}
// Check for track range less than Rne, if so, FORCE a weapon fire.
bool forceWeaponFire = false;
if (range < theRne)
{
writeln_d(" Engagement is forcing a weapon fire due to inside Rne.");
writeln_d(" Range versus Rne constraint = ", range, ", ", theRne);
forceWeaponFire = true;
}
if (forceWeaponFire == false)
{
######################################TRY THIS######################################
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid() && plat.CategoryMemberOf("fighter"))
{
#theRmax = theRne;
theRmax = (theRmax + theRne)/2.0; //for highly maneuverable fighter targets
}
####################################END TRY THIS####################################
// Check for track range less than k * Rmax, if not, return.
if (theRmax == -1.0)
{
writeln_d(" Engagement did not shoot since Rmax was not valid.");
continue;
#return;
}
//double RmaxConstraint = theRmax * DefaultPercentRangeMax;
double percentRMax = GetLaunchPercentRangeMaxOnThreat(weaponName, track);
double RmaxConstraint = theRmax * percentRMax;
if (range > RmaxConstraint)
{
writeln_d(" Engagement did not shoot since outside the k * Rmax constraint distance.");
writeln_d(" Range versus Rne constraint = ", range, ", ", theRne);
continue;
#return;
}
}
writeln_d(" Engagement meets constraints for firing a weapon (continue).");
}
else if (lcPtr.IsValid() &&
lcPtr.IsA_TypeOf("WSF_ATG_LAUNCH_COMPUTER"))
{
writeln_d(" using air-to-ground launch computer");
if (lcPtr.CanIntercept(track))
{
//intercept works, this weapon is a candidate
}
else
{
continue;
}
}
else
{
writeln_d(" using script input mWeaponArray array range values");
//check our own ranges & angles --> hacky!!!
extern double EffectiveRange(WsfPlatform, WsfTrack);
double effectiveRange = EffectiveRange(platform, track);
double absRelativeBearing = MATH.Fabs(PLATFORM.RelativeBearingTo( track ));
double rangeScale = GetLaunchPercentRangeMaxOnThreat(weaponName, track);
if (absRelativeBearing > mDegradedFiringAngle)
{
rangeScale = MATH.Min(mDegradedPercentRange, rangeScale);
}
if ((double)curWeapon["rangeMin"] > effectiveRange)
{
writeln_d(" target too close");
continue;
}
if (absRelativeBearing > GetMaxFiringAngleForWeapon(weaponName, track))
{
writeln_d(" target firing angle too large");
continue;
}
if ((double)curWeapon["rangeMax"] * rangeScale < effectiveRange)
{
writeln_d(" target too far away");
continue;
}
double TOF = 180;
double missileAvgSpeed = 1000;
if (curWeapon.Exists("avgSpeed"))
{
missileAvgSpeed = (double)curWeapon["avgSpeed"];
}
if (curWeapon.Exists("TOF"))
{
TOF = (double)curWeapon["TOF"];
}
double range = PLATFORM.SlantRangeTo(track);
//double closingSpeed = PLATFORM.ClosingSpeedOf(track);
double relBearing = track.RelativeBearingTo(PLATFORM);
if (relBearing > 90.0)
{
if (track.Speed() > missileAvgSpeed)
{
continue;
}
double speedDiff = missileAvgSpeed - track.Speed();
if ((range/speedDiff) > TOF)
{
continue;
}
}
}
return (string)curWeapon["name"];
}
return "";
end_script
#on_init
#end_on_init
precondition
writeln_d("precondition engage-target");
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
}
extern WsfTrack GetTrackByName(WsfPlatform, string);
double pitch = PLATFORM.Pitch();
if (MATH.Fabs(PLATFORM.Roll()) > mMaxFiringRollAngle ||
pitch > mMaxFiringPitchAngle ||
pitch < mMinFiringPitchAngle)
{
string msgStr = write_str(" ", PLATFORM.Name(), " orientation too far off to fire! (roll or pitch)");
writeln_d(msgStr);
//PLATFORM.Comment(msgStr);
return Failure(msgStr);
}
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
if (commander.IsValid())
{
#check all job channels, not just the main target
for (int channel = 0; channel < ((WsfRIPRProcessor)PROCESSOR).GetNumJobChannels(); channel = channel + 1)
{
WsfRIPRJob aJob = commander.GetJobFor(((WsfRIPRProcessor)PROCESSOR), channel);
if (aJob.IsValid() &&
aJob.Name() == "pursue-target")
{
string targetName = (string)aJob.GetData("targetTrackName");
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (!targetTrack.IsNull() &&
targetTrack.IsValid())
{
extern bool TestTrackCategory( WsfTrack, string );
if (!TestTrackCategory(targetTrack, "unknown") &&
targetTrack.BelievedAlive())
{
return true;
}
}
}
}
}
return Failure("no acceptable target to shoot at!");
end_precondition
script bool FireWeapon(WsfTrack targetTrack)
bool launched = false;
writeln_d(" Time= ", TIME_NOW, " Attempting a shot against: ", targetTrack.TargetName(), " Index: ", targetTrack.TargetIndex(), " Type: ", targetTrack.TargetType());
extern bool TestTrackCategory(WsfTrack, string);
if (!TestTrackCategory(targetTrack, "unknown") &&
targetTrack.BelievedAlive())
{
if ((((WsfRIPRProcessor)PROCESSOR).WeaponsActive(targetTrack) > 0) ||
(((WsfRIPRProcessor)PROCESSOR).PeersWeaponsActive(targetTrack) > 0))
{
mTrackWeaponActiveMap[targetTrack.TargetName()] = TIME_NOW;
writeln_d(" FAIL: Weapons already active against ", targetTrack.TargetName());
return launched;
}
else
{
writeln_d("no weapons active against target ", targetTrack.TargetName());
}
if ((TIME_NOW - mTrackWeaponActiveMap[targetTrack.TargetName()]) < mInactiveLaunchDelay)
{
writeln_d(" FAIL: Waiting to see what last active weapon did, score a kill?");
return launched;
}
// if this is a ttr, it should ignore the check for coop engage one
if (targetTrack.CheckAuxData("notlocal") == false)
{
if (mCoopEngageOne == false)
{
WsfLocalTrack targetLocalTrack = (WsfLocalTrack)targetTrack;
if (targetLocalTrack.IsValid())
{
if(!targetLocalTrack.ContributorOf(PLATFORM) &&
!targetLocalTrack.IsPredefined())
{
writeln_d(" FAIL: Not able to coop engage! ", PLATFORM.Name(), " targeting ",targetTrack.TargetName(), ". NumContributors: ", targetLocalTrack.NumContributors() );
return launched;
}
}
}
else if (mCoopEngageOneFlightOnly == true)
{
//check if this platform needs somebody in his flight to have track on the target
WsfLocalTrack targetLocalTrack = (WsfLocalTrack)targetTrack;
if (targetLocalTrack.IsValid())
{
if (targetLocalTrack.IsPredefined())
{
//its fine, go ahead & shoot
}
else
{
bool OkToShoot = false;
Array<WsfPlatform> peers = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().SubordinatePlatforms();
foreach (WsfPlatform peer in peers)
{
if(targetLocalTrack.ContributorOf(peer))
{
OkToShoot = true;
break;
}
}
if (!OkToShoot)
{
writeln_d(" FAIL: Cant engage tracks not supported by flight group! ", PLATFORM.Name(), " targeting ", targetTrack.TargetName(), ".");
return launched;
}
}
}
}
}
// We can launch once we have a target-quality track.
//TODO probably need something to test for failure to lockon
writeln_d (" targetTrack.TrackQuality == ", targetTrack.TrackQuality());
if (targetTrack.TrackQuality() < GetRequiredTrackQualityForThreat(targetTrack))
{
writeln_d(" FAIL: track quality not good enough to fire on target");
return launched;
}
string selectedWeapon = GetWeaponForThreat(PLATFORM, targetTrack); #checks domain & kinematic capability, & valid quantity remaining
if (selectedWeapon == "")
{
writeln_d(" FAIL: No domain capable weapon within range available!");
return launched;
}
WsfWeapon weaponToLaunch = PLATFORM.Weapon(selectedWeapon);
//writeln_d(" using a conventional weapon!");
extern Array<Map<string, Object>> mWeaponArray;
extern int GetWeaponNumberActiveMax(string, Array<Map<string, Object>>);
int maxActiveOfType = GetWeaponNumberActiveMax(selectedWeapon,mWeaponArray);
int curActiveOfType = ((WsfRIPRProcessor)PROCESSOR).WeaponsActiveOfType(weaponToLaunch);
if (MustShootAt(targetTrack))
{
curActiveOfType = maxActiveOfType - 1;
}
if (curActiveOfType >= maxActiveOfType)
{
writeln_d(" FAIL: Max number(", maxActiveOfType,") of ", selectedWeapon, " weapon type are already active! (", curActiveOfType,")");
return launched;
}
int salvoCount = GetSalvoForThreat(targetTrack);
writeln_d(" salvo count for ", targetTrack, " is: ", salvoCount);
extern bool LaunchWeapon(WsfPlatform, WsfTrack, WsfWeapon, int);
launched = LaunchWeapon(PLATFORM, targetTrack, weaponToLaunch, salvoCount);
writeln_d(" launched == ", launched, ", weapon: ", selectedWeapon);
if (launched == true)
{
double dPreviousRoundsFiredAt = mRoundsFiredAtMap.Get(targetTrack);
mRoundsFiredAtMap.Set(targetTrack,dPreviousRoundsFiredAt + salvoCount);
string msg = "Shot at: " + targetTrack.TargetName();
PLATFORM.Comment(msg);
writeln_d(" SUCCESS: ", PLATFORM.Name(), " ", msg);
}
return launched;
}
return launched;
end_script
execute
writeln_d(PLATFORM.Name(), " executing engage-target, T=", TIME_NOW);
extern WsfTrack GetTrackByName(WsfPlatform, string);
#check all possible targets on all channels
########################################################################
### fire on any pursue-target jobs we are assigned to
########################################################################
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
for (int channel = 0; channel < ((WsfRIPRProcessor)PROCESSOR).GetNumJobChannels(); channel = channel + 1)
{
WsfRIPRJob aJob = commander.GetJobFor(((WsfRIPRProcessor)PROCESSOR), channel);
if (aJob.IsValid() &&
aJob.Name() == "pursue-target")
{
string targetName = (string)aJob.GetData("targetTrackName");
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (!targetTrack.IsNull() &&
targetTrack.IsValid())
{
writeln_d(" ", PLATFORM.Name(), " trying to shoot at job track: ", targetName, " at time: ", TIME_NOW);
if(FireWeapon(targetTrack) == false)
{
writeln_d(" ", PLATFORM.Name(), " could NOT fire at track: ", targetTrack.TargetName(), " at time: ", TIME_NOW);
}
}
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,272 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
include_once ../common/weapon_defs.txt
behavior engage_weapon_task_target
script_debug_writes off
script_variables
//**********************************************************************//
//** platform / agent specific shooting parameters **//
//**********************************************************************//
bool mCoopEngageOne = false;
#bool mCoopEngageOneFlightOnly = false;
double mDegradedFiringAngle = 55.0; //negative if not valid
double mDegradedPercentRange = 0.50; //range constraint if past degraded firing angle
//specify orientation limits for shooting
double mMaxFiringRollAngle = 10.0; //dont shoot if rolled more/less than this
double mMaxFiringPitchAngle = 15.0; //dont shoot if pitched more than this
double mMinFiringPitchAngle = -10.0; //dont shoot if pitched less than this
//**********************************************************************//
//** threat specific shooting parameters **//
//**********************************************************************//
//require different track qualities to fire on different kinds of threats
double DefaultRequiredTrackQuality = 0.49;
Map<string, double> ThreatTypeRequiredTrackQuality = Map<string, double>();
ThreatTypeRequiredTrackQuality["bomber"] = 0.49;
ThreatTypeRequiredTrackQuality["fighter"] = 0.49;
//fire off different salvos at different types of threats
int DefaultAirSalvo = 1;
int DefaultGndSalvo = 1;
Map<string, int> ThreatTypeSalvo = Map<string, int>();
ThreatTypeSalvo["sam"] = 2;
ThreatTypeSalvo["ship"] = 2;
ThreatTypeSalvo["bomber"] = 2;
ThreatTypeSalvo["fighter"] = 1;
ThreatTypeSalvo["FIRE_CONTROL"] = 1;
ThreatTypeSalvo["primary_target"] = 2;
ThreatTypeSalvo["secondary_target"] = 2;
//**********************************************************************//
//** weapon + threat specific shooting parameters **//
//**********************************************************************//
//specify an Rmax based on which weapon used and which threat engaged
double DefaultPercentRangeMax = 0.80; // don't launch unless within this percent of Rmax
double DefaultPercentRangeMin = 1.20; // don't launch unless beyond this percent of Rmin
Map<string, Map<string, double>> WeaponThreatRmaxMap = Map<string, Map<string, double>>();
WeaponThreatRmaxMap["base_weapon"] = Map<string, double>();
WeaponThreatRmaxMap["base_weapon"].Set("fighter", 0.80);
end_script_variables
script int GetSalvoForThreat(WsfTrack track)
#writeln_d("checking salvo size for category: ", category);
#WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetIndex() );
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : int salvo in ThreatTypeSalvo )
{
if( plat.CategoryMemberOf( aCategory ) )
{
writeln_d("salvo for type ", aCategory, " = ", salvo);
return salvo;
}
}
}
#extern string GetTargetDomain(WsfTrack);
string sTargetDomain = GetTargetDomain(track);
if ( (sTargetDomain == "LAND") || (sTargetDomain == "SURFACE") )
{
return DefaultGndSalvo;
}
return DefaultAirSalvo;
end_script
script double GetRequiredTrackQualityForThreat(WsfTrack threat)
writeln_d("checking required TQ for track: ", threat.TargetName());
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : double quality in ThreatTypeRequiredTrackQuality )
{
if( plat.CategoryMemberOf( aCategory ) )
{
writeln_d("TQ for type ", aCategory, " = ", quality);
return quality;
}
}
}
return DefaultRequiredTrackQuality;
end_script
script double GetLaunchPercentRangeMaxOnThreat(string weaponName, WsfTrack threat)
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
if (WeaponThreatRmaxMap.Exists(weaponName))
{
Map<string, double> categoryRangeMap = WeaponThreatRmaxMap.Get(weaponName);
foreach (string aCategory : double percent in categoryRangeMap)
{
if( plat.CategoryMemberOf( aCategory ) )
{
return percent;
}
}
}
}
return DefaultPercentRangeMax;
end_script
#on_init
#end_on_init
precondition
#writeln_d("precondition engage-target");
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
return Failure("behavior not attached to a quantum tasker processor!");
}
#extern WsfTrack GetTrackByName(WsfPlatform, string);
# todo - try using a state machine to setup the shot ??
double pitch = PLATFORM.Pitch();
if (MATH.Fabs(PLATFORM.Roll()) > mMaxFiringRollAngle ||
pitch > mMaxFiringPitchAngle ||
pitch < mMinFiringPitchAngle)
{
string msgStr = write_str(" ", PLATFORM.Name(), " orientation too far off to fire! (roll or pitch)");
writeln_d(msgStr);
//PLATFORM.Comment(msgStr);
return Failure(msgStr);
}
WsfQuantumTaskerProcessor proc = (WsfQuantumTaskerProcessor)PROCESSOR;
WsfTaskList tasks = proc.TasksReceivedOfType("weapon");
if (tasks.Count() > 0)
{
return true;
}
return Failure("no weapon task target to shoot at!");
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing engage-target, T=", TIME_NOW);
#extern WsfTrack GetTrackByName(WsfPlatform, string);
#check all possible targets on all channels
########################################################################
### fire on any pursue-target jobs we are assigned to
########################################################################
WsfQuantumTaskerProcessor proc = (WsfQuantumTaskerProcessor)PROCESSOR;
WsfTaskList tasks = proc.TasksReceivedOfType("weapon");
foreach (WsfTask task in tasks)
{
WsfTrack targetTrack = PLATFORM.MasterTrackList().FindTrack(task.LocalTrackId());
if (targetTrack.IsNull() || !targetTrack.IsValid())
{
writeln_d("target track not valid");
continue;
}
bool launched = false;
writeln_d(" Time= ", TIME_NOW, " Attempting a shot against: ", targetTrack.TargetName(), " Index: ", targetTrack.TargetIndex(), " Type: ", targetTrack.TargetType());
if (mCoopEngageOne == false)
{
WsfLocalTrack targetLocalTrack = (WsfLocalTrack)targetTrack;
if (targetLocalTrack.IsValid())
{
if(!targetLocalTrack.ContributorOf(PLATFORM) &&
!targetLocalTrack.IsPredefined())
{
writeln_d(" FAIL: Not able to coop engage! ", PLATFORM.Name(), " targeting ",targetTrack.TargetName(), ". NumContributors: ", targetLocalTrack.NumContributors() );
return;
}
}
}
writeln_d (" targetTrack.TrackQuality == ", targetTrack.TrackQuality());
if (targetTrack.TrackQuality() < GetRequiredTrackQualityForThreat(targetTrack))
{
writeln_d(" FAIL: track quality not good enough to fire on target");
return;
}
if ((PLATFORM.WeaponsPendingFor(task.LocalTrackId()) + PLATFORM.WeaponsActiveFor(task.LocalTrackId())) > 0)
{
writeln_d("already have weapons assigned for target track");
return;
}
WsfWeapon weapon;
# if (task.ResourceName() != "")
# {
# weapon = PLATFORM.Weapon(task.ResourceName());
# writeln_d("checking if weapon ", weapon.Name(), " can be fired against track.");
# if (!WeaponCapableAvailableAgainstThreat(weapon, targetTrack) ||
# !InRangeToFire(PLATFORM, weapon, targetTrack, GetLaunchPercentRangeMaxOnThreat(weapon.Name(), targetTrack), DefaultPercentRangeMin))
# {
# writeln_d("task defined weapon not available or in range!");
# return;
# }
# }
# else
{
bool weaponUsable = false;
#first weapon found will be used
for (int i=0; i < PLATFORM.WeaponCount(); i+=1)
{
weapon = PLATFORM.WeaponEntry(i);
writeln_d("checking if weapon ", weapon.Name(), " is usable.");
if (WeaponCapableAvailableAgainstThreat(weapon, targetTrack) &&
InRangeToFire(PLATFORM, weapon, targetTrack, GetLaunchPercentRangeMaxOnThreat(weapon.Name(), targetTrack), DefaultPercentRangeMin))
{
weaponUsable = true;
break;
}
}
if (weaponUsable == false)
{
writeln_d("no usable weapon found!");
return;
}
}
int salvoCount = GetSalvoForThreat(targetTrack);
writeln_d(" salvo count for ", targetTrack, " is: ", salvoCount);
if (weapon.IsTurnedOn())
{
writeln_d(" Attempting launch at ", targetTrack.TargetName());
if (salvoCount > 1)
{
writeln_d("FIRING SALVO AT ", targetTrack.TargetName());
launched = weapon.FireSalvo(targetTrack, salvoCount);
}
else
{
writeln_d("FIRING AT ", targetTrack.TargetName());
launched = weapon.Fire(targetTrack);
}
}
writeln_d(" launched == ", launched, ", weapon: ", weapon.Name());
if(launched == false)
{
writeln_d(" ", PLATFORM.Name(), " could NOT fire at track: ", targetTrack.TargetName(), " at time: ", TIME_NOW);
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,321 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior escort
script_debug_writes off
script_variables
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawEscortData = false;
//**********************************************************************//
//** control / mode of operation parameters **//
//**********************************************************************//
bool mCheckOnlyTasks = true;
bool mCheckMasterTracks = false;
//**********************************************************************//
//** escort parameters (who to escort, and what ranges) **//
//**********************************************************************//
Array<string> mEscortNames = Array<string>();
double mEscortProtectDistance = 100.0 * MATH.M_PER_NM(); #engage threats within this range of the escort package
double mEscortChaseDistance = 15.0 * MATH.M_PER_NM(); #allowed to chase a threat this far out of protect area if it entered
double mWeaponRangeToInclude = 50.0 * MATH.M_PER_NM();
//**********************************************************************//
//** flying parameters, for offset and tightness **//
//**********************************************************************//
double mFormationPositionX = 0; #meters in front of of package
double mFormationPositionY = 0; #meters off right wing of package
double mGoodFormationRatio = 0.15; #percentage of total offset
double mFormationLookAhead = 30.0; #seconds
double mFormationAltitude = -1.0; #used if positive
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfDraw mDraw = WsfDraw();
bool mLastInPosition = false; #boolean flag, utility, don't change
end_script_variables
### find escorted platform, return it
script WsfPlatform GetEscortPackage()
WsfPlatform escortPlatform;
foreach ( string sEscortName in mEscortNames )
{
escortPlatform = WsfSimulation.FindPlatform(sEscortName);
if (escortPlatform.IsValid() )
{
break;
}
}
return escortPlatform;
end_script
script bool IsTrackAThreatToPackage(WsfTrack aTrack, WsfPlatform aPackage)
double slantRange = aPackage.SlantRangeTo(aTrack);
double currentlyTargeted = 0;
WsfTaskList tasks = ((WsfQuantumTaskerProcessor)PROCESSOR).TasksReceivedOfType("weapon");
foreach(WsfTask task in tasks)
{
if(task.TrackId() == aTrack.TrackId())
{
currentlyTargeted = 1.0;
break;
}
}
# determine if the target is a threat to your escort package, check if it lies within the protect radius
# if already engaging the threat, allow a little chase
if (slantRange < (mEscortProtectDistance + mWeaponRangeToInclude + (currentlyTargeted * mEscortChaseDistance)))
{
writeln_d("Target ", aTrack.TargetName()," is a threat to escort package! Stop formation flying, go engage!!!");
return true;
}
return false;
end_script
script bool IsTaskAThreatToPackage(WsfTask aTask, WsfPlatform aPackage, WsfTrack aTrack)
#aTrack = PLATFORM.MasterTrackList().FindTrack(aTask.LocalTrackId());
if (aTrack.IsValid())
{
# determine if the target is a threat to your escort package, check if it lies within the protect radius
# if already engaging the threat, allow a little chase
if (aPackage.SlantRangeTo(aTrack) < (mEscortProtectDistance + mWeaponRangeToInclude + mEscortChaseDistance))
{
//writeln_d("Target ", aTrack.TargetName()," is a threat to escort package! Stop formation flying, go engage!!!");
return true;
}
}
return false;
end_script
script void DrawThreat(WsfTrack track)
if (!track.IsValid())
{
return;
}
if (mDrawEscortData == true)
{
mDraw.SetLayer("behavior_escort");
mDraw.SetDuration(PROCESSOR.UpdateInterval());
// draw line to desired formation position
mDraw.SetColor(1, 0, 0);
mDraw.SetLineSize(3);
mDraw.SetLineStyle("dashed");
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(track.CurrentLocation());
mDraw.End();
mDraw.SetLineSize(2);
mDraw.SetLineStyle("solid");
mDraw.SetEllipseMode("line");
mDraw.SetColor(0, 1, 1);
mDraw.BeginEllipse(0,20,20);
mDraw.Vertex(track.CurrentLocation());
mDraw.End();
}
end_script
precondition
writeln_d("precondition escort");
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
return Failure("behavior not attached to a quantum tasker processor!");
}
WsfPlatform escortPlatform = GetEscortPackage();
if (!escortPlatform.IsValid() )
{
return Failure("no listed escort packages found to escort");
}
//check jobs?
//check tracks?
if (mCheckOnlyTasks)
{
bool packageInDanger = false;
Array<WsfTrack> threats = Array<WsfTrack>();
WsfTaskList tasks = ((WsfQuantumTaskerProcessor)PROCESSOR).TasksReceivedOfType("weapon");
WsfTrack tempTrack;
foreach(WsfTask task in tasks)
{
tempTrack = PLATFORM.MasterTrackList().FindTrack(task.LocalTrackId());
if (IsTaskAThreatToPackage(task, escortPlatform, tempTrack))
{
threats.PushBack(tempTrack);
packageInDanger = true;
}
}
if (packageInDanger)
{
foreach (WsfTrack threat in threats)
{
DrawThreat(threat);
}
return Failure("target is threat to package"); //pre-condition not met, can't just fly in formation
}
}
else if (mCheckMasterTracks == true)
{
foreach (WsfLocalTrack t in PLATFORM.MasterTrackList())
{
//check if this track is a threat
if (t.SideValid() && t.Side() == PLATFORM.Side())
{
continue;
}
if (IsTrackAThreatToPackage(t, escortPlatform))
{
DrawThreat(t);
return Failure("track is threat to package"); //pre-condition not met, can't just fly in formation
}
}
}
writeln_d("--- agent ", PLATFORM.Name(), " is escorting ", escortPlatform.Name());
return true;
end_precondition
script bool AmInFormationPosition(WsfGeoPoint formationPoint, double radius)
//make it fly to the inner 50% of the acceptable radius on re-entry
if (!mLastInPosition)
{
radius = 0.5 * radius;
}
mLastInPosition = false;
double range = PLATFORM.GroundRangeTo(formationPoint);
if (range <= radius)
{
mLastInPosition = true;
}
return mLastInPosition;
end_script
execute
writeln_d(PLATFORM.Name(), " executing escort, T=", TIME_NOW);
//PLATFORM.Comment("escort");
//make sure escorted platform exists, find it, save it
WsfPlatform escortPlatform = GetEscortPackage();
if (!escortPlatform.IsValid() )
{
writeln_d("--- fighter ", PLATFORM.Name(), " no valid platform to escort!");
return;
}
//check if I am approximately in my formation position
WsfGeoPoint formationPoint = escortPlatform.Location();
if (mFormationAltitude > 0)
{
formationPoint.Set(formationPoint.Latitude(), formationPoint.Longitude(), mFormationAltitude);
}
if (mFormationPositionX > 0)
{
formationPoint.Extrapolate(escortPlatform.Heading(), mFormationPositionX);
}
else
{
formationPoint.Extrapolate(escortPlatform.Heading()+180, -mFormationPositionX);
}
if (mFormationPositionY > 0)
{
formationPoint.Extrapolate(escortPlatform.Heading()+90.0, mFormationPositionY);
}
else
{
formationPoint.Extrapolate(escortPlatform.Heading()-90.0, -mFormationPositionY);
}
if (!formationPoint.IsValid())
{
writeln_d("--- fighter ", PLATFORM.Name(), " invalid formation point from ", escortPlatform.Name());
return;
}
if (mDrawEscortData == true)
{
mDraw.SetLayer("behavior_escort");
mDraw.SetDuration(PROCESSOR.UpdateInterval());
// draw protection bubbles (outter ring includes chase distance)
#mDraw.SetColor(0.5, 0.5, 0.5, 0.33); //gray with 0.33 alpha
#mDraw.SetEllipseMode("fill");
mDraw.SetColor(0.5, 0.5, 0.5, 1.0); //gray
mDraw.SetEllipseMode("line");
mDraw.SetLineSize(2);
double R = mEscortProtectDistance + mWeaponRangeToInclude;
mDraw.BeginEllipse(0, R, R);
mDraw.Vertex(escortPlatform.Location());
mDraw.End();
R += mEscortChaseDistance;
mDraw.BeginEllipse(0, R, R);
mDraw.Vertex(escortPlatform.Location());
mDraw.End();
// draw line to desired formation position
mDraw.SetColor(0, 1, 0); //green
mDraw.SetLineSize(4);
mDraw.BeginLines();
mDraw.Vertex(escortPlatform.Location());
mDraw.Vertex(formationPoint);
mDraw.End();
}
double radius = mGoodFormationRatio * escortPlatform.SlantRangeTo(formationPoint);
double formAlt = escortPlatform.Altitude();
double formSpeed = escortPlatform.Speed();
double formYaw = escortPlatform.Heading();
if (formAlt < PLATFORM.Altitude())
{
formAlt = PLATFORM.Altitude();
}
WsfGeoPoint tgt = WsfGeoPoint.Construct(formationPoint.Latitude(), formationPoint.Longitude(), formAlt);
double lookAheadDistance = mFormationLookAhead * escortPlatform.Speed();
tgt.Extrapolate(formYaw, lookAheadDistance);
if (! AmInFormationPosition(formationPoint, radius))
{
//fly towards formation position, extrapolated ahead X seconds, in order to catch up to the point in X seconds
formSpeed = PLATFORM.GroundRangeTo(tgt) / mFormationLookAhead;
}
#extern bool FlyTarget (WsfPlatform, WsfGeoPoint, double);
FlyTarget (PLATFORM, tgt, formSpeed);
end_execute
end_behavior

View File

@@ -0,0 +1,469 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior evade
script_debug_writes off
script_variables
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawNearestThreat = false;
bool mDrawEvasionVector = false;
//**********************************************************************//
//** control / mode of operation parameters **//
//**********************************************************************//
double weightPeersForEvade = 0.25; //percentage to scale peers influence for evasion vector
bool mWobbleLeftRight = true;
bool mWobbleUpDown = true;
double cFAST_UPDATE_INTERVAL = 0.25;
double cSLOW_UPDATE_INTERVAL = 2.0;
//**********************************************************************//
//** flying parameters, for for evasive manuevering **//
//**********************************************************************//
double cNORMAL_SPEED = 200.0; // m/s
double cEVADE_SPEED = 1000.0; // m/s (faster than a speeding bullet...M3.0+)
double mAltitudeMin = 1000.0; //meters
double mAltitudeMax = 20000.0; //meters
double mAltitudeToDiveEvade = 1500.0; //distance to dive (meters) (~5000 ft)
double mBankAngleForEvading = 45.0; //banks left & right, back & forth, at this angle, while evading
double mMaxClimbRate = 500.0; // meters/second
double mVerticalAccel = 1.5 * Earth.ACCEL_OF_GRAVITY(); // meters/second^2
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
double mLastTime = 0.0;
double mClimbRate = 0.0;
Array<WsfPlatform> mIncoming = Array<WsfPlatform>();
WsfDraw mDraw = WsfDraw();
bool mDiveDownFlag = true;
bool mBankLeftFlag = true;
end_script_variables
script WsfThreatProcessor GetThreatProcessor()
for (int i=0; i<PLATFORM.ProcessorCount(); i+=1)
{
WsfProcessor proc = PLATFORM.ProcessorEntry(i);
if (proc.IsValid() && proc.IsA_TypeOf("WSF_THREAT_PROCESSOR"))
{
return (WsfThreatProcessor)proc;
}
}
WsfThreatProcessor empty;
return empty;
end_script
script bool Fly(WsfPlatform flyer, double heading, double altitude, double speed)
WsfGeoPoint pt = flyer.Location();
pt.Extrapolate(heading, 1852*3);
pt.Set(pt.Latitude(), pt.Longitude(), MATH.Max(altitude, mAltitudeMin));
if (mDrawEvasionVector == true)
{
mDraw.SetLayer("behavior_evade");
mDraw.SetDuration(PROCESSOR.UpdateInterval());
mDraw.SetColor(0,1,0);
mDraw.SetLineSize(1);
mDraw.SetLineStyle("dash_dot");
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(pt);
mDraw.End();
}
if (flyer.Mover().IsValid())
{
if (flyer.Mover().IsA_TypeOf("WSF_6DOF_MOVER"))
{
##flyer.GoToSpeed(speed);
##flyer.GoToAltitude(MATH.Max(altitude, mAltitudeMin), 200);
##flyer.TurnToHeading(heading, 500);
#flyer.GoToSpeed(speed);
#flyer.GoToLocation(pt);
flyer.GoToSpeed(speed);
double altRate = flyer.Speed() * MATH.Sin(40.0);
flyer.GoToAltitude(pt.Altitude(), altRate);
flyer.TurnToHeading(flyer.TrueBearingTo(pt), 500);
return true;
}
else if (flyer.Mover().IsA_TypeOf("WSF_AIR_MOVER"))
{
double delta = TIME_NOW - mLastTime;
mLastTime = TIME_NOW;
if (delta > cSLOW_UPDATE_INTERVAL)
{
delta = cSLOW_UPDATE_INTERVAL;
}
double deltaV = mVerticalAccel * delta;
if (altitude > PLATFORM.Altitude())
{
if (mClimbRate < 0.0)
{
//increase climb rate to a positive value (must keep pursuing a lower altitude though)
altitude = mAltitudeMin;
mClimbRate = mClimbRate + deltaV;
}
else if (mClimbRate < mMaxClimbRate)
{
//increase climb rate to max value (can pursue target altitude now)
mClimbRate = mClimbRate + deltaV;
}
}
else if (altitude < PLATFORM.Altitude())
{
if (mClimbRate > 0.0)
{
//decrease climb rate to a negative value (must keep pursuing a higher altitude though)
altitude = 9999999;
mClimbRate = mClimbRate - deltaV;
}
else if (mClimbRate > -mMaxClimbRate)
{
//decrease climb rate to max value (can pursue target altitude now)
mClimbRate = mClimbRate - deltaV;
}
}
double climbRateUsed = MATH.Fabs(mClimbRate);
flyer.GoToSpeed(speed);
flyer.GoToAltitude(altitude, climbRateUsed);
flyer.TurnToHeading(heading);
return true;
}
}
writeln_d(flyer.Name(), " aiai error: unknown or invalid mover for flight");
return false;
end_script
precondition
writeln_d(PLATFORM.Name(), " precondition evade, T=", TIME_NOW);
//always evade incoming weapons
int ownshipWeaponsIncoming = 0;
WsfProcessor proc = PLATFORM.Processor("incoming_threats");
if (proc.IsValid() && proc.ScriptExists("ThreatProcessorWeaponsIncoming"))
{
writeln_d("using incoming_threats threat processor!!!");
mIncoming = (Array<WsfPlatform>)(proc.Execute("ThreatProcessorWeaponsIncoming"));
ownshipWeaponsIncoming = mIncoming.Size();
}
else
{
writeln_d("using standard WSF_THREAT_PROCESSOR!!!");
mIncoming.Clear(); ownshipWeaponsIncoming = 0;
WsfThreatProcessor threatProc = GetThreatProcessor();
if (!threatProc.IsNull() && threatProc.IsValid())
{
Array<WsfTrackId> threatIds = threatProc.Threats();
foreach(WsfTrackId id in threatIds)
{
WsfTrack track = PLATFORM.MasterTrackList().Find(id);
if (track.IsValid())
{
mIncoming.PushBack(track.Target());
}
}
ownshipWeaponsIncoming = mIncoming.Size();
}
}
if (ownshipWeaponsIncoming > 0)
{
//we now have weapons incoming, check to see if we are currently guiding any missiles with an uplink
//basically: check if we have any active weapons
int WeaponCount = PLATFORM.WeaponsActiveFor(WsfTrackId());
if (WeaponCount > 0)
{
writeln_d(PLATFORM.Name(), " weapons incoming, checking weapons active, count: ", WeaponCount);
double threat = 1000.0;
double asset = 1000.0;
//find most threatening incoming weapon
foreach(WsfPlatform p in mIncoming)
{
double range = PLATFORM.SlantRangeTo(p); # meters
double speed = p.Speed(); # meters/sec
double time = range / speed; # seconds
if (time < threat)
{
threat = time;
}
}
//find most valuable launched weapon (most threatening to enemy)
WsfPlatformList activeWeapons = PLATFORM.ActiveWeaponPlatformsFor(WsfTrackId());
for (int i=0; i< activeWeapons.Count(); i=i+1)
{
WsfPlatform w = activeWeapons.Entry(i);
WsfTrack t = w.CurrentTargetTrack();
//TODO - replace with check for weather or not the weapon has active sensors
# // include weapons we are uplinking to.
# if (((WsfRIPRProcessor)PROCESSOR).IsUplinkingTo(w) &&
# t.IsValid())
# {
double range = w.SlantRangeTo(t); # meters
double speed = w.Speed(); # meters/sec
double time = range / speed; # seconds
if (time < asset)
{
asset = time;
}
# }
}
extern double mEngagementAggressiveness;
//factor in our aggressiveness, and decide whether or not we should evade yet
double requiredAggressiveness = asset / (threat + asset);
writeln_d(PLATFORM.Name(), " threat: ", threat, ", asset: ", asset, ", required aggressiveness: ", requiredAggressiveness);
if (mEngagementAggressiveness < requiredAggressiveness)
{
#PROCESSOR.SetUpdateInterval(cFAST_UPDATE_INTERVAL);
return true;
}
else
{
Failure("my active weapons are closer, hold course");
}
}
else
{
#PROCESSOR.SetUpdateInterval(cFAST_UPDATE_INTERVAL);
return true;
}
}
else
{
writeln_d("no weapons incoming");
Failure("no weapons incoming");
}
#PROCESSOR.SetUpdateInterval(cSLOW_UPDATE_INTERVAL);
return false;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing evade, T=", TIME_NOW);
//PLATFORM.Comment("evade");
### transition to evade incoming
PLATFORM.GoToSpeed(cEVADE_SPEED);
writeln_d(" GoToSpeed( ", cEVADE_SPEED," )");
extern double cDEFAULT_ALTITUDE;
double safeAltitudeToDiveTo = MATH.Max(mAltitudeMin, (cDEFAULT_ALTITUDE - mAltitudeToDiveEvade));
// Calculate a heading to evade all incoming missiles, weighted by distance, and then turn to it
double evadeHeading = 0;
double evadeAltitude = 0;
double evadeDivisor = 0;
double distMod = 0;
double bearingMod = 0;
int incomingCount = mIncoming.Size();
writeln_d(PLATFORM.Name(), " evade. dive/climb between altitudes: ", cDEFAULT_ALTITUDE, " <-> ", safeAltitudeToDiveTo);
writeln_d("evading ", incomingCount, " threats");
double y = 0;
double x = 0;
double dist = MATH.DOUBLE_MAX();
WsfPlatform nearestThreat;
// calculate an average heading to incoming platforms weighted by distance
for (int i = 0; i < incomingCount; i = i + 1)
{
WsfPlatform temp = (WsfPlatform)(mIncoming[i]);
if (!temp.IsValid() || (temp.Index() == PLATFORM.Index()))
{
continue;
}
double range = PLATFORM.SlantRangeTo(temp);
if (range < dist)
{
dist = range;
nearestThreat = (WsfPlatform)(mIncoming[i]);
}
if (range > 0)
{
distMod = 1 / range;
}
else
{
distMod = 1000000;
}
bearingMod = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(temp));
x = x + MATH.Sin(bearingMod) * distMod;
y = y + MATH.Cos(bearingMod) * distMod;
writeln_d(" Incoming ", temp.Name(), " at distance: ", 1 / distMod, ", bearing: ", bearingMod, ", x: ", MATH.Sin(bearingMod), ", y: ", MATH.Cos(bearingMod), ", (", temp.Latitude(), ", ", temp.Longitude(), ", ", temp.Altitude(), ") @ ", temp.Speed(), "m/s");
evadeDivisor = evadeDivisor + distMod;
evadeHeading = evadeHeading + bearingMod * distMod;
}
# // get the GCI if there is one
WsfPlatform aiflPlat = PLATFORM.Commander();
WsfPlatform gciPlat;
if (aiflPlat.IsValid())
{
gciPlat = aiflPlat.Commander();
}
// if there's a gci, avoid centroids of all his subs
if (gciPlat.IsValid() && gciPlat.Index() != aiflPlat.Index())
{
writeln_d("found gci : ", gciPlat.Name());
foreach (WsfPlatform aifl in gciPlat.Subordinates())
{
if (!aifl.IsValid() || aifl == PLATFORM || aifl == aiflPlat)
{
continue;
}
WsfGeoPoint centroid = aifl.GetSubsCentroid();
if (centroid.X() == 0 && centroid.Y() == 0 && centroid.Z() == 0)
{
continue;
}
distMod = 1 / (PLATFORM.SlantRangeTo(centroid));
bearingMod = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(centroid));
x = x + MATH.Sin(bearingMod) * distMod * weightPeersForEvade;
y = y + MATH.Cos(bearingMod) * distMod * weightPeersForEvade;
writeln_d(" AIFL ", aifl.Name(), " at distance: ", 1 / distMod, ", bearing: ", bearingMod, ", x: ", MATH.Sin(bearingMod), ", y: ", MATH.Cos(bearingMod), ", (", centroid.Latitude(), ", ", centroid.Longitude(), ", ", centroid.Altitude(), ")");
// but we'll avoid peers with less strength than we avoid incoming missiles
// so let's divide the distMod by 2
evadeDivisor = evadeDivisor + distMod;
evadeHeading = evadeHeading + bearingMod * distMod;
}
}
// otherwise, avoid members in your own squadron
else if (aiflPlat.IsValid())
{
writeln_d("also evading flight lead subordinates (peers)");
foreach (WsfPlatform sub in aiflPlat.Subordinates())
{
writeln_d("considering peer ", sub.Name());
if (!sub.IsValid() ||
sub == PLATFORM)
{
continue;
}
distMod = 1 / (PLATFORM.SlantRangeTo(sub));
bearingMod = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(sub));
x = x + MATH.Sin(bearingMod) * distMod * weightPeersForEvade;
y = y + MATH.Cos(bearingMod) * distMod * weightPeersForEvade;
writeln_d(" Peer ", sub.Name(), " at distance: ", 1 / distMod, ", bearing: ", bearingMod, ", x: ", MATH.Sin(bearingMod), ", y: ", MATH.Cos(bearingMod), ", (", sub.Latitude(), ", ", sub.Longitude(), ", ", sub.Altitude(), ") @ ", sub.Speed(), "m/s");
// but we'll avoid peers with less strength than we avoid incoming missiles
// so let's divide the distMod by 2
evadeDivisor = evadeDivisor + distMod;
evadeHeading = evadeHeading + bearingMod * distMod;
}
}
else
{
writeln_d("evade : no commanders found!!!");
}
if (evadeDivisor == 0)
{
return;
}
// correct for quadrant
double theta = MATH.NormalizeAngle0_360(MATH.ATan(x/y));
if (y < 0)
{
theta = MATH.NormalizeAngle0_360(theta - 180);
}
writeln_d(" x: ", x, ", y: ", y, ", theta: ", theta);
evadeHeading = MATH.NormalizeAngle0_360(theta - 180);
if (mWobbleLeftRight == true)
{
//turn to angle to evade
if (mBankLeftFlag == true)
{
evadeHeading = MATH.NormalizeAngle0_360(theta - 180 - mBankAngleForEvading);
double headDiff = MATH.NormalizeAngleMinus180_180( evadeHeading - MATH.NormalizeAngle0_360(PLATFORM.Heading()) );
if (MATH.Fabs(headDiff) < 2.0 &&
nearestThreat.RelativeBearingTo(PLATFORM) > 0.0)
{
mBankLeftFlag = false;
}
}
else // bank right
{
evadeHeading = MATH.NormalizeAngle0_360(theta - 180 + mBankAngleForEvading);
double headDiff = MATH.NormalizeAngleMinus180_180(evadeHeading - MATH.NormalizeAngle0_360(PLATFORM.Heading()));
if (MATH.Fabs(headDiff) < 2.0 &&
nearestThreat.RelativeBearingTo(PLATFORM) < 0.0)
{
mBankLeftFlag = true;
}
}
}
evadeAltitude = MATH.Max(safeAltitudeToDiveTo, evadeAltitude);
if (mWobbleUpDown == true)
{
//compute the dive or climb
if (mDiveDownFlag == true)
{
writeln_d(PLATFORM.Name(), " diving to ", safeAltitudeToDiveTo);
evadeAltitude = safeAltitudeToDiveTo;
if (PLATFORM.Altitude() <= (cDEFAULT_ALTITUDE - 0.95*(cDEFAULT_ALTITUDE-safeAltitudeToDiveTo)))
{
mDiveDownFlag = false;
}
}
else
{
writeln_d(PLATFORM.Name(), " climbing to ", cDEFAULT_ALTITUDE);
evadeAltitude = cDEFAULT_ALTITUDE;
if (PLATFORM.Altitude() >= (safeAltitudeToDiveTo + 0.95*(cDEFAULT_ALTITUDE-safeAltitudeToDiveTo)))
{
mDiveDownFlag = true;
}
}
}
writeln_d(" Evading incoming at heading ", evadeHeading);
writeln_d(" Evading incoming, dive/climb to ", evadeAltitude);
Fly(PLATFORM, evadeHeading, evadeAltitude, cEVADE_SPEED);
if (mDrawNearestThreat)
{
mDraw.SetLayer("behavior_evade");
mDraw.SetDuration(PROCESSOR.UpdateInterval());
mDraw.SetColor(1,0,0);
mDraw.SetLineSize(5);
mDraw.SetLineStyle("dashed");
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(nearestThreat.Location());
mDraw.End();
}
end_execute
end_behavior

View File

@@ -0,0 +1,65 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior force_overshoot
script_variables
double cGRAVITY_ACCEL = 9.80665; # 1 G
double cDEFAULT_ACCEL = (cGRAVITY_ACCEL * 7.5); # m/s^2 ~7.5 Gs
double cMAX_RADIAL_ACCEL = 100 * cGRAVITY_ACCEL; # larger than possible, make the aircraft limit the turn
double cMAX_SPEED = 9999999999.99; # m/s
double mLastProcTime = -1.0;
end_script_variables
script bool RanLastTick()
if ((TIME_NOW-mLastProcTime) < 1.5*PROCESSOR.UpdateInterval())
{
return true;
}
else return false;
end_script
precondition
writeln("precondition force_overshoot");
//turn hard into threat
extern WsfTrack mBiggestThreat;
if (mBiggestThreat.IsValid())
{
mLastProcTime = TIME_NOW;
return true;
}
mLastProcTime = -1.0;
return false;
end_precondition
execute
writeln("executing force_overshoot");
PLATFORM.Comment("force_overshoot");
//turn into the attacker as hard as possible
extern WsfTrack mBiggestThreat;
//any out of plan manuevers? climb/dive ?
// no: match threat
extern bool FlyTarget (WsfPlatform, WsfGeoPoint, double);
FlyTarget( PLATFORM, mBiggestThreat.CurrentLocation(), cMAX_SPEED);
end_execute
end_behavior

View File

@@ -0,0 +1,304 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior go_home
script_debug_writes off
script_variables
bool mDrawRoute = false; // draw the home route
WsfDraw mDraw = WsfDraw();
bool mCheckFuel = true; // check fuel levels
bool mCheckMyWeapons = true; // check the remaining quanitity of munitions on this platform
#bool mCheckAllWeapons = false; // check the remaining quantity of munitions on all platforms in the peer group, including my own
#bool mCheckUplinks = false; // check if uplinks are still existent
bool mWaitOnActiveWeapons = false; // don't go home as long as active weapons are being controlled
string mMainWeapon = ""; // main weapon of concern, not necessarily this platform's main weapon
bool mCheckEscorts = false; // check if escort platforms are still existent and on course
Array<string> mEscortNames = Array<string>(); // the names of platforms this platform is responsible for escorting
double cBINGO_SPEED = 516 * MATH.MPS_PER_NMPH(); // ~M0.8 or 248 m/s @ 25 kft#removed 1.5 * that was added to help 6dof movers 14Oct11
WsfGeoPoint mFirstKnownPoint = WsfGeoPoint();
string mRouteName = "";
int mRouteHomeIndex = 0; // the index of the waypoint on the default route the platform should return to
string mLastComment = "<none yet>";
end_script_variables
script bool HasEscorts()
WsfPlatform escortPlatform;
foreach ( string sEscortName in mEscortNames )
{
escortPlatform = WsfSimulation.FindPlatform(sEscortName);
if (escortPlatform.IsValid() )
{
return true;
}
}
return false;
end_script
script double NumWeaponsRemaining(WsfPlatform aPlatform)
double total = 0.0;
for (int i=0; i<aPlatform.WeaponCount(); i=i+1)
{
total = total + aPlatform.WeaponEntry(i).QuantityRemaining();
}
return total;
end_script
script void DrawRoute()
WsfRoute currRoute = PLATFORM.Route();
if (currRoute.IsValid())
{
//PLATFORM.Comment("draw current route : " + PLATFORM.Route().Name());
mDraw.SetLayer("behavior_go_home");
mDraw.Erase(PLATFORM.Name());
mDraw.SetId(PLATFORM.Name());
mDraw.SetColor(0,1,1);
mDraw.SetLineSize(2);
mDraw.SetLineStyle("dash_dot2");
mDraw.BeginPolyline();
for (int i=0; i<currRoute.Size(); i=i+1)
{
mDraw.Vertex(currRoute.Waypoint(i).Location());
}
mDraw.End();
}
end_script
on_init
mFirstKnownPoint = PLATFORM.Location();
end_on_init
precondition
writeln_d("precondition go_home");
# if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
# {
# return Failure("behavior not attached to a RIPR processor!");
# }
string msg = "";
bool result = false;
// go home if bingo on fuel
if (mCheckFuel == true &&
PLATFORM.FuelRemaining() < PLATFORM.FuelBingoQuantity())
{
msg = "GO HOME: bingo fuel";
result = true;
}
// go home if all my escorts are dead or gone
else if (mCheckEscorts == true &&
!HasEscorts())
{
msg = "GO HOME: all escorts are dead or gone";
result = true;
}
// DO NOT go home if I have any active weapons still under my control
else if (mWaitOnActiveWeapons == true &&
PLATFORM.WeaponsActiveFor(WsfTrackId()) <= 0)
{
msg = "GO HOME: no active weapons";
result = true;
}
# // go home if there are no uplinks remaining
# else if (mCheckUplinks == true &&
# ((WsfRIPRProcessor)PROCESSOR).UplinkCount() <= 0)
# {
# msg = "GO HOME: no active uplinks";
# result = true;
# }
// go home if all weapons, including my own, in the peer group are out of ammo
# else if (mCheckAllWeapons == true &&
# ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderPlatform().IsValid())
# {
# msg = "GO HOME: all weapons in group are out of ammo";
# result = true;
# foreach( WsfPlatform sub in ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderPlatform().Subordinates() )
# {
# if (mMainWeapon != "")
# {
# WsfWeapon temp = sub.Weapon(mMainWeapon);
# if (temp.IsValid() &&
# temp.QuantityRemaining() > 0)
# {
# msg = "";
# result = false;
# }
# }
# else if (NumWeaponsRemaining(sub) > 0.0)
# {
# msg = "";
# result = false;
# }
# }
# }
// go home if my weapons are out of ammo
else if (mCheckMyWeapons == true)
{
if (mMainWeapon != "")
{
WsfWeapon temp = PLATFORM.Weapon(mMainWeapon);
if (temp.IsValid() &&
temp.QuantityRemaining() <= 0)
{
msg = "GO HOME: main weapon out of ammo";
result = true;
}
}
else if (NumWeaponsRemaining(PLATFORM) <= 0.0)
{
msg = "GO HOME: out of weapons";
result = true;
}
}
// debug - why is this platform going home?
if (result)
{
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
if (msg != mLastComment)
{
PLATFORM.Comment(msg);
mLastComment = msg;
}
return true;
}
return false;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing go_home, T=", TIME_NOW);
//PLATFORM.Comment("go_home");
string msg = "";
# WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).CommanderProcessor();
# if (commander.IsValid())
# {
# for (int i = 0; i < ((WsfRIPRProcessor)PROCESSOR).NumJobChannels(); i = i + 1)
# {
# commander.ClearBidsFor(((WsfRIPRProcessor)PROCESSOR), i);
# }
# }
//TODO - reject or cancel any received tasks, we are going home
// make sure we are at the right speed so we don't burn the fuel we have left too fast
PLATFORM.GoToSpeed(cBINGO_SPEED);
writeln_d(" GoToSpeed( ", cBINGO_SPEED," )");
bool onHomeRoute = false;
// if an egress route is defined, and that is the current route,
// find the closest waypoint and fly the route from there.
// this is mainly used to correct some bugs in the 6dof mover
if (mRouteName != "")
{
WsfRoute myRoute = PLATFORM.Route();
if(myRoute.Name() == "home_route")
{
int routeIndex = PLATFORM.RoutePointIndex();
if (routeIndex < 0 || routeIndex >= myRoute.Size())
{
routeIndex = 0;
}
double distThreshold = 4.0*185.2; ## 4/10th nm
if (myRoute.Waypoint(routeIndex).Location().GroundRangeTo(PLATFORM.Location()) < distThreshold)
{
routeIndex = routeIndex + 1;
if (routeIndex >= myRoute.Size())
{
routeIndex = 1;
}
}
onHomeRoute = PLATFORM.FollowRoute(myRoute, routeIndex);
#string msg = write_str("FollowRoute(home_route, ", routeIndex, ")");
#PLATFORM.Comment(msg);
}
// if there is an egress route defined, follow it
if (!onHomeRoute)
{
msg = write_str("attempting to construct and fly route: ", mRouteName);
//PLATFORM.Comment(msg);
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
WsfRoute original = PLATFORM.Route();
WsfRoute homeRoute = WsfRoute.Create("home_route");
WsfRoute capRoute = WsfRoute.CopyGlobal(mRouteName);
double goHomeSpeed = cBINGO_SPEED;
#if (capRoute.Front().IsValid() && capRoute.Front().Speed() > 0)
#{
# goHomeSpeed = capRoute.Front().Speed();
#}
extern double cDEFAULT_ALTITUDE;
WsfGeoPoint startPoint = WsfGeoPoint.Construct(mFirstKnownPoint.Latitude(), mFirstKnownPoint.Longitude(), cDEFAULT_ALTITUDE);
homeRoute.Append(startPoint, goHomeSpeed);
capRoute.Transform(startPoint.Latitude(), startPoint.Longitude(), 0);
homeRoute.Append(capRoute);
onHomeRoute = PLATFORM.FollowRoute(homeRoute);
#PLATFORM.Comment("go_home FollowRoute(homeRoute)");
}
}
// if the platform is still not on an egress route, then there is not one
// defined or there was a problem with it, so one needs to be created.
if (!onHomeRoute)
{
if (PLATFORM.FollowRoute("DEFAULT_ROUTE", mRouteHomeIndex))
{
msg = write_str("should be flying default route");
//PLATFORM.Comment(msg);
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
//PLATFORM.Comment("FollowRoute(DEFAULT_ROUTE, 1)");
}
else // what if no default route is provided? (fly to first known point)
{
extern double cDEFAULT_ALTITUDE;
WsfGeoPoint tempPt = WsfGeoPoint.Construct(mFirstKnownPoint.Latitude(), mFirstKnownPoint.Longitude(), cDEFAULT_ALTITUDE);
PLATFORM.GoToLocation(tempPt);
msg = write_str("should be flying to point: ", mFirstKnownPoint.ToString());
//PLATFORM.Comment(msg);
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
//PLATFORM.Comment("GoToLocation(tempPt)");
}
}
// debug
if (mDrawRoute)
{
DrawRoute();
}
end_execute
end_behavior

View File

@@ -0,0 +1,329 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior guide_weapons
script_debug_writes off
script_variables
//**********************************************************************//
//** parameters for guiding weapons **//
//**********************************************************************//
double mSensorAzimuthHalfAngle = 50.0; # degrees (represents uplink sensor)
//**********************************************************************//
//** parameters for approximating or flying target pursuit **//
//**********************************************************************//
double cINTERCEPT_SPEED = 1000.0; # m/s
double mOffsetAngle = 30.0; # degrees (for flying f-pole)
double mInterceptHeading = -1.0;
end_script_variables
precondition
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
}
mInterceptHeading = -1.0;
//writeln_d("precondition guide_weapons");
if (((WsfRIPRProcessor)PROCESSOR).UplinkCapable() && ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().IsValid())
{
//set current target, for main job (if its an uplink job)
//the pursue-target behavior does this for pursue jobs
WsfRIPRJob job = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(((WsfRIPRProcessor)PROCESSOR));
if (job.IsValid() && job.Name() == "weapon_uplink")
{
string targetName = (string)job.GetData("targetTrackName");
#extern WsfTrack GetTrackByName (WsfPlatform, string);
#extern bool TestTrackCategory (WsfTrack, string);
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (targetTrack.IsValid() && !TestTrackCategory(targetTrack, "unknown"))
{
((WsfRIPRProcessor)PROCESSOR).SetTarget(targetTrack);
}
}
bool haveUplinkJob = false;
for (int channel = 0; channel < ((WsfRIPRProcessor)PROCESSOR).GetNumJobChannels(); channel = channel + 1)
{
WsfRIPRJob aJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(((WsfRIPRProcessor)PROCESSOR), channel);
if (aJob.IsValid() && aJob.Name() == "weapon_uplink")
{
writeln_d("uplinking for job: ", aJob.GetDescription());
haveUplinkJob = true;
int targetIndex = (int)aJob.GetData("targetPlatformIndex");
WsfPlatform targetPlatform = WsfSimulation.FindPlatform(targetIndex);
mInterceptHeading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(targetPlatform));
break;
}
}
for (int up=0; up<((WsfRIPRProcessor)PROCESSOR).UplinkCount(); up = up+1)
{
WsfPlatform weaponPlatform = ((WsfRIPRProcessor)PROCESSOR).UplinkPlatformEntry(up);
writeln_d("uplinking to ", weaponPlatform.Name());
if (mInterceptHeading < 0)
{
WsfTrack weaponTarget = weaponPlatform.CurrentTargetTrack();
if (weaponTarget.IsValid() && weaponTarget.BelievedAlive())
{
mInterceptHeading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(weaponTarget));
}
}
}
if ((((WsfRIPRProcessor)PROCESSOR).UplinkCount() > 0) || (haveUplinkJob == true))
{
return true;
}
else
{
writeln_d(PLATFORM.Name(), " has no uplink jobs and no active uplinks!");
Failure("no uplink jobs found, & no active uplink");
}
}
else
{
writeln_d(PLATFORM.Name(), " is not uplink capable or has no commander!");
Failure("platform not uplink capable");
}
return false;
end_precondition
#on_init
#end_on_init
script double GetWeaponRangeMax(WsfPlatform aPlatform)
double max = 0.0;
for (int i=0; i < aPlatform.WeaponCount(); i+=1)
{
WsfWeapon weapon = aPlatform.WeaponEntry(i);
struct weaponData = GetWeaponData(weapon.Type());
if (weaponData->rangeMax > max)
{
max = weaponData->rangeMax;
}
}
return max;
end_script
execute
writeln_d(PLATFORM.Name(), " executing guide_weapons, T=", TIME_NOW);
//PLATFORM.Comment("guide_weapons");
extern double cDEFAULT_ALTITUDE;
double interceptAltitude = cDEFAULT_ALTITUDE;
WsfTrack targetTrack = ((WsfRIPRProcessor)PROCESSOR).GetTarget();
if (targetTrack.IsValid())
{
#extern Array<Map<string, Object>> mWeaponArray;
#extern WsfTrack GetTrackByName (WsfPlatform, string);
#extern double GetWeaponRangeMax (WsfPlatform, Array<Map<string, Object>>);
#extern string CalculatePositioning (WsfPlatform, WsfTrack, double);
//perform a decent estimation of desired intercept angle
// (to use as a starting point for intelligent maneuvering for guiding missiles)
double ownSpeed = PLATFORM.Speed();
double targetSpeed = targetTrack.Speed();
#double engageRangeMax = GetWeaponRangeMax(PLATFORM, mWeaponArray);
double engageRangeMax = GetWeaponRangeMax(PLATFORM);
double slantRangeTo = PLATFORM.SlantRangeTo(targetTrack);
string positioning = CalculatePositioning(PLATFORM, targetTrack, 10.0);
//"pure" pursuit (by default)
mInterceptHeading = PLATFORM.TrueBearingTo(targetTrack);
if (((WsfRIPRProcessor)PROCESSOR).WeaponsActive(targetTrack) > 0)
{
//"f-pole" pursuit (fly offset)
#extern double MaximizeFPole(WsfPlatform, WsfTrack, double);
mInterceptHeading = MaximizeFPole(PLATFORM, targetTrack, mOffsetAngle);
}
else if (targetTrack.AirDomain() &&
slantRangeTo >= engageRangeMax &&
positioning != "head-to-head" &&
positioning != "head-to-tail" &&
targetSpeed >= ownSpeed)
{
//"lead" pursuit
WsfWaypoint interceptPoint = WsfWaypoint();
double timeToIntercept = PLATFORM.InterceptLocation3D(targetTrack, interceptPoint);
// If timeToIntercept is positive then we know intercept is possible
if (timeToIntercept > 0.0)
{
mInterceptHeading = interceptPoint.Heading();
}
}
if ((targetTrack.ElevationValid() || targetTrack.LocationValid()) && targetTrack.Altitude() > interceptAltitude)
{
interceptAltitude = targetTrack.Altitude();
}
if ( (interceptAltitude - PLATFORM.Altitude()) < 100)
{
interceptAltitude = PLATFORM.Altitude();
}
}
# else
# {
# writeln_d("no target track, not changing course for weapon guidance!");
# }
//double minYaw = PLATFORM.RelativeBearingTo(targetTrack);
//double maxYaw = minYaw;
double minYaw = MATH.NormalizeAngleMinus180_180(mInterceptHeading - PLATFORM.Heading());
double maxYaw = minYaw;
//first be sure to cover any uplinks against a current target
string targetName = ((WsfRIPRProcessor)PROCESSOR).GetTargetName();
double tMin = minYaw;
double tMax = maxYaw;
for (int up=0; up<((WsfRIPRProcessor)PROCESSOR).UplinkCount(); up = up+1)
{
WsfPlatform weaponPlatform = ((WsfRIPRProcessor)PROCESSOR).UplinkPlatformEntry(up);
WsfTrack weaponTarget = weaponPlatform.CurrentTargetTrack();
if (weaponTarget.TargetName() != targetName)
{
continue;
}
if (weaponTarget.IsValid() &&
weaponTarget.BelievedAlive() &&
((WsfRIPRProcessor)PROCESSOR).WeaponsActive(weaponTarget) )
{
tMin = MATH.Min(tMin, PLATFORM.RelativeBearingTo(weaponTarget));
tMax = MATH.Max(tMax, PLATFORM.RelativeBearingTo(weaponTarget));
double coverage = tMax - tMin;
if ((mSensorAzimuthHalfAngle*2*0.9) > coverage) //take off 10% for padding
{
//can cover this target
minYaw = tMin;
maxYaw = tMax;
}
else
{
//can NOT cover this target, drop the uplink
string msg = write_str(PLATFORM.Name(), " CAN NOT SUPPORT ACTIVE UPLINK AGAINST ", weaponTarget.TargetName());
//PLATFORM.Comment(msg);
writeln_d(msg);
}
}
}
//iterate over current uplinks, find relative angles, adjust bounds
for (int up=0; up<((WsfRIPRProcessor)PROCESSOR).UplinkCount(); up = up+1)
{
WsfPlatform weaponPlatform = ((WsfRIPRProcessor)PROCESSOR).UplinkPlatformEntry(up);
WsfTrack weaponTarget = weaponPlatform.CurrentTargetTrack();
if (weaponTarget.IsValid() &&
weaponTarget.BelievedAlive() &&
((WsfRIPRProcessor)PROCESSOR).WeaponsActive(weaponTarget) )
{
tMin = MATH.Min(tMin, PLATFORM.RelativeBearingTo(weaponTarget));
tMax = MATH.Max(tMax, PLATFORM.RelativeBearingTo(weaponTarget));
double coverage = tMax - tMin;
if ((mSensorAzimuthHalfAngle*2*0.9) > coverage) //take off 10% for padding
{
//can cover this target
minYaw = tMin;
maxYaw = tMax;
}
else
{
//can NOT cover this target, drop the uplink.
string msg = write_str(PLATFORM.Name(), " CAN NOT SUPPORT ACTIVE UPLINK AGAINST ", weaponTarget.TargetName());
//PLATFORM.Comment(msg);
writeln_d(msg);
}
}
}
if (((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().IsValid())
{
for (int channel = 1; channel < ((WsfRIPRProcessor)PROCESSOR).GetNumJobChannels(); channel = channel + 1)
{
double tempMin = minYaw;
double tempMax = maxYaw;
WsfRIPRJob aJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(((WsfRIPRProcessor)PROCESSOR), channel);
if (!aJob.IsValid())
{
continue;
}
if (aJob.Name() == "weapon_uplink")
{
string targetName = (string)aJob.GetData("targetTrackName");
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (!targetTrack.IsValid() || !targetTrack.BelievedAlive())
{
continue;
}
if (((WsfRIPRProcessor)PROCESSOR).WeaponsActive(targetTrack) <= 0)
{
continue;
}
tempMin = MATH.Min(tempMin, PLATFORM.RelativeBearingTo(targetTrack)); //[-180,180]
tempMax = MATH.Max(tempMax, PLATFORM.RelativeBearingTo(targetTrack)); //[-180,180]
double neededCoverage = tempMax - tempMin;
double sensorCoverage = mSensorAzimuthHalfAngle * 2 * 0.9; //take 10% off for padding
if (sensorCoverage > neededCoverage)
{
//can cover this target
minYaw = tempMin;
maxYaw = tempMax;
}
else
{
//can NOT cover this target, drop the uplink.
string msg = write_str(PLATFORM.Name(), " CAN NOT SUPPORT ACTIVE UPLINK AGAINST ", targetTrack.TargetName());
//PLATFORM.Comment(msg);
writeln_d(msg);
}
}
}
}
// now minYaw and maxYaw define relative headings that must be included by our sensor coverage
// use the desired interceptHeading as a starting point
// adjust if necessary according to our mSensorAzimuthHalfAngle
double relativeInterceptHeading = MATH.NormalizeAngleMinus180_180(mInterceptHeading - PLATFORM.Heading());
writeln_d("minyaw: ", minYaw, ", maxyaw: ", maxYaw);
if (minYaw < (relativeInterceptHeading - mSensorAzimuthHalfAngle))
{
//adjust a bit to the left
relativeInterceptHeading = minYaw + mSensorAzimuthHalfAngle*0.9;
writeln_d("intercept heading BEFORE adjusting for active weapons: ", mInterceptHeading);
mInterceptHeading = MATH.NormalizeAngleMinus180_180(PLATFORM.Heading() + relativeInterceptHeading);
writeln_d("intercept heading AFTER adjusting for active weapons: ", mInterceptHeading);
}
else if (maxYaw > (relativeInterceptHeading + mSensorAzimuthHalfAngle))
{
//adjust a bit to the right
relativeInterceptHeading = maxYaw - mSensorAzimuthHalfAngle*0.9;
writeln_d("intercept heading BEFORE adjusting for active weapons: ", mInterceptHeading);
mInterceptHeading = MATH.NormalizeAngleMinus180_180(PLATFORM.Heading() + relativeInterceptHeading);
writeln_d("intercept heading AFTER adjusting for active weapons: ", mInterceptHeading);
}
#extern bool FlyHold (WsfPlatform, double, double, double);
FlyHold( PLATFORM, mInterceptHeading, interceptAltitude, cINTERCEPT_SPEED);
end_execute
end_behavior

View File

@@ -0,0 +1,127 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
#this is a parent behavior of any defensive manuevers
# first determine if we are in danger, then defend in the child behaviors
include_once behavior_unload.txt
include_once behavior_force_overshoot.txt
behavior in_danger
script_variables
double cANGLE_TOLERANCE = 45.0; # degrees
WsfTrack mBiggestThreat;
end_script_variables
script bool NotWeapon(WsfTrack aTrack)
if (aTrack.Target().IsValid() && aTrack.Target().WeaponEngagement().IsValid())
{
return false; //it is a weapon
}
return true;
end_script
script bool IsFlyer(WsfPlatform aPlat)
if (!aPlat.IsValid())
{
return false;
}
if (aPlat.Mover().IsA_TypeOf("WSF_AIR_MOVER" ) ||
aPlat.Mover().IsA_TypeOf("WSF_6DOF_MOVER") )
{
return true;
}
else if (aPlat.MakeTrack().AirDomain())
{
return true;
}
else if((aPlat.Altitude() > 152.4) && (aPlat.Speed() > 51.44) ) // ~500 feet alt, ~100 knots speed
{
return true;
}
return false;
end_script
precondition
writeln("precondition in_danger");
//check track list for any threats
extern double mVisualRange;
extern string CalculatePositioning( WsfPlatform, WsfTrack, double );
//see if anybody is threatening me
mBiggestThreat = null;
foreach (WsfLocalTrack t in PLATFORM.MasterTrackList())
{
if (!t.SideValid() || t.Side() != PLATFORM.Side())
{
double range = PLATFORM.SlantRangeTo(t);
if ((range < mVisualRange) && NotWeapon(t) && IsFlyer(t.Target()))
{
string pos = CalculatePositioning(PLATFORM, t, cANGLE_TOLERANCE );
if (pos=="tail-to-head" || pos=="target-facing-me")
{
if (!mBiggestThreat.IsValid() || (range < PLATFORM.SlantRangeTo(mBiggestThreat)))
{
#mBiggestThreat = (WsfTrack)t;
mBiggestThreat = t;
}
}
}
}
}
if (mBiggestThreat.IsValid())
{
//if we are closer to our target, stay in the fight
WsfTrack targetTrack = PROCESSOR.GetTarget();
if (!targetTrack.IsNull() && targetTrack.IsValid())
{
extern double mEngagementAggressiveness;
double threatRange = PLATFORM.SlantRangeTo(mBiggestThreat);
double requiredAggressiveness = threatRange / (threatRange + PLATFORM.SlantRangeTo(targetTrack));
if (mEngagementAggressiveness >= requiredAggressiveness)
{
string myPos = CalculatePositioning(PLATFORM, targetTrack, cANGLE_TOLERANCE );
if (myPos=="head-to-tail" || myPos="me-facing-target")
{
writeln(" not in enough danger, I am chasing target: ", targetTrack.TargetName());
return false; #do not defend, I am aggressive enough to stay after my target, and I am facing my target
}
}
}
return true;
}
return false;
end_precondition
execute
writeln("executing in_danger");
PLATFORM.Comment("in_danger");
end_execute
selector
behavior unload end_behavior
behavior force_overshoot end_behavior
end_selector
end_behavior

View File

@@ -0,0 +1,59 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior low_speed_recovery
script_variables
double mLastAltitude = 0.0;
double mMinimumSpeedAllowed = 102.9; # units: meters/sec, == 200 knots
double cDIVE_ALTITUDE = 304.8; # 1000 feet
double cMAX_SPEED = 9999999999.99; # m/s
double cGRAVITY_ACCEL = 9.80665; # 1 G
double cDEFAULT_ACCEL = (cGRAVITY_ACCEL * 7.5); # m/s^2 ~7.5 Gs
end_script_variables
precondition
writeln("precondition low_speed_recovery");
WsfTrack targetTrack = PROCESSOR.GetTarget();
WsfMover mover = PLATFORM.Mover();
if (targetTrack.IsNull() || !targetTrack.IsValid() || mover.IsNull() || !mover.IsValid())
{
return false;
}
if (PLATFORM.Speed() < mMinimumSpeedAllowed)
{
return true;
}
return false;
end_precondition
execute
writeln("executing low_speed_recovery");
PLATFORM.Comment("low_speed_recovery");
//straighten out, fly forward, and negative 1 G to minimize lift drag
PLATFORM.GoToSpeed(cMAX_SPEED, cDEFAULT_ACCEL, true); # go max speed
writeln(" GoToSpeed( ", cMAX_SPEED," )");
if (PLATFORM.Pitch()>0)
{
PLATFORM.GoToAltitude(cDIVE_ALTITUDE, cGRAVITY_ACCEL, false); # unload, dive "slowly" at 1 negative G so there is zero lift drag
}
end_execute
end_behavior

View File

@@ -0,0 +1,31 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior manage-fuel
script_debug_writes off
script_variables
end_script_variables
precondition
writeln_d("precondition manage-fuel");
return false;
end_precondition
execute
writeln_d("executing manage-fuel");
end_execute
end_behavior

View File

@@ -0,0 +1,31 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior manage-signature
script_debug_writes off
script_variables
end_script_variables
precondition
writeln_d("precondition manage-signature");
return false;
end_precondition
execute
writeln_d("executing manage-signature");
end_execute
end_behavior

View File

@@ -0,0 +1,325 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior pincer
script_debug_writes off
script_variables
//debug parameters
bool mDrawSteering = false;
//parameters for how to initially fly pincer (1st phase, separation)
string mDirection = "none";
double mPincerSpeed = 500 * MATH.MPS_PER_NMPH(); //400 kts
double mPincerOffsetAngle = 70.0; //degrees
//parameters for determining if to chase and how to do so (2nd phase, option A)
double mEnemyFOVHalfAngle = 50.0; //degrees
double mChaseAngle = 75.0; //degrees
double mChaseSpeedlnsideFOV = 600 * MATH.MPS_PER_NMPH(); //600 kts
double mChaseSpeedOutsideFOV = 1200 * MATH.MPS_PER_NMPH(); //1200 kts
//parameters for determining if to drag (run) and how to do so (2nd phase, option B)
double mRunDistance = 130 * 1852; //130nm (meters)
double mRunAngleLimit = 15.0; //degrees
double mDragSpeed = 800 * MATH.MPS_PER_NMPH(); //800 kts
double mDragAddedAngle = -1.0; //degrees
//util var, not for user edit
WsfGeoPoint mPincerPoint;
bool mDragging = false;
bool mChasing = false;
WsfDraw mDraw = WsfDraw();
WsfRIPRJob mCurrentJob;
end_script_variables
script double GetPincerDragOffset(WsfTrack aTgt)
if (aTgt.Speed() >= PLATFORM.Speed())
{
return 180.0;
}
else
{
return (180 - MATH.ACos(aTgt.Speed()/PLATFORM.Speed()));
}
end_script
precondition
#writeln_d("precondition pincer");
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
} // ((WsfRIPRProcessor)PROCESSOR)
if (((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().IsValid())
{
mCurrentJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
if (mCurrentJob.IsValid())
{
// If we're supposed to fly towards a point, go for it!
if (mCurrentJob.Name() == "pincer")
{
mPincerPoint = (WsfGeoPoint)mCurrentJob.GetData("ZonePoint");
mDirection = (string)mCurrentJob.GetData(PLATFORM.Name());
if (mPincerPoint.IsValid())
{
return true;
}
else
{
writeln_d(PLATFORM.Name(), " pincer point not valid!");
return Failure("pincer job did not have valid point");
}
}
else
{
writeln_d(PLATFORM.Name(), " job not a pincer job: ", mCurrentJob.Name());
}
}
else
{
writeln_d(PLATFORM.Name(), " job not valid!");
}
}
else
{
writeln_d(PLATFORM.Name(), " commander not found!");
return Failure("no commander found");
}
return Failure("current job not a valid pincer job");
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing pincer!, T=", TIME_NOW);
//provide for another channel for pursue-target jobs
if (((WsfRIPRProcessor)PROCESSOR).NumJobChannels() <= 1)
{
((WsfRIPRProcessor)PROCESSOR).SetNumJobChannels(2);
}
//writelnd("executing pincer.");
((WsfRIPRProcessor)PROCESSOR).ClearTarget();
//calculate heading if we are still flying offset
double angle = 0;
if (mDirection == "left")
{
angle = -mPincerOffsetAngle;
}
else if (mDirection == "right")
{
angle = mPincerOffsetAngle;
}
double heading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(mPincerPoint) + angle);
//find out if we are being chased & should drag threats away
WsfTrack worstTrack;
double worstDist = MATH.DOUBLE_MAX();
double worstFOV = MATH.DOUBLE_MAX();
Array<string> targetNames = (Array<string>)mCurrentJob.GetData("ZoneThreatNameArray");
extern WsfTrack GetTrackByName (WsfPlatform, string);
int allOnCap = (int)mCurrentJob.GetData("all_on_cap");
if (allOnCap <= 0)
{
//save off the closest opponent track
foreach(string tgtName in targetNames)
{
WsfTrack tgt = GetTrackByName(PLATFORM, tgtName);
if (tgt.IsValid() && tgt.LocationValid())
{
double attackRange = tgt.GroundRangeTo(PLATFORM);
if (attackRange < worstDist)
{
//run away, drag threats out
worstDist = attackRange;
worstTrack = tgt;
}
double fov = MATH.Fabs(tgt.RelativeBearingTo(PLATFORM));
if (fov < worstFOV)
{
worstFOV = fov;
}
}
}
//manage dragging state
if ( (mDragging == false) &&
(worstDist < mRunDistance) &&
(worstTrack.IsValid()) &&
(worstTrack.HeadingValid()) &&
(MATH.Fabs(worstTrack.TrueBearingTo(PLATFORM)-worstTrack.Heading()) < mRunAngleLimit))
{
mDragging = true;
if (mDirection == "right")
{
int count = (int)mCurrentJob.GetData("right_drag");
mCurrentJob.SetData("right_drag",count+1);
writeln_d(PLATFORM.Name(), " increased right_drag to: ", count+1);
}
else if (mDirection == "left")
{
int count = (int)mCurrentJob.GetData("left_drag");
mCurrentJob.SetData("left_drag",count+1);
writeln_d(PLATFORM.Name(), " increased left_drag to: ", count+1);
}
}
else if ( (mDragging == true) &&
( (!worstTrack.IsValid()) ||
(worstDist > (mRunDistance*1.1)) ||
(!worstTrack.HeadingValid()) ||
(MATH.Fabs(worstTrack.TrueBearingTo(PLATFORM)-worstTrack.Heading()) > (mRunAngleLimit*1.1))))
{
mDragging = false;
if (mDirection == "right")
{
int count = (int)mCurrentJob.GetData("right_drag");
mCurrentJob.SetData("right_drag",count-1);
writeln_d(PLATFORM.Name(), " decreased right_drag to: ", count-1);
}
else if (mDirection == "left")
{
int count = (int)mCurrentJob.GetData("left_drag");
mCurrentJob.SetData("left_drag",count -1);
writeln_d(PLATFORM.Name(), " decreased left_drag to: ", count-1);
}
}
mChasing = false;
if (mDragging == true)
{
writeln_d("dragging!");
//try to maintain distance
PLATFORM.GoToSpeed(mDragSpeed);
double dragOffset = GetPincerDragOffset(worstTrack);
if (mDirection == "right")
{
if (mDragAddedAngle > 0)
{
heading = MATH.NormalizeAngle0_360(heading + mDragAddedAngle);
}
else
{
heading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(mPincerPoint) + dragOffset);
}
}
else if (mDirection == "left")
{
if (mDragAddedAngle > 0)
{
heading = MATH.NormalizeAngle0_360(heading - mDragAddedAngle);
}
else
{
heading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(mPincerPoint) - dragOffset);
}
}
}
else
{
//look for reasons to chase
PLATFORM.GoToSpeed(mPincerSpeed);
//check if other pair is dragging, so we should chase
int count = 0;
if (mDirection == "right")
{
count = (int)mCurrentJob.GetData("left_drag");
}
else if (mDirection == "left")
{
count = (int)mCurrentJob.GetData("right_drag");
}
double diff = 0;
if (worstTrack.IsValid() && worstTrack.HeadingValid())
{
double b1 = worstTrack.Heading();
double b2 = worstTrack.TrueBearingTo(PLATFORM.Location());
diff = MATH.NormalizeAngleMinus180_180(b2 - b1);
}
if (count > 0 && MATH.Fabs(diff) > mEnemyFOVHalfAngle)
{
//the other pincer group is being engaged, turn in now
writeln_d(PLATFORM.Name(), " chasing because other pair is dragging");
mChasing = true;
}
//check if we have flanked & can now chase
else
{
if (mDirection == "right" && diff < -mChaseAngle)
{
writeln_d(PLATFORM.Name(), " right chasing because past chase angle");
mChasing = true;
}
else if (mDirection == "left" && diff > mChaseAngle)
{
mChasing = true;
writeln_d(PLATFORM.Name(), " left chasing because past chase angle");
}
}
}
}
else
{
writeln_d("All targets still on cap, no dragging or chasing yet!");
}
if (mChasing == true)
{
writeln_d("chasing!");
//double FOV = MATH.Fabs(worstTrack.RelativeBearingTo(PLATFORM));
if (worstFOV <= mEnemyFOVHalfAngle)
{
PLATFORM.GoToSpeed(mChaseSpeedlnsideFOV);
}
else
{
PLATFORM.GoToSpeed(mChaseSpeedOutsideFOV);
}
if (worstTrack.IsValid())
{
heading = PLATFORM.TrueBearingTo(worstTrack);
((WsfRIPRProcessor)PROCESSOR).SetTarget(worstTrack);
}
else
{
heading = PLATFORM.TrueBearingTo((WsfGeoPoint)mCurrentJob.GetData("ZonePoint"));
}
}
PLATFORM.TurnToHeading(heading);
if (mDrawSteering == true)
{
WsfGeoPoint pt = PLATFORM.Location();
pt.Extrapolate(heading, 185200);
mDraw.SetLayer("behavior_pincer");
mDraw.SetDuration(PROCESSOR.UpdateInterval());
mDraw.SetColor(0.0, 1.0, 0.75); //green-blue
mDraw.SetLineSize(1);
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(pt);
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(mPincerPoint);
mDraw.End();
}
# # writeln_d(" T=", TIME_NOW, ", range: ", interceptRange, " true-bearing; interceptHeading); #
##if ( (interceptAltitude - PLATFORM.Altitude()) > 5) #if ( (interceptAltitude - PLATFORM.Altitude()) > 10000*MATH.M_PER_FT())
#{
# writeln_d("GoToAltitude: ",interceptAltitude); # #PLATF0RM.GoToAltitude(interceptAltitude);
#>
end_execute
end_behavior

View File

@@ -0,0 +1,372 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
##### put this commented out script below on any processor that uses this behavior
##### it enables coordinated manuevering (when used in tandem with this behavior)
#script_variables
# int mLeftDragCount = 0;
# int mRightDragCount = 0;
#end_script_variables
#on_message
# type WSF_CONTROL_MESSAGE
# script
# WsfControlMessage controlMsg = (WsfControlMessage)MESSAGE;
# if (controlMsg.Function() == "pincer" &&
# controlMsg.Resource() == "drag")
# {
# int adjust = 1;
# if (controlMsg.AuxDataBool("dragging") == false)
# {
# adjust = -1;
# }
# if (controlMsg.AuxDataString("side") == "left")
# {
# mLeftDragCount += adjust;
# }
# else //if (controlMsg.AuxDataString("side") == "right")
# {
# mRightDragCount += adjust;
# }
# }
# writeln("T=", TIME_NOW, " Received control, function: ", controlMsg.Function(), ", resources: ", controlMsg.Resource());
# end_script
#end_on_message
behavior pincer_fsm
script_debug_writes off
script_variables
//debug parameters
bool mDrawSteering = false;
//parameters for how to initially fly pincer (1st phase, separation)
double mPincerSpeed = 500 * MATH.MPS_PER_NMPH(); //400 kts
double mPincerOffsetAngle = 70.0; //degrees
//parameters for determining if to chase and how to do so (2nd phase, option A)
double mEnemyFOVHalfAngle = 50.0; //degrees
double mChaseAngle = 75.0; //degrees
double mChaseSpeedlnsideFOV = 600 * MATH.MPS_PER_NMPH(); //600 kts
double mChaseSpeedOutsideFOV = 1200 * MATH.MPS_PER_NMPH(); //1200 kts
//parameters for determining if to drag (run) and how to do so (2nd phase, option B)
double mRunDistance = 130 * 1852; //130nm (meters)
double mRunAngleLimit = 15.0; //degrees
double mDragSpeed = 800 * MATH.MPS_PER_NMPH(); //800 kts
double mDragAddedAngle = -1.0; //degrees
// bidding parameters (similar to pursue-target parameters)
double cMIN_JOB_BID = -MATH.DOUBLE_MAX();
# double cWEIGHT_CURRENT_TARGET = 10.0;
# double cWEIGHT_CLOSING_SPEED_OF = 0.5; #1.0;
# double cWEIGHT_SLANT_RANGE_TO = -4.0; #-3.0;
# double cWEIGHT_FUEL = 2.0;
# double cWEIGHT_WEAPONS_IN_FLIGHT = 0.0;
# double cWEIGHT_ANY_WEAPONS_ACTIVE = 20.0;
# double cWEIGHT_THREAT_WEAPONS_ENVELOPE = 10000.0;
# double cBASE_SLANT_RANGE_CONSTANT = 600000.0; //over 300 nm away [How is this used???]
# double cBASE_CLOSING_SPEED_CONSTANT = 1050.0; //over 2000 kts closing speed
double cMAX_SLANT_RANGE = 1000000.0; #over 539 nm away, target ranges beyond this are considered unfavorable
double cWEIGHT_SLANT_RANGE_TO = 1.0;
double cMIN_CLOSING_SPEED = -1050.0; #threats running away (negative closing) faster are considered unfavorable
double cWEIGHT_CLOSING_SPEED = 1.0; #scale for how closing speed translates to distance
double cWEIGHT_FUEL = 0.0; #try a value of 2.0 if you care about fuel
double cWEIGHT_MY_WEAPONS_ACTIVE = 0.0; #changes bid if your own weapons are active on target
double cWEIGHT_PEERS_WEAPONS_ACTIVE = 0.0; #changes bid if your peers weapons are active on target
double cWEIGHT_THREAT_WEAPONS_ENVELOPE = 10000.0; #uses the global "mWeaponsEnvelope" array, try value of 10000 if you care about that
//careful with these two parameters, they are stateful
double cWEIGHT_CURRENT_TARGET = 0.0; #changes bid if you are currently targeting the threat
//util var, not for user edit (data grabbed from task)
string mDirection = "none";
WsfGeoPoint mPincerPoint;
int mAllOnCap = 0;
WsfDraw mDraw = WsfDraw();
//WsfRIPRJob mCurrentJob;
WsfTrack mWorstTrack;
double mWorstDist = MATH.DOUBLE_MAX();
double mWorstFOV = MATH.DOUBLE_MAX();
end_script_variables
script void SendDraggingChangeToPeers(string direction, bool dragging)
writeln_d("sending drag state change now!");
WsfControlMessage controlMsg = WsfControlMessage();
controlMsg.SetFunction("pincer");
controlMsg.SetResource("drag");
controlMsg.SetAuxData("side", direction);
controlMsg.SetAuxData("dragging", dragging);
controlMsg.SetSizeInBits(500000); //half megabit
WsfComm com = PLATFORM.Comm("sub_net");
#com.SendUnicastMessage(controlMsg, "Blue_2");
com.SendMessageToPeers("", controlMsg);
end_script
script double GetPincerDragOffset(WsfTrack aTgt)
if (aTgt.Speed() >= PLATFORM.Speed())
{
return 180.0;
}
else
{
return (180 - MATH.ACos(aTgt.Speed()/PLATFORM.Speed()));
}
end_script
precondition
if (!PROCESSOR.IsA_TypeOf("WSF_QUANTUM_TASKER_PROCESSOR"))
{
return Failure("behavior not attached to a quantum tasker processor!");
} // ((WsfQuantumTaskerProcessor)PROCESSOR)
WsfTaskList tasks = ((WsfQuantumTaskerProcessor)PROCESSOR).TasksReceivedOfType("PINCER");
WsfTask task = tasks.Entry(0); //just do first one for now
if (task.IsValid() && task.CheckAuxData("ZonePoint"))
{
mDirection = task.AuxDataString(PLATFORM.Name());
mAllOnCap = task.AuxDataInt("all_on_cap");
mPincerPoint = (WsfGeoPoint)task.AuxDataObject("ZonePoint");
if (mPincerPoint.IsValid())
{
return true;
}
else
{
writeln_d(PLATFORM.Name(), " pincer point not valid!");
return Failure("pincer job did not have valid point");
}
}
else
{
return Failure("have not received a pincer task!");
}
end_precondition
### FSM states are evaluated after "execute"
execute
writeln_d(PLATFORM.Name(), " executing pincer!, T=", TIME_NOW);
//save off the closest opponent track
mWorstDist = MATH.DOUBLE_MAX();
mWorstFOV = MATH.DOUBLE_MAX();
WsfTask task = ((WsfQuantumTaskerProcessor)PROCESSOR).TasksReceivedOfType("PINCER").Entry(0);
Array<string> targetNames = (Array<string>)task.AuxDataObject("ZoneThreatNameArray");
foreach(string tgtName in targetNames)
{
WsfTrack tgt = GetTrackByName(PLATFORM, tgtName);
if (tgt.IsValid() && tgt.LocationValid())
{
double attackRange = tgt.GroundRangeTo(PLATFORM);
if (attackRange < mWorstDist)
{
//run away, drag threats out
mWorstDist = attackRange;
mWorstTrack = tgt;
}
double fov = MATH.Fabs(tgt.RelativeBearingTo(PLATFORM));
if (fov < mWorstFOV)
{
mWorstFOV = fov;
}
}
}
# if (mDrawSteering == true)
# {
# WsfGeoPoint pt = PLATFORM.Location();
# pt.Extrapolate(heading, 185200);
# mDraw.SetLayer("behavior_pincer");
# mDraw.SetDuration(((WsfRIPRProcessor)PROCESSOR).UpdateInterval());
# mDraw.SetColor(0.0, 1.0, 0.75); //green-blue
# mDraw.SetLineSize(1);
# mDraw.BeginLines();
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(pt);
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(mPincerPoint);
# mDraw.End();
# }
end_execute
script bool ShouldChase()
if (mAllOnCap > 0)
{
return false;
}
int other_dragging_count = 0;
if (mDirection == "right")
{
extern int mLeftDragCount;
other_dragging_count = mLeftDragCount;
}
else if (mDirection == "left")
{
extern int mRightDragCount;
other_dragging_count = mRightDragCount;
}
double diff = 0;
if (mWorstTrack.IsValid() && mWorstTrack.HeadingValid())
{
double b1 = mWorstTrack.Heading();
double b2 = mWorstTrack.TrueBearingTo(PLATFORM.Location());
diff = MATH.NormalizeAngleMinus180_180(b2 - b1);
}
if (other_dragging_count > 0 && MATH.Fabs(diff) > mEnemyFOVHalfAngle)
{
//the other pincer group is being engaged, turn in now
writeln_d(PLATFORM.Name(), " chasing because other pair is dragging");
return true;
}
else if ((mDirection == "right" && diff < -mChaseAngle) ||
(mDirection == "left" && diff > mChaseAngle) )
{
//we have already flanked, so now we can chase (regardless of other side dragging or not)
writeln_d(PLATFORM.Name(), " chasing because past chase angle");
return true;
}
return false;
end_script
show_state_transitions
#first default state, start here and go back to here if confused
state SEPARATE
next_state DRAG
if ( (mAllOnCap <= 0) &&
(mWorstDist < mRunDistance) &&
(mWorstTrack.IsValid()) &&
(mWorstTrack.HeadingValid()) &&
(MATH.Fabs(mWorstTrack.TrueBearingTo(PLATFORM)-mWorstTrack.Heading()) < mRunAngleLimit))
{
return true;
}
return false;
end_next_state
next_state CHASE
return ShouldChase();
end_next_state
next_state SEPARATE
double separate_angle = 0;
if (mDirection == "left")
{
separate_angle = -mPincerOffsetAngle;
}
else if (mDirection == "right")
{
separate_angle = mPincerOffsetAngle;
}
double heading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(mPincerPoint) + separate_angle);
PLATFORM.GoToSpeed(mPincerSpeed);
PLATFORM.TurnToHeading(heading);
return true;
end_next_state
end_state
state DRAG
next_state SEPARATE
if ( (!mWorstTrack.IsValid()) ||
(mWorstDist > (mRunDistance*1.1)) ||
(!mWorstTrack.HeadingValid()) ||
(MATH.Fabs(mWorstTrack.TrueBearingTo(PLATFORM)-mWorstTrack.Heading()) > (mRunAngleLimit*1.1)))
{
return true;
}
return false;
end_next_state
next_state DRAG
writeln_d("dragging!");
//try to maintain distance
PLATFORM.GoToSpeed(mDragSpeed);
double dragOffset = GetPincerDragOffset(mWorstTrack);
double heading;
if (mDirection == "right")
{
if (mDragAddedAngle > 0)
{
heading = MATH.NormalizeAngle0_360(heading + mDragAddedAngle);
}
else
{
heading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(mPincerPoint) + dragOffset);
}
}
else if (mDirection == "left")
{
if (mDragAddedAngle > 0)
{
heading = MATH.NormalizeAngle0_360(heading - mDragAddedAngle);
}
else
{
heading = MATH.NormalizeAngle0_360(PLATFORM.TrueBearingTo(mPincerPoint) - dragOffset);
}
}
PLATFORM.TurnToHeading(heading);
return true;
end_next_state
on_entry
SendDraggingChangeToPeers(mDirection, true);
writeln_d(PLATFORM.Name(), " increasing drag on side: ", mDirection);
end_on_entry
on_exit
SendDraggingChangeToPeers(mDirection, false);
writeln_d(PLATFORM.Name(), " decreasing drag on side: ", mDirection);
end_on_exit
end_state
state CHASE
next_state SEPARATE
return ! ShouldChase();
end_next_state
next_state CHASE
writeln_d("chasing!");
if (mWorstFOV <= mEnemyFOVHalfAngle)
{
PLATFORM.GoToSpeed(mChaseSpeedlnsideFOV);
}
else
{
PLATFORM.GoToSpeed(mChaseSpeedOutsideFOV);
}
double heading = 0;
if (mWorstTrack.IsValid())
{
heading = PLATFORM.TrueBearingTo(mWorstTrack);
#((WsfRIPRProcessor)PROCESSOR).SetTarget(mWorstTrack);
}
else
{
heading = PLATFORM.TrueBearingTo(mPincerPoint);
}
PLATFORM.TurnToHeading(heading);
return true;
end_next_state
end_state
end_behavior

View File

@@ -0,0 +1,121 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
//TODO use default values from higher level context (processor or parent behavior that holds default)
#assumes aDraw duration & layer is set
script void DrawRoute(WsfDraw aDraw, WsfRoute aRoute)
if (aRoute.IsValid())
{
aDraw.SetColor(0,1,1); //teal?
aDraw.SetLineSize(2);
aDraw.SetLineStyle("solid");
aDraw.BeginPolyline();
for (int i=0; i<aRoute.Size(); i=i+1)
{
aDraw.Vertex(aRoute.Waypoint(i).Location());
}
aDraw.End();
aDraw.SetColor(1.0,0.3,0.3); //pink?
aDraw.SetPointSize(4);
aDraw.BeginPoints();
for (int i=0; i<aRoute.Size(); i=i+1)
{
aDraw.Vertex(aRoute.Waypoint(i).Location());
}
aDraw.End();
}
end_script
behavior planned_route
script_debug_writes off
script_variables
bool mDrawRoute = false;
WsfDraw mDraw = WsfDraw();
double cDEFAULT_SPEED = 450.0 * MATH.MPS_PER_NMPH();
double cDEFAULT_ACCEL = 7.5 * Earth.ACCEL_OF_GRAVITY(); // 7.5 G (m/s^2)
end_script_variables
precondition
writeln_d("precondition planned_route");
return true;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing planned_route, T=", TIME_NOW);
#only command the platform to do something different if its not currently flying a route
WsfMover aMover = PLATFORM.Mover();
if (aMover.IsValid()) {
if (aMover.IsExtrapolating()) {
WsfGeoPoint pt = PLATFORM.Location();
WsfRoute ro = aMover.DefaultRoute().Copy(); #now we have a modifiable route
if (!ro.IsValid())
return;
writeln_d("flying route, name: ", ro.Name(), ", type: ", ro.Type());
WsfGeoPoint close = ro.LocationAtDistance(ro.DistanceAlongRoute(pt));
if (!close.IsValid()) {
return;
}
close.SetAltitudeAGL(pt.Altitude());
if (mDrawRoute)
{
mDraw.BeginLines();
mDraw.Vertex(pt);
mDraw.Vertex(close);
mDraw.End();
}
double d1 = ro.DistanceFromRoute(pt);
double d2 = pt.GroundRangeTo(close);
double d3 = -1;
Array<double> turnRad = aMover.PropertyDouble("turn_radius");
if (turnRad.Size() > 0) {
d3 = 2*turnRad[0];
}
int i = 0;
for (; i < ro.Size(); i = i+1)
{
WsfWaypoint wpt = ro.Waypoint(i);
WsfGeoPoint rpt = wpt.Location();
//check if we are close to an existing waypoint, if so... break & fly at that one
if (rpt.GroundRangeTo(close) < 926) {
break;
}
double dist = ro.DistanceAlongRoute(rpt);
if (dist > d1) {
if (d2 > d3) {
ro.Insert(i, WsfWaypoint.Create(close, wpt.Speed()));
}
break;
}
}
if (i >= ro.Size()) {
i = ro.Size() - 1;
}
//go at default speed; this gets overwritten if route waypoint has defined a speed
PLATFORM.GoToSpeed(cDEFAULT_SPEED, cDEFAULT_ACCEL, true);
PLATFORM.FollowRoute(ro, i);
}
}
if (mDrawRoute)
{
mDraw.SetDuration(PROCESSOR.UpdateInterval());
mDraw.SetLayer("behavior_planned_route");
DrawRoute(mDraw, PLATFORM.Route());
}
end_execute
end_behavior

View File

@@ -0,0 +1,108 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior pursue-point
script_debug_writes off
script_variables
bool tempVariable;
bool mConsiderFuel = false;
WsfGeoPoint mCurrentPointIntercept;
#double cSLOW_UPDATE_RATE = 3.0;
double cINTERCEPT_SPEED = 1000; # m/s
string mOldPointStr = "no point";
end_script_variables
precondition
writeln_d("precondition pursue-point");
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
}
string anOldPointStr = mOldPointStr;
mOldPointStr = "no point";
if (((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().IsValid())
{
WsfRIPRJob currentJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
if (currentJob.IsValid())
{
// If we're supposed to fly towards a point, go for it!
if (currentJob.Name() == "pursue-point")
{
mCurrentPointIntercept = (WsfGeoPoint)currentJob.GetData("targetPoint");
if (mCurrentPointIntercept.IsValid())
{
########################################################################
### print output / comments for any point change
########################################################################
mOldPointStr = "Job: " + currentJob.Name() + ", " + currentJob.GetDescription();
writeln_d(" - ", mOldPointStr);
if (mOldPointStr != anOldPointStr)
{
PLATFORM.Comment(mOldPointStr);
}
return true;
}
}
}
}
return Failure("current job not a valid pursue-point job");
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing pursue-point, T=", TIME_NOW);
#PROCESSOR.SetUpdateInterval(cSLOW_UPDATE_RATE);
PLATFORM.GoToSpeed(cINTERCEPT_SPEED);
extern double cDEFAULT_ALTITUDE;
PLATFORM.GoToAltitude(cDEFAULT_ALTITUDE, 200);
if (!mCurrentPointIntercept.IsValid())
{
#PLATFORM.Comment("ignoring invalid point");
return;
}
double interceptAltitude = mCurrentPointIntercept.Altitude();
if (interceptAltitude < 0)
{
#PLATFORM.Comment("ignoring invalid point");
return;
}
double interceptRange = PLATFORM.SlantRangeTo(mCurrentPointIntercept);
double interceptHeading = PLATFORM.TrueBearingTo(mCurrentPointIntercept);
PLATFORM.TurnToHeading(interceptHeading);
writeln_d(" T=", TIME_NOW, ", range: ", interceptRange, " true-bearing: ", interceptHeading);
##if ( (interceptAltitude - PLATFORM.Altitude()) > 5)
#if ( (interceptAltitude - PLATFORM.Altitude()) > 10000*MATH.M_PER_FT())
#{
# writeln_d("GoToAltitude: ",interceptAltitude);
# #PLATFORM.GoToAltitude(interceptAltitude);
#}
end_execute
end_behavior

View File

@@ -0,0 +1,81 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior pursue-point_pathing
script_variables
bool tempVariable;
WsfGeoPoint mCurrentPointIntercept;
double cSLOW_UPDATE_RATE = 3.0;
double cINTERCEPT_SPEED = 1000; # m/s
end_script_variables
precondition
writeln("precondition pursue-point_pathing");
if (!PLATFORM.GetPathFinder().IsValid())
{
writeln("no path-finder available");
return false;
}
if (PROCESSOR.GetRIPRCommanderProcessor().IsValid())
{
WsfRIPRJob currentJob = PROCESSOR.GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, PROCESSOR);
if (currentJob.IsValid())
{
// If we're supposed to fly towards a point, go for it!
if (currentJob.Name() == "pursue-point")
{
mCurrentPointIntercept = (WsfGeoPoint)currentJob.GetData("targetPoint");
if (mCurrentPointIntercept.IsValid())
{
return true;
}
}
}
}
return false;
end_precondition
execute
writeln("executing pursue-point_pathing.");
PROCESSOR.SetUpdateInterval(cSLOW_UPDATE_RATE);
PLATFORM.GoToSpeed(cINTERCEPT_SPEED);
extern double cDEFAULT_ALTITUDE;
PLATFORM.GoToAltitude(cDEFAULT_ALTITUDE, 200);
double interceptAltitude = mCurrentPointIntercept.Altitude();
double interceptHeading = PLATFORM.TrueBearingTo(mCurrentPointIntercept);
double interceptRange = PLATFORM.SlantRangeTo(mCurrentPointIntercept);
writeln_d(" T=", TIME_NOW, ", range: ", interceptRange, " true-bearing: ", interceptHeading);
WsfGeoPoint startGeoPoint = PLATFORM.Location();
if (!PLATFORM.FindAndSetPath(startGeoPoint, mCurrentPointIntercept))
{
PLATFORM.FollowRoute("DEFAULT_ROUTE","CLOSEST_POINT");
}
#if ( (interceptAltitude - PLATFORM.Altitude()) > 5)
if ( (interceptAltitude - PLATFORM.Altitude()) > 10000*MATH.M_PER_FT())
{
writeln_d("GoToAltitude: ",interceptAltitude);
#PLATFORM.GoToAltitude(interceptAltitude);
}
end_execute
end_behavior

View File

@@ -0,0 +1,449 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior pursue-target
script_debug_writes off
script_variables
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** control / mode of operation parameters **//
//**********************************************************************//
bool mCheckOwnJobBoardToo = false; # can this agent bid on & win a job off his own board
bool mUseMoverDuringPursuit = true;
//**********************************************************************//
//** flying parameters, for intercept or approach **//
//**********************************************************************//
//target point to fly at
WsfGeoPoint mTargetPoint = WsfGeoPoint();
double mTargetSpeed = 0; # will be overwritten
// larger values, suggested for air to air fighters & jets
double mMatchSpeedDistanceMin = 1 * 1852; # 1 mile
double mMatchSpeedDistanceMax = 20 * 1852; # 20 miles
#double mWaitSpeed = 500 * MATH.MPS_PER_NMPH();
#double mInterceptSpeed = 800 * MATH.MPS_PER_NMPH();
#double mInterceptSpeed = 293.941; //mach 0.95 at 25200 ft altitude
double mWaitSpeed = 293.941; //mach 0.95 at 25200 ft altitude
double mInterceptSpeed = 600 * MATH.MPS_PER_NMPH();
double mDefaultAccel = 7.5 * Earth.ACCEL_OF_GRAVITY(); # m/s^2 ~7.5 Gs
// smaller values, suggest for a UAV intercepting or following ground forces
#double mMatchSpeedDistanceMin = 185.2; # one tenth of a mile
#double mMatchSpeedDistanceMax = 1852.0; # a mile
#double mWaitSpeed = 22; # m/s (~50 mph)
#double mInterceptSpeed = 52; # m/s (~100 knots)
double mMinAltitude = 4572; # ~15000 feet
//switch for matching threat's altitude during pursuit
bool DefaultMatchThreatAltitude = false;
Map<string, bool> mThreatTypeMatchAltitude = Map<string, bool>();
//mThreatTypeMatchAltitude["missile_fast"] = true;
//mThreatTypeMatchAltitude["awacs"] = true;
//mThreatTypeMatchAltitude["bomber"] = true;
//mThreatTypeMatchAltitude["fighter"] = true;
mThreatTypeMatchAltitude["unknown"] = false;
mThreatTypeMatchAltitude["uav"] = false;
mThreatTypeMatchAltitude["sam"] = false;
mThreatTypeMatchAltitude["ship"] = false;
mThreatTypeMatchAltitude["jammer"] = false;
mThreatTypeMatchAltitude["missile"] = false;
//specify offset angle to fly at, during f-pole pursuit
double DefaultOffsetDistance = 1852*50; //50 nm
double DefaultOffsetAngle = 30.0; // should this be radar-specific?
Map<string, double> ThreatTypeOffsetAngle = Map<string, double>();
//ThreatTypeOffsetAngle["awacs"] = 15.0;
//ThreatTypeOffsetAngle["unknown"] = 20.0;
//ThreatTypeOffsetAngle["sam"] = 50.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfRIPRJob mCurrentJob;
WsfDraw mDraw = WsfDraw();
string mOldTargetStr = "no target";
double mLastTime = 0.0;
end_script_variables
script double GetOffsetAngleOnThreat(WsfTrack threat)
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : double angle in ThreatTypeOffsetAngle )
{
if( plat.CategoryMemberOf( aCategory ) )
{
writeln_d("offset angle for type ", aCategory, " = ", angle);
return angle;
}
}
}
return DefaultOffsetAngle;
end_script
script bool MatchAltitudeForThreat(WsfTrack track)
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid())
{
foreach (string aCategory : bool match in mThreatTypeMatchAltitude)
{
if (plat.CategoryMemberOf(aCategory))
{
return match;
}
}
}
return DefaultMatchThreatAltitude;
end_script
precondition
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
}
writeln_d(PLATFORM.Name(), " precondition pursue-target, T=", TIME_NOW);
((WsfRIPRProcessor)PROCESSOR).ClearTarget();
double duration = TIME_NOW - mLastTime;
mLastTime = TIME_NOW;
if (duration > (1.5*((WsfRIPRProcessor)PROCESSOR).UpdateInterval()))
{
mOldTargetStr = "no target";
}
string anOldTargetStr = mOldTargetStr;
mOldTargetStr = "no target";
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
if (commander.IsValid())
{
if (commander.IsJobWindowOpen())
{
writeln_d("pursue-target: commander.GetJobFor()");
mCurrentJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
}
else
{
writeln_d("pursue-target: commander's job window closed, keeping current job!");
}
}
if (mCheckOwnJobBoardToo &&
(mCurrentJob.IsNull() || !mCurrentJob.IsValid()))
{
writeln_d("pursue-target: myself.GetJobFor()");
mCurrentJob = ((WsfRIPRProcessor)PROCESSOR).GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
}
if (mCurrentJob.IsNull() || !mCurrentJob.IsValid() )
{
writeln_d("pursue-target ClearTarget -> job not a valid pursue-target job");
return Failure("job is not a valid pursue-target job");
}
if (mCurrentJob.Name() != "pursue-target")
{
string msg = write_str("job is a ", mCurrentJob.Name(), " instead of a pursue-target job");
writeln_d(msg);
return Failure("job is not a pursue-target job");
}
extern WsfTrack GetTrackByName (WsfPlatform, string);
string targetName = (string)mCurrentJob.GetData("targetTrackName");
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (!targetTrack.IsValid())
{
writeln_d(" No valid target track found for target named ", targetName);
return Failure("target track not found");
}
########################################################################
### print output / comments for any target change
#######################################################################
mOldTargetStr = "Job: " + mCurrentJob.Name() + ", " + mCurrentJob.GetDescription();
writeln_d(" - ", mOldTargetStr);
if (mOldTargetStr != anOldTargetStr)
{
PLATFORM.Comment(mOldTargetStr);
}
((WsfRIPRProcessor)PROCESSOR).SetTarget(targetTrack);
return true;
end_precondition
execute
string comment = write_str(PLATFORM.Name(), " executing pursue-target, T=", TIME_NOW);
writeln_d(comment);
#PLATFORM.Comment(comment);
extern string CalculatePositioning (WsfPlatform, WsfTrack, double);
extern double GetWeaponRangeMax(WsfPlatform aPlatform, Array<Map<string, Object>> aWeaponArray);
extern Array<Map<string, Object>> mWeaponArray;
//get target from ripr processor, to be sure
WsfTrack targetTrack = ((WsfRIPRProcessor)PROCESSOR).GetTarget();
if (targetTrack.IsNull() ||
!targetTrack.IsValid())
{
writeln_d(" UpdateInterceptLocation, targetTrack is null or not valid");
return;
}
if (mUseMoverDuringPursuit)
{
double ownSpeed = PLATFORM.Speed();
double targetSpeed = targetTrack.Speed();
double slantRangeTo = PLATFORM.SlantRangeTo(targetTrack);
double closingSpeed = PLATFORM.ClosingSpeedOf(targetTrack);
string positioning = CalculatePositioning(PLATFORM, targetTrack, 10.0);
int weaponsActive = ((WsfRIPRProcessor)PROCESSOR).WeaponsActive(targetTrack);
double engageRangeMax = 185200.0; //100 miles
double engageRangeMin = 1852.0; // 1 mile
# // determine the fuel needed to engage
# double fuelRequired = 0;
# double bingoQuantity = -1;
# if (mConsiderFuel)
# {
# WsfFuel fuelObj = PLATFORM.Fuel();
# if (fuelObj)
# {
# double maxWeaponRange = GetWeaponRangeMax(PLATFORM, mWeaponArray);
# double distToWeaponRange = slantRangeTo - maxWeaponRange;
# double timeToTarget = distToWeaponRange / closingSpeed;
# double distToTravel = timeToTarget * ownSpeed;
#
# fuelRequired = fuelObj.QuantityRequired(distToTravel);
# bingoQuantity = fuelObj.BingoQuantity();
# }
# }
string PursuitMode = "pure";
if (weaponsActive > 0)
{
PursuitMode = "f-pole";
}
else if (targetTrack.AirDomain())
{
if (slantRangeTo >= engageRangeMax &&
positioning != "head-to-head" &&
positioning != "head-to-tail" &&
targetSpeed >= ownSpeed)
{
PursuitMode = "lead";
}
else if (slantRangeTo <= engageRangeMax &&
positioning != "head-to-head" &&
positioning != "head-to-tail")
{
PursuitMode = "lag";
}
//else if (slantRangeTo > engageRangeMax ||
// (slantRangeTo <= engageRangeMax &&
// (positioning == "head-to-head" ||
// positioning == "head-to-tail")))
//{
// PursuitMode = "pure";
//}
}
writeln_d(" PursuitMode = ", PursuitMode);
// Our track quality (or target range) may not be good enough yet, so keep moving towards the target.
// If we got the altitude from the TRACK, match it
double interceptHeading = PLATFORM.Heading();
double distanceToTarget = PLATFORM.SlantRangeTo(targetTrack);
extern double cDEFAULT_ALTITUDE;
double interceptAltitude = cDEFAULT_ALTITUDE;
//check for targets altitude, and whether or not we should match it
if (targetTrack.ElevationValid() ||
targetTrack.LocationValid())
{
if (targetTrack.Altitude() > interceptAltitude) //always climb up to target
{
interceptAltitude = targetTrack.Altitude();
}
else if (MatchAltitudeForThreat(targetTrack) == true)
{
interceptAltitude = targetTrack.Altitude();
}
}
//always bound the altitude by the min & max restrictions (in case mover is not setup to do it)
if (interceptAltitude < mMinAltitude)
{
interceptAltitude = mMinAltitude;
}
writeln_d("desired intercept altitude: ", interceptAltitude);
mTargetSpeed = mInterceptSpeed;
if (targetTrack.VelocityValid())
{
if (targetTrack.AirDomain())
{
extern double EffectiveRange(WsfPlatform, WsfTrack);
double speedOfTarget = targetTrack.Speed();
double effRange = EffectiveRange(PLATFORM, targetTrack);
double distanceWindow = mMatchSpeedDistanceMax - mMatchSpeedDistanceMin;
double speedWindow = mInterceptSpeed - speedOfTarget;
if(effRange < mMatchSpeedDistanceMax && effRange > mMatchSpeedDistanceMin)
{
double rangeScale = (effRange - mMatchSpeedDistanceMin) / distanceWindow;
mTargetSpeed = speedOfTarget + (speedWindow * rangeScale);
writeln_d(PLATFORM.Name(), " pursue-target, speed scaled down in matching window!");
}
else if (effRange <= mMatchSpeedDistanceMin)
{
mTargetSpeed = speedOfTarget * 0.99;
writeln_d(PLATFORM.Name(), " pursue-target, speed set to match target!");
}
if (mTargetSpeed < mWaitSpeed)
{
mTargetSpeed = mWaitSpeed;
writeln_d(PLATFORM.Name(), " pursue-target, speed was lower than wait speed, adjust!");
}
}
else if (targetTrack.LandDomain())
{
writeln_d(PLATFORM.Name(), " pursue-target, target is land domain, adjust speed!");
double speedOfTarget = targetTrack.Speed();
double range = PLATFORM.GroundRangeTo(targetTrack);
double distanceWindow = mMatchSpeedDistanceMax - mMatchSpeedDistanceMin;
double speedWindow = mInterceptSpeed - speedOfTarget;
if(range < mMatchSpeedDistanceMax && range > mMatchSpeedDistanceMin)
{
double rangeScale = (range - mMatchSpeedDistanceMin) / distanceWindow;
mTargetSpeed = speedOfTarget + (speedWindow * rangeScale);
}
else if (range <= mMatchSpeedDistanceMin)
{
mTargetSpeed = speedOfTarget * 0.99;
}
if (mTargetSpeed < mWaitSpeed)
{
mTargetSpeed = mWaitSpeed;
}
}
}
double leadOrLagTime = 15.0; //seconds
if (PursuitMode == "lead")
{
WsfWaypoint wpt = WsfWaypoint();
double tti = PLATFORM.InterceptLocation3D(targetTrack, wpt);
if (tti > 0.0)
{
mTargetPoint = wpt.Location();
}
else
{
mTargetPoint = targetTrack.LocationAtTime(TIME_NOW + leadOrLagTime);
}
}
else if(PursuitMode == "lag")
{
double usedLagDelay = (slantRangeTo/engageRangeMax) * leadOrLagTime;
double maxLagDist = 0.35 * PLATFORM.SlantRangeTo(targetTrack);
double maxLagTime = maxLagDist / targetTrack.Speed();
if (usedLagDelay > maxLagTime)
{
usedLagDelay = maxLagTime;
}
mTargetPoint = targetTrack.LocationAtTime(TIME_NOW - usedLagDelay);
}
else if (PursuitMode == "f-pole")
{
extern double MaximizeFPole(WsfPlatform, WsfTrack, double);
interceptHeading = MaximizeFPole(PLATFORM, targetTrack, GetOffsetAngleOnThreat(targetTrack));
mTargetPoint = PLATFORM.Location();
mTargetPoint.Extrapolate(interceptHeading, DefaultOffsetDistance);
}
else
{
//PursuitMode == pure
mTargetPoint = targetTrack.LocationAtTime(TIME_NOW);
}
if (!mTargetPoint.IsValid())
{
mTargetPoint = targetTrack.CurrentLocation();
}
mTargetPoint.Set(mTargetPoint.Latitude(), mTargetPoint.Longitude(), interceptAltitude);
if (mDrawSteering == true)
{
mDraw.SetLayer("behavior_pursue_target");
mDraw.SetDuration(((WsfRIPRProcessor)PROCESSOR).UpdateInterval());
mDraw.SetColor(1.0, 0.5, 0.0);
mDraw.SetLineSize(1);
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(mTargetPoint);
mDraw.End();
}
string msg = write_str("pursue-target: ", targetTrack.TargetName(), " at speed ", (string)mTargetSpeed);
//PLATFORM.Comment(msg);
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
extern bool FlyTarget (WsfPlatform, WsfGeoPoint, double);
FlyTarget( PLATFORM, mTargetPoint, mTargetSpeed);
}
else
{
//go at default speed; this gets overwritten if route waypoint has defined a speed
PLATFORM.GoToSpeed(mInterceptSpeed, mDefaultAccel, true);
//return to route, at the last target route point as re-entry
extern bool ReEnterRoute(WsfPlatform);
ReEnterRoute(PLATFORM);
if (mDrawSteering == true)
{
WsfRoute currRoute = PLATFORM.Route();
if (currRoute.IsValid())
{
mDraw.SetLayer("behavior_pursue-target");
mDraw.Erase(PLATFORM.Name());
mDraw.SetId(PLATFORM.Name());
mDraw.SetColor(0,1,1);
mDraw.SetLineSize(1);
mDraw.SetLineStyle("dash_dot2");
mDraw.BeginPolyline();
for (int i=0; i<currRoute.Size(); i=i+1)
mDraw.Vertex(currRoute.Waypoint(i).Location());
mDraw.End();
}
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,627 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior pursue-target
script_debug_writes off
script_variables
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
bool mDrawSteering = false;
//**********************************************************************//
//** bidding parameters (pursue-target jobs) **//
//** slant range and closing speed are the most important **//
//** bids are now in units of distance (meters) **//
//** all other bid contributions are converted with their weight **//
//** range will dominate the bids **//
//**********************************************************************//
double cMIN_JOB_BID = -MATH.DOUBLE_MAX();
double cMAX_SLANT_RANGE = 1000000.0; #over 539 nm away, target ranges beyond this are considered unfavorable
double cWEIGHT_SLANT_RANGE_TO = 1.0;
double cMIN_CLOSING_SPEED = -1050.0; #threats running away (negative closing) faster are considered unfavorable
double cWEIGHT_CLOSING_SPEED = 1.0; #scale for how closing speed translates to distance
double cWEIGHT_FUEL = 0.0; #try a value of 2.0 if you care about fuel
double cWEIGHT_MY_WEAPONS_ACTIVE = 0.0; #changes bid if your own weapons are active on target
double cWEIGHT_PEERS_WEAPONS_ACTIVE = 0.0; #changes bid if your peers weapons are active on target
double cWEIGHT_THREAT_WEAPONS_ENVELOPE = 0.0; #uses the global "mWeaponsEnvelope" array, try value of 10000 if you care about that
//careful with these two parameters, they are stateful
double cWEIGHT_CURRENT_TARGET = 0.0; #changes bid if you are currently targeting the threat
double cWEIGHT_OTHERS_TARGETING = 0.0; #changes bid if peers are currently targeting the threat
//**********************************************************************//
//** control / mode of operation parameters **//
//**********************************************************************//
bool mFilterJobsOnWeapons = true; # ignore pursue-target jobs that we cant shoot a weapon at
bool mFilterJobsOnCategory = false; # ignore pursue-target jobs that are for platform of unknown category
bool mFilterJobsOnFuel = false; # ignore pursue-target jobs that we dont have the fuel to reach
bool mFilterJobsOnZone = false; # ignore pursue-target jobs that are for platforms outsize of zone "mZoneName"
string mZoneName = "";
WsfZone mFezZone;
bool mCheckOwnJobBoardToo = false; # can this agent bid on & win a job off his own board
bool mUseMoverDuringPursuit = true;
//**********************************************************************//
//** flying parameters, for intercept or approach **//
//**********************************************************************//
//target point to fly at
WsfGeoPoint mTargetPoint = WsfGeoPoint();
double mTargetSpeed = 0; # will be overwritten
// larger values, suggested for air to air fighters & jets
double mMatchSpeedDistanceMin = 1 * 1852; # 1 mile
double mMatchSpeedDistanceMax = 20 * 1852; # 20 miles
#double mWaitSpeed = 500 * MATH.MPS_PER_NMPH();
#double mInterceptSpeed = 800 * MATH.MPS_PER_NMPH();
#double mInterceptSpeed = 293.941; //mach 0.95 at 25200 ft altitude
double mWaitSpeed = 293.941; //mach 0.95 at 25200 ft altitude
double mInterceptSpeed = 600 * MATH.MPS_PER_NMPH();
double mDefaultAccel = 7.5 * Earth.ACCEL_OF_GRAVITY(); # m/s^2 ~7.5 Gs
// smaller values, suggest for a UAV intercepting or following ground forces
#double mMatchSpeedDistanceMin = 185.2; # one tenth of a mile
#double mMatchSpeedDistanceMax = 1852.0; # a mile
#double mWaitSpeed = 22; # m/s (~50 mph)
#double mInterceptSpeed = 52; # m/s (~100 knots)
double mMinAltitude = 4572; # ~15000 feet
//switch for matching threat's altitude during pursuit
bool DefaultMatchThreatAltitude = false;
Map<string, bool> mThreatTypeMatchAltitude = Map<string, bool>();
//mThreatTypeMatchAltitude["missile_fast"] = true;
//mThreatTypeMatchAltitude["awacs"] = true;
//mThreatTypeMatchAltitude["bomber"] = true;
//mThreatTypeMatchAltitude["fighter"] = true;
mThreatTypeMatchAltitude["unknown"] = false;
mThreatTypeMatchAltitude["uav"] = false;
mThreatTypeMatchAltitude["sam"] = false;
mThreatTypeMatchAltitude["ship"] = false;
mThreatTypeMatchAltitude["jammer"] = false;
mThreatTypeMatchAltitude["missile"] = false;
//specify offset angle to fly at, during f-pole pursuit
double DefaultOffsetDistance = 1852*50; //50 nm
double DefaultOffsetAngle = 30.0; // should this be radar-specific?
Map<string, double> ThreatTypeOffsetAngle = Map<string, double>();
//ThreatTypeOffsetAngle["awacs"] = 15.0;
//ThreatTypeOffsetAngle["unknown"] = 20.0;
//ThreatTypeOffsetAngle["sam"] = 50.0;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfRIPRJob mCurrentJob;
WsfDraw mDraw = WsfDraw();
string mOldTargetStr = "no target";
double mLastTime = 0.0;
end_script_variables
script bool HaveWeaponsForThreat(WsfTrack track)
extern bool IsWeaponDomainCapable(WsfTrack, Map<string, Object>);
extern Array<Map<string, Object>> mWeaponArray;
foreach (Map<string, Object> curWeapon in mWeaponArray)
{
WsfWeapon weapon = (WsfWeapon)curWeapon["weapon"];
if (weapon.QuantityRemaining() > 0 &&
IsWeaponDomainCapable(track,curWeapon))
{
if (curWeapon.Exists("onlyUseInRange") &&
(int)curWeapon["onlyUseInRange"] == 1 &&
PLATFORM.SlantRangeTo(track) > (double)curWeapon["rangeMax"] )
{
continue;
}
return true;
}
}
return false;
end_script
#
# query_bid_type pursue-target
#
# extern Map<string, double> ThreatTypePriority;
#
# extern WsfTrack GetTrackByName (WsfPlatform, string);
# extern bool HasEnoughFuelToTravel (WsfPlatform,double);
# extern string DetermineTrackCategory (WsfTrack);
# extern bool TestTrackCategory (WsfTrack, string);
# extern double GetWeaponsEnvelope (WsfPlatform);
# extern double GetWeaponRangeMax(WsfPlatform aPlatform, Array<Map<string, Object>> aWeaponArray);
# extern Array<Map<string, Object>> mWeaponArray;
#
# if (!JOB.IsValid())
# {
# writeln_d("query_bid_type pursue-target: JOB not valid");
# return cMIN_JOB_BID;
# }
#
# string targetTrackName = (string)JOB.GetData("targetTrackName");
# WsfTrack targetTrack = GetTrackByName(PLATFORM, targetTrackName);
# if (!targetTrack.IsValid())
# {
# writeln_d("!!! No track for JOB: ", JOB.Name(), ", ", JOB.GetDescription(), ", ", targetTrackName);
# return cMIN_JOB_BID;
# }
#
# double slantRangeTo = PLATFORM.SlantRangeTo(targetTrack);
# double closingSpeed = PLATFORM.ClosingSpeedOf(targetTrack);
# double maxWeaponRange = GetWeaponRangeMax(PLATFORM, mWeaponArray);
#
# if (mFilterJobsOnFuel == true)
# {
# if (!HasEnoughFuelToTravel(PLATFORM,slantRangeTo-maxWeaponRange))
# {
# writeln_d("!!! Not enough fuel for JOB: ", JOB.Name(), ", ", JOB.GetDescription(), ", ", targetTrackName);
# return cMIN_JOB_BID;
# }
# }
#
# if (mFilterJobsOnCategory == true)
# {
# if (TestTrackCategory(targetTrack, "unknown"))
# {
# writeln_d("!!! Target type unknown for current job. ");
# return cMIN_JOB_BID;
# }
# }
#
# if (mFilterJobsOnWeapons == true)
# {
# //check here if we have any weapons remaining that are capable against target domain
# if (!HaveWeaponsForThreat(targetTrack) &&
# PROCESSOR.WeaponsActive(targetTrack) <= 0)
# {
# writeln_d("!!! No domain capable weapons left for target!");
# return cMIN_JOB_BID;
# }
# }
#
# if (mFilterJobsOnZone == true)
# {
# if (mZoneName != "")
# {
# mFezZone = PLATFORM.Zone(mZoneName);
# if (!mFezZone.IsValid() || !mFezZone.PointIsInside(PLATFORM.Location()))
# {
# writeln_d("!!! Target outside of given FEZ!");
# return cMIN_JOB_BID;
# }
# }
# }
#
# double weight_closing_speed = cWEIGHT_CLOSING_SPEED;
# if (targetTrack.LandDomain())
# {
# weight_closing_speed = 2.0 * cWEIGHT_CLOSING_SPEED;
# }
#
# /////////////////////////////////////////////////////////////////////////
# // calculate bulk of the bid HERE
# double bid = 0.0;
# bid += cWEIGHT_SLANT_RANGE_TO * (cMAX_SLANT_RANGE - slantRangeTo);
# bid += weight_closing_speed * (-cMIN_CLOSING_SPEED + closingSpeed);
# // the bid has its major contributers now
# /////////////////////////////////////////////////////////////////////////
#
# //calculate other optional bid contributions here
# WsfFuel fuelObj = PLATFORM.Fuel();
# if (fuelObj.IsValid())
# {
# bid = bid + cWEIGHT_FUEL * fuelObj.QuantityRemaining();
# }
# //contribution if I have an active weapon on the target
# bid = bid + cWEIGHT_MY_WEAPONS_ACTIVE * PROCESSOR.WeaponsActive(targetTrack);
# //contribution if peers have an active weapon on the target
# bid = bid + cWEIGHT_PEERS_WEAPONS_ACTIVE * PROCESSOR.PeersWeaponsActive(targetTrack);
# //contribution if I am currently targeting the target
# if (PROCESSOR.GetTargetName() == targetTrackName)
# {
# bid = bid + cWEIGHT_CURRENT_TARGET;
# }
# //contribution if any peers are targeting the target
# WsfRIPRProcessor commander = PROCESSOR.GetRIPRCommanderProcessor();
# if (commander.IsValid())
# {
# bid = bid + cWEIGHT_OTHERS_TARGETING * commander.SubsTargeting(targetTrack, PLATFORM);
# }
# //contribution bonus if you care about weapon envelopes
# if (slantRangeTo < GetWeaponsEnvelope(targetTrack.Target()))
# {
# bid = bid + cWEIGHT_THREAT_WEAPONS_ENVELOPE;
# }
# //contribution bonus from threat type (category)
# string targetType = DetermineTrackCategory(targetTrack);
# if( ThreatTypePriority.Exists( targetType ) )
# {
# bid = bid + ThreatTypePriority.Get( targetType );
# }
#
# writeln_d(PLATFORM.Name(), " bid on target ", targetTrackName, ": ", bid);
# return bid;
# end_query_bid_type
script double GetOffsetAngleOnThreat(WsfTrack threat)
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : double angle in ThreatTypeOffsetAngle )
{
if( plat.CategoryMemberOf( aCategory ) )
{
writeln_d("offset angle for type ", aCategory, " = ", angle);
return angle;
}
}
}
return DefaultOffsetAngle;
end_script
script bool MatchAltitudeForThreat(WsfTrack track)
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid())
{
foreach (string aCategory : bool match in mThreatTypeMatchAltitude)
{
if (plat.CategoryMemberOf(aCategory))
{
return match;
}
}
}
return DefaultMatchThreatAltitude;
end_script
precondition
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
}
writeln_d(PLATFORM.Name(), " precondition pursue-target, T=", TIME_NOW);
((WsfRIPRProcessor)PROCESSOR).ClearTarget();
double duration = TIME_NOW - mLastTime;
mLastTime = TIME_NOW;
if (duration > (1.5*((WsfRIPRProcessor)PROCESSOR).UpdateInterval()))
{
mOldTargetStr = "no target";
}
string anOldTargetStr = mOldTargetStr;
mOldTargetStr = "no target";
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
if (commander.IsValid())
{
if (commander.IsJobWindowOpen())
{
writeln_d("pursue-target: commander.GetJobFor()");
mCurrentJob = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
}
else
{
writeln_d("pursue-target: commander's job window closed, keeping current job!");
}
}
if (mCheckOwnJobBoardToo &&
(mCurrentJob.IsNull() || !mCurrentJob.IsValid()))
{
writeln_d("pursue-target: myself.GetJobFor()");
mCurrentJob = ((WsfRIPRProcessor)PROCESSOR).GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
}
if (mCurrentJob.IsNull() || !mCurrentJob.IsValid() )
{
writeln_d("pursue-target ClearTarget -> job not a valid pursue-target job");
return Failure("job is not a valid pursue-target job");
}
if (mCurrentJob.Name() != "pursue-target")
{
string msg = write_str("job is a ", mCurrentJob.Name(), " instead of a pursue-target job");
writeln_d(msg);
return Failure("job is not a pursue-target job");
}
extern WsfTrack GetTrackByName (WsfPlatform, string);
string targetName = (string)mCurrentJob.GetData("targetTrackName");
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (!targetTrack.IsValid())
{
writeln_d(" No valid target track found for target named ", targetName);
return Failure("target track not found");
}
########################################################################
### print output / comments for any target change
#######################################################################
mOldTargetStr = "Job: " + mCurrentJob.Name() + ", " + mCurrentJob.GetDescription();
writeln_d(" - ", mOldTargetStr);
if (mOldTargetStr != anOldTargetStr)
{
PLATFORM.Comment(mOldTargetStr);
}
((WsfRIPRProcessor)PROCESSOR).SetTarget(targetTrack);
return true;
end_precondition
execute
string comment = write_str(PLATFORM.Name(), " executing pursue-target, T=", TIME_NOW);
writeln_d(comment);
#PLATFORM.Comment(comment);
extern string CalculatePositioning (WsfPlatform, WsfTrack, double);
extern double GetWeaponRangeMax(WsfPlatform aPlatform, Array<Map<string, Object>> aWeaponArray);
extern Array<Map<string, Object>> mWeaponArray;
//get target from ripr processor, to be sure
WsfTrack targetTrack = ((WsfRIPRProcessor)PROCESSOR).GetTarget();
if (targetTrack.IsNull() ||
!targetTrack.IsValid())
{
writeln_d(" UpdateInterceptLocation, targetTrack is null or not valid");
return;
}
if (mUseMoverDuringPursuit)
{
double ownSpeed = PLATFORM.Speed();
double targetSpeed = targetTrack.Speed();
double slantRangeTo = PLATFORM.SlantRangeTo(targetTrack);
double closingSpeed = PLATFORM.ClosingSpeedOf(targetTrack);
string positioning = CalculatePositioning(PLATFORM, targetTrack, 10.0);
int weaponsActive = ((WsfRIPRProcessor)PROCESSOR).WeaponsActive(targetTrack);
double engageRangeMax = 185200.0; //100 miles
double engageRangeMin = 1852.0; // 1 mile
# // determine the fuel needed to engage
# double fuelRequired = 0;
# double bingoQuantity = -1;
# if (mConsiderFuel)
# {
# WsfFuel fuelObj = PLATFORM.Fuel();
# if (fuelObj)
# {
# double maxWeaponRange = GetWeaponRangeMax(PLATFORM, mWeaponArray);
# double distToWeaponRange = slantRangeTo - maxWeaponRange;
# double timeToTarget = distToWeaponRange / closingSpeed;
# double distToTravel = timeToTarget * ownSpeed;
#
# fuelRequired = fuelObj.QuantityRequired(distToTravel);
# bingoQuantity = fuelObj.BingoQuantity();
# }
# }
string PursuitMode = "pure";
if (weaponsActive > 0)
{
PursuitMode = "f-pole";
}
else if (targetTrack.AirDomain())
{
if (slantRangeTo >= engageRangeMax &&
positioning != "head-to-head" &&
positioning != "head-to-tail" &&
targetSpeed >= ownSpeed)
{
PursuitMode = "lead";
}
else if (slantRangeTo <= engageRangeMax &&
positioning != "head-to-head" &&
positioning != "head-to-tail")
{
PursuitMode = "lag";
}
//else if (slantRangeTo > engageRangeMax ||
// (slantRangeTo <= engageRangeMax &&
// (positioning == "head-to-head" ||
// positioning == "head-to-tail")))
//{
// PursuitMode = "pure";
//}
}
writeln_d(" PursuitMode = ", PursuitMode);
// Our track quality (or target range) may not be good enough yet, so keep moving towards the target.
// If we got the altitude from the TRACK, match it
double interceptHeading = PLATFORM.Heading();
double distanceToTarget = PLATFORM.SlantRangeTo(targetTrack);
extern double cDEFAULT_ALTITUDE;
double interceptAltitude = cDEFAULT_ALTITUDE;
//check for targets altitude, and whether or not we should match it
if (targetTrack.ElevationValid() ||
targetTrack.LocationValid())
{
if (targetTrack.Altitude() > interceptAltitude) //always climb up to target
{
interceptAltitude = targetTrack.Altitude();
}
else if (MatchAltitudeForThreat(targetTrack) == true)
{
interceptAltitude = targetTrack.Altitude();
}
}
//always bound the altitude by the min & max restrictions (in case mover is not setup to do it)
if (interceptAltitude < mMinAltitude)
{
interceptAltitude = mMinAltitude;
}
writeln_d("desired intercept altitude: ", interceptAltitude);
mTargetSpeed = mInterceptSpeed;
if (targetTrack.VelocityValid())
{
if (targetTrack.AirDomain())
{
extern double EffectiveRange(WsfPlatform, WsfTrack);
double speedOfTarget = targetTrack.Speed();
double effRange = EffectiveRange(PLATFORM, targetTrack);
double distanceWindow = mMatchSpeedDistanceMax - mMatchSpeedDistanceMin;
double speedWindow = mInterceptSpeed - speedOfTarget;
if(effRange < mMatchSpeedDistanceMax && effRange > mMatchSpeedDistanceMin)
{
double rangeScale = (effRange - mMatchSpeedDistanceMin) / distanceWindow;
mTargetSpeed = speedOfTarget + (speedWindow * rangeScale);
writeln_d(PLATFORM.Name(), " pursue-target, speed scaled down in matching window!");
}
else if (effRange <= mMatchSpeedDistanceMin)
{
mTargetSpeed = speedOfTarget * 0.99;
writeln_d(PLATFORM.Name(), " pursue-target, speed set to match target!");
}
if (mTargetSpeed < mWaitSpeed)
{
mTargetSpeed = mWaitSpeed;
writeln_d(PLATFORM.Name(), " pursue-target, speed was lower than wait speed, adjust!");
}
}
else if (targetTrack.LandDomain())
{
writeln_d(PLATFORM.Name(), " pursue-target, target is land domain, adjust speed!");
double speedOfTarget = targetTrack.Speed();
double range = PLATFORM.GroundRangeTo(targetTrack);
double distanceWindow = mMatchSpeedDistanceMax - mMatchSpeedDistanceMin;
double speedWindow = mInterceptSpeed - speedOfTarget;
if(range < mMatchSpeedDistanceMax && range > mMatchSpeedDistanceMin)
{
double rangeScale = (range - mMatchSpeedDistanceMin) / distanceWindow;
mTargetSpeed = speedOfTarget + (speedWindow * rangeScale);
}
else if (range <= mMatchSpeedDistanceMin)
{
mTargetSpeed = speedOfTarget * 0.99;
}
if (mTargetSpeed < mWaitSpeed)
{
mTargetSpeed = mWaitSpeed;
}
}
}
double leadOrLagTime = 15.0; //seconds
if (PursuitMode == "lead")
{
WsfWaypoint wpt = WsfWaypoint();
double tti = PLATFORM.InterceptLocation3D(targetTrack, wpt);
if (tti > 0.0)
{
mTargetPoint = wpt.Location();
}
else
{
mTargetPoint = targetTrack.LocationAtTime(TIME_NOW + leadOrLagTime);
}
}
else if(PursuitMode == "lag")
{
double usedLagDelay = (slantRangeTo/engageRangeMax) * leadOrLagTime;
double maxLagDist = 0.35 * PLATFORM.SlantRangeTo(targetTrack);
double maxLagTime = maxLagDist / targetTrack.Speed();
if (usedLagDelay > maxLagTime)
{
usedLagDelay = maxLagTime;
}
mTargetPoint = targetTrack.LocationAtTime(TIME_NOW - usedLagDelay);
}
else if (PursuitMode == "f-pole")
{
extern double MaximizeFPole(WsfPlatform, WsfTrack, double);
interceptHeading = MaximizeFPole(PLATFORM, targetTrack, GetOffsetAngleOnThreat(targetTrack));
mTargetPoint = PLATFORM.Location();
mTargetPoint.Extrapolate(interceptHeading, DefaultOffsetDistance);
}
else
{
//PursuitMode == pure
mTargetPoint = targetTrack.LocationAtTime(TIME_NOW);
}
if (!mTargetPoint.IsValid())
{
mTargetPoint = targetTrack.CurrentLocation();
}
mTargetPoint.Set(mTargetPoint.Latitude(), mTargetPoint.Longitude(), interceptAltitude);
if (mDrawSteering == true)
{
mDraw.SetLayer("behavior_pursue_target");
mDraw.SetDuration(((WsfRIPRProcessor)PROCESSOR).UpdateInterval());
mDraw.SetColor(1.0, 0.5, 0.0);
mDraw.SetLineSize(1);
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(mTargetPoint);
mDraw.End();
}
string msg = write_str("pursue-target: ", targetTrack.TargetName(), " at speed ", (string)mTargetSpeed);
//PLATFORM.Comment(msg);
writeln_d(" T=", TIME_NOW, " ", PLATFORM.Name(), " ", msg);
extern bool FlyTarget (WsfPlatform, WsfGeoPoint, double);
FlyTarget( PLATFORM, mTargetPoint, mTargetSpeed);
}
else
{
//go at default speed; this gets overwritten if route waypoint has defined a speed
PLATFORM.GoToSpeed(mInterceptSpeed, mDefaultAccel, true);
//return to route, at the last target route point as re-entry
extern bool ReEnterRoute(WsfPlatform);
ReEnterRoute(PLATFORM);
if (mDrawSteering == true)
{
WsfRoute currRoute = PLATFORM.Route();
if (currRoute.IsValid())
{
mDraw.SetLayer("behavior_pursue-target");
mDraw.Erase(PLATFORM.Name());
mDraw.SetId(PLATFORM.Name());
mDraw.SetColor(0,1,1);
mDraw.SetLineSize(1);
mDraw.SetLineStyle("dash_dot2");
mDraw.BeginPolyline();
for (int i=0; i<currRoute.Size(); i=i+1)
mDraw.Vertex(currRoute.Waypoint(i).Location());
mDraw.End();
}
}
}
end_execute
end_behavior

View File

@@ -0,0 +1,290 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
//pursue-target_pathing
behavior pursue-target_pathing
script_variables
double cBUCKET_BASE = 1.2;
double cINTERCEPT_SPEED = 1000; # m/s
double cWAIT_SPEED = 200; # m/s
double ownshipEngagementRangeMin = 0; // set later GetWeaponRangeMin(PLATFORM, mWeaponArray);
double ownshipEngagementRangeMax = 0; // set later GetWeaponRangeMax(PLATFORM, mWeaponArray);
#bool mUseMoverDuringPursuit = true; #set to false to force aiai to follow route during pursuit of target
//use this offset angle if a category specific offset isn't found
double mFPoleAngle = 45.0; // this should be radar-specific
//fly different offset angles, depending on the type or category of threat
Map<string, double> ThreatTypeOffsetAngle = Map<string, double>();
ThreatTypeOffsetAngle["unknown"] = 45.0;
ThreatTypeOffsetAngle["sam"] = 50.0;
ThreatTypeOffsetAngle["awacs"] = 15.0;
ThreatTypeOffsetAngle["fighter"] = 35.0;
end_script_variables
precondition
writeln("precondition pursue-target_pathing");
extern WsfTrack GetTrackByName (WsfPlatform, string);
extern bool TestTrackCategory (WsfTrack, string);
if (!PLATFORM.GetPathFinder().IsValid())
{
writeln("no path-finder available");
return false;
}
// Clear the variables we'll use to store the agent's output
PROCESSOR.ClearTarget();
WsfRIPRJob currentJob = null;
if (PROCESSOR.GetRIPRCommanderProcessor().IsValid())
{
currentJob = PROCESSOR.GetRIPRCommanderProcessor().GetJobFor(TIME_NOW, PROCESSOR);
}
if (!currentJob.IsValid() || currentJob.Name() != "pursue-target")
{
writeln_d(" job not valid pursue-target job from board!");
return false;
}
string targetName = (string)currentJob.GetData("targetTrackName");
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (!targetTrack.IsValid() || TestTrackCategory(targetTrack, "unknown"))
{
writeln_d(" No known category track found for target ", targetName);
return false;
}
PROCESSOR.SetTarget(targetTrack);
return true;
end_precondition
on_init
extern double GetWeaponRangeMax (WsfPlatform, Array<Map<string, Object>>);
extern double GetWeaponRangeMin (WsfPlatform, Array<Map<string, Object>>);
extern Array<Map<string, Object>> mWeaponArray;
ownshipEngagementRangeMin = GetWeaponRangeMin(PLATFORM, mWeaponArray);
ownshipEngagementRangeMax = GetWeaponRangeMax(PLATFORM, mWeaponArray);
end_on_init
script double GetOffsetAngleOnThreat(WsfTrack threat)
WsfPlatform plat = WsfSimulation.FindPlatform( threat.TargetName() );
if (plat.IsValid())
{
foreach( string aCategory : double angle in ThreatTypeOffsetAngle )
{
if( plat.CategoryMemberOf( aCategory ) )
{
writeln_d("offset angle for type ", aCategory, " = ", angle);
return angle;
}
}
}
return mFPoleAngle;
end_script
execute
writeln("executing pursue-target_pathing.");
extern int GetBucket (double, double);
extern string CalculatePositioning (WsfPlatform, WsfTrack, double);
//get target from ripr processor, to be sure
WsfTrack targetTrack = PROCESSOR.GetTarget();
double ownSpeed = GetBucket(PLATFORM.Speed(), cBUCKET_BASE);
double engageRangeMin = GetBucket(ownshipEngagementRangeMin, cBUCKET_BASE);
double engageRangeMax = GetBucket(ownshipEngagementRangeMax, cBUCKET_BASE);
double slantRangeTo = GetBucket(PLATFORM.SlantRangeTo(targetTrack), cBUCKET_BASE);
double targetSpeed = GetBucket(targetTrack.Speed(), cBUCKET_BASE);
string positioning = CalculatePositioning(PLATFORM, targetTrack, GetOffsetAngleOnThreat(targetTrack));
int weaponsActive = PROCESSOR.WeaponsActive(targetTrack);
string mPursuitMode = "pure";
if (weaponsActive > 0)
{
mPursuitMode = "f-pole";
}
else if (targetTrack.AirDomain())
{
if (slantRangeTo >= engageRangeMax &&
positioning != "head-to-head" &&
positioning != "head-to-tail" &&
targetSpeed >= ownSpeed)
{
mPursuitMode = "lead";
}
else if (slantRangeTo <= engageRangeMax &&
positioning != "head-to-head" &&
positioning != "head-to-tail")
{
mPursuitMode = "lag";
}
else if (slantRangeTo > engageRangeMax ||
(slantRangeTo <= engageRangeMax &&
(positioning == "head-to-head" ||
positioning == "head-to-tail")))
{
mPursuitMode = "pure";
}
}
#TransitionToINTERCEPT( targetTrack, mPursuitMode );
#PLATFORM.GoToSpeed(cINTERCEPT_SPEED);
#if (mUseMoverDuringPursuit)
#{
# #nothing
# PLATFORM.GoToAltitude(cDEFAULT_ALTITUDE, 200);
#}
#else
#{
# #TransitionToWAIT(true); #FAIL
# #PLATFORM.FollowRoute("DEFAULT_ROUTE", "CLOSEST_POINT"); #better
# PLATFORM.ReturnToRoute();
# PLATFORM.GoToAltitude(cDEFAULT_ALTITUDE, 200, true);
#}
#PROCESSOR.SetUpdateInterval(cFAST_UPDATE_RATE);
#writeln_d(" Transition to INTERCEPT due to pursuing ", targetTrack.TargetName(), " mode ", mPursuitMode);
#end_script
#CheckAndFire(targetTrack); #do this in the weapon management behavior???
// Our track quality (or target range) may not be good enough yet, so keep moving towards the target.
if (targetTrack.IsNull())
{
writeln_d("behavior pursue-target_pathing, targetTrack is null");
return;
}
writeln_d(" ", mPursuitMode, " pursuit");
// If we got the altitude from the TRACK, match it
extern double cDEFAULT_ALTITUDE;
double interceptAltitude = cDEFAULT_ALTITUDE;
//double interceptAltitude = PLATFORM.Altitude();
double interceptHeading = PLATFORM.Heading();
double distanceToTarget = PLATFORM.SlantRangeTo(targetTrack);
bool useIntercept = false;
double desiredSpeed = cINTERCEPT_SPEED;
if (targetTrack.VelocityValid() && targetTrack.AirDomain())
{
extern double EffectiveRange(WsfPlatform, WsfTrack);
extern double GetWeaponRangeMax (WsfPlatform, Array<Map<string, Object>>);
extern double GetWeaponRangeMin (WsfPlatform, Array<Map<string, Object>>);
double rangeMin = GetWeaponRangeMin(PLATFORM, mWeaponArray);
double rangeMax = GetWeaponRangeMax(PLATFORM, mWeaponArray);
double speedOfTarget = targetTrack.Speed();
double effRange = EffectiveRange(PLATFORM, targetTrack);
double missileWindow = rangeMax - rangeMin;
double speedWindow = cINTERCEPT_SPEED - speedOfTarget;
if(effRange < rangeMax && effRange > rangeMin)
{
double rangeScale = (effRange - rangeMin) / missileWindow;
desiredSpeed = speedOfTarget + (speedWindow * rangeScale);
}
else if (effRange <= rangeMin)
{
desiredSpeed = speedOfTarget;
}
if (desiredSpeed < cWAIT_SPEED)
{
desiredSpeed = cWAIT_SPEED;
}
}
PLATFORM.GoToSpeed(desiredSpeed);
WsfGeoPoint startGeoPoint = PLATFORM.Location();
WsfGeoPoint endGeoPoint = targetTrack.ReportedLocation();
if (mPursuitMode == "lead")
{
double timeToIntercept = 0.0;
WsfWaypoint interceptPoint = WsfWaypoint();
timeToIntercept = PLATFORM.InterceptLocation3D(targetTrack, interceptPoint);
// If timeToIntercept is positive then we know intercept is possible
if (timeToIntercept > 0.0)
{
endGeoPoint = targetTrack.ReportedLocation();
#writeln_d(" T=", TIME_NOW, " TTI=", timeToIntercept, " range: ", PLATFORM.SlantRangeTo(targetTrack), " true-bearing: ", interceptPoint.Heading());
#writeln_d(" lead pursuit: ", interceptPoint.Latitude(), ", ", interceptPoint.Longitude(), ", ", interceptPoint.Altitude());
}
else
{
writeln_d(" lead pursuit attempt with timeToIntercept < 0");
}
}
else if (mPursuitMode == "f-pole")
{
extern double MaximizeFPole(WsfPlatform, WsfTrack, double);
interceptHeading = MaximizeFPole(PLATFORM, targetTrack, GetOffsetAngleOnThreat(targetTrack));
endGeoPoint = PLATFORM.Location();
//f-pole towards a point 30 miles away in the correct direction
endGeoPoint.Extrapolate(interceptHeading, 55560);
#writeln_d(" T=", TIME_NOW, ", range: ", PLATFORM.SlantRangeTo(targetTrack), " true-bearing: ", PLATFORM.TrueBearingTo(targetTrack));
}
else
{
//otherwise... just fly at the target
endGeoPoint = targetTrack.ReportedLocation();
#writeln_d(" T=", TIME_NOW, ", range: ", PLATFORM.SlantRangeTo(targetTrack), " true-bearing: ", PLATFORM.TrueBearingTo(targetTrack),
# " (", endGeoPoint.Latitude(), "/", targetTrack.Latitude(), ",", endGeoPoint.Longitude(), "/", targetTrack.Longitude(), ")");
}
//make sure we don't dive, staying above the target is fine
if (endGeoPoint.Altitude() < interceptAltitude)
{
endGeoPoint.Set(endGeoPoint.Latitude(), endGeoPoint.Longitude(), interceptAltitude);
}
if (!PLATFORM.FindAndSetPath(startGeoPoint, endGeoPoint))
{
PLATFORM.FollowRoute("DEFAULT_ROUTE","CLOSEST_POINT");
#PLATFORM.Comment("Route: DEFAULT");
}
end_execute
end_behavior

View File

@@ -0,0 +1,105 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
behavior pursue_altitude
script_debug_writes off
script_variables
WsfTrack mTargetTrack;
double mMinAltitude = 4572; # ~15000 feet
//switch for matching threat's altitude during pursuit
bool DefaultMatchThreatAltitude = false;
Map<string, bool> mThreatTypeMatchAltitude = Map<string, bool>();
mThreatTypeMatchAltitude["unknown"] = false;
mThreatTypeMatchAltitude["uav"] = false;
mThreatTypeMatchAltitude["sam"] = false;
mThreatTypeMatchAltitude["ship"] = false;
mThreatTypeMatchAltitude["jammer"] = false;
mThreatTypeMatchAltitude["missile"] = false;
//mThreatTypeMatchAltitude["missile_fast"] = true;
//mThreatTypeMatchAltitude["awacs"] = true;
//mThreatTypeMatchAltitude["bomber"] = true;
//mThreatTypeMatchAltitude["fighter"] = true;
end_script_variables
script bool MatchAltitudeForThreat(WsfTrack track)
WsfPlatform plat = WsfSimulation.FindPlatform( track.TargetName() );
if (plat.IsValid())
{
foreach (string aCategory : bool match in mThreatTypeMatchAltitude)
{
if (plat.CategoryMemberOf(aCategory))
{
return match;
}
}
}
return DefaultMatchThreatAltitude;
end_script
precondition
writeln_d(PLATFORM.Name(), " precondition pursue_altitude, T=", TIME_NOW);
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
} // ((WsfRIPRProcessor)PROCESSOR)
//get target from ripr processor, to be sure
mTargetTrack = ((WsfRIPRProcessor)PROCESSOR).GetTarget();
if (mTargetTrack.IsNull() || !mTargetTrack.IsValid())
{
writeln_d(" No valid target track found to pursue!");
return Failure("target track not found");
}
return true;
end_precondition
execute
string comment = write_str(PLATFORM.Name(), " executing pursue_altitude, T=", TIME_NOW);
writeln_d(comment);
#PLATFORM.Comment(comment);
extern double mDesiredAltitude;
// If we got the altitude from the TRACK, match it
extern double cDEFAULT_ALTITUDE;
mDesiredAltitude = cDEFAULT_ALTITUDE;
//check for targets altitude, and whether or not we should match it
if (mTargetTrack.ElevationValid() ||
mTargetTrack.LocationValid())
{
if (mTargetTrack.Altitude() > mDesiredAltitude) //always climb up to target
{
mDesiredAltitude = mTargetTrack.Altitude();
}
else if (MatchAltitudeForThreat(mTargetTrack) == true) //just useful for diving down to threat lower level
{
mDesiredAltitude = mTargetTrack.Altitude();
}
}
//always bound the altitude by the min & max restrictions (in case mover is not setup to do it)
if (mDesiredAltitude < mMinAltitude)
{
mDesiredAltitude = mMinAltitude;
}
writeln_d("desired intercept altitude: ", mDesiredAltitude);
end_execute
end_behavior

View File

@@ -0,0 +1,232 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
##
## purse_base, aggregate behavior
## this behavior owns the bidding block for pursue-target jobs and acquires the target
## this behavior owns the [main] precondition block for this set of behaviors
## this behavior owns the variables for heading, alt, speed, but child behaviors calculate them
## last child behavior should actually do the flying
##
include_once behavior_pursue_heading.txt //original ripr intercept logic
#include_once behavior_pursue_heading_smooth.txt //option: smooth turning intercept
include_once behavior_pursue_altitude.txt
include_once behavior_pursue_speed.txt
include_once behavior_pursue_fly_simple.txt //original ripr flight command
#include_once behavior_pursue_fly_route_finder.txt //option: fly around avoidances using WsfRouteFinder
behavior pursue_base
script_debug_writes off
script_variables
//**********************************************************************//
//** aggregate parameters (modifeid by or used by child behaviors) **//
//**********************************************************************//
//these three are modified by child behaviors, not edited here
double mDesiredHeading;
double mDesiredAltitude;
double mDesiredSpeed;
//user can edit these three
double mDesiredLinearAccel = 7.5 * Earth.ACCEL_OF_GRAVITY(); // 7.5 G (m/s^2)
double mDesiredRadialAccel = 6.0 * Earth.ACCEL_OF_GRAVITY(); // 6.0 G (m/s^2) //default max limit for air mover
double mDesiredClimbDiveAngle = 35; //(degrees) //should this be climb/dive rate instead of angle?
//**********************************************************************//
//** bidding parameters (pursue-target jobs) **//
//** slant range and closing speed are the most important **//
//** bids are now in units of distance (meters) **//
//** all other bid contributions are converted with their weight **//
//** range will dominate the bids **//
//**********************************************************************//
double cMIN_JOB_BID = -MATH.DOUBLE_MAX();
double cMAX_SLANT_RANGE = 1000000.0; #over 539 nm away, target ranges beyond this are considered unfavorable
double cWEIGHT_SLANT_RANGE_TO = 1.0;
double cMIN_CLOSING_SPEED = -1050.0; #threats running away (negative closing) faster are considered unfavorable
double cWEIGHT_CLOSING_SPEED = 1.0; #scale for how closing speed translates to distance
double cWEIGHT_FUEL = 0.0; #try a value of 2.0 if you care about fuel
double cWEIGHT_MY_WEAPONS_ACTIVE = 0.0; #changes bid if your own weapons are active on target
double cWEIGHT_PEERS_WEAPONS_ACTIVE = 0.0; #changes bid if your peers weapons are active on target
double cWEIGHT_THREAT_WEAPONS_ENVELOPE = 0.0; #uses the global "mWeaponsEnvelope" array, try value of 10000 if you care about that
//careful with these two parameters, they are stateful
double cWEIGHT_CURRENT_TARGET = 0.0; #changes bid if you are currently targeting the threat
double cWEIGHT_OTHERS_TARGETING = 0.0; #changes bid if peers are currently targeting the threat
//**********************************************************************//
//** control / mode of operation parameters **//
//**********************************************************************//
#bool mFilterJobsOnWeapons = true; # ignore pursue-target jobs that we cant shoot a weapon at
bool mFilterJobsOnWeapons = false; # ignore pursue-target jobs that we cant shoot a weapon at
bool mFilterJobsOnCategory = false; # ignore pursue-target jobs that are for platform of unknown category
bool mFilterJobsOnFuel = false; # ignore pursue-target jobs that we dont have the fuel to reach
bool mFilterJobsOnZone = false; # ignore pursue-target jobs that are for platforms outsize of zone "mZoneName"
string mZoneName = "";
WsfZone mFezZone;
bool mCheckOwnJobBoardToo = false; # can this agent bid on & win a job off his own board
//**********************************************************************//
//** debugging parameters **//
//**********************************************************************//
#bool mDrawSteering = false;
//**********************************************************************//
//********* VARIABLES BELOW THIS LINE ARE NOT FOR USER EDITING *********//
//**********************************************************************//
WsfRIPRJob mCurrentJob;
#WsfDraw mDraw = WsfDraw();
string mOldTargetStr = "no target";
double mLastTime = 0.0;
end_script_variables
script bool HaveWeaponsForThreat(WsfTrack track)
extern bool IsWeaponDomainCapable(WsfTrack, Map<string, Object>);
extern Array<Map<string, Object>> mWeaponArray;
foreach (Map<string, Object> curWeapon in mWeaponArray)
{
WsfWeapon weapon = (WsfWeapon)curWeapon["weapon"];
if (weapon.QuantityRemaining() > 0 &&
IsWeaponDomainCapable(track,curWeapon))
{
if (curWeapon.Exists("onlyUseInRange") &&
(int)curWeapon["onlyUseInRange"] == 1 &&
PLATFORM.SlantRangeTo(track) > (double)curWeapon["rangeMax"] )
{
continue;
}
return true;
}
}
return false;
end_script
precondition
writeln_d(PLATFORM.Name(), " precondition pursue-target, T=", TIME_NOW);
if (!PROCESSOR.IsA_TypeOf("WSF_RIPR_PROCESSOR"))
{
return Failure("behavior not attached to a RIPR processor!");
} // ((WsfRIPRProcessor)PROCESSOR)
double duration = TIME_NOW - mLastTime;
mLastTime = TIME_NOW;
if (duration > (1.5*PROCESSOR.UpdateInterval()))
{
mOldTargetStr = "no target";
}
string anOldTargetStr = mOldTargetStr;
mOldTargetStr = "no target";
WsfRIPRProcessor commander = ((WsfRIPRProcessor)PROCESSOR).GetRIPRCommanderProcessor();
if (commander.IsValid())
{
if (commander.IsJobWindowOpen())
{
writeln_d("pursue-target: commander.GetJobFor()");
mCurrentJob = commander.GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
}
else
{
writeln_d("pursue-target: commander's job window closed, keeping current job!");
}
}
if (mCheckOwnJobBoardToo &&
(mCurrentJob.IsNull() || !mCurrentJob.IsValid()))
{
writeln_d("pursue-target: myself.GetJobFor()");
mCurrentJob = ((WsfRIPRProcessor)PROCESSOR).GetJobFor(TIME_NOW, ((WsfRIPRProcessor)PROCESSOR));
}
if (mCurrentJob.IsNull() || !mCurrentJob.IsValid() )
{
writeln_d("pursue-target ClearTarget -> job not a valid pursue-target job");
((WsfRIPRProcessor)PROCESSOR).ClearTarget();
return Failure("job is not a valid pursue-target job");
}
if (mCurrentJob.Name() != "pursue-target")
{
string msg = write_str("job is a ", mCurrentJob.Name(), " instead of a pursue-target job");
writeln_d(msg);
return Failure("job is not a pursue-target job");
}
extern WsfTrack GetTrackByName (WsfPlatform, string);
string targetName = (string)mCurrentJob.GetData("targetTrackName");
WsfTrack targetTrack = GetTrackByName(PLATFORM, targetName);
if (!targetTrack.IsValid())
{
writeln_d(" No valid target track found for target named ", targetName);
return Failure("target track not found");
}
########################################################################
### print output / comments for any target change
#######################################################################
mOldTargetStr = "Job: " + mCurrentJob.Name() + ", " + mCurrentJob.GetDescription();
writeln_d(" - ", mOldTargetStr);
if (mOldTargetStr != anOldTargetStr)
{
PLATFORM.Comment(mOldTargetStr);
}
((WsfRIPRProcessor)PROCESSOR).SetTarget(targetTrack);
return true;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing pursue_base, T=", TIME_NOW);
# if (mDrawSteering == true)
# {
# mDraw.SetLayer("behavior_pursue_target");
# mDraw.SetDuration(PROCESSOR.UpdateInterval());
# mDraw.SetColor(1.0, 0.5, 0.0);
# mDraw.SetLineSize(1);
# mDraw.BeginLines();
# mDraw.Vertex(PLATFORM.Location());
# mDraw.Vertex(mTargetPoint);
# mDraw.End();
# }
end_execute
parallel
precondition
WsfTrack target = ((WsfRIPRProcessor)PROCESSOR).GetTarget();
if (target.IsNull() || !target.IsValid()) {
return Failure("target track not found");
}
if (!target.AirDomain()) {
#writeln("track is not for an air-domain target");
return Failure("track is not for an air-domain target");
}
return true;
end_precondition
behavior_node pursue_heading
behavior_node pursue_altitude
behavior_node pursue_speed
behavior_node pursue_fly_simple
end_parallel
end_behavior

View File

@@ -0,0 +1,185 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
# THIS BEHAVIOR ASSUMES THE FOLLOWING VARIABLES EXIST AND ARE SET
# extern double mDesiredHeading;
# extern double mDesiredAltitude;
# extern double mDesiredSpeed;
behavior pursue_fly_route_finder
script_debug_writes off
script_variables
//expected global externs
#extern Array<WsfGeoPoint> gAvoidPoints;
#extern Array<double> gAvoidRadii;
WsfRouteFinder mRouteFinder = WsfRouteFinder();
bool mDebugDraw = true;
WsfGeoPoint mTargetPoint;
WsfDraw mDraw = WsfDraw();
bool mIgnoreHeadingFindMyOwn = false; // if true: find own heading towards target track
bool mUseGlobalAvoids = false; //true: use extern gAvoidPoints and gAvoidRadii
//false: use these two arrays below
Array<WsfGeoPoint> mAvoidPoints = Array<WsfGeoPoint>();
Array<double> mAvoidRadii = Array<double>();
end_script_variables
on_init
mDraw.SetLayer("pursue-target_route_finder");
mDraw.SetLineSize(1);
#mRouteFinder.SetImpossibleRouteResponse(2); //shift starting or ending point outside of any avoidances (dont shrink the avoidance regions)
if (mUseGlobalAvoids == true)
{
extern Array<WsfGeoPoint> gAvoidPoints;
extern Array<double> gAvoidRadii;
for (int i=0; i < gAvoidPoints.Size() && i < gAvoidRadii.Size(); i=i+1)
{
WsfGeoPoint pt = gAvoidPoints[i];
double radius = gAvoidRadii[i];
writeln_d(PLATFORM.Name(), " avoiding: ", pt.ToString(), ", at radius: ", radius);
mRouteFinder.Avoid(pt, radius);
}
}
else
{
for (int i=0; i < mAvoidPoints.Size() && i < mAvoidRadii.Size(); i=i+1)
{
WsfGeoPoint pt = mAvoidPoints[i];
double radius = mAvoidRadii[i];
writeln_d(PLATFORM.Name(), " avoiding: ", pt.ToString(), ", at radius: ", radius);
mRouteFinder.Avoid(pt, radius);
}
}
end_on_init
precondition
writeln_d(PLATFORM.Name(), " precondition pursue_fly_route_finder, T=", TIME_NOW);
if (mIgnoreHeadingFindMyOwn == true)
{
WsfTrack targetTrack = PROCESSOR.GetTarget();
if (targetTrack.IsNull() || !targetTrack.IsValid())
{
writeln_d(" No valid target track found to pursue!");
return Failure("target track not found");
}
mTargetPoint = targetTrack.CurrentLocation();
}
else
{
//extrapolate desired heading foward far enough to account for our speed & turning ability
extern double mDesiredHeading;
double dist = 1852*10; //calculate based on speed & turning
mTargetPoint = PLATFORM.Location();
mTargetPoint.Extrapolate(mDesiredHeading, dist);
}
return true;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing pursue_fly_route_finder, T=", TIME_NOW);
extern double mDesiredHeading;
extern double mDesiredAltitude;
extern double mDesiredSpeed;
extern double mDesiredLinearAccel;
#extern double mDesiredRadialAccel; #this will be ignored, the route finder gives us this
extern double mDesiredClimbDiveAngle;
# PLATFORM.GoToSpeed(mDesiredSpeed, mDesiredLinearAccel);
# double altRateOfChange = PLATFORM.Speed() * MATH.Sin(mDesiredClimbDiveAngle);
# PLATFORM.GoToAltitude(mDesiredAltitude, altRateOfChange);
# PLATFORM.TurnToHeading(mDesiredHeading, mDesiredRadialAccel);
if (PLATFORM.SlantRangeTo(mTargetPoint) > (3*mDesiredSpeed)) // if we are more than 2 seconds away from our target
{
#mRouteFinder.SetImpossibleRouteResponse(3); //dont shrink any avoidances or shift any points
mRouteFinder.SetImpossibleRouteResponse(2); //shift points to exist outside of avoidances
WsfRoute path = mRouteFinder.Route(TIME_NOW, PLATFORM.Location(), mTargetPoint, mDesiredSpeed);
if (!path.IsValid())
{
writeln_d("***** ERROR: INVALID PATH!!!");
return;
}
WsfRoute avoidances = mRouteFinder.RouteAvoidances();
if (!avoidances.IsValid())
{
writeln_d("***** ERROR: INVALID AVOIDANCES!!!");
return;
}
writeln_d("T=", TIME_NOW, ", path size: ", path.Size(), ", avoidances: ", avoidances.Size());
if (path.Size() >= 2 && avoidances.Size() >= 1)
{
double speed = path[0].Speed();
double radAccel;
double heading;
double avoidAngle = 90;
if (PLATFORM.RelativeBearingTo(avoidances[0].Location()) < 0)
{
avoidAngle = -90;
}
if (path[0].Location().SlantRangeTo(path[1].Location()) < (speed*3))
{
//just stay orthogonal to avoidance, we are riding the edge of the circle now
heading = PLATFORM.TrueBearingTo(avoidances[0].Location()) - avoidAngle;
radAccel = path[0].RadialAcceleration();
}
else
{
//we are on a leg of the route, not on a circle right now
//just turn towards the next point
heading = PLATFORM.TrueBearingTo(path[1].Location());
radAccel = 100; //incredible radial acceleration, let mover limit it
//this is to get platform oriented onto straight leg of the route
}
writeln_d(PLATFORM.Name(), ", rad accel: ", radAccel, ", speed: ", speed, ", loc: ", path[1].Location().ToString());
PLATFORM.TurnToHeading( heading, radAccel);
PLATFORM.GoToSpeed( path[0].Speed(), path[0].LinearAcceleration(), true);
if (mDebugDraw == true)
{
//draw white line on avoidance side, length = radius of avoidance
double radAccel = path[0].RadialAcceleration();
double speed = path[0].Speed();
double radius = speed * speed / radAccel;
WsfGeoPoint center = PLATFORM.Location();
center.Extrapolate(PLATFORM.Heading()+avoidAngle, radius);
mDraw.SetDuration(1);
mDraw.SetColor(1.0, 1.0, 1.0); //white
mDraw.BeginLines();
mDraw.Vertex(PLATFORM.Location());
mDraw.Vertex(center);
mDraw.End();
}
}
}
if (mDebugDraw == true)
{
mRouteFinder.DrawRoute(PROCESSOR.UpdateInterval(), Vec3.Construct(0.0, 0.75, 0.0)); #green
mRouteFinder.DrawAvoidances(PROCESSOR.UpdateInterval(), Vec3.Construct(0.5, 0.5, 0.5)); #gray
}
end_execute
end_behavior

View File

@@ -0,0 +1,44 @@
# ****************************************************************************
# CUI
#
# The Advanced Framework for Simulation, Integration, and Modeling (AFSIM)
#
# The use, dissemination or disclosure of data in this file is subject to
# limitation or restriction. See accompanying README and LICENSE for details.
# ****************************************************************************
# THIS BEHAVIOR ASSUMES THE FOLLOWING VARIABLES EXIST AND ARE SET
# extern double mDesiredHeading;
# extern double mDesiredAltitude;
# extern double mDesiredSpeed;
behavior pursue_fly_simple
script_debug_writes off
#script_variables
#end_script_variables
precondition
writeln_d(PLATFORM.Name(), " precondition pursue_fly_simple, T=", TIME_NOW);
return true;
end_precondition
execute
writeln_d(PLATFORM.Name(), " executing pursue_fly_simple, T=", TIME_NOW);
extern double mDesiredHeading;
extern double mDesiredAltitude;
extern double mDesiredSpeed;
extern double mDesiredLinearAccel;
extern double mDesiredRadialAccel;
extern double mDesiredClimbDiveAngle;
writeln_d("flying heading: ", mDesiredHeading, ", alt: ", mDesiredAltitude, ", speed: ", mDesiredSpeed);
PLATFORM.GoToSpeed(mDesiredSpeed, mDesiredLinearAccel);
double altRateOfChange = PLATFORM.Speed() * MATH.Sin(mDesiredClimbDiveAngle);
PLATFORM.GoToAltitude(mDesiredAltitude, altRateOfChange);
PLATFORM.TurnToHeading(mDesiredHeading, mDesiredRadialAccel);
end_execute
end_behavior

Some files were not shown because too many files have changed in this diff Show More