e2nIEE / pandapower

Convenient Power System Modelling and Analysis based on PYPOWER and pandas
https://www.pandapower.org
Other
885 stars 485 forks source link

Line-switch position is not on the line if the line-ends are not in the middle of a busbar #302

Closed marhofmann closed 5 years ago

marhofmann commented 5 years ago

Description

Busbar representations are a nice feature since it looks quite messy if a certain number of elements are connected to a bus. So i tried to use the new feature in an example. I tried to connect some lines to busbars at different positions on the busbar. I noticed, that the switching positions are not on the line if the ends of the line are not connected to the middle of the busbar even if i set the argument use_line_geodata=True in the function "pandapower.plotting.create_line_switch_collection".

See what happens with the following code

import numpy as np
import pandapower as pp
import pandapower.plotting as plot
import matplotlib.pyplot as plt

net = pp.create_empty_network()

# Createing buses as busbars
# Creating firstBus as Polygon with horizontal, vertical and diagonal lines
coords = [(3.5, 5), (4.5, 5), (5.5, 5), (5, 6), (3.5, 6), (3.5, 5)]
firstBus = pp.create_bus(
    net=net, vn_kv=10, geodata=coords[1], coords=[coords], index=1)
# Creating two buses as horizontal lines
coords = [(2.5, 2), (1.5, 2), (0.5, 2)]
secondBus = pp.create_bus(
    net=net, vn_kv=10, geodata=coords[1], coords=[coords], index=2)
coords = [(6.5, 2), (8.5, 2)]
thirdBus = pp.create_bus(
    net=net, vn_kv=10, geodata=(7.5, 2), coords=[coords], index=3)
# Creating bus as diagonal line
coords = [(6.5, 5), (8.5, 6)]
fourthBus = pp.create_bus(
    net=net, vn_kv=10, geodata=(7.5, 5.5), coords=[coords], index=4)
# Creating a bus as normal bus
fifthBus = pp.create_bus(net, vn_kv=10, geodata=(4.2, 3), index=5)

# Creating a line from the center of the busbar "firstBus" to the center of the busbar "thirdBus"
coords = [(4.5, 5), (5, 3.5), (7, 3.5), (7.5, 2)]
line = pp.create_line(net=net, from_bus=firstBus, to_bus=thirdBus, geodata=coords,
                      length_km=0.5, std_type="24-AL1/4-ST1A 0.4")
# Adding switches between the lines and the busbars
pp.create_switch(net, firstBus, element=line, et="l")
pp.create_switch(net, thirdBus, element=line, et="l")

# Creating a line from another point of busbar "firstBus"
# to a point on the busbar "secondBus" (not the center points of the busbars)
coords = [(3.8, 5), (3.8, 3.5), (2, 3.5), (2, 2)]
line2 = pp.create_line(net=net, from_bus=firstBus, to_bus=secondBus, geodata=coords,
                       length_km=0.5, std_type="24-AL1/4-ST1A 0.4")
# Adding switches between the lines and the busbars
pp.create_switch(net, firstBus, element=line2, et="l")
pp.create_switch(net, secondBus, element=line2, et="l")

# creating a line from a point on the vertical line of the busbar "firstBus"
coords = [(3.5, 5.5001), (0.5, 5.5001), (0.5, 2)]
line3 = pp.create_line(net=net, from_bus=firstBus, to_bus=secondBus, geodata=coords,
                       length_km=0.5, std_type="24-AL1/4-ST1A 0.4")
# Adding switches between the lines and the busbars
pp.create_switch(net, firstBus, element=line3, et="l")
pp.create_switch(net, secondBus, element=line3, et="l")

# Creating a line from the diagonal part of the busbar "firstBus" (not the center)
# to another diagonal busbar "fourthBus"
coords = [(6.7, 5.1),  (5.18694, 5.62612)]
line4 = pp.create_line(net=net, from_bus=firstBus, to_bus=fourthBus, geodata=coords,
                       length_km=0.5, std_type="24-AL1/4-ST1A 0.4")
# Adding switches between the lines and the busbars
pp.create_switch(net, firstBus, element=line4, et="l")
pp.create_switch(net, fourthBus, element=line4, et="l")

# Creating a line from the busbar "firstBus" (not the center)
# to the normal bus "fifthBus"
coords = [(4.2, 5),  (4.2, 3)]
line5 = pp.create_line(net=net, from_bus=firstBus, to_bus=fifthBus, geodata=coords,
                       length_km=0.5, std_type="24-AL1/4-ST1A 0.4")
# Adding switches between the lines and the busbars
pp.create_switch(net, firstBus, element=line5, et="l")
pp.create_switch(net, fifthBus, element=line5, et="l")

# Checking the grid with a power flow
pp.create.create_ext_grid(net, secondBus)
pp.create.create_load(net, secondBus, p_kw=100)
pp.create.create_load(net, fourthBus, p_kw=100)
pp.create.create_sgen(net, thirdBus, p_kw=200)
pp.runpp(net)

# Creating collections for busbars, lines, switches and the normal bus(no collections for external grid, loads and static generator)
li = plot.create_line_collection(net, use_bus_geodata=False, color="k")
bb = plot.create_busbar_collection(net, color="b")
ls = plot.create_line_switch_collection(
    net, size=0.12, distance_to_bus=0.2, use_line_geodata=True)
b = plot.create_bus_collection(net, buses=[fifthBus], size=0.02, color="b")

# Creating annotation collections for busbars
buses = net.bus.index.tolist()
coords = zip(net.bus_geodata.x.loc[buses].values+0.2,
             net.bus_geodata.y.loc[buses].values-0.2)
bic = plot.create_annotation_collection(size=0.2, texts=np.char.mod(
    '%d', buses), coords=coords, zorder=3, color="r")

# Draw collections
plot.draw_collections([bb, b, li, ls, bic], figsize=(9, 4))
plt.show()

switches_not_on_lines

Fix

I fixed this with a new function "onBusbar" in the collections.py. The function returns the intersection of a line with a certain busbar. Additionally i added a call of this funciton in the "pandapower.plotting.create_line_switch_collection" function and i changed an operator in an if-condition. The result looks like this: switches_on_lines

I will add a pull request for this Fix.

lthurner commented 5 years ago

The create_busbar_collection was only recently added, so it wasn't yet tested with the switch collections. Great job on making it work, thanks a lot!

Yes the solution does look a little clunky, but I would merge it for now and see if it can be refactored at some point. The easiest way to do this would be using the shapely package, but that can be a little tricky to install so it wouldn't be worth it to include this as a requirement....