-
Notifications
You must be signed in to change notification settings - Fork 227
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
[feature] More control over wire parameters #56
Comments
A simple solution might be to allow every parameter of the cable/bundle to be either a string / int (applying it to all wires) or a list (length = wirecount),similar to how e.g. part numbers for bundles are handled now. It would be slightly more concise, and, when formatted cleverly, easier to read? W1:
category: bundle
length: 0.3 # maybe even this could become a list? does it make sense?
colors: [BK, BU, BU, RD ]
gauge: [0.25, 0.25, 0.5, 0.5 ]
manufacturer_part_number: [12344, 12345, 12346, 12343] Templating would not be as easy, though. Just a thought. |
Parameterizing is one of the major convenience factors of tools found in the commercial marketplace. For example being able to say "This part" then have that part be defined by a separate drawing, which is then pulled in at compile time - allows for that to be a separate file even that can be managed separately. Similarly, being able to do math in line on a parameter, allows for cases like "this branch needs to be 2/3 of the way along this trunk", where the trunk length is a variable and the Branch(Length) = Trunk(Length) * (2/3). This way if the trunk length is changed, the branch length will be changed maintaining the ratio. I think since this can become multi-dimensional, it's a good ideal to break this out earlier in a file as a general practice - much like doing "global defines". When it gets down to a bundle, this would be an array or arrays, with each conductor definition being its own array of defined attributes inherited from the conductor definition. |
For including data/templates from a separate file it looks to be possible to add support for this in pyyaml https://stackoverflow.com/questions/528281/how-can-i-include-a-yaml-file-inside-another |
It was added very discreetly and I haven't tested it, but at least running WireViz from CLI allows to include a 'prepend file' in addition to the source YAML (see code). I wouldn't want to mess too much with the pyyaml internals TBH, maybe this is a more reasonable approach? |
Just a bit of brainstorming here. We should look at this issue from two perspectives: 1. The internal data representationIt might make sense to shuffle around the representation of connectors and cables in the code, towards a more "object-oriented" approach, for lack of a better term. Example (not intended to be complete, just to show my general idea): cable:
name: ...
category: ...
type: ...
show_equiv: ...
... # other global parameters
wires:
1: # unique internal auto-incremented number
id: Wire1 # unique user-assigned ID, with case-sensitivity issues as per #160
label: VCC # arbitrary label
length: 123
gauge: 0.25 mm2
color: 0xFF0000 # internal unambiguous color for rendering
color_name: RD # user-visible color label
...
2:
... # repeat
... # repeat
additional_bom_items: This nested hierarchy would allow a good degree of granularity for all kinds of parameters, and cleanly separate between user-assigned info ( 2. The user inputFor many cases, some parameters nested within each individual wire in the example above, will be identical for all wires in a cable/bundle. Therefore, it would be nice to keep the current syntax for these simple cases to avoid repetition: W1:
gauge: 0.25mm2 # applies to all wires
length: 1 m # applies to all wires
colors: [RD, BK, ...] # gets split among all the wires
.. The question is how to expand this for cases where not all wires are identical.
Since the proposed internal representation would have all info split across all children (so as not to have to back-track to find inherited parameter values), it would be necessary to check at rendering time, whether a parameter (e.g. I am afraid that this would require a major refactoring, and perhaps it would be wise to issue a feature-freeze at some point to tackle this. I welcome any thoughts on this topic. |
When I read this, I get the impression that you are work down to the wire from the major cable - rather than defining a wire and then building a cable out of it parametrically. Think of it from the perspective of the cable designer. They would determine solid or stranded, and if stranded how many strands of what gauge wire. Then they would pick an insulation for that conductor or conductor bundle. From there they would group wire types (insulated, non insulated, non conductive, etc...), then that group might have a foil shield around it and that shield may be conductive to a drain wire on either face. There might be a a braided shield on outside that foil shield, then a jacket. This may be produced on a spool "put up" of 1000Meters or so (from my experience quoting custom cables). From there, the cable may be cut down to a length, then the jacket stripped back to reveal a conductor or sub group of conductors, and those individual conductors may then be stripped back and terminated to one of possibly many variety of terminations... If you built a wire, then a cable, then bundled cables - it might be more organizationally rational to manage the data that way, but be ready to override data both up and down.... For example, building a CAT-5 cable: Conductor:
Name: TypeA
Material: Copper
Type: Solid
Gauge: 23
Wire:
Name: TPHalf
Insulator: Fluorinated Ethylene Propylene
Conductor: TypeA
Bundle:
Name: TP
Wire1:
WireType: TPHalf
ColorSolid: {DEFAULT} # <-- need some mechanism to populate this variable with a later call by a reference name
Wire2:
WireType: TPHalf
ColorSolid: WH
ColorStripe: {DEFAULT}
TwistLength: 10mm
Name: CAT-5
Bundle1:
Type: TP
Wire1>ColorSolid: BU # <-- this is an example of overriding a child's variable with a later call by a reference name
Wire2>ColorStripe: BU
Bundle2:
Type: TP
Wire1>ColorSolid: OR
Wire2>ColorStripe: OR
Bundle3:
Type: TP
Wire1>ColorSolid: GR
Wire2>ColorStripe: GR
Bundle4:
Type: TP
Wire1>ColorSolid: BR
Wire2>ColorStripe: BR
Jacket:
Insulator: Polyvinyl Chloride
ColorSolid: {DEFAULT}
Cable:
Name: Network
Type: CAT-5
CAT-5>Jacket>ColorSolid:BU This would define a Blue Cat5 cable in a PVC jacket, with 4x twisted pairs of FPE insulated 23 gauge copper, in color groups of: Where I think you need a bit of work is the splits. Right now you seem to work on the individual conductor only presuming it has a start and end. I think you need to refactor that to presume cable bundling... If you define a cable bundle, your working presumption is that all of those internal wires are going to the same place (because... they are bundled). Say I wanted to split of just the Blue and Orange pairs from this bundle. Until I cut open the bundle and pull those pairs out, they are the same length as the other two pairs. I also can't have any more wires that I have inside a defined bundle - you'll see reference to this in my cable work-around in issue #174 . A bundle will stay a bundle until you split it. If I did split, it should only be able to fan-out what is inside it, the longest length of the fan-out plus the length of the unseparated bundle defines how long the total original bundle must be before cutting it (useful to know for BOM purposes, i.e. "start with a 25-foot length of CAT-5). I envision being able to connect a bundle only to what I'll call a "fan-out" on either end. Fan-out being either connected:
In this way I could, take an entire group of twisted pair conductors and (respectively):
So the take-away here is that if one defines the cable bundle from its base components, and spends a bit of effort defining what happens at each end of the bundle, there is no room for interpretation. Probably clear as mud... |
Thanks for your perspective! Really interesting insights.
Time to think about this a bit more, since it's clearly a major potential change... |
Copying the contents of #127 (closed for being closely related to the discussion here) for reference.
Currently, I believe @tim292stro's perspective is quite valuable, and might lead to a major refactoring in a later WireViz release... definitely not v0.3; perhaps a release of its own to prevent conflicts with other PRs running in parallel. |
I'm glad my comments helped rather than the alternative (sorry about the code block thing- my son needed my attention and I did not think to return to fixing that afterwards). I'll help where I can as WireViz's utility genuinely interests me. Looking at the above comment from #127 , I wanted to comment an agreement regarding leaving the pin types open to being sub-classified - when I read that comment I recalled MIL-DTL-38999 circular connectors with varying types of pins that can be used. Examples:
I see this as a common requirement, even if you refer up to my comment above (here) - a custom manufactured header for a robot to interchange end-effectors has essentially the same needs, where a drilled hole would be an equivalent "pin" location and could be stuffed with really anything (compressed air, vacuum, hydraulic pressure and return, locating boss, etc...). For the sake of conversation, what are the current data structures and limitations on inheritance (and which direction do those flow)? Above in this thread (here), @formatc1702 mentions a parameter being either a STRING or INT - I wanted to plant the seed of inline variable, and movement of data up and down the parent/child relationship. I did an example (which I'll edit in a moment to improve) of this above in the CAT-5 cable definition by surrounding something that had to be a reference in curly braces {}. Why I think this would be important, some values may need to be defined by default to exists, but you may wish to push down from a parent an attribute to a child, and being able to reference it and set its value (like a key/value pair). How I conceive of this being implemented from a high level, is that you define a structure that will eventually become the child of another object later. Then when creating a parent, all of the attributes of the parent and pre-processed, then if a replacement/override set exists - as the parent pulls in the child structure it does a replace as it come across the various matching parent definitions. Also consider the case of templates and workflows. Once I had created a part for CAT-5, I would not want to recreate that in future designs if none of the characteristics have changed - I'd want to pull that defined part from an external template. This would be especially important in the bundle level abstraction... Why I think this would be important, in engineering and manufacturing - cost sensitivity and functional performance is often related but secondary to what it already in a parts bin. from the perspective of a hobbyist or hardware hacker - one makes do with what they have laying around. If cost or performance genuinely creates a need for obtaining a new cable or wire, then that is the point of time where that effort is expended. This is similar to PCB design - one selects a part to do a job. If they already have it and "it'll do" then they probably already have the schematic symbol and the hole/pad layout. In pretty much every tool I've ever used in either the professionally or as a hobbyist, there has been some sort of component library. I consider WireViz as a back-end tool for a CAD-like workflow - we aren't necessarily designing the cable in YAML. If I said I wanted a cable to run from one termination point to another, and drew a complex 3D path - I might already need that path to know what the diameter of the cable is in order to bundle it or drill a hole for the bundle to pass through at the design stage to reduce rework needed when it's actually built. In a CAD program I might select a wire type as a template - and passing that template reference out to WireViz to build the harness simplifies/eliminates hand coding steps, and reduces the total amount of data that has to be managed. |
One idea that is developing in my mind, is to create a generic Originally posted by @kvid in #127 (comment), and slightly modified above A basic draft structure might look something like this: @dataclass
class BaseComponent:
# Maybe use this class as an attribute instead of a superclass below?
type: str
manufacturer: Optional[str] = None
mpn: Optional[str] = None
pn: Optional[str] = None
@dataclass
class AdditionalComponent(BaseComponent):
subtype: Optional[str] = None # Maybe move this to BaseComponent?
qty: float = 1
unit: Optional[str] = None
qty_multiplier: Union[DeviceMultiplier, ConductorMultiplier, None] = None
@dataclass
class Component(BaseComponent):
name: str
category: Optional[str] = None
color: Optional[Color] = None
image: Optional[Image] = None
notes: Optional[str] = None
show_name: bool = True
ignore_in_bom: bool = False
additional_components: List[AdditionalComponent] = field(default_factory=list)
@dataclass
class Device(Component):
style: Optional[str] = None
subtype: Optional[str] = None
pincount: Optional[int] = None
pinlabels: List[Pin] = field(default_factory=list)
pins: List[Pin] = field(default_factory=list)
show_pincount: Optional[bool] = None
hide_disconnected_pins: bool = False
autogenerate: bool = False
loops: List[List[Pin]] = field(default_factory=list)
@dataclass
class Connector(Device):
# Overriding BOM description and maybe add an optional reference to a mating connector
@dataclass
class Conductor(Component):
# Split this class into several subclasses: Cable, Bundle, Wire, OpticFibre, Tube, etc.
# while collecting common attributes in a common superclass
manufacturer: Union[str, List[str], None] = None
mpn: Union[str, List[str], None] = None
pn: Union[str, List[str], None] = None
gauge: Optional[float] = None
gauge_unit: Optional[str] = None
show_equiv: bool = False
length: float = 0
wirecount: Optional[int] = None
shield: Union[bool, Color] = False
colors: List[Colors] = field(default_factory=list)
color_code: Optional[ColorScheme] = None
show_wirecount: bool = True |
I've stewed on this for a bit and I think a way to express the relationship of a child object's structure is probably the least painful approach. An example revision to my above CAT-5 example:
In this way some simple rules can be defined which are probably easier to code:
|
I've decided to start a separate repo, dubbed Feel free to have a look, check the Readme, discuss in the issues and submit PRs! I expect this to be a parallel process to the regular WireViz development, and at some point in the future, I'd like to refactor WireViz using the results from WireViz-OO as a template. |
Based on discussions in #11 it might be worth adding the ability alter more properties of individual wires in a cable or bundle e.g. guage (an example would be a usb cable with two thinner wires and two power wires). This will obviously add some additional complexity to both the definition format and to rendering cables/bundles with multiple parameters.
This feature could also allow for sub wires to be templated which will make reusing wires in multiple bundles or several times in the same bundle easier. A modified format concept from #11 is shown below for reference.
The text was updated successfully, but these errors were encountered: