Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation of connect #89

Closed
tallakt opened this issue Apr 21, 2023 · 8 comments
Closed

Documentation of connect #89

tallakt opened this issue Apr 21, 2023 · 8 comments

Comments

@tallakt
Copy link

tallakt commented Apr 21, 2023

Hi. The connect functionality seems most useful, but after looking at the docs I was left very confused. After a little experimenting, I maybe figured out some things. I am asking to please elaborate the docs on this part to make it more understandable for an outsider.

An example;

# System is A -> B -> C
# no feedback for simplicity

my_named_tf = (tf, name) -> named_ss(ss(tf), x = Symbol("x_$name"), u = Symbol("u_$name"), y = Symbol("y_$name"))
a = my_named_tf(tf([1], [1, 0]), :a)
b = my_named_tf(laglink(10^-1, 10^0.5), :b)
c = my_named_tf(leadlink(10^0, 10^1, 1.0), :c)

# the docs do not describe such straightforward 1:1 connection
# actually I dont understand why the docs would have a connection :yC => :yC ?
connections = [b.y[1] => c.u[1], a.y[1] => b.u[1]]

# I want to be able to access my block diagram from any input and any output
yy = vcat([sys.y for sys = [a, b, c]]...)

# also I want to be able to access from any input
uu = vcat([sys.u for sys = [a, b, c]]...)

# create the graph
# note the docs dont really mention the z parameter which I found useful
block_diagram = connect([a, b, c], connections, w1 = uu, z1 = yy)

# now use the block diagram for different purposes
bodeplot(block_diagram[:y_c, :u_b])
bodeplot(block_diagram[:y_c, :u_a])
bodeplot(block_diagram[:y_b, :u_a])

The code above makes sense to me...

@tallakt
Copy link
Author

tallakt commented Apr 21, 2023

Also, no examples of using splitter or any docs that I can find

@baggepinnen
Copy link
Member

The code you post looks mostly correct, on master, you can use the Colon operator to denote "all signals". Here's an example using this

using ControlSystemsBase, RobustAndOptimalControl

a = named_ss(ss(tf([1], [1, 0])), :a)
b = named_ss(ss(laglink(10^-1, 10^0.5)), :b)
c = named_ss(ss(leadlink(10^0, 10^1, 1.0)), :c)

connections = [b.y[1] => c.u[1], a.y[1] => b.u[1]]

# I want to be able to access my block diagram from any input and any output
yy = (:)

# also I want to be able to access from any input
uu = (:)

block_diagram = RobustAndOptimalControl.connect([a, b, c], connections, w1 = uu, z1 = yy)

# now use the block diagram for different purposes
plot(
    bodeplot(block_diagram[:cy, :bu]),
    bodeplot(block_diagram[:cy, :au]),
    bodeplot(block_diagram[:by, :au]),
)

image

actually I don't understand why the docs would have a connection :yC => :yC

in the example, there is one output and one input both named yC so the connection becomes :yC => :yC

@baggepinnen
Copy link
Member

baggepinnen commented Apr 21, 2023

The z1 parameter is mentioned in the docstring
image

and here's an example using the splitter
https://juliacontrol.github.io/RobustAndOptimalControl.jl/dev/hinf_connection/
and this is mentioned in the docstring for connect

If an external input is to be connected to multiple points, use a splitter to split up the signal into a set of unique names which are then used in the connections.

@tallakt
Copy link
Author

tallakt commented Apr 21, 2023

I realize its possible to make this work, and even work better. My issue was just that even though the information is maybe there, it would benefit the average person who wanted to try this out to explain the details of the code a bit more... I could suggest some docs, but right now I'm not sure what to write.

@tallakt
Copy link
Author

tallakt commented Apr 21, 2023

help?> splitter
search: splitter splitext splitpath

  No documentation found.

  RobustAndOptimalControl.splitter is a Function.

  # 2 methods for generic function "splitter":
  [1] splitter(u::Symbol, n::Int64) in RobustAndOptimalControl at /Users/tallakt/.julia/packages/RobustAndOptimalControl/nd5G8/src/named_systems2.jl:470
  [2] splitter(u::Symbol, n::Int64, timeevol) in RobustAndOptimalControl at /Users/tallakt/.julia/packages/RobustAndOptimalControl/nd5G8/src/named_systems2.jl:470

@baggepinnen
Copy link
Member

I don't know what aspects of the docs you find confusing, I of course know how the function works so it's hard for me to see what's not clear for someone. This tutorial goes into a bit more depth of creating a block diagram, does that help?
https://juliacontrol.github.io/RobustAndOptimalControl.jl/dev/hinf_connection/

@tallakt
Copy link
Author

tallakt commented Apr 21, 2023

in the example, there is one output and one input both named yC so the connection becomes :yC => :yC

This is an example of something that is quite confusing to me. It seems there are two namespaces, one for inputs and one for outputs? But I don't understand why I need to connect?

Also, what is the first argument to connect? Should it include splitters?

This code has a lot going on, but the docs seem very sparse to explain whats going on between the lines.

@baggepinnen
Copy link
Member

Do these additional instructions help?
e50bfce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants