Jump to content

Myrten

Members
  • Posts

    121
  • Joined

  • Last visited

Everything posted by Myrten

  1. There is nothing about that in this code: https://github.com/FractalUK/KSPInterstellar/tree/develop/FNPlugin remember that what used to be transmitter is now medium transreceiver and can receive too.
  2. Range is only applicable to receivers so there is no point for using large one for relays\transmitters. For receivers only thing that matters is the collector area they have, the larger it is the greater distance it can get power from without efficiency loss, here are the ranges: Large:27.16 million KM Medium:6.06 million KM Small:2.37 million KM
  3. I suggest that you start setting up your network already instead of waiting for Fractal to add my routing algorithm since you really must have good infrastructure in 3 dimensions for this and it takes time to place all these relays... My network actually provides stable enough power to do microwave powered thermal turbojet->quantum plasma two stage (Yes, thermal turbo is so fast that I have re-entry effects during launch and it gives me 160 km apoapsis before I even turn plasma on...)
  4. Thanks With properly working microwave network thermal turbojet + quantum plasma might be an awesome combination Although my rockets somehow almost always ends up with 1000+ ton weight Maybe I've played for too much with super heavy NovaPunch's 5 meter parts
  5. Hey Fractal Here is complete version of my relay routing algorithm with routes optimized for efficiency. http://www.sendspace.com/file/1k16uz (updated for this dev version: https://github.com/FractalUK/KSPInterstellar/commit/17f5e268461f7abb072bda608dc1c93a2b524cdd) This zip contains 2 files: MicrowavePowerReceiver.cs - there are some changes in few places besides primary algorithm so I think it's better to post entire file. If you don't want some changes like extended labels with satellites\relays connected which I've made for testing let me know, I'll remove them. MicrowaveRoute.cs - This file has to be added to the project, I had to create this class since KSP doesn't support System.Tuple. It's only for storing optimal route when algorithm is processing satellites. How it works: Algorithm is in GetConnectedTransmitters method and returns all transmitters towards which there is a line of sight and optimal routes to them in terms of highest efficiency possible given current vessel's orientation and position. Since effective range of receivers is quite big, algorithm primarily focuses on angle (but since it calculates actual efficiency it will adapt to any changes if for example in future versions of KSPI receiver's ranges get nerfed). Detailed explanation: It's design is based on https://en.wikipedia.org/wiki/Dynamic_programming and these two algorithms adapted to this problem: https://en.wikipedia.org/wiki/Breadth-first_search https://en.wikipedia.org/wiki/Dijkstra's_algorithm I've divided relays into groups in which every relay in group must have line of sight with another relay in previous group: For example: Receiver can see 4 relays and they form Group 1. Relays from Group 1 together can see 5 other relays which will now form Group 2. Relays from Group 2 can together see 7 other relays so they form Group 3 and so on.... This not only allows it to stop quicker if there are no more relays in sight but groups also constitute https://en.wikipedia.org/wiki/Optimal_substructure necessary for dynamic programming. Steps: Create dictionaries for storing optimal routes to each relay\transmitter Filter out inactive relays and transmitters with no power Compute distances and line of sights between receiver and all transmitters\relay, if there is a direct connection then compute efficiency and store it in step 1 dictionaries. All relays with LOS to receiver are placed in Relay Group 1 This step has Nr + Nt operations Now we precompute line of sight checks and distance calculations for all combinations of relays, transmitters and relays, relays. Since distance and line of sight calculations for (R1,R2) are the same as for (R2,R1) we can limit number of operations in this step to: Nt * Nr + Nr*(Nr+1)/2 All results are put in two dimensional arrays. This is primary step: we go through all Relay groups and for each relay in particular relay group we: a)Check for line of sights to all transmitters using pre-computed array from step 4, if there is a connection we check in dictionary from step 1 if this route is more efficient then route which is already stored in dictionary. If that's the case or there is no other route known we put route using this relay in dictionary as optimal. b)Do the same as in step a) but for all other relays. We want to know current (sub)optimal route to each relay in line of sight. c)all relays which have not yet been processed and are in line of sight to any of relays in this relay group are added to next relay group to be processed in next iteration. Another dictionary containing final results is build from step 1's dictionaries. Performance: Number of line of sight\distance check operations: Nr + Nt + Nt * Nr + Nr*(Nr+1)/2 Number of facing factor calculations: Nr + Nt Number of efficiency calculations (very pessimistic): Nr+Nt + Nr(Nt+Nr-1) I've optimized efficiency calculation and in most cases it will just check if distance< penalty-free distance and return 1*facingFactor, if not it's very simple calculation as facing factor is inherited from relay\transmitter on start of this route which is visible from receiver. I hope this is understandable, I'm a bit sleepy now so sorry if there are any errors in this description
  6. I've tested it even more, take a look at this case: Route A is obviously shorter but since receiver isn't pointed at Kerbin but at relay near Sun new algorithm will choose longer route B. Penalty from bad angle would be huge if we were to connect directly to Kerbin, and since route B's length is still within distance limit of this big receiver there is no distance penalty thus it's clearly a better choice. Everything is running as fast as before and with this complexity I seriously doubt it will ever lag unless you go into hundreds of relays...
  7. I've finished changing relay routing algorithm from using optimal distance to using optimal efficiency(angle,distance) and I must say it seems to be working pretty awesome and has some interesting gameplay consequences. In this game I have a lot of satellites in Kerbin's equatorial orbits but almost nothing in higher/lower inclinations. This has huge effect now... In first 4 screenshots you can see that my input power stays at very similar stable level when receiver is at 'horizontal' positions since there are relays everywhere. In next 2 screenshots receiver is pointed upwards and downwards - power drops almost to zero since there are no relays up/down. Next two screenshot shows thermal receiver in vertical and horizontal positions - since it collects best on sides vertical position is the best for thermal receiver, horizontal is not so great but it still has pretty decent input power. Generally speaking now you can get pretty stable power levels if you place relays in 3 dimensions or have multiple receivers pointed at different directions. I've added for testing purposes Network Depth label here which displays longest connection in terms of hops between relays and made Satellites\Relays connected also display total number of transmitters\relays. I'll post all the code as soon as I clean & comment it properly, should be done by tomorrow.
  8. Trying to optimize transmission efficiency calculations for routing multiple relays I've made following method protected double CalculateTransmissionBaseEfficiency(double distance, double facingFactor) { double powerdissip = 1;//if distance is <= penaltyFreeDistance then powerdissip will always be 1 if (distance > penaltyFreeDistance) { powerdissip = (microwaveAngleTan*distance*microwaveAngleTan*distance)/collectorArea;//dissip is always > 1 here } return facingFactor/powerdissip; } To avoid calculating penaltyFreeDistance each time this method is called I've placed it in a field but since it depends on [KSPField(isPersistant = false)] public float collectorArea = 1; Can anyone tell me if it will be already set by the game to correct value when public override void OnStart(PartModule.StartState state) is being executed? This is the formula for a penalty free distance which I've derived from Fractal's original formula for power dissip, microwaveAngleTan is 3,64773822258968E-10 if anyone is interested penaltyFreeDistance = Math.Sqrt(1/((microwaveAngleTan*microwaveAngleTan)/collectorArea));
  9. Yes, that could be a nice feature when coupled with ability to re-transmit this energy at shorter distances so not every vessel would have to carry long-range transmitter. Currently thermal receiver + generator can act a bit in this fashion but this can lead to infinite energy On the other hand if distance doesn't really matter that much now and angle is way more important I guess I'll have to rewrite that multi-relay algorithm once again and this time use combined angle and distance penalty to determine optimal route lol but since it won't affect complexity (It's basicly capped at O(Nr * (Nr + Nt) + Nt)) I think it's a good idea
  10. I took a look at distance penalty calculation code for Microwave transmission and made some interesting observations: Depending on receiver's collector area for each receiver there is a distance up to which there is no distance penalty to efficiency at all. If I'm correct these distances are from largest antenna to smallest: 27,16 million KM 6.06 million KM 2.37 million KM If we put multiple large receivers on single vessel we can eliminate distance penalty at all so transmission from Jool to Kerbin's orbit would be as efficient as transmissions withing Kerbin's sphere of influence. Judging by what's happening in my game this looks correct.
  11. My optimized multi-relay MW transmission algorithm including optimal route calculation seems to be working, I'll post it when all testing will be OK and after little code cleanup
  12. Ship with collector(s) and container has to be in Van Allen belt, 9000 km orbit around Jool gives the highest collection rate.
  13. Yes, pre-sorting relay list might be a good idea - actually for first layer we might also include angle between them and receiver since it does affect power. This can get complicated in case of multi-relays but I'll think about this. Also, is this code executed for vessel or for each receiver? If it's the second one changing it to for vessel might save a lot of calculations. Meanwhile: Both infinite power and 200 GW pseudo-antimatter energy bugs are still working in my game, maybe it's sth wrong with my save since this infinite energy had spread everywhere. Why do I have activate receiver button on transmitters?
  14. Great to see new update, thanks for your work I took a quick look at new microwave receiver code and maybe you've noticed this but I think there is a significant problem with distance calculation, for example: We got one receiver Rc, one transmitter T and two relays R1, R2 Rc cannot see T but can see both relays R1 and R2 and both of them can see T. Your current algorithm will always measure distance using R1 since it's first in a list but what if: Rc, T and R2 are on Kerbin's orbit R1 is on ~low Sun orbit.. Calculated distance will be Rc->R1->T which is enormous Kerbin->Sun->Kerbin while Rc->R2->T is just Kerbin->Kerbin->Kerbin I'll rewrite my algorithm for 0.82, correct me if I'm wrong but I think that on output it should produce list of transmitters to which there is a connection and for each transmitter there should be a list of relays through which connection is going on. Another condition is that selected connection should have smallest possible distance from all possible connections.
  15. 1)Does it work across many vessels or only active one? 2)Going back to multi relays I've made simple BFS-based method for finding transmitters using many relays, pessimistic complexity is O(NR* (NT + 1)) O(Nr * (Nr + Nt) + Nt) *fixed*, for 50 transmitters and 20 relays it will be exactly 1260 calculations in most pessimistic case (receiver can only see one relay, that relay can only see one relay and so on without any relay seeing trasmiters) I'm not sure if KSP can use LINQ expressions, if not I'll rewrite it. I'll also add information through which relays is the connection going, but generally the algorithm looks like this: /// <summary> /// Returns transmitters which to which this vessel can connect, either directly or through relays /// </summary> /// <param name="maxHops">Maximum number of relays which can be used for connection to transmitter</param> protected IEnumerable<VesselMicrowavePersistence> GetConnectedTransmitters(int maxHops = 100) { var connectedTransmitters = new List<VesselMicrowavePersistence>();//transmitter to which we can connect var notConnectedTransmitters = new List<VesselMicrowavePersistence>();//rest foreach (VesselMicrowavePersistence vmp in vmps) //first check for direct connection from current vessel to transmitters { if (lineOfSightTo(vmp.getVessel())) { connectedTransmitters.Add(vmp); } else { notConnectedTransmitters.Add(vmp); } } var relaysRemaining = vrps.Where(relay=>relay.isActive()).ToList(); // active relays which we have not yet checked var relaysToCheck = relaysRemaining.Where(vrp => lineOfSightTo(vrp.getVessel())).ToList();//relays which will be checked in next iterations, initialized by relays visible from receiver relaysRemaining.RemoveAll(r => relaysToCheck.Contains(r));//remove them from previous list int hops = 0; //number of hops between relays while (hops < maxHops && relaysToCheck.Any())//runs as long as there is any relay to which we can connect and maximum number of hops have not been breached { var newRelaysToCheck = new List<VesselRelayPersistence>(); //we will put every relay which is connected to any relay in relaysToCheck here foreach (var relay in relaysToCheck) { var transmittersConnectedToRelay = notConnectedTransmitters.Where(ncs => relay.lineOfSightTo(ncs.getVessel())); //transmitters which are in LOS of checked relay //add/remove them from list of connected/not connected transmitters foreach (var sourceConnectedToRelay in transmittersConnectedToRelay) { connectedTransmitters.Add(sourceConnectedToRelay); notConnectedTransmitters.Remove(sourceConnectedToRelay); } //if all transmitters are connected we can stop searching if (!notConnectedTransmitters.Any()) break; var remainingRelaysInSightOfThisRelay = relaysRemaining.Where(remainingRelay => relay.lineOfSightTo(remainingRelay.getVessel()));//relays which are in LOS of checked relay and have not yet been checked //add/remove them from list of toCheck/remaining foreach (var relayInSight in remainingRelaysInSightOfThisRelay) { newRelaysToCheck.Add(relayInSight); relaysRemaining.Remove(relayInSight); } } relaysToCheck = newRelaysToCheck;//we don't have to check old relays so we just replace whole List hops++; } return connectedTransmitters; }
  16. Yeah I've realized that this could be the reason, but that's only the case if you check it by 'brute force' method. I think there might be a smarter way to do this with lower algorithmic complexity, I'll check this. Viable solution might be also limiting maximum number of 'hops' between relays to prevent the worst case scenario from happening.
  17. OK thanks, I must have missed that, although I hope it will change
  18. I've found another bug: Microwave receiver dish also works behind - if ship is directly on the opposite side of where dish points, dish will also receive full power just like it would be in front of it. I've also took a look at receiver's source code since relays acted a bit weird, can you confirm these two things: 1)Power can only be routed through single relay so such connection as in this image won't work right now: 2)If receiver is connected to transmitter via single relay it has to be pointed at transmitter not at relay to receive maximum power even though it doesn't see transmitter at all.
  19. You should use use 'Activate Transmitter' button instead of 'Activate Relay'
  20. I think that solution very similar to what I wrote above will work in this case too.
  21. Generally this problem can be divided into following sub-problems: Power multiplication effect: -It's caused by generator being able to generate power from thermal receiver which is connected to it - this feature must be disabled as it causes positive feedback loop which can lead to insane levels of power. Power creation from nothing effects: -Generator connected to offline\not full capacity reactor producing full power despite reactor being offline because there are thermal receivers adding 'Thermal Power' resource - I'd solve this by making sure that generator cannot produce more power then current capacity of the reactor permits, even if there is 1000000000 thermal power available. -Transmitter transmitting generator's full efficiency despite generator running not at full capacity because electric receivers produce mega joules - again I'd limit transmitter's output to sum of all generators and solar panels CURRENT output. This solutions can conflict with your feature of reactor\generator not operating at full capacity if there's no need that is - if thermal power\mega joules are at 100%. To solve this conflict I'd disable this feature if vessel contains any active transmitter.
  22. My suggestion would be to prevent generators from using thermal receiver's thermal power to generate electricity as I'm pretty sure this effect cannot be replicated to this extend by electric receivers only.
  23. I managed to get 8.31 petawatts of energy. Therefore I hereby claim :D:D::D Last rover on this screenshot generates 200 GW of power and all other ones increase total network output by 48%
×
×
  • Create New...