Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

Auto pilot to block location rather than GPS?

Discussion in 'Programming Questions and Suggestions' started by woostyboy, Jan 31, 2017.

  1. woostyboy

    Joined:
    Jul 17, 2014
    Messages:
    38
    Trophy Points:
    52
    Hi Guys

    First off, I've no idea how to program, generally rely on the amazing work of others through copy/paste from the workshop scripts. Have had a bit of a search but not entirely certain what to search for!

    Is it possible for the RC block autopilot to navigate to a block location on a moving grid rather than a fixed GPS point?

    I wondered if I could 'auto' dock a small ship onto a connector of a moving large ship?

    Any assistance would be greatly appreciated.

    Thanks,
    Woostyboy
     
  2. Wicorel

    Joined:
    Jan 10, 2015
    Messages:
    1,066
    Trophy Points:
    157
    No, keen autopilot cannot do that.

    An ingame script could do it.
     
  3. woostyboy

    Joined:
    Jul 17, 2014
    Messages:
    38
    Trophy Points:
    52
    Thanks for the reply. Would you know of such a script?
     
  4. Wicorel

    Joined:
    Jan 10, 2015
    Messages:
    1,066
    Trophy Points:
    157
    No, not yet.

    I have code for known location, but not moving.
     
  5. woostyboy

    Joined:
    Jul 17, 2014
    Messages:
    38
    Trophy Points:
    52
    OK, thank you. For now then I think I'll convert my capital ship to a station and use GPS to simulate what I'm after.
     
  6. Pharap

    Joined:
    Nov 11, 2015
    Messages:
    69
    Trophy Points:
    27
    I don't have a working example but I have an idea about how it can be done.

    If your drone ship has a sensor equipped and the ship it's supposed to follow is within detection range then it can use the sensor's entity detection capability to find the ship's position, which it can then add to its waypoint list.

    Alternatively you can give the drone ship and the other ship an antenna (a laser antenna is preferable) and have the main ship transmit its location to the drone ship.
     
  7. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    Now by "moving" do you mean "currently moving" or "may have moved to any given point and is stopped while I try to dock another ship at it with a programmable block"?

    Because I literally just released a script for the second one. The first one might be possible but would probably be...challenging
     
  8. Pharap

    Joined:
    Nov 11, 2015
    Messages:
    69
    Trophy Points:
    27
    Sadly they mean the first one: trying to dock with a ship while both ships are in motion.
    Glad to know that a script for the latter exists though. It might not be far off doing the former with a bit of modification.
     
  9. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    It'd be a matter of modifying it so the mothership sent a motion vector as well as its position and rotation, then modify the childship's thrust method to no longer rely on dampers but get it moving in the same relative direction after orienting and make adjustments relative to that motion.

    So not impossible and not the worst place to start, but probably messier than it sounds. Not sure it could deal with rotation very well though, and acceleration/deceleration might pose problems unless a second PB was built into the mothership to broadcast current speed when it changed.

    I'd be happy (ish, the code is an undocumented mess that I'm working on commenting and cleaning it up) to have someone help or may try to tackle this after I'm confident all the features work as is.
     
  10. Pharap

    Joined:
    Nov 11, 2015
    Messages:
    69
    Trophy Points:
    27
    Actually if you're using an IMySensorBlock you can get the ship's Belocity, BoundingBox and Orientation (in matrix form) from the MyDetectedEntityInfo.

    You're right about possibly needing to manually pilot the ship though, and collision avoidance mode would probably have to be off if the remote control block was used.
     
  11. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    While true, that relies on being close enough and having that one ship (or filtering through the list. I haven't played with IMySensorBlock but I'm guessing it returns a list of detected entities or the like) already in range - the script I'm referring to is intended for use anyplace within antenna two way communication range, including if relayed across a satellite network. Leveraging that intergrid comms!

    And yeah I think it'd have to be manual thruster override in the PB, Remote blocks would probably just get fidgety if you tried to constantly feed them new GPS coordinates. Heck they get fidgety just giving them one sometimes
     
  12. Pharap

    Joined:
    Nov 11, 2015
    Messages:
    69
    Trophy Points:
    27
    Sensor blocks do indeed return a list. Once you've isolated the correct ship once you can easily find it again using its entity id.

    The only flaw with the antenna based solution is that unless they're laser antennae, they're susceptible to being intercepted or they have to be able to identify what messages aren't intended for them.
     
  13. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    If I understood it right the MyTransmitTarget gets around this, I'd guess they justify it by saying "its like you encrypted it if you set it to go to just your allies" or something along those lines, though I haven't tested trying to intercept as an enemy
     
  14. woostyboy

    Joined:
    Jul 17, 2014
    Messages:
    38
    Trophy Points:
    52
    Watching this with great interest Guys, looking forward to some magic! ;)
     
  15. woostyboy

    Joined:
    Jul 17, 2014
    Messages:
    38
    Trophy Points:
    52
    Thanks for the replies Guys. Just wanted to clarify, what I'm looking for is effectivly an 'Aircraft Carrier' style landing - Moving capital ship and moving small ship (on scripted autopilot of some description) landing on/in it.
     
  16. cheerkin

    Joined:
    Dec 8, 2015
    Messages:
    42
    Trophy Points:
    47
    Once you have the script for convenient landing at a static carrier, it could be combined with raycast scanning for getting target's position and velocity vectors. Knowing those and your owns makes you able to do the vector math for finding relative speed and positioning.
    I have the script which can follow and approach any point at any distance, static or moving, using its thrusters and gravity drive, but docking is another story.
    So what you want to achieive is totally possible, but requires quite a bit of work.
     
  17. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    Thats the part I'm currently lacking, and unfortunately my docking currently relies on dampeners to come to stop movement. That said it should be plausible to modify it so that it takes a "movement vector" to be the zero-speed instead of actual zero and thrust in the opposite directions manually instead of relying on dampeners. I think velocity changes would be problematic as well... but to be honest i have no experience with raycasts yet and everything I know about vectors I learned just to do the docking part.
     
  18. cheerkin

    Joined:
    Dec 8, 2015
    Messages:
    42
    Trophy Points:
    47
    You don't even need the raycast, if it's owner-owner communication you can just transmit two vectors via the carrier antenna (position and velocity). And perhaps additional vectors for connector location/orientation.
     
    • Agree Agree x 1
  19. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    More or less what I'm doing (Transmitting locations, not movement vector). My concern is velocity changes, be it in direction or speed, though I may be able to set up a subscription like concept frequent enough changes could interrupt docking logic.
     
  20. cheerkin

    Joined:
    Dec 8, 2015
    Messages:
    42
    Trophy Points:
    47
    If you pass 2 vectors, you can calculate predicted interception point and implement "parallel approach"-type of guidance (not sure if I named it correctly in English). This way you constantly take into account target's velocity changes and make approach trajectory as straight and short as possible. The only problem that stops me from implementing docking - I have yet to implement direction-independent movement (so I could align craft according to connector's orientation and approach by controlling only thruster's overrides).
     
  21. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    Hm not a bad idea.

    I solved the alignment/orientation portion of that by requiring a "orientation" remote block on both and setting it up so they'd align so the faces of the dock blocks and the "up" sides of the dock blocks are either the "up" or "front" of the remote blocks, depending on if the "Up" of the remote is oriented so it faces the docking blocks face or not.

    Once you're aligned properly its not too bad to figure out the distance on a given axis to travel.

    I use this code snippet in my mothership scripts. directionOfChange is the axis you want to move in, directionToGo is a vector representing the total change in position you want to take (IE the docking block on the ship's position - docking block on the dock's position), and buffer is a bit of a buffer distance. You could use it to get the velocity you'd need along a given axis too, its only limitation being you need to know if left or right is "positive" before you pass it in:
    Code:
    //Gets a vector representing the total best distance to travel in that direction to get closer to the nearest tenth unit
    private Vector3D getRemainingDistanceVector(Vector3D directionOfChange, Vector3D directionToGo, double bufferDistance) {
    	Vector3D returnVector = directionOfChange;
    	returnVector.Normalize();
    	Vector3D normalizedDirectionToGo = directionToGo;
    	double directionLength = normalizedDirectionToGo.Normalize();
    	double movementLength = Math.Abs(directionLength * Vector3D.Dot(normalizedDirectionToGo, returnVector)) - bufferDistance;
    	
    	returnVector = returnVector * movementLength;
    	
    	return returnVector;
    } 
     
  22. cheerkin

    Joined:
    Dec 8, 2015
    Messages:
    42
    Trophy Points:
    47
    Yeah, that should work I guess. Right now I'm trying to get to work more generalized solution - to create BoundingBox with dimensions representing six thrust capacities, and then to find the intersection with Ray to target point. If my idea is correct, I'm hoping to get coordinates of intersection point and they'd represent relative thrust percentages along all axis.
    --- Automerge ---
    Had some success with it today
     
    • Like Like x 1
  23. Pharap

    Joined:
    Nov 11, 2015
    Messages:
    69
    Trophy Points:
    27
    There's a built in way to get the orientation of a block, but it involves quaternions and matrices which generally aren't fun to work with.

    Before I go any further I'd like to point out that the mothership has to be travelling at a slower speed than the 100m/s cap or the child ships will never catch up. Even speeds of 90m/s would mean the child ships would have a hard time catching up. I'm going to ignore that for now while I propose some potential approaches to solving the "auto-pilot to dynamic grids" problem.

    Generally speaking, there's several approaches you could take.

    Approach 1:
    A two-phase process.
    In the first phase you treat the target ship as a sphere or box to get close to, where you don't care about alignment and only care about proximity. When you're close enough, begin phase 2.
    In the second phase you start figuring out where the landing area is in relation to your ship and use the camera's raycast feature to discover how far away you are from a flat surface of the ship.

    Approach 2:
    Have the mothership calculate the path the child ships should take and transmit the path to them as a series of waypoints, as required (hence the mothership can keep recalculating as required). The mothership has to coordinate the paths to ensure the child ships don't collide, or instruct some of the child ships to wait so they arrive sequentially.

    Approach 3:
    Stop the mothership while the child ships land (yep, I'm a heretic).

    Approach 4:
    Abuse the extra power gained from the modding API to come up with a mod-based solution.


    Some additional abstract thoughts:
    • You can use sensor blocks to track the location and velocity of other ships in range.
    • There's no way to avoid a small ship colliding with the mothership unless the coordinator knows the voxel-makeup of the mothership because bounding spheres and boxes are too imprecise for large ships.
    • Spherical coordinates might come in handy.
    • Whatever you do this will be terrible for combat situations.
    • Small ships need more speed than large ships.
    • You'd have to control the small ship's decceleration so it can precisely match the speed of the mothership, which would be damned hard without mods because the thruster interface for scripts is awkward and the waypoint system doesn't offer that kind of control.
    • Seriously it would be much easier to just stop the mothership momentarily, but I suppose that makes it less 'fun'.
     
  24. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    Thats why I'm using vectors instead and just calculating angles, because honestly trying to figure that out with no background in that kind of math wasn't working out. Plus, most of the docking blocks honestly don't have an "up" that you can easily tell by looking at it (heck the merge face of a merge block is "Right"), hence why I used a block that does that you need to have anyways as a reference.

    The less fun way is already done (though still be tweaked), so can't really blame people for wanting to expand it further. I think I'll bow out for this one though and try to fend off the occasional too complex gremlins in my current script
     
  25. cheerkin

    Joined:
    Dec 8, 2015
    Messages:
    42
    Trophy Points:
    47
    My solution is this:
    1. Once a drone dequeues a waypoint with type "docking-approach" it requests the carrier to provide 3 vectors (pos, velocity, rotation) for a point perpendicular to landing plane at some distance from it. This type of waypoint is handled using ThrustVector-method of flying (craft maintains its orientation no matter where it flies).
    2. The carrier constantly transmits those vectors.
    3. After the drone approaches this point, it requests the carrier to provide 3 vectors (pos, velocity, rotation) for exact docking point.
    4. The carrier constantly transmits those vectors.
    5. Do docking stuff (connector management etc), mark docking waypoint as complete.
    * all of above could be managed by the carrier for multiple drones or docking points (not implemented yet).
    ** for collision detection the carrier can transmit its radius for BoundingSphere (something similar to vanilla GetFreeDestination method)
     
  26. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    The only problem I can see offhand is dealing with multiple incoming ships using separate dock points - though you could serialize the data so that it knows which set out of several Pos/Velocity/rotation sets is for that specific docking ship and broadcast all of the data for both ships at once. If you don't multiple ships competing to get in will cause messages to get dropped. I ran into that when building a test swarm ship with a few children docking all at once
     
  27. cheerkin

    Joined:
    Dec 8, 2015
    Messages:
    42
    Trophy Points:
    47
    You mean the message loss if more than one drone transmits the request command in a single tick? Or what was your case, could you please be more specific? Right now I'm designing the code for two-way communication and message filtering, that would help a lot and possibly save me from numerous derps
    --- Automerge ---
    I like the idea of packing the data for all consumers in one transmit though - that would hugely improve overall performance, since string parsing is for sure much faster than sandboxing overhead for several broadcasts.
     
  28. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    No the game seems to handle simultaneous incoming broadcasts pretty well. The scenario that bit me was basically the below:

    Ship A with Antenna A put out a request to multiple ships to send it information.

    Ships B and C sent back replies and expected further orders from ship A

    Ship A's programmable block received both messages and attempted to reply to B and C all within the same tick. Only Ship B's message is successfully sent as the game does not allow multiple broadcasts during the same tick.

    Packing the data like you describe would fix that..and in fact now that I think of what I'm doing I may try for that route in my own script after I finish up efficiency updates.
     
  29. Pharap

    Joined:
    Nov 11, 2015
    Messages:
    69
    Trophy Points:
    27
    Yeah, I've been programming with vectors for several years and I still find quaternions vexing.
    Matrices I'm more comfortable with but they're still not fun to think about (since they're effectively nothing more than a grid of 16 numbers).

    They've added a thing that lets you tell the front face when placing blocks now, but yeah, they can be inconsistant. I think the 'face right' think might be a general rule or a side effect of the file formats because I've seen things in Garry's Mod that face right (several clocks and chairs at least).

    I'd be tempted to use a battery block or light for orientation. Lights are a good one since they can be both visual landing lights and landing lights for your code to use.

    I find the best solution to that is to broadcast the recipient's entity id at the front of the message with an 'end of id' character (e.g. semicolon, exclamation mark, hash sign, pound sign, ampersand) to signify the end, then make each programming block parse the id out and check it against its parent cube grid to find out if the message was intended for it.

    Solution 1:
    Make the code pick a ship and stick with that ship, ignoring future messages.

    Solution 2: (Inspired by how Dynamic Host Configuration Protocol works, which is worth a look at because it handles a conceptually similar issue.)
    Track all incoming replies and only respond after a timeout. At that timeout, pick a ship and broadcast a message to notify all ships which ship you've picked so the ones that aren't picked know to stop listening for another reply.
     
  30. Erna_Vida

    Joined:
    Jul 31, 2014
    Messages:
    40
    Trophy Points:
    47
    Eh the remote block was a matter of "The child ship HAS to have one for this to work the way I intended," so it was convenient, plus "up" is generally always "up" for any given dock regardless of where on the ship. Then, events (On dock/undock/accept) lets users do whatever else they want with another programmable block for things like lights that blink or turn on for landing. Its already stepping on "too complex" errors sometimes that I'm weeding out, I don't want to worsen it too much more :D.

    For this specific project in this thread though the remote block may be unnecessary so those may be better options

    Agreed.

    There's also a decent solution 3 for scripts that run constantly but do not broadcast constantly:
    Since antennas let you know if a message could not be sent due to this issue, add any failed sends to a queue. On the next run, if no further messages are to be sent, dequeue the next message and send it.

    As long as you have a reasonable timeout on those waiting for the response it seems to work well enough.