Search Unity

Cables to pass eletricity between objects

Discussion in 'General Discussion' started by rkaetano, Oct 6, 2013.

  1. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    Hey guys, what's up !?
    I've a question, but I don't believe that this should be categorized as a script question. And I can't find a better place do ask. So... :p

    I'm trying to create a object to my game, which has a need for energy (or water), and to provide this, I need to connect this object to a energy supplier. Ok, I'm already doing that. But I really don't know the better way to transfer this energy. I mean, how can I do this in a good way, where my object will only works, if any energy is been supplied ?

    To be situated. Think about prison architect, or minecraft with the industrial mod. In both games, you need to place some cables to transfer electricity between 2 points. And you can add another cable making a cross, to split this electricity to another point.
    My first approach was to have a script attached to any cable, which would hold a certain amount of energy. So everytime I place a new cable, I call a event to all cables checks adjacents cables, and store them in a list.
    Those cables has a coroutine to check if they have any energy inside, and if don't, they do a loop over all other adjacent cables, to "ask" for energy.
    The energy supplier has a script to "provide" energy, every time "someone" ask. And the object which will consume this energy has another script, to only ask this energy.
    The problems I had with this solution, it's that I'm "consuming" energy without a object to use that, because all cable "ask" for energy, and this energy stay there without being used. And of course, if I lay down a lot of cables, at some point, the supplier will be exhausted without anyone use this energy. And of course, I've a lot of coroutines running in background, which I didn't checked, but I believe that could be very processing consuming, right ?

    I was thinking to have a "parent" gameobject to hold energy lines. So, everytime I lay down a cable, I could check if this cable is adjacent to any other cable which is already a member of one energy line. If true, I make this cable a member of this energy line, if false, I would create a new energy line, for this cable. Then, when one consumer needs energy, I could simple check in the energy line, if is there any provider, and ask for energy.
    The problem with this approach, is that each provider can only be a member of one energy line. So, I cannot have multiple energy lines connected to a single provider. And if I remove one cable in the middle, I would need to do a check to all other cables, to see if they are still a member of one energy line, or if they should create a new energy line to be member.

    I was looking into the minecraft mod approach, where they have a generator which can be linked to at least 6 cables, one at each side of the block. The cables can admit different voltages, and have a "bandwich limit" per model. And if I don't have a machine to use this energy, the generator do not consume any energy. So, I really don't know how they did that. :p

    Can anyone here, please, give me one insight about this situation ? Maybe a better approach.
     
  2. miksumortti

    miksumortti

    Joined:
    Apr 7, 2012
    Posts:
    204
    The power consuming components (eg. motor or something) could ask all cables connected to it for an amount of energy, each part of the cable then sends this 'question' to next cable part connected until the energy provider has been reached, then the asked amount of energy will be removed from the provider.
     
  3. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    Yeah, this could be a good way to do that. I just need to check how this implementation works, because I need to take care about "fake" answers or late ones. I can have a cross of cables, which are connected to 3 more providers, and in a situation like that, the "ask" routine will be sent to all 3. And I need to make sure, to receive only one answer, and ignore the others. :p
     
  4. miksumortti

    miksumortti

    Joined:
    Apr 7, 2012
    Posts:
    204
    Maybe the 'asker' could send first only a check that would determine how many power providers are connected and divide the 'asked' amount of energy by the number of providers connected to get correct amount of energy. But iff you need only one to supply energy when multiple connected then I don't have any good ideas...
     
  5. Photon-Blasting-Service

    Photon-Blasting-Service

    Joined:
    Apr 27, 2009
    Posts:
    423
    I would make a truth table that defines all valid paths for the power to travel. This is a basic technique taught to all electronics students.

    The manager checks the truth table and if true, the motor would run and the generator would supply the energy.

    You can get fancy and calculate power losses due to the cables but I would just ignore that for now.
     
  6. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    Hey Photon, a truth table could work, If I'm sure that I have a connection between all the objects. But right now, I'm trying to "know" if this connection exists. I mean, the player will be creating the circuit between the inputs and outputs. And is this what's I'm trying to figure out.

    Maybe I did not understand what you meant with your proposition, but I really can't see how to implement your Idea, to identify a connection.
     
  7. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    $schema.png

    Look at this image.

    Machine 2 ask for energy to the adjacent cable. Ok, then I can do the same for the next adjacent cable, and to the next, untill arrives at the generator. No problem with this setup.

    Machine 3 asks for energy, and do the same thing, but since there's only one cable connected, theres no answer, so, no energy for you.

    Machine 1 asks for energy, and do the same thing. When arriving at the 4rd cable, we have a split. I will check for both sides, to see if I have any answer. The side to the Machine 3 will not give any answer, so the generator will be achieved.

    But the problem is, if I have a lot more connections, this could be very painfull to the processing, cause, they will be checking against all cable connected, and even worse, to all other machines connected to this cables, to check if they can provide any energy.
     
  8. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,445
    Minecraft's method is based on cellular automata rules.

    * A set of world locations is kept that indicate something about redstone power has changed or not. Only the potential changes are worth computing, to save CPU time.

    * If the player puts down a bit of wire, it is assumed to be unpowered and marked as a change.
    * If the player rips up a piece of wire, the empty space left behind is made to be unpowered and marked as a change.
    * If the player flips a switch or places or breaks a block that produces or consumes power, this is marked as a change.

    * Twenty times a second, power is calculated on all blocks in the world that are marked as a change, or are a neighbor to a changed block.
    --> if the block supplies power, it has strength 15
    --> if the block can carry power (like a wire), it has strength of the maximum neighbor minus 1, or 0 at minimum
    --> otherwise it has strength of 0
    --> if the block receives power, perform its action if the strength is above 0
    --> if this new calculated strength is different from last time, mark it as a change for the next round

    In this way, power propagates from supplier through all wires up to a distance of 15, but you don't spend extra CPU figuring out what has power next time. It doesn't matter if five wires all come together in a knot. The "maximum neighbor" rule ensures that power can only flow a maximum distance. The rules are a little more complicated sometimes, because blocks only receive or deliver power in certain directions, but that's the basics.
     
    Last edited: Oct 6, 2013
  9. Photon-Blasting-Service

    Photon-Blasting-Service

    Joined:
    Apr 27, 2009
    Posts:
    423
    Just google "truth tables" and "electronics" and you can learn from there.
     
  10. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    While this may work OK for voxel or tile-based world like Minecraft or The Powder Toy, for free-form world I'd suggest node-based approach.

    Basically each device keeps list of devices it is connected into (with some feedback capability so e.g. coffee maker can send to power outlet message "Can I join" and power outlet can respond "Sure"/"Nope" to avoid situations like connecting two things into one power outlet).

    You can then send signal easily without overheat characteristic for cellular automata.

    Power is trickier part there though. Basically you have distance between power outlet and say, coffee maker (need to get some coffee soon btw.) and know electrical resistance per in-game meter.
    Then based on resistance for specific kind of wire (can be more than one) devices are connected with, initial charge and distance, you can calculate final energy output out of simple formula.

    Node-based approach has this advantage that it runs faster compared to cellular automata one, but wires goes in straight way, even through walls, unless you incorporate some wacky math and some rope physics package (there is one on asset store) and calculate actual length of cable instead of distance between two devices.

    So it is not best of all possible solution, but certainly better than cellular automata unless you are making mineclone.
     
    Last edited: Oct 7, 2013
  11. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    Hey Photon, thanks again for your input, I already searched for this on google, and even watched a video on youtube which explains how this works.
    And after all I can only see this application to create a circuit between the inputs and outputs.
    I mean, I'm 2 inputs with 0 and 1 and I want to output 1, so I need to create some kind of circuit to make this possible.

    Again, I'm not a eletronic guy, but this was what I understand from the links I saw.
     
  12. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,445
    darkhog, agreed, you don't want to voxel the problem if you don't have to. But the same steps apply. It's a mark-and-sweep problem. You don't want to recalc everything but you want to recalc all the nodes and edges of a wiring graph that may have changed. Otherwise you put an unconnected wire on the floor in a circle, and it stays "hot" all day.
     
  13. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    Hey Halley... this could be a good approach. If I keep track of all cables inside de scene, and all adjacents cable to then, I believe that this could work.
    I mean, I'm not creating a mine clone, but I could hold some vector3 pointers to indentify each cable inside the scene, and do this thing.
    I will create some manager to handle this, and see, if this could work better than my actual approach.

    Thanks for your input.
     
  14. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    Hey darkhog, let's see if I understand your idea.
    So, every object energy capable, will keep a list of all other objects connected to them. Right ?
    Then, when the coffee maker needs power, this should loop over his list, to ask for energy. Then all objects which received this request, will do the same for theyre own list, and next do the same, until someone be able to provide, and return the energy. Is this ?

    [ coffe maker ] [ cable 1 ][ cable 2 ][ cable 3][ generator ]

    Using your approach, coffe maker, would have a list with cable 1 inside.
    When the energy need appears, coffee maker would send a request to cable 1, right ?

    Then cable 1, cannot supply energy, so cable 1 would send a request to cable 2. Not to coffee maker, because coffee maker cannot supply energy, and is not a energy conduit.
    Then cable 2, would do the same, send a request to cable 3, and to cable 1. Right ? Ok, I could handle a little, to avoid the request to the "requester", right ?

    But after all, cable 3 will reach the generator, and send back the energy to all other cables, and coffee maker will have the energy needed. But the problem I see, is when I have more than 1 cable connected to each other. Because then, I would need to have a manager for each cable, to handle all requests, and avoid requests to other "requesters". I really don't know if this is good solution. Specially when we talk about 20 or 30 cables inside the scene, doing the same thing over and over again.

    miksumortti already suggested something like this. Maybe I'm too dumb to understand how this really works. :p
     
  15. darkhog

    darkhog

    Joined:
    Dec 4, 2012
    Posts:
    2,218
    No, my idea is message-based. It only recalculates when signal is sent through wire (for that Unity's SendMessage would suffice).

    //edit: @rkaetano: Yes and no.

    Yes, because design like your is possible.

    No since it is not viable.

    Think of it like wiring of your house. You don't use lot of extenders to connect everything to one power outlet. That's just asking for trouble. You just connect it to nearest available socket.

    Also halley's method looks like this (excuse me my poor ms paint):

    So you have like 7 wires connecting to each other and asking for power. Not very efficient, is it?

    My solution looks like this:


    Just one wire.

    Also my idea makes wires "virtual" - each device stores list of other devices connected to it, where devices are power outlets, coffee makers, etc.. Then it calculate power from formula based on distance between devices, initial power (at output) and resistance of wire.

    If you have GMod, install WireMod - it's best example of this design I have seen so far.
     
    Last edited: Oct 7, 2013
  16. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    I see... the list with connected devices, it's just to know if they are connected or not. To pass the energy, I use the distance between.
    Today I will try to make something using this approach. This weekend I was far away from my computer with Unity. :p

    I will try, and I post here the results. Thanks.
     
  17. MarkrosoftGames

    MarkrosoftGames

    Joined:
    Jan 5, 2012
    Posts:
    442
    how complex are you trying to make this? do you really want it to be so life like, and worry about distance and volts and stuff?

    for a simple start, use a power source, transmitter (the cable) and the receiver (coffe machine, door, etc)
    then just keep track of wether its connected, and wether its powered.

    if your game is going to use it in a more complex manner, eg player has to find and place cable components, has to use batteries of certain power to add up to a correct voltage for the device to work etc, then expand it from there, but again try to keep it simple, is it connected? is it powered on? is the voltage correct? is the gap in the cable filled?
     
  18. rkaetano

    rkaetano

    Joined:
    Aug 27, 2012
    Posts:
    61
    Hey banreaxe, I'm not trying to create something life like. I just want to be able to detect when the machine is receiving energy or not... :p
    Something like the prison architect, and other games which allows you to connect machines with electricity, and have a generator doing that.
    I had some problems today, so I will not be able to check this today... :p

    But I will try some approach I saw here. ;)
     
  19. Divinux

    Divinux

    Joined:
    Jul 5, 2011
    Posts:
    205
    Skipping over the answers, this seemed like the perfect solution and I wondered why there were more alternative solutions following. Then I realized it's your own post. It's late. :confused:

    Even though you have some great answers by now, let me try this just for fun, because if the only concern is that it will check all connected cables I think can be eliminated by introducing a current direction.

    A Generator has a script with an array that takes gameobjects. That array is called Outbound or "-".

    A Wirepart has a script with that takes two gameobjects, one is called Inbound(+) and one is called Outbound(-). Additionally it takes a third object that is called "asking". When clicking on a Generator or other wirepart, it attaches itself to that object and adds itself to that objects Outbound variable. Then it adds that object to its own Inbound variable. On removal, the wirepart first deletes itself from the Outbound variable of the object that is its inbound, then deletes itself.

    A Machine has a script with an array Inbound or "+" that also takes gameobjects. When clicking a generator or wirepart it adds that object to its inbound variable, and itself to the objects outbound variable. Every minute it checks the first object in its Inbound array, and adds itself as the "asking" object. If its a generator, it remains powered. If its empty, check the next object in the array. If no objects in the array are connected to anything, it remains unpowered. If it is a wirepart, check that wireparts inbound object. If that object is also a wire, check that wires inbound object. If that object is a generator, return true to the "asking" gameobject so it remains powered.

    This works in my head. This way, each gameobject will only check once a minute, only one connection at a time, and only the connections that lead to a generator, and not away from one.
     
  20. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    This is going to be fun :)

    There are going to be a bunch of different ways to get functionality - all with different pro's and cons.

    Here's another way of thinking about it:

    //Initial Generation
    1) Put all the cable elements into a collection 'elements'.
    2) While there are elements:
    2.1) Pick an element.
    2.2) Find all adjacent cable elements, suppliers and consumers (recursively)
    2.3) Save this in a 'Cable' Object.
    2.4) Remove all used elements from the collection 'elements'.

    //Can I Receive Power?
    1) Since we now have a list of all generators and consumers attached to cable, comparing generation with consumption is easy.
    Option A) If we want to simulate this like a 'real' cable - if consumption is greater than generation consumers will work on reduced power. This can mean lower function or no function at all depending on the device.
    Option B) If we want to power devices in a first come first served basis, I suggest keeping consumers in order as you add them.
    Option C) If we want to apply other arbitrary rules e.g. max devices, types of power - this is relatively easy.

    //Adding/Removing a Generator/Consumer
    1) As long as we limit a generator/consumer to 1 cable this is fairly easy - simply add/remove the device to the 'cable' object and recalculate 'Can I Receive Power' for all consumers.

    //Adding/Removing a cable element
    1) Adding/removing cable element is easy, except when it:
    1.1) Merges two cables.
    1.2) Segments a cable into two.
    1.3) Disconnects a device.
    1.4) Connects a device
    2) For simplicities sake - I'd suggest running Initial Generation all over again, to ensure a consistent state.
    3) However, if performance does become an issue, each of the 'problem' cases can be identified and optimised without too much effort. Use the initial generation approach to validate your optimisations, and when confident turn it off for debug release.

    Basically I remove the idea of message passing and treat the system as one entity. The benefit of this system as it's very easy to treat everything as 'instantaneous'. Instead of sending message after message and then resolving those messages (which is entirely doable), we simple see how much power is being generated and consumed for each cable. Should any device change its consumption/generation than we simply redo this check. This is how the power grid works - it has consumers and generators attached together with a conductor... very simple. When we plug in a device, we are simply hoping there is enough capacity in the network for it to work without everything falling apart.


     
    Last edited: Oct 8, 2013