Closed zrisher closed 8 years ago
Wow, that sounds really ambitious, I had a much lazier harvester in mind.
For controlling the movement of the ship, the easiest way is to accelerate to the desired speed and, instead of disabling dampeners, disable the reverse thrusters. ThrustProfiler is already keeping track of the directions of each thruster, so this should be relatively simple.
Turning while inside of a tunnel is a bit tricky, we do not want the ship banging into the sides of the tunnel more than it has to. Reversing out of an asteroid when there is nothing left to harvest is an even bigger problem, it is very easy to get stuck and we want harvesting to work with as many different ships as possible. It would be much easier to implement a straight-through asteroid approach.
I have not done any work with voxels, but I believe that the way to get the content of a voxel is IMyVoxelMap.Storage.ReadRange().
Random Musings: The harvester should be able to function even if the remote is facing the wrong way. Initially I thought checking inventory would be complicated, but it is only necessary to check the drills' inventory. The ore detection should be kept separate from the harvesting, there may be other uses for it.
I did not intend to abandon you to the will of the code; I am happy to explain my poorly-documented code to you, assist in writing code, explain what I can about modding S.E., or any other help you need.
Ok thanks, that's all very helpful. I don't feel abandoned! I'll keep asking questions, the code is fairly self-explanatory so far but I'll add comments where I can too.
Do we really need to give users the ability to specify a different direction for harvesting? Seems definitely like an edge case. We could detect the average forward vector of all the selected drills and just use that when harvesting instead if we needed to support that. Just trying to think of a way to integrate that easily with the existing command system.
As far as navigating while harvesting, with my in-game-programming miners I found that if I approached the rocks in pulses, slowly, had a few gyros, and idle drill shake was off, I could cut an exact straight line through. So backing up would be completely do-able. Backing up takes less time and wastes less of the asteroid. But if you're low on gyros or idle drill shake is on it's probably not completely reliable. In that case, we might need to go all the way through. Maybe we could try both, let it toggle between and see what works best?
I did not mean that the user should specify which direction to harvest, just that the remote's forward might not be the same as the drills' forward. Like you said, averaging the vectors of the drills is the best way to get the direction.
If we are going to build both, we could use drilling through as a fall-back for when it gets stuck.
Sounds perfect.
I took a first look at scanning asteroids for ore content, and the results were disappointing. Reading the storage from IMyVoxelMap is far too slow, we will have to come up with something else.
Can we scan it infrequently and just store the location and types in memory? There's a lot of data in the VoxelMaps that we don't need right? Since these don't move and would only go away if they were mined, we can probably limit updates to every 5 minutes or longer.
We just need to look at the voxelmap for the current asteroid target right? Then we can store the asteroid's material list at the asteroid level and check that against people's harvesting targets to determine if we need to go in and give more frequent updates to locations.
I did not actually grab the voxels for the entire asteroid, it is much faster to use a subsection. So first I just read the voxels in a bounding box into a cache, using a side length of 100, 200, and 300 metres. I ran 100 iterations of each and got median times of 3.22 ms, 26.5 ms, and 98.4 ms.
I tried to do the same thing for an entire asteroid, I will let you know when it finishes. Edit: 7.28 s.
Ok, so that's a long time, but if we did it asynchronously and only after an asteroid is first loaded or occasionally as it's being harvested, it would be doable.
Is there any way to ready the material type without doing an intersection test? Sorry I know nothing about this, could you post a bit of the method you're using to find the materials? Ore detectors seem to do this pretty easily, but I get the feeling their detection logic just isn't exposed at all.
I'll push the branch so you can take a look. Hopefully I made a mistake somewhere. Even if everything is performed asynchronously, I can't see the script keeping pace with a mutiplayer game.
Looks reasonable, eventually I can look at this stuff in detail but it's a few weeks off for me unfortunately. I posted to the forums, hopefully a dev will chime in: http://forums.keenswh.com/threads/getting-ore-locations.7358404/
Ohh! I found a mod that does this! Edit: Nevermind it was all lies.
Lol, unfortunate.
There's an API feature request out that would make this really easy, I linked to it in that forum post. Until they support this via the API, it may not worth be attempting over all the other stuff you could make faster progress on.
I knew that there is an API request for this, I just do not expect it to be filled any time soon.
Anyway, we could implement a random harvester and then direct complaints about the Ore Detectors to Keen :P
True, probably a good stopgap.
"Harvest : extract resources from the nearest asteroid Example - [ C 0,0,0 : Drill ] - fly to {0,0,0} then harvest the closest asteroid"
This might be confusing. You say the command is Harvest, but in your example you use the word* Drill.
This might be confusing.
That is a very polite way of putting it.
You could just use H
right? As in [ C 0,0,0 : H ]
Nope, single letter commands are always thrown out.
working on changes to S.E. that will allow mods to get ores from Ore Detector: https://github.com/Rynchodon/SpaceEngineers/tree/OreDetector-OreLocations
It seems we have access to ore markers displayed on the HUD, so I can at least get started on harvesting particular ores.
YAY!
That's very awesome.
I have good news and bad news. The bad news is that they took ore markers off the whitelist. The good news is that ReadRange() is thread safe and I have a working solution to grab all the detected ores.
:trophy:
Alright I'm taking a stab at harvesting and here's how I was thinking of implementing:
We add a command
H
that works likeM
but targets ore voxels.E
takes precedence (so you can have military harvesters...) and if we ever implement a "flee" functionality that would take precedence too.H
can be called with no arguments to target all ore types besides stone, or a prioritized list of ore types by periodic symbol i.e.Co, Si, Ag, Au, Ni
. If you wanted to actually harvest stone, you'd need to specify this list and include it (maybe asSo
orSt
) likeCo, Si, So
. Clearly this should require a connected ore detector, but we could also eventually add the ability to run it with just a sensor and ignore the ore type arguments.Harvesting would occur whenever a targeted ore is detected within the range of the currently used detector and would continue every time such ores exist until inventory is full or another command takes over.
Example - Fly out to an asteroid at 1000,1000,1000, stopping to mine any Uranium that comes into detector range everywhere between here and there until full. Once there and full or no more U detected, fly back to 0,0,0, dock, unload, and repeat.
Do the same thing, but engage detected enemies 1km away along the way:
@Rynchodon What do you think?
In terms of implementation, I'd add a case for
'h'
intoNavigator.addInstruction
that would hook into the CNS at a lower priority than E or M (or F for flee later?), and would function very similarly to a missile but with different search and engagement algorithms.I haven't gotten much farther than trying to get my arguments parsed and logged (not very experienced with C#), but I'm working on it. : )
I think engagement will be moderately straight forward - approach voxel at range, then slowly go forward towards it with drills on, pulsing forward so as to minimize shake due to asteroid collision. Remember vector in, follow it directly out when voxel no longer in front or inv full, resume unless inventory full.
But search - that's a bit of a mystery to me. How can I find the part of an asteroid voxel that is of a particular type of ore? The ore detector does it and finds their centers, so I know it's possible. I see we get voxels a few different ways and IMyVoxel exists, but I can't find any examples of finding parts of an asteroid by material. Are the ore patches seperate voxels? How do I get material type?
@Rynchodon Any guidance on implementation at this point would be highly appreciated.