Home   Help Search Login Register  

Author Topic: HeliCAS - a helicopter collision avoidance script (ACCEPTED)  (Read 7945 times)

0 Members and 1 Guest are viewing this topic.

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
I've got a script that helps keep AI helicopters from flying into each other, a common and frustrating occurrence. Download the demo below and watch the helicopters try to avoid each other.  I have two issues with which I need help. Well, I have many issues that need helping but that is between me and my psychiatrist.  

1)I have the following code line in the main script:

Code: [Select]
If ((([_newpos Select _i, _newpos Select _j] Call Distance3D) < _dist) And (Alive ( _heli Select _i)) And (Alive (_heli Select _j))) Then {[(_heli Select _i),(_heli Select _j),(_newpos Select _i),(_newpos Select _j),(_hvel Select _i),(_hvel Select _j),(_hlist Select _i),(_hlist Select _j),_spd,_dt] Exec "avoid.sqs"}  
Even though I detect whether the two helicopters are alive, sometimes this causes an error if a helicopter dies just as this code line is being executed. It doesn't cause any problems in the script, but I would like to get rid of the unsightly error message.

2) Since this script is for only meant for AI helicopters, I think it could work in MP if run only on the server, but I am not certain. Any thoughts on this would be welcome.


Get HeliCAS v1.1
« Last Edit: 07 Jul 2008, 17:34:15 by Mandoble »
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #1 on: 16 Dec 2004, 08:04:34 »
What was the error message?

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #2 on: 16 Dec 2004, 22:09:07 »
I can't read the %^#%&^ error message because it gets cut off.
sigh... to reproduce the error use these settings in the demo.

_dist = 10
_spd = 1
_dt = 1
_delay = 0.1
urp!

Offline SEAL84

  • Members
  • *
  • Always lurking
Re:HeliCAS - a helicopter collision avoidance script
« Reply #3 on: 16 Dec 2004, 23:06:49 »
Eh, I fired this up....and they all plowed into each other and exploded.

Tried again and nobody went down, but they were constantly bumping into each other.  They don't seem to start avoiding until they're literally about to smash into another chopper, and if they're going too fast, they're just going to collide anyway.

Is there a way to make them give each other wider margins?  Even if they don't go down, seeing two choppers get into a fender-bender is still bad.

Homefry31464

  • Guest
Re:HeliCAS - a helicopter collision avoidance script
« Reply #4 on: 16 Dec 2004, 23:17:01 »
As for the error, perhaps it is because you are starting with '((([' and ending with ']'?  If you can follow what I mean, perhaps the brackets are wrong..?

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #5 on: 17 Dec 2004, 00:13:13 »
That's strange. On my machine they rarely collide with the settings provided in the demo, though sometimes they take 10-20 seconds to sort themselves out.  Having 8 helicopters colliding at once was just to show that they don't all die every time.  Remove the helicas line from the init.sqs and then watch what happens.

Try increasing the avoidance speed and distance i.e. _spd and _dist. It's not a perfect script but it is not load heavy and does help prevent helicopters from colliding.

Eh, I fired this up....and they all plowed into each other and exploded.

Tried again and nobody went down, but they were constantly bumping into each other.  They don't seem to start avoiding until they're literally about to smash into another chopper, and if they're going too fast, they're just going to collide anyway.

Is there a way to make them give each other wider margins?  Even if they don't go down, seeing two choppers get into a fender-bender is still bad.
« Last Edit: 17 Dec 2004, 00:14:37 by Mr.Peanut »
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #6 on: 17 Dec 2004, 00:14:21 »
PROBLEM SOLVED ! I think ...

In helicas you have the line :
Code: [Select]
#testalive
    If Not(Alive (_heli Select _i)) Then {_tmpheli = _tmpheli - [_heli Select _i]; _tmphlist = _tmphlist - [_hlist Select _i]}

The problem is _tmphlist = _tmphlist - [_hlist Select _i]}
. Reason: upon examination, all members of '_tmphlist' are the same: something like ["_i","_i","_i" ...] and so on. The error occurs whenever one of the helicopters dies.
When you subtract [_hlist select _i] from _tmphlist, ofp removes All the elments, as they are all the same.

Therefore, you end up with
Code: [Select]
... (_hlist Select _i) ... |#| Error Zero Divisor, as for this particular loop of "heli2" your _hlist is empty, []. (Doing a hint format ["%1",(_hlist Select _i) ]) confirms it is this that is causing the error zero divisor message

The _hlist is regenerated after the next #mainloop so you don't get repeated error messages.

Solution: Replace the code after #testalive with this code:
Code: [Select]
#testalive
_hlist = []
    If Not(Alive (_heli Select _i)) Then {_tmpheli = _tmpheli - [_heli Select _i]}
    _i = _i + 1
If (_i < _n) Then {Goto "testalive"}
_heli = +_tmpheli
"_hlist = _hlist + [""_i""] " foreach _heli
_hlist = +_tmphlist
_tmpheli = NIL
_n = Count _heli
;Don't need  a CAS for only 1 helicopter
If (_n < 2) Then {Exit}
Hope that solves the problem.
« Last Edit: 17 Dec 2004, 00:16:54 by Fragorl »

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #7 on: 17 Dec 2004, 00:27:42 »
Well, I found one bug thanks to your comment.
I had a line that read:
Code: [Select]
{_hlist Set [_i, Format["_i"]]; _i = _i + 1 } ForEach _heli
but it should be:

Code: [Select]
{_hlist Set [_i, Format["%1",_i]]; _i = _i + 1 } ForEach _heli
This list is used in generating names for boolean variables that  allow only one entry into avoid.sqs for a colliding pair of helicopters.

I have updated code download above...

How did you manage to see the whole error message?
« Last Edit: 17 Dec 2004, 00:32:49 by Mr.Peanut »
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #8 on: 17 Dec 2004, 02:38:03 »
I saw that the error message was coming from that long line starting with 'if...' after #heli2
I guessed it was a zero divisor error, coz that happens to me alot, so i commented out the if... line and replaced it with
"hint format ["%1",[_hlist select _i]]" (actually i tried that probably last)
then it came up with  the hint format line + the error message which i could read.

Also i checked _hlist with a hint format, thats how i could see it was empty []. Did replacing that section of code work?

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #9 on: 17 Dec 2004, 14:51:28 »
I didn't replace the section of code because it didn't seem necessary after I made the correction indicated in my last post.
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #10 on: 19 Dec 2004, 04:33:30 »
Ah, I see, _hlist = [0,1,2,3,4...] not ["_i","_i","_i" ...]. So you can remove nmbers individually without cleaning out the whole array

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #11 on: 21 Dec 2004, 12:34:38 »
_hlist = ["0","1","2","3","4",...]
urp!

Big Nasty

  • Guest
Re:HeliCAS - a helicopter collision avoidance script
« Reply #12 on: 27 Feb 2005, 17:37:14 »
How is this script coming along? It sounds very useful.

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #13 on: 01 Mar 2005, 15:52:08 »
Script works and is fully debugged.  I've tested it for use in a mission I'm making in which the player is pursued by 6 helicopters.  The helicopters rarely crash into each other.  I didn't bother doing any more work or docs on it due to the lack of a positive response, and I am not sure how to get it to work in multiplayer.  I suspect if it is run only on the server it may work in multiplayer, but without expert advice on SetVelocity, I can not make any guarantees.

I have updated the demo download with a small change and also submitted to ofpec.

« Last Edit: 01 Mar 2005, 16:15:30 by Mr.Peanut »
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #14 on: 02 Mar 2005, 07:56:00 »
Prolly a bit too late for this, but seeming as the thread has been revived, I have a couple of ideas for making the script itself more user-friendly.

1.) The calling bit requires lots of numbers that the user has to look up in the readme. Perhaps give them some 'default' values (the ones that u find work best) and so allow them the opportunity to put nothing in. So, from the main script:

Code: [Select]
;  I have found the following values to work best.
;  _dist = 10
;  _spd = 2
;  _dt = 1
;  _delay = 0.05

_heli = _this Select 0
_dist = _this Select 1
_spd = _this Select 2
_dt = _this Select 3  
_delay = _this Select 4  

?format["%1",_dist] == "scalar bool array string 0xfcffffef":_dist = 10
?format["%1",_spd] == "scalar bool array string 0xfcffffef":_spd = 2
?format["%1",_dt] == "scalar bool array string 0xfcffffef":_dt = 1
?format["%1",_delay] == "scalar bool array string 0xfcffffef":_delay = 0.05
2.) Instead of requiring the user to basically give you an array of all the choppers in the game, perhaps allow them to just use the choppers they want helicas for. Then run a looping 'nearestobject' command and check for tyoe using "air" counttype [_nearestobj] ==1 to find if it should do a helicas or not.

Regardless, I thought it was a very cool script, and I often use it out of sheer frustration when im dealing with more than about 2 choppers. shoopid ai.
;)

EDIT: i can never remeber when to use "scalar etc etc etc" and when to use "<null>". Tis one of the two
« Last Edit: 02 Mar 2005, 07:59:28 by Fragorl »

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #15 on: 02 Mar 2005, 21:17:05 »
Yep.. too late... script already submitted. But providing default values would have made sense.

My only reservation about using NearestObject would be whether it would slow execution speed or not.
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #16 on: 03 Mar 2005, 04:12:23 »
I dont think that makes a difference when you have delays greater or equal to about 0.05. Or thereabouts. Actually, thats a complete guess

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #17 on: 07 Mar 2005, 15:37:00 »
I tried your suggestion Fragorl, but I get a zero divisor error from the _delay = _this Select 4 when I do not provide a value.  The code still works, but the display of the error message is unsightly.


1.) The calling bit requires lots of numbers that the user has to look up in the readme. Perhaps give them some 'default' values (the ones that u find work best) and so allow them the opportunity to put nothing in. So, from the main script:

Code: [Select]
;  I have found the following values to work best.
;  _dist = 10
;  _spd = 2
;  _dt = 1
;  _delay = 0.05

_heli = _this Select 0
_dist = _this Select 1
_spd = _this Select 2
_dt = _this Select 3  
_delay = _this Select 4  

?format["%1",_dist] == "scalar bool array string 0xfcffffef":_dist = 10
?format["%1",_spd] == "scalar bool array string 0xfcffffef":_spd = 2
?format["%1",_dt] == "scalar bool array string 0xfcffffef":_dt = 1
?format["%1",_delay] == "scalar bool array string 0xfcffffef":_delay = 0.05
« Last Edit: 07 Mar 2005, 15:42:13 by Mr.Peanut »
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #18 on: 08 Mar 2005, 09:56:55 »
EDIT: no, scrap that, use this:
Code: [Select]

?count _this == 1 goto "defaultvalues"

_heli = _this Select 0
_dist = _this Select 1
_spd = _this Select 2
_dt = _this Select 3
_delay = _this Select 4
goto"starthelicas"

#defaultvalues
_dist = 10
_spd = 2
_dt = 1
_delay = 0.05

#starthelicas
...
That *should* work ;)
« Last Edit: 08 Mar 2005, 11:31:34 by Fragorl »

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re:HeliCAS - a helicopter collision avoidance script
« Reply #19 on: 08 Mar 2005, 16:18:51 »
Yes that should do it.  Now why didn't I think of that?  ???
« Last Edit: 08 Mar 2005, 16:19:47 by Mr.Peanut »
urp!

Offline Fragorl

  • Coding Team
  • Former Staff
  • ****
Re:HeliCAS - a helicopter collision avoidance script
« Reply #20 on: 09 Mar 2005, 11:38:54 »
Don't you worry..... it took me 4 attempts over an entire week (i edited the others out, it was getting embarrasing) to simply remember something I'd already done before.  :P :-\ :-[ ;D

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re: HeliCAS - a helicopter collision avoidance script
« Reply #21 on: 24 May 2008, 17:21:28 »
Re-attached this resource since it somehow disappeared from the ED in the past half year. Feel free to delete this post once it is back in so that the thread sinks to its proper place in time

OFPR, SMUC code is C, demo mission included. Text from script header to help for ED entry:


;======================================================================
;HeliCAS - A Helicopter Collision Avoidance System for AI pilots;
;by Mr.Peanut
;Version 1.0 : March 7, 2005
;
;SYNTAX:  [_heli] Exec "helicas.sqs"
;EXAMPLE: [[H1,H2,H3,H4,H5,H6,H7,H8,...,H?]] Exec "helicas.sqs"
;  where H1-H? are the helicopter names. In this case the default values will be used for the input parameters.
;
; OR for total control
;
;SYNTAX:  [_heli, _dist, _ spd, _dt, _delay] Exec "helicas.sqs"
;EXAMPLE: [[H1,H2,H3,H4,H5,H6,H7,H8,...,H?],10,2.0,1.0,0.05] Exec "helicas.sqs"
;  where H1-H? are the helicopter names
;
;INPUT VARIABLES:
; _heli = array of helicopters piloted by AI
; _dist = collision detection distance (m) 
; _spd = collision avoidance speed   (m/s)
; _dt = collision prediction time  (seconds)       
; _delay = collision detection delay  (seconds)
;
;FUNCTIONS USED:
;  The following functions must be declared in init.sqs
;  Distance3D = preprocessFile "distancepos3d.sqf"
;  Sign = preprocessFile "sign.sqf"
;
;DESCRIPTION:
;  This script works by predicting each helicopter's position _dt seconds from present.  If any of the helicopters are
;  closer to each other than distance _dist, then they are nudged apart from each other with a speed based on the value
;  of _spd. The _delay variable is the loop delay between collision checks.  The helicopters will not always successfully avoid
;  collision, but that is true of the real world too.
;
;  I have found the following values to work well and provided them as defaults:
;  _dist = 10
;  _spd = 2
;  _dt = 1
;  _delay = 0.05
;
; Increasing _delay above 0.1 is not advised if you have more than  three helicopters. Increasing _spd above 5
; will make the helicopters flit and bounce around unnaturally.  If you  decrease _dist, it is a good idea to increase _dt.
;
; For fewer helicopters, decrease _dist, decrease _spd, decrease _dt and increase _delay.
;
;WARNING:
;   There is no check for whether the array _hlist is a valid list of helicopters.  I did not want to hard code a list
;   of helicopter types.
;
« Last Edit: 01 Jul 2008, 16:27:08 by Mr.Peanut »
urp!

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: HeliCAS - a helicopter collision avoidance script
« Reply #22 on: 04 Jun 2008, 18:37:26 »
Finally got it working for ArmA too, did some changes for ArmA version: call format -> call compile format, preprocess -> compile preprocess, camCreate -> createVehicleLocal.

As it uses several scripts, before submission, please renamte them all using your tag first, or put them all in a subfolder named at your convenience. Check also how can this be made fully MP compatible as you are using setVelocity to avoid collisions, and this command requires local units as parameter. As everything is done with a single instance of a single script, the choppers in the array might have different localities and one might evade while the rest dont.

EDIT:
There is a situation I missed to test, where several choppers take off close to each other following the same direction.
« Last Edit: 07 Jul 2008, 17:32:40 by Mandoble »

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re: HeliCAS - a helicopter collision avoidance script
« Reply #23 on: 17 Jun 2008, 00:51:57 »
v 1.1
« Last Edit: 07 Jul 2008, 17:32:29 by Mandoble »
urp!