5.3 User-defined Primitives shipped with OpenCSM
8.0 Bug Reports and Other Feedback
The Engineering Sketch Pad (ESP) is a browser-based program for
creating, editing, and generating constructive solid models for
use in the multi-disciplinary analysis and optimization of
engineered systems. ESP
can use either the
EGADS/OpenCASCADE
or CAPRI
geometric
modeler.
In most cases, a user will start with a configuration that is
described in a .csm
file and then modify it and/or
build it via OpenCSM
's various commands.
This Tutorial will help you understand the use
of serveCSM
and ESP
for a variety of
tasks. Details about the Command Line, cursor and keyboard
options, and the .csm
file are contained in
sections that follow this Tutorial.
The Tutorial starts with a pre-made part that is defined by the
file tutorial1.csm
. (See
"Example .csm
file" below for a listing of this
file.)
To start ESP
there are two steps: (1) start the
"server" and (2) start the "browser". This can be done in a
variety of ways, but the two most common follow.
Technique 1: issue the two commands:
setenv WV_START "open -a /Applications/Firefox.app ../ESP/ESP.html" serveCSM ../data/tutorial1if using a c-shell; make appropriate changes for your shell and/or operating system.
The first of these tells serveCSM
to open FireFox
on the file ../ESP/ESP.html
when serveCSM
has generated a graphical
representation of the configuration. The second of these
actually starts the serveCSM
server. As long as
the browser stays connected
to serveCSM
, serveCSM
will stay alive
and handle requests sent to it from the browser. Once the last
browser that is connected to serveCSM
exits, serveCSM
will shut down.
Technique 2: issue the command:
serveCSM ../data/tutorial1Once the server starts, start a browser (for example, FireFox) and open the page
ESP/ESP.html
. As
above, serveCSM
will stay alive as long as there is
a browser attached to it.
Note that the default "port" used by serveCSM
is
7681. One can change the port in the call
to serveCSM
with a command such as:
serveCSM ../data/tutorial1 -port 7788
Once the browser starts, you will be prompted for a "hostname:port" as in:
Most of the time, the "hostname" will be "Localhost" (meaning
that serveCSM
and the browser are on the same
computer). It is possible to attach to serveCSM
that is running on another computer by giving an appropriate
"hostname".
As mentioned above, it is possible to change the "port" with
a command line argument when starting serveCSM
; if
that is done, then the alternative "port" must be included in
ESP
's prompt.
Once all the setup is done, the browser then presents the following 4 windows:
The window on the top left is called the "Tree" window. It contains listings of the Parameters and Branches in the Model. It also contains the controls for the "Graphics" window.
The window on the top right is called the "Graphics" window. It contains a graphical representation of the current configuration. Occasionally, the "Graphics" window will contain a form (such as when adding or editting a Branch); when a form is present, you must press Cancel or OK in the form to return to the graphical representation.
The window on the bottom left is the "Key" window. If the user has asked for a sensitivity calculation, this window will contain an annotated spectrum to tell the user the meaning of the colors in the "Graphics" window; otherwise the "Key" window will be blank.
The window on the bottom right is called the "Messages" window.
It contains the messages that ESP
posts for the
user.
The first thing to do is to play with the image in the "Graphics" window. This is done with the mouse in the following ways:
When using the mouse, it is possible to enter "flying mode", in which the view continually changes until the mouse button is released. Flying mode is particularly useful when one needs to translate a long distance. Toggling flying mode is done by pressing the "!" key in the "Graphics" window.
At any time, a user might want to "save" a view for later use in the browser session. This is done by pressing the ">" key; the "saved" view can be retrieved by pressing the "<" key.
The default (home) view can be obtained by pressing "<Home>". (The home view is one in which the x-coordinate increases from left to right and the y-coordinate increases from bottom to top.)
The function of the arrow keys depends on whether "flying mode" is active or not. For example, if "flying mode" is not active (the default), pressing the "<Left>" key causes the object to rotate to the left by 30 degrees; if "flying mode" is active (because the "!" key was pressed), then pressing the "<Left>" key causes the object on the screen to translate to the left. If the Shift is held while the <Left> key is pressed, the increments are 5 degrees and the translations are also smaller.
The "<PgUp>" key can be used to zoom in and the "<PgDn>" key can be used to zoom out. The behavior of these keys does not depend on the current "flying mode".
To re-center the image at a given point and simultaneously reset the point about which mouse rotations will occur, point to any location in the "Graphics" window and press "*"; the image will be recentered and a message will be posted in the "Messages" window.
To determine the identity of any object in the "Graphics" window, simply put your cursor on the object and press "^"; a summary of the identified object is shown in the "Messages" window.
To determine the approximate coordinates of any location in the "Graphics" window, simply put your cursor on the location and press "@"; the approximate coordinates of the location are shown in the "Messages" window.
Lastly, to get help on the commands that are available in the "Graphics" window, press "?" and a short listing will be given in the "Messages" window.
The results of several of these commands is shown in:
Now it is time to understand the "Tree" window. At the top of the "Tree" window is a series of buttons:
ESP
HELP document (that you are now
reading).csm
file
Below the buttons is a tree-like representation of the "Design Parameters", "Local Variables", and "Branches" that describe the current "Model". In all cases, pressing the "+" at the beginning of any line expands (opens up) that particular entry in the tree; pressing the "-" at the beginning of any line collapses (closes) that particular entry.
Start off by pressing the "+" to the left of the words "Design Parameters". When this is done, all the Design Parameters in the current Model are displayed as shown in:
Notice that the Design Parameter names are shown in green type; this indicates that the Parameter can be "edited" by the user; the Local Variable names are listed in black type and cannot be edited.
Press on the label "Lbar" to edit the Parameter named "Lbar". When this is done, the user is provided with a prompt that asks for the new value; the current value is pre-loaded in this prompt window, as in:
For now change the value to "9" and press OK. Note that the Parameter name is now listed in red (to indicate that it has been changed) and that the button at the top of the "Tree" window has changed to a green button that says "Press to Re-build". This tells the user that changes have been made, but that the configuration shown in the "Graphics" window has not been updated. (The reason this is done is that a user might want to make several changes to the "Model" before spending the CPU time necessary to re-build.)
Press the "Press to Re-build" button and notice that it first turns yellow while the configuration is being rebuilt. Then (after a few seconds) the image in the "Graphics" window will be updated and the "Design Parameters" will no longer be red.
We will now change the value of "Lbar" back to "6". (Do not re-build yet.)
Collapse the Parameters by pressing the "-" to the left of the word "Design Parameters" and expand the Branches by pressing the "+" to the left of the word "Branches". This will result in a screen that looks like:
There is an "Undo" button near the top of the "Tree" window. This button un-does your last change; an example of using this is shown later in this tutorial.
We are going to want to add a "sphere" to this configuration. Do this by pressing "Branches", giving you:
The different types of Branches that can be added are listed in groups. The groups at the top, which are labelled, generally construct or modify Bodys. The Branches listed at the bottom are utilities, which generally effect the order in which the Branches are executed. Those branches marked with a star (*) are deprecated, meaning that they may be removed in future versions of ESP. Those marked with plus signs (+) are commands that are expected to be added in the future.
We will choose a "sphere" and press OK, giving us:
Now fill in the entries with "xcent" set to "1", "ycent" set to "0", "zcent" set to "0", and "radius" set to "2". Press OK and then "Press to Re-build" and you should see:
Now let's look at the "Display" part of the "Tree" window. By default "Display" is expanded and you can see that you have two bodies named "Body 10" and "Body 9". Expand the listing for Body 9 by pressing the "+" to the left of "Body 9" and you will see entries for faces and edges. To the right of "Faces" (below "Body 9") you will see three items:
Notice also that there is a "+" to the left of "Faces", which indicates that you can interact with the object on a face-by-face basis. The basic rules here are:
Now let's "combine" the sphere and the original solid by adding a "union" Branch. (Press "Branches" and add a "union"). This operation wants to know if the operation should be applied to the top two Bodys on the stack (tomark=0) or to all the Bodys on the stack since the last mark (tomark=1). For now, we want to use the default (tomark=0). Re-build the configuration and you should get the solid shown in:
Note that we now only have one body. (Body 11)
After some thought you realize that you really didn't want the fusion of these two volumes, but instead you wanted the solid that is common to them. First, remove the "union"; this can easily be done by clicking on "Brch_00012" and then choosing "Delete this Branch". (Alternatively you can press the "Undo" button at the top of the "Tree" window.)
Now add the intersection by pressing "Branches" and then choosing "intersect". This operation wants to know what happens if more than one solid is produced by the operation. Specifically, the "$order" argument describes how the bodies that are produced should be ordered: for example in order of volume, surface area, ... The "index" argument tells which body in the list should be selected. Since we are only expecting one body to be produced, we can leave the defaults and then "Press to Re-build", producing:
You notice that the "head" is too thin, and so you change the "radius" of the "sphere" to "2.3". (Press "Brch_000011" and change the "radius".) While you are at it, change the Parameter "Rbar" to "0.4" (you will need to expand the Design Parameters) and rebuild, producing:
Now we want to drill a hole through the center of the shaft; this is done by subtracting a cylinder from the solid. Create a cylinder by selecting "Branches" and "cylinder". We want the hole to go the entire length of the configuration (which is centered and whose length is 2*L), and so we enter "-1.2*L" for "xbeg" and "+1.2*L" for "xend"; the "1.2" simply ensures that the cylinder extends beyond the end of the configuration. Since it is on the centerline, set "ybeg", "zbeg", "ybeg", and "yend" all to "0", and finally the "radius" to "0.2".
Note that any argument can either be entered as a numeric constant or as an expression (using Matlab-like syntax), possibly using the name of a Design Parameter (such as "L") or a Local Variable.
To add the "subtract" Branch, we will click on "Branches" and then choose "subtract", use the defaults and rebuild, producing:
Now we want to create a series (pattern) of small holes that
are drilled across the shaft. Start by creating a new Parameter
(by clicking on "Design Parameters") and name
it "Rhole". The rules for names is that they must start with a
letter and contain up to 32 letters, digits, and underscores.
Since Design Parameters can have multiple values (think
"array"), ESP
asks for the number of rows and
columns. Since we only have a single value, enter "1" for both
of these. You are then presented with a form such as:
Set the (only) value to "0.08".
Now we are going to add a pattern of holes. Do this by adding a new "patbeg" Branch; the "$pmtrName" will be "i" and the "ncopy" will be 7 (since we want 7 holes). (The "$" at the beginning of "$pmtrName" says that this is the name of the Parameter that will be created rather than the value of the Parameter "i". Also add a "cylinder" with "xbeg" and "xend" set to "i/3", "ybeg" and "yend" set to "0", "zbeg" set to "-1", "zend" set to "+1", and "radius" set to "Rhole". Press OK.
We would now like to name this Branch. To do this, edit the Branch (by pressing "Brch_000017") and change its "Name" to "small_holes". (Notice that we could not name it when we created it since the names are originally auto-created to ensure that we do not get an illegal name.)
Next add another "subtract" Branch (with the default arguments) and finally a "patend" Branch and then re-build (which will take several seconds), giving:
Now we want to change the hole in the center of the shaft into a hole that starts at "xbeg" equal to "0". Make the change to "Brch_000014" and re-build. To see if you were successful, change the visibility of the faces and ensure that you have the correct hole, as in:
Now change the cylindrical hole into a conical hole. To do this, we must delete the cylinder hole (which is Brch_000014). Click on "Brch_000014" and choose "Delete this Branch". Notice that doing this tells you that you have an error. To fix the error, add a conical hole after "Brch_000013" by clicking "Brch_000013" and choosing "Add new Branch after this Branch", as in:
Re-build and notice that the vertex of the cone is near the head; you will have to change the visibility of the Faces to see this. We had meant to do it the other way, so change "xvrtx" to "0" and "xbase" to "1.2*L" and re-build, producing (after manipulating the display):
Now let's rotate the small holes, so after the "small_holes" Branch, add a "rotatex" with arguments "-15*(i-1)", "0", and "0", and rebuild, producing:
Now we will experiment with the "activity" of the Branches. A Branch that is "suppressed" is skipped during the re-build process. So click on the "small_holes" branch and change the "Activity" from "Active" to "Suppressed", and select OK. Note that a few other Branches become "inactive" (since they cannot be executed). Re-build, producing:
Now similarly suppress "Brch_000021" and activate "small_holes" and re-build. Note that the hole re-appeared but that the rotatex is not executed. Finally, re-activate all Branches and re-build.
Another feature is ESP
allows a user to only build
part of the configuration. This is done by clicking on a Branch
(for example, "Brch_000010") and choosing "Build to this
Branch", giving:
To rebuild the whole configuration, re-build to the last Branch by clicking it and choosing "Build to this Branch".
The next part of the ESP
tutorial involves
attributes. Each Branch can have zero or more attributes
associated with it that are carried throughout the build
process. By pressing the "+" to the left of
"Brch_000009", its attribute ("clipper") can be seen to have the
value "1". Change the attribute to "10" by pressing "clipper"
and entering "10" at the prompt.
We can add an attribute to "Brch_000009" by choosing "Add Attribute"; use the name "test" and the value "ESP". Press the "+" to the left of "Brch_000009" and you will see that the Branch now has 2 attributes. After some thought, you realize that "ESP" is not defined, so you can "undo" this change by pressing the "Undo" button at the top of the "Tree" window. Re-build.
Now point to the face that represents the corner of the head (as shown with its grid here) and press the "^" key, producing:
(Depending on the version of OpenCASCADE that you are using, the face number that is returned may be different.)
Note that the "Messages" window contains a description of the face including the attribute that we edited ("clipper" is "10") as well as a "body" and "brch" attribute. The latter tells which Branch ("Brch_000009") was responsible for generating that face.
A unique feature of ESP is that it allows a user to compute the sensitivity of the configuration with respect to any perturbation in the specified parameters. Most often this is done by clicking on a the name of one of the Design Parameters and selecting "Compute Sensitivity".
For the current case, expand the Parameters list (in the Tree window) and click on "Rbar" and select "Compute Sensitivity". ESP notes this by putting a caret before the "Rbar" and then will automatically compute the sensitivity and display, in the Graphics window, an updated configuration that is colored based upon the change in the local surface normal; positive sensitivity indicates that the surface will tend to move in the direction of the outward normal. The Key window will show the meanings of the various colors and will be titled "d(norm)/d(Rbar)", as in:
To change the limits of the color spectrum, left click in the Key window and you will be prompted for the minimum value (associated with blue) and the maximum value (associated with red). Try clicking on the Key window and set the limits to "-1" and "+1" and see how the display changes.
Now ask for the sensitivity with respect to "D" (click on "D" and select "Compute Sensitivity") and again the display will automatically update.
Occasionally one wants to know the change in the configuration based upon the perturbation of more than one Parameter (at the same time). To do this, first clear all the Design Velocities by clicking on any Design Parameter and choosing "Clear Design Velocities". Now click on "Rbar" and "Set Design Velocity" to 1 and then click on "Rhole" and "Set Design Velocity" to 1.5. Now manually re-build the configuration (since you may want to set the Design Velocity for multiple parameters before rebuilding). Note that the legend in the Key window will now be "d(norm)/d(***)", indicating that there was either more than one Design Parameter for which the Design Velocity was set (see that Rbar and Rhole both are prepended with a caret to indicate this), or there is one Parameter whose Design Velocity is not unity (and hence the color does not show sensitivity but rather a scaled sensitivity.)
Readjust the limits of the Key window again to -2 and 1 (by clicking in the Key window to get the prompts).
Lastly, save your work by pressing the "Save" button and
choosing "tutorial1_new.csm" as the name of the new file. Exit
the browser and you should see that serveCSM
also
shuts down.
If we now rename the file journal file (which was automatically generated while you were running ESP) with:
mv port7681.jrnl tutorial1.jrnlwe can replay our session by the command:
serveCSM ../data/tutorial1 -jrnl tutorial1.jrnl
Alternatively, we can start with the new
tutorial1_new.csm
file with the command:
serveCSM tutorial1_new
This tutorial covered most of ESP
's user
interface. Further details are contained in the sections that
follow.
For the second tutorial, we will start serveCSM
without a .csm
file and investigate the various
filleting, chamfering, and hollowing options.
Start serveCSM
with commands such as
setenv WV_START "open -a /Applications/Firefox.app ../ESP/ESP.html" serveCSMThis will bring up the browser with no "Design Parameters", "Local Variables", or "Branches".
Click on "Branches" and create a "sphere" centered at the origin with radius of "0.5". Then click on "Branches" to create a "box" anchored at "0", "0", "0" (which is at the center of the sphere) and specify its length, width, and height to be "1". Build this configuration, producing:
We will now set up for our exploration of fillets (and chamfers). These operations are performed on the last primitive (such as "box" or "cylinder") or last Boolean operation (such as "intersect", "union", or "subtract"). If we were to add a "fillet" Branch now, it would be applied to the "box".
But before we do that, let up set up a design parameter that defines the Edges to be filleted. Do this by clicking "Design Parameters" and adding one called "edges", that has 2 rows and 2 columns with the values "2", "4", "2", and "3".
We can now add a "fillet" Branch with a radius of "0.1" and an "$edgeList" set to "edges". Build this configuration, producing:
The way
ESP
determines which edges to fillet is
based upon the code included in "edges". Specifically,
ESP
takes pairs of elements from "edges" and
interprets them (in order) as:
We will now investigate several other options. To do this, we will specify the "$edgeList" directly with a comma-separated list rather than by reference to a Design Parameter. Expand the "Branches" list (by clicking on the "+" to the left of "Branches"). Now click on "Brch_000002" and change "$edgeList" to "2,4,2,3" and rebuild. You should get exactly the same result as before.
Now change the "$edgeList" of "Brch_000002" to simply "2" and
rebuild. You should get an error, since ESP
expects
the entries in "$edgeList$" to come in pairs.
Now change the "$edgeList" of "Brch_000002" to "2," and rebuild. Since there was a naked "," at the end of "$edgeList", a "0" was implicitly added. The pair of entries now consisted of "2" and "0", meaning that all Edges associated with the "2" (right) Face are to be filleted, producing:
Now change the "$edgeList" of "Brch_000002" to "2,4" and rebuild. This should fillet the "2" (right) "4" (top) Edge.
Now change the "$edgeList" of "Brch_000002" to "2,4," and rebuild. Again the naked "," at the end of "$edgeList" adds a "0". Since there is not an even number of entries ("2", "4", and "0") an error results.
Now change the "$edgeList" of "Brch_000002" to "2,4,2" and rebuild. Again, an odd number of entries causes an error.
Now change the "$edgeList" of "Brch_000002" to "2,4,2," and rebuild. This results in the Edge(s) between "2" (right) and "4" (top) being selected, followed by all the Edges associated with Face "2". Since the latter pair essentially over-writes the "2" "4" selection, this is the same as "2,0" which we saw above.
Now change the "$edgeList" of "Brch_000002" to "2,4,2,3" and rebuild. This should fillet the "2" (right) "4" (top) Edge and the "2" (right) "3" (bottom) Edge, yielding the same result as we had when we used "edges".
Changing the "$edgeList" of "Brch_000002" to "2,4,2,3," and rebuilding once again produces an error since the implicitly-added "0" (by the naked trailing ",") results in an odd number of entries.
Finally, change the "$edgeList" of "Brch_000002" to "0,0,-2,-4,-2,-3" and rebuild, producing:
To understand why this happens, the "0,0" at the beginning
selects all the Edges, then the "-2,-4" unselects the Edge
between "2" (right) and "4" (top), then the "-2,-3" unselects
the Edge between the "2" (right) and "3" (bottom) Faces.
Now add a "union" Branch with the defaults and then a "chamfer" Branch with its "radius" to set "0.2" and "$edgeList" to "0".
The "chamfer" works exactly the same as the "fillet". But because the last Branch was a Boolean ("union"), it creates the chamfer on the intersection of the sphere and the box. When the "fillet" or "chamfer" is associated with a Boolean, the values in "$edgeList" are ignored and all Edges are automatically filleted of chamfered. The resulting configuration is:
Fillets and chamfers can be suppressed by changing their "Activity" to "Suppressed". Rebuild. Reactivate them and rebuild.
Lastly we will investigate the "hollow" command. Since this command is rather fragile, we are going to start off by deleting "Brch_000005", "Brch_000004", and "Brch_000003" (by selecting them and choosing "Delete this Branch"). Rebuild.
Now identify the Faces on the left and right of the configuration by pointing to it and pressing "^"; you should see that they are faces 1 and 2. Here we are using the actual Face number and not the face-order as we did for fillets and chamfers.
Now add a "hollow" Branch with its "thick" set to "0.1" and "$faceList" set to "2,1". This says to make a Body whose shell thickness is 0.1 and which pokes through the left (1) Face of Body 2.
If we wanted to remove both the left and right Faces, edit "Brch_000006" and set "$faceList" to "2,1,2,2" and rebuild.
Note that we significantly simplified the configuration before using "hollow". Experience has shown that this command is very fragile and should be avoided if possible. For example to avoid it in t his case, it would have been more robust to "subtract" a smaller "box" from the outer "box".
For the third tutorial, we will start serveCSM
with the file data/tutorial3.csm
, which represents
a fighter-like aircraft using blends and ruled surfaces.
Start serveCSM
with commands such as
setenv WV_START "open -a /Applications/Firefox.app ../ESP/ESP.html" serveCSM ../data/tutorial3After a few minutes, the following will appear:
We are going to modify this case by using the Edit button. Pressing it gives:
Listed in the "Graphics" window is a listing of
the tutorial3.csm
file. We will dissect this file
in a few minutes. But first, edit the file by adding the
following after line 2:
# this is an added line
If you now press the Cancel button, the change
you made will not be saved and the original aircraft picture
will appear. To see this, press the Edit
button again and you will see that we have the
original tutorial3.csm
file. Now edit the file by
adding the following after line 2:
# this is another added lineWhen we press the OK button, you will be asked if you want to over-write the original file. Press OK to this question and then the file will be updated and the configuration will rebuild with the updated file. (This happens now even though the changes were inconsequential because all we did is added a comment.)
Now add a new Design Parameter called "xyz" that has 1 row and 3 columns, with the values "11", "22", and "33". (Recall that this done by clicking on "Design Parameters" in the "Tree" window.)
If we try to Edit the file
again, ESP
will inform you that you made changes
interactively and that you must save those changes first. Press
the "Save" button and give the new file the name "foo".
If you now press Edit, you will see that the
new current file is foo.csm
. You will also see
that this file is formatted differently from your
original tutorial3.csm
file. For example, the
arguments in foo.csm
are not nicely spaced as they
were in the original tutorial3.csm
file. As a
result, you will probably find it easier to only make changes
via the user interface (as you did in tutorial 1) or to edit the
file directly using the Edit button. You can
now Cancel out of the editor, bringing back the
picture of the airplane.
In addition to understanding how
to Edit .csm
files, this tutorial
also describes best practices when writing a .csm
file. So let's now dissect the
original tutorial3.csm
file.
As a good practice, it is suggested that you add comments to the top of the file, such as:
# tutorial3 # written by John Dannenhoffer
This is then followed by the Design Parameters. Those that describe the fuselage are given by:
# design parameters associated with fuselage # x y zmin zmax dimension fuse 15 4 1 despmtr fuse " 1.00; -0.40; -0.20; 0.20;\ 2.00; -0.60; -0.30; 0.50;\ 3.00; -0.60; -0.30; 0.80;\ 4.00; -0.60; -0.30; 1.20;\ 5.00; -0.60; -0.20; 1.20;\ 6.00; -0.60; -0.10; 1.00;\ 7.00; -0.60; 0.00; 0.80;\ 8.00; -0.50; 0.00; 0.70;\ 9.00; -0.40; 0.00; 0.60;\ 10.00; -0.30; 0.00; 0.60;\ 11.00; -0.30; 0.00; 0.60;\ 12.00; -0.30; 0.00; 0.60;\ 13.00; -0.30; 0.00; 0.60;\ 13.90; -0.30; 0.00; 0.60;\ 14.00; -0.30; 0.00; 0.60;" dimension noseList 2 4 1 despmtr noseList "0.20; 0; 1; 0;\ 0.10; 0; 0; 1"Here,
fuse
is a 15 row, 4 column, Design Parameter
with the given values. The values are listed across rows, with
semi-colons between the various entries. Since spaces are used
to enhance readability, the entire list of values is placed
between quotation marks. Also, since the inputs are split
across multiple lines, the backslash character is used to
denote that the next line should be concatenated with the
current line before processing; all characters starting at the
backslash are ignored. The noseList
Design
Parameter has 2 rows and 4 columns. (More on the use of these
Design Parameters below.)
The Design Parameters that describe the wing, horizontal and vertical tails are given by:
# design parameters associated with wing despmtr series_w 4409 dimension wing 3 5 1 # x y z chord angle despmtr wing " 4.00; 0.00; 0.20; 6.00; 0.00;\ 7.00; 1.00; 0.20; 3.00; 0.00;\ 9.00; 4.60; 0.10; 1.00; 20.00;" # design parameters associated with htail despmtr series_h 0406 despmtr xroot_h 12.10 despmtr zroot_h 0.20 despmtr aroot_h 0.00 despmtr area_h 7.28 despmtr taper_h 0.55 despmtr aspect_h 3.70 despmtr sweep_h 25.00 despmtr dihed_h 3.00 despmtr twist_h 2.00 set cbar_h sqrt(area_h/aspect_h) set span_h cbar_h*aspect_h set croot_h (2*cbar_h)/(taper_h+1) set ctip_h taper_h*croot_h set xtip_h xroot_h+(span_h/2)*tand(sweep_h) set ytip_h span_h/2 set ztip_h zroot_h+(span_h/2)*tand(dihed_h) set atip_h aroot_h+twist_h # design parameters associated with vtail despmtr series_v 0404 despmtr xroot_v 11.20 despmtr zroot_v 0.50 despmtr area_v 9.60 despmtr taper_v 0.30 despmtr aspect_v 3.00 despmtr sweep_v 45.00 set cbar_v sqrt(area_v/aspect_v) set span_v cbar_v*aspect_v set croot_v (2*cbar_v)/(taper_v+1) set ctip_v taper_v*croot_v set xtip_v xroot_v+(span_v/2)*tand(sweep_v) set ztip_v zroot_v+span_v/2
Notice the "set" statements that compute Local Variables in
terms of the Design Variables. For example, the mean-chord of
the horizontal tail (cbar_h
) is computed as the
square-root of the ratio of the tail area and the tail aspect
ratio.
Now we are going to build the fuselage. This will be done using by blending data from various cross-sections. The sections the will ultimately be blended are those back to the previous "mark". This is done with the code:
# build the fuselage mark
We want to begin the fuselage at a point. This is accomplished by using a sketch with only one entry, such as:
skbeg 0 0 0 skendThis creates a point at the origin.
Then we need to generate the remaining 15 cross-sections. This is done with a "pattern" (similar to a "for" loop in MATLAB):
patbeg i 15 udprim ellipse ry abs(fuse[i,2]) rz (fuse[i,4]-fuse[i,3])/2 translate fuse[i,1] 0 (fuse[i,4]+fuse[i,3])/2 patendWithin the pattern we create an ellipse (using the "ellipse" user-defined primitive) with its parameters taken from the second, third, and fourth columns of the
fuse
Design Parameter. Each cross-section is then translated into
its final position using the translate
statement.
The patend
statement closes the pattern. (Although
not used here, it is possible to enclose patterns within
patterns.)
Finally we will generate the fuselage by blending the point and
15 sections (everything since the mark
) using:
blend noseList
At this point it is worth looking into
the noseList
. The first four entries (the first
row) contain the nose radius in the direction specified (in this
case, "0,1,0", which is a vector in the "y"-direction). The
next four entries contain the nose radius in the "0,0,1"
direction (which is the "z"-direction). Similar coding would be
used at the tail if a tailList
had been specified
as the second argument in the blend
command.
The wing is built in a similar manner using a ruled surface. The code here is:
# build the wing mark udprim naca Series series_w rotatez -wing[3,5] 0 0 rotatex 90 0 0 scale wing[3,4] translate wing[3,1] -wing[3,2] wing[3,3] udprim naca Series series_w rotatez -wing[2,5] 0 0 rotatex 90 0 0 scale wing[2,4] translate wing[2,1] -wing[2,2] wing[2,3] udprim naca Series series_w rotatez -wing[1,5] 0 0 rotatex 90 0 0 scale wing[1,4] translate wing[1,1] wing[1,2] wing[1,3] udprim naca Series series_w rotatez -wing[2,5] 0 0 rotatex 90 0 0 scale wing[2,4] translate wing[2,1] +wing[2,2] wing[2,3] udprim naca Series series_w rotatez -wing[3,5] 0 0 rotatex 90 0 0 scale wing[3,4] translate wing[3,1] +wing[3,2] wing[3,3] ruleNotice here that instead of using a pattern, the five sections were explicitly created; this was done to ensure that the left and right wings were the same. Also note that the
naca
user-defined primitive was used to
generate the cross-sections.
The next statement:
unioncombines the fuselage and wing into a single Body.
The code for the tails is:
# build the horizontal tail mark udprim naca Series series_h rotatez -atip_h 0 0 rotatex 90 0 0 scale ctip_h translate xtip_h -ytip_h ztip_h udprim naca Series series_h rotatez -aroot_h 0 0 rotatex 90 0 0 scale croot_h translate xroot_h 0 zroot_h udprim naca Series series_h rotatez -atip_h 0 0 rotatex 90 0 0 scale ctip_h translate xtip_h ytip_h ztip_h rule union # build the vertical tail mark udprim naca Series series_v scale croot_v translate xroot_v 0 zroot_v udprim naca Series series_v scale ctip_v translate xtip_v 0 ztip_v rule union
The tutorial3.csm
file completes with the
statement:
endAlthough such a statement is not required, it is good practice to use it.
Feel free to experiment by modifying this file.
To start serveCSM
, one uses the command:
serveCSM filename [-port portnum] [-outLevel n] [-jrnl jrnlname] [-batch]
The -port
option tells serveCSM
with which
port to connect.
The -outLevel
option sets the level of output (0
to 3) that the server should produce during its execution.
Higher numbers are useful for debugging and should seldom be used
by most users.
The -jrnl
option is useful for replaying a
previous session. This journal file is an ASCII file that can
be created with any text-editor. But more typically, user
modifies the file portX.jrnl
that is automatically
produced every time serveCSM
is started. (Note: be
sure to copy and/or rename this file before using it as an input
to serveCSM
since the next serveCSM
will overwrite this file.)
If the -batch
option is given,
serveCSM
is started without any graphical user
interface. This option is useful for regenerating
configurations as part of a bigger process, such as within an
MDAO environment.
The Tutorial (above) gives an overview of nearly all the
interactive commands that are available in ESP
.
Future versions of this document will add more details here.
.csm
FileThe .csm
file contains a series of statements.
If a line contains a hash (#), all characters starting at the hash are ignored.
If a line contains a backslash, all characters starting at the backslash are ignored and the next line is appended; spaces at the beginning of the next line are treated normally.
All statements begin with a keyword (described below) and must contain at least the indicated number of arguments.
Extra arguments in a statement are discarded and can thus be used as a comment.
The last statement must be 'end'. (Everything else is ignored.)
All arguments must not contain any spaces or must be enclosed in a pair of double quotes (for example, 'a + b').
Parameters are evaluated in the order that they appear in the file, using MATLAB-like syntax (see 'Expression rules' below).
During the build process, OpenCSM
maintains a LIFO
'Stack' that can contain Bodies and Sketches.
The csm statements are executed in a stack-like way, taking their inputs from the Stack and depositing their results onto the Stack.
The default name for each Branch is 'Brch_xxxxxx', where xxxxxx is a unique sequence number.
# introduces comment " ignore spaces until following " \ ignore this and following characters and concatenate next line <space> separates arguments in .csm file 0-9 digits used in numbers and in names A-Z a-z _ letters used in names . decimal separator (used in numbers) , separates function arguments and row/column in subscripts ; multi-value item separator ( ) groups expressions and function arguments [ ] specifies subscripts in form [row,column] + - * / ^ arithmetic operators $ as first character, forces argument not to be evaluated (used internally) @ as first character, introduces @-parameters (see below) ! not used (but allowed within names for backward compatibility) ~ not used % not used & not used = not used { } not used ' not used : not used < > not used ? not used
The following is taken from the OpenCSM.h
file:
dimension pmtrName nrow ncol despmtr=0 use: set up an array Parameter pops: - pushes: - notes: sketcher may not be open solver may not be open nrow >= 1 ncol >= 1 pmtrName must not start with '@' if despmtr=0, then marked as INTERNAL if despmtr=1, then marked as EXTERNAL does not create a Branch despmtr pmtrName values use: define a (constant) driving design Parameter pops: - pushes: - notes: sketcher may not be open solver may not be open pmtrName can be in form 'name' or 'name[irow,icol]' pmtrName must not start with '@' name must not refer to an INTERNAL Parameter name will be marked as EXTERNAL if pmtrName already exists, value is set by last despmtr statement name is used directly (without evaluation) irow and icol cannot contain a comma or open bracket values cannot refer to any other Parameter if values has multiple values (separated by ;), then any subscripts in pmtrName are ignored values are defined across rows if values is longer than Parameter size, extra values are lost if values is shorter than Parameter size, last value is repeated does not create a Branch lbound pmtrName bounds use: defines a lower bound for a design Parameter pops: - pushes: - notes: sketcher may not be open solver may not be open pmtrName must have been defined previously by despmtr statement pmtrName can be in form 'name' or 'name[irow,icol]' bound is set by last lbound statement name is used directly (without evaluation) irow and icol cannot contain a comma or open bracket bounds cannot refer to any other Parameter does not create a Branch if value of Parameter is smaller than bounds, a warning is generated ubound pmtrName bounds use: defines an upper bound for a design Parameter pops: - pushes: - notes: sketcher may not be open solver may not be open pmtrName must have been defined previously by despmtr statement pmtrName can be in form 'name' or 'name[irow,icol]' bound is set by last ubound statement name is used directly (without evaluation) irow and icol cannot contain a comma or open bracket bounds cannot refer to any other Parameter does not create a Branch if value of Parameter is larger than bounds, a warning is generated box xbase ybase zbase dx dy dz use: create a box Body pops: - pushes: Body notes: sketcher may not be open solver may not be open face-order is: xmin, xmax, ymin, ymax, zmin, zmax sphere xcent ycent zcent radius use: create a sphere Body pops: - pushes: Body notes: sketcher may not be open solver may not be open face-order is: ymin, ymax cone xvrtx yvrtx zvrtx xbase ybase zbase radius use: create a cone Body pops: - pushes: Body notes: sketcher may not be open solver may not be open face-order is: (empty), base, umin, umax cylinder xbeg ybeg zbeg xend yend zend radius use: create a cylinder Body pops: - pushes: Body notes: sketcher may not be open solver may not be open face-order is: beg, end, umin, umax torus xcent ycent zcent dxaxis dyaxis dzaxis majorRad minorRad use: create a torus Body pops: - pushes: Body notes: sketcher may not be open solver may not be open face-order is: xmin/ymin, xmin/ymax, xmax/ymax, xmax,ymax import filename bodynumber=1 use: import from filename pops: - pushes: Body notes: sketcher may not be open solver may not be open filename is used directly (without evaluation) if filename starts with '$$/', use path relative to .csm file face-order is based upon order in file udprim primtype argName1 argValue1 argName2 argValue2 argName3 argValue3 argName4 argValue4 use: create a Body by executing a user-defined primitive pops: - pushes: Body notes: sketcher may not be open solver may not be open primtype determines the type of primitive and the number of argName/argValue pairs primtype is used directly (without evaluation) argName# is used directly (without evaluation) argValue# is used directly if it starts with '$', otherwise it is evaluated if argValue# is <<, use data to matching >> as inline file if argValue# starts with '$$/', use path relative to .csm file extra arguments can be set with udparg statement face-order is based upon order returned from udprim see udp documentation for full information extrude dx dy dz use: create a Body by extruding a Sketch pops: Sketch pushes: Body notes: sketcher may not be open solver may not be open if Sketch is a SHEET Body, then a SOLID Body is created if Sketch is a WIRE Body, then a SHEET Body is created face-order is: base, end, feat1, ... rule use: create a Body by creating ruled surfaces through Sketches since mark pops: Sketch1 ... mark pushes: Body notes: sketcher may not be open solver may not be open all Sketches must have the same number of Segments if all Sketches are WIRE Bodies, then a SHEET Body is created otherwise a SOLID Body is created the first and/or last Sketch can be a point face-order is: base, end, seg1a, seg1b, ..., seg2a, ... loft smooth use: create a Body by lofting through Sketches since mark pops: Sketch1 ... mark pushes: Body notes: sketcher may not be open solver may not be open all Sketches must have the same number of Segments if Sketch is a SHEET Body, then a SOLID Body is created if Sketch is a WIRE Body, then a SHEET Body is created face-order is: base, end, feat1, ... if NINT(smooth)==1, then sections are smoothed the first and/or last Sketch can be a point loft (through OpenCASCADE) is not very robust use blend or rule if possible loft may be deprecated in the future blend noseList=0 tailList=0 use: create a Body by blending through Sketches since mark pops: Sketch1 ... mark pushes: Body notes: sketcher may not be open solver may not be open all Sketches must have the same number of Segments if all Sketches are WIRE Bodies, then a SHEET Body is created otherwise a SOLID Body is created the first and/or last Sketch can be a point noseList is either a 0 or the name of an 8-valued parameter noseList is only applied if first Sketch is a point tailList is either a 0 or the name of an 8-valued parameter tailList is only applied if last Sketch is a point noseList and tailList contain rad1;dx1;dy1;dz1;rad2;dx2;dy2;dz2 face-order is: base, end, seg1, seg2, ... revolve xorig yorig zorig dxaxis dyaxis dzaxis angDeg use: create a Body by revolving a Sketch around an axis pops: Sketch pushes: Body notes: sketcher may not be open solver may not be open if Sketch is a SHEET Body, then a SOLID Body is created if Sketch is a WIRE Body, then a SHEET Body is created face-order is: (base), (end), feat1, ... sweep use: create a Body by sweeping a Sketch along a Sketch pops: Sketch1 Sketch2 pushes: Body notes: sketcher may not be open solver may not be open Sketch1 must be either a SHEET or WIRE Body Sketch2 must be a WIRE Body if Sketch2 is not slope-continuous, result may not be as expected face-order is: base, end, feat1a, feat1b, ... fillet radius edgeList=0 use: apply a fillet to a Body pops: Body pushes: Body notes: sketcher may not be open solver may not be open if previous operation is boolean, apply to all new Edges edgeList=0 is the same as edgeList=[0;0] edgeList is a multi-value Parameter or a comma-separated list pairs of edgeList entries are processed in order pairs of edgeList entries are interpreted as follows: col1 col2 meaning =0 =0 add all Edges >0 >0 add Edges between iford=+icol1 and iford=+icol2 <0 <0 remove Edges between iford=-icol1 and iford=-icol2 >0 =0 add Edges adjacent to iford=+icol1 <0 =0 remove Edges adjacent to iford=-icol1 face-order is based upon order that is returned from EGADS chamfer radius edgeList=0 use: apply a chamfer to a Body pops: Body pushes: Body notes: sketcher may not be open solver may not be open if previous operation is boolean, apply to all new Edges edgeList=0 is the same as edgeList=[0;0] edgeList is a multi-value Parameter or a comma-separated list pairs of edgeList entries are processed in order pairs of edgeList entries are interpreted as follows: col1 col2 meaning =0 =0 add all Edges >0 >0 add Edges between iford=+icol1 and iford=+icol2 <0 <0 remove Edges between iford=-icol1 and iford=-icol2 >0 =0 add Edges adjacent to iford=+icol1 <0 =0 remove Edges adjacent to iford=-icol1 face-order is based upon order that is returned from EGADS hollow thick iface1=0 iface2=0 iface3=0 iface4=0 iface5=0 iface6=0 use: hollow out a solid Body pops: Body pushes: Body notes: sketcher may not be open solver may not be open if thick==0, then SOLID is converted to SHEET or SHEET to WIRE if iface*=0, then Face not added to list if all iface*=0 then create an offset body instead face-order is based upon faceID order of offset Faces intersect order=none index=1 use: perform Boolean intersection (Body2 & Body1) pops: Body1 Body2 pushes: Body notes: sketcher may not be open solver may not be open Body1 and Body2 must be SOLID Bodys if intersection does not produce at least index Bodies, an error is returned order may be one of: none same order as returned from geometry engine xmin minimum xmin is first xmax maximum xmax is first ymin minimum ymin is first ymax maximum ymax is first zmin minimum zmin is first zmax maximum zmax is first amin minimum area is first amax maximum area is first vmin minimum volume is first vmax maximum volume is first order is used directly (without evaluation) subtract order=none index=1 use: perform Boolean subtraction (Body2 - Body1) pops: Body1 Body2 pushes: Body notes: sketcher may not be open solver may not be open Body1 and Body2 must be SOLID Bodys if subtraction does not produce at least index Bodies, an error is returned order may be one of: none same order as returned from geometry engine xmin minimum xmin is first xmax maximum xmax is first ymin minimum ymin is first ymax maximum ymax is first zmin minimum zmin is first zmax maximum zmax is first amin minimum area is first amax maximum area is first vmin minimum volume is first vmax maximum volume is first order is used directly (without evaluation) union tomark=0 use: perform Boolean union pops: Body1 Body2 -or- Body1 ... mark pushes: Body notes: sketcher may not be open solver may not be open if tomark=0 union SOLID Body1 and SOLID Body2 create a SOLID Body if tomark=0 union SHEET Body1 and SHEET Body2 create a SHEET Body if tomark=1 union all SOLID Bodys since mark create a SOLID Body if tomark=2 union all SHEET Bodys since mark create a SOLID Body translate dx dy dz use: translates the entry on top of Stack pops: any pushes: any notes: sketcher may not be open solver may not be open rotatex angDeg yaxis zaxis use: rotates entry on top of Stack around x-like axis pops: any pushes: any notes: sketcher may not be open solver may not be open rotatey angDeg zaxis xaxis use: rotates entry on top of Stack around y-like axis pops: any pushes: any notes: sketcher may not be open solver may not be open rotatez angDeg xaxis yaxis use: rotates entry on top of Stack around z-like axis pops: any pushes: any notes: sketcher may not be open solver may not be open scale fact use: scales entry on top of Stack pops: any pushes: any notes: sketcher may not be open solver may not be open mirror nx ny nz dist=0 use: mirrors entry on top of Stack pops: any pushes: any notes: sketcher may not be open solver may not be open normal of the mirror plane is given by nx,ny,nz mirror plane is dist from origin skbeg x y z use: start a new sketch with the given point pops: - pushes: - notes: opens sketcher solver may not be open linseg x y z use: create a new line segment, connecting the previous and specified points pops: - pushes: - notes: sketcher must be open solver may not be open cirarc xon yon zon xend yend zend use: create a new circular arc, using t he previous point as well as the two points specified pops: - pushes: - notes: sketcher must be open solver may not be open spline x y z use: add a point to a spline pops: - pushes: - notes: sketcher must be open solver may not be open skend use: completes a Sketch pops: - pushes: Sketch notes: sketcher must be open solver may not be open all linsegs and cirarcs must be x-, y-, or z-co-planar if sketch is closed, then a SHEET Body is created if sketch is not closed, then a WIRE Body is created if skend immediately follows skbeg, then a Point is created (which can be used at either end of a loft or blend) closes sketcher solbeg varlist use: starts a solver block pops: - pushes: - notes: solver must not be open opens the solver varlist is a list of semi-colon-separated INTERNAL parameters varlist must end with a semi-colon solcon expr use: constraint used to set solver variables pops: - pushes: - notes: sketcher must not be open solver must be open solend will drive expr to zero solend use: close a solver block pops: - pushes: - notes: sketcher must not be open solver must be open adjust variables to drive constrains to zero closes the solver set pmtrName exprs use: define a (redefinable) driven Parameter pops: - pushes: - notes: solver may not be open pmtrName can be in form 'name' or 'name[irow,icol]' pmtrName must not start with '@' name must not refer to an EXTERNAL Parameter name will be marked as INTERNAL name is used directly (without evaluation) irow and icol cannot contain a comma or open bracket if exprs has multiple values (separated by ;), then any subscripts in pmtrName are ignored exprs are defined across rows if exprs is longer than Parameter size, extra exprs are lost if exprs is shorter than Parameter size, last expr is repeated include filename arg1=0 arg2=0 arg3=0 arg4=0 arg5=0 arg6=0 arg7=0 arg8=0 use: include a file into the current input stream pops: - pushes: - notes: sketcher may not be open solver may not be open filename is used directly (without evaluation) include files have the extension .csmi if filename starts with '$$/', use path relative to .csm file include file may not contain despmtr, lbound, or ubound statements include files can be nested, but not circular if include file does not have a return statement, one is generated automatically at end when the include file starts, @arg1 contains the evaluated value of arg1, ... any set statements within the include file have local scope (ie, they cannot be seen by the caller) return ret1=0 ret2=0 ret3=0 ret4=0 ret5=0 ret6=0 ret7=0 ret8=0 use: return from an include file pops: - pushes: - notes: sketcher may not be open solver may not be open statements after a return statement are not processed after execution of include file, the caller will have access to @ret1, @ret2, ... @ret8 updarg primtype argName argValue use: pre-set arguments for next udprim statement pops: - pushes: - notes: sketcher may not be open solver may not be open primtype determines the type of primitive primtype must match primtype of next udprim statement primtype is used directly (without evaluation) argName is used directly (without evaluation) argValue is used directly if it starts with '$', otherwise it is evaluated if argValue starts with '$$/', use path relative to .csm file arguments for following udprim statement are evaluated in the order they are encountered (udparg first) select type arg1 ... use: selects entity for which @-parameters are evaluated pops: - pushes: - notes: if arguments are: body @-parameters apply to last Body on Stack if arguments are: face iface @-parameters apply to Face iface in the last Body on Stack if arguments are: face ibody1 iford1 iseq=1 @-parameters apply to the Face in the last Body on Stack that matches ibody1/iford1 if arguments are: edge iedge @-parameters apply to Edge iedge in the last Body on Stack if arguments are: edge ibody1 iford1 ibody2 iford2 iseq=1 @-parameters apply to the Edge in the last Body on Stack that adjoins Faces ibody1/iford1 and ibody2/iford2 if arguments are: node inode @-parameters apply to Node inode in the last Body on Stack if arguments are: node ibody1 iford1 ibody2 iford2 ibody3 iford3 iseq=1 @-paramaters apply to the Node in the last Body on Stack that adjoins Faces ibody1/iford1, ibody2/iford2, and ibody3/iford3 Face specifications are stored in faceID attribute Edge specifications are stored in edgeID attribute Node specifications are stored in nodeID attribute iseq selects from amongst multiple Faces/Edges/Nodes that match the ibody/iford specifications macbeg imacro use: marks the start of a macro pops: - pushes: - notes: sketcher may not be open solver may not be open imacro must be between 1 and 100 cannot overwrite a previous macro macend use: ends a macro pops: - pushes: - notes: recall imacro use: recalls copy of macro from a storage location imacro pops: - pushes: any notes: sketcher may not be open solver may not be open storage location imacro must have been previously filled by a macro command store name use: stores Body on top of Stack pops: any pushes: - notes: sketcher may not be open solver may not be open name is used directrly (without evaluation) previous Body in name is overwritten restore name use: restores Body from previous store statement pops: - pushes: any notes: sketcher may not be open solver may not be open name is used directrly (without evaluation) error results if nothing has been stored in name patbeg pmtrName ncopy use: execute the pattern multiple times pops: - pushes: - notes: solver may not be open pattern contains all statement up to the matching patend pmtrName must not start with '@' pmtrName takes values from 1 to ncopy (see below) pmtrName is used directly (without evaluation) patend use: mark the end of a pattern pops: - pushes: - notes: solver may not be open there must be a matching patbeg for each patend mark use: used to identify groups such as in rule, loft, or blend pops: - pushes: - notes: sketcher may not be open solver may not be open dump filename remove=0 pops: - pushes: - notes: solver may not be open if file exists, it is overwritten filename is used directly (without evaluation) if filename starts with '$/', it is prepended with path of .csm file if remove == 1, then Body is removed after dumping name branchName use: names the entry on top of Stack pops: any pushes: any notes: sketcher may not be open does not create a Branch attribute attrName attrValue use: sets an attribute for the entry on top of Stack pops: any pushes: any notes: sketcher may not be open if first char of attrValue is '$', then do not evaluate does not create a Branch if before first Branch, then defines a global Attribute end pops: - pushes: - notes: sketcher may not be open solver may not be open does not create a Branch Bodys on Stack are returned last-in-first-out
udprim bezier arguments: filename name of bezier file (prepended with '$' or '$$/') debug =0 for no debug, =1 for debug [default 0] usage: read imax, jmax for (j=0; j < jmax; j++) for (i=0; i < imax; i++) read x(i,j), y(i,j), z(i,j) endfor endfor if (jmax==1) generate WIRE Body elseif (surface is open) generate SHEET Body else generate SOLID Body endif notes: vsp files can be converted to this format by vsp2csm udprim box arguments: dx width in x-direction [default 0] dy width in y-direction [default 0] dz width in z-direction [default 0] rad corner radius [default 0] usage: if (dx>0 && dy>0 && dz>0) if (2*rad>dx && 2*rad>dy && 2*rad>dz) ERROR elseif (rad>0) generate SOLID Body with rounded edges else generate SOLID Body endif elseif (dx==0 && dy>0 && dz>0) if (2*rad>dy && 2*rad>dz) generate SHEET Body in yz-plane with rounded corners else generate SHEET Body iy yz-plane endif elseif (dx>0 && dy==0 && dz>0) if (2*rad>dx && 2*rad>dz) generate SHEET Body in xz-plane with rounded corners else generate SHEET Body iy xz-plane endif elseif (dx>0 && dy>0 && dz==0) if (2*rad>dx && 2*rad>dy) generate SHEET Body in xy-plane with rounded corners else generate SHEET Body in xy-plane endif elseif (dx==0 && dy==0 && dz>0) generate WIRE Body along z-axis elseif (dx>0 && dy==0 && dz==0) generate WIRE Body along x-axis elseif (dx==0 && dy>0 && dz==0) generate WIRE Body along y-axis else ERROR endif notes: all Bodys are centered at origin udprim ellipse arguments: rx radius in x-direction [default 0] ry radius in y-direction [default 0] rz radius in z-direction [default 0] usage: if (rx==0 && ry>0 && rz>0) generate an elliptical SHEET Body in yz-plane elseif (rx>0 && ry==0 && rz>0) generate an elliptical SHEET Body in xz-plane elseif (rx>0 && ry>0 && rz==0) generate an elliptical SHEET Body in xy-plane else ERROR endif note: all Bodys are centered at origin udprim freeform arguments: filename name of file (prepended with '$' or '$$/') imax number of points in i-direction [default 1] jmax number of points in j-direction [default 1] kmax number of points in k-direction [default 1] xyz coordinates usage: if (filename exists) read imax, jmax, kmax if (kmax <= 1) for (k=0; k < kmax; k++) for (j=0; j < jmax; j++) for (i=0; i < imax; i++) if (i==0 || i==imax-1 || j==0 || j==jmax-1 || k==0 || k==kmax-1 ) read x(i,j,k), y(i,j,k), z(i,j,k) endif endfor endfor endfor else for (j=0; j < jmax; j++) for (i=0; i < imax; i++) read x(i,j,0), y(i,j,0), z(i,j,0) endfor endfor endif else for (k=0; k < kmax; k++) for (j=0; j < jmax; j++) for (i=0; i < imax; i++) x(i,j,k) = xyz[3*(i+imax*(j+jmax*k) ] y(i,j,k) = xyz[3*(i+imax*(j+jmax*k)+1] z(i,j,k) = xyz[3*(i+imax*(j+jmax*k)+2] endfor endfor endfor endif if (jmax <= 1) generate WIRE Body elseif (kmax <= 1) generate SHEET Body else generate SOLID Body from outer planes of data endif udprim import arguments: filename name of file (prepended with '$' or '$$/') bodynumber number of body within filename (bias-1) [default 1] usage: read the .egads or .stp file extract the bodynumber'th Body udprim naca arguments: series NACA 4-digit designator [default 0012] camber maximum camber (percent chord) [default 0.0] thickness maximum thickness (percent chord) [default 0.0] usage: if (camber <= 0 && thickness <= 0) extract camber and thickness from series endif if (thickness==0) generate WIRE Body of camber line in xy-plane else generate SHEET Body in xy-plane endif notes: leading edge is at (0,0,0) trailing edge is at (1,0,0) udprim parsec arguments: yte trailing edge height [default 0] param Sobiesky's parameters [no defaults] [1] = rle [2] = xtop [3] = ytop [4] = d2x/dy2 at top [5] = top theta at trailing edge (degrees) [6] = xbot [7] = ybot [8] = d2x/dy2 at bot [9] = bot theta at trailing edge (degrees) poly polynomial coefficient [no defaults] [ 1 to n] for top polynomial [n+1 to 2n] for bot polynomial usage: either param or poly (but not both) must be specified notes: leading edge is at (0,0,0) trailing edge is at (1,yte,0) udprim sew arguments: filename name of file (prepended with '$' or '$$/') toler tolerance usage: read the .egads or .stp file combines the various bodies into a single SHEET or SOLID Body if specified toler is smaller than Face tolers, use Face tolers udprim waffle arguments: depth depth in z-direction [default 1] segments array of segments usage: if (length(segments)%4 != 0) ERROR else for (i=0; i < length(segments)/4; i++) xbeg=segments[4*i ] ybeg=segments[4*i+1] xend=segments[4*i+2] yend=segments[4(i+3] generate SHEET Body from (xbeg,ybeg,0) to (xend,yend,depth) endfor endif
The following is taken from the OpenCSM.h
file:
Valid names: start with a letter contains letters, digits, and underscores contains fewer than 32 characters Array names: basic format is: name[irow,icol] name must follow rules above irow and icol must be valid expressions values are stored across rows ([1,1], [1,2], ..., [2,1], ...) Types: EXTERNAL if a scalar, declared and defined by a despmtr statement if an array, declared by a dimension statement values defined by one or more despmtr statements each value can only be defined in one despmtr statement can have an optional lower bound can have an optional upper bound has global scope (accessible everywhere) can be set outside ocsmBuild by a call to ocsmSetValu can be read outside ocsmBuild by a call to ocsmGetValu INTERNAL if a scalar, declared and defined by a despmtr statement if an array, declared by a dimension statement values defined by one or more set statements values can be overwritten by subsequent set statements see scope rules (below) SOLVER not implemented yet @-parameters that depend on the last 'select' statement. each time a new Body is added to the Stack, 'select body' is implicitly called depending on last select statement, the values of the @-parameters are given by: body face edge node @nbody x x x x current body (also number of bodies) @nface x x x x number of faces in current body @nedge x x x x number of edges in current body @nnode x x x x number of nodes in current body @ibody1 x x first element of 'Body' attribute @ibody2 x x second element of 'Body' attribute @iface x current face @iedge x current edge @inode x current node @xmin x x * x x-min of bounding box or x at beg of edge @ymin x x * x y-min of bounding box or y at beg of edge @zmin x x * x z-min of bounding box or z at beg of edge @xmax x x * x x-max of bounding box or x at end of edge @ymax x x * x y-max of bounding box or y at end of edge @zmax x x * x z-max of bounding box or z at end of edge @length x length of edge @area x x area of face or surface area of body @volume x volume of body (if a solid) @xcg x x x x location of center of gravity @ycg x x x x @zcg x x x x @Ixx x x x centroidal moment of inertia @Ixy x x x @Ixz x x x @Iyx x x x @Iyy x x x @Iyz x x x @Izx x x x @Izy x x x @Izz x x x @-parameters that are associated with include and return statements: these are only seeable within included file: @arg1 first argument in include statement @arg2 second argument in include statement @arg3 third argument in include statement @arg4 fourth argument in include statement @arg5 fifth argument in include statement @arg6 sixth argument in include statement @arg7 seventh argument in include statement @arg8 eighth argument in include statement these are only seeable after the return statement has been executed: @ret1 value associated with first argument of return statement in include file @ret2 value associated with second argument of return statement in include file @ret3 value associated with third argument of return statement in include file @ret4 value associated with fourth argument of return statement in include file @ret5 value associated with fifth argument of return statement in include file @ret6 value associated with sixth argument of return statement in include file @ret7 value associated with seventh argument of return statement in include file @ret8 value associated with eighth argument of return statement in include file Scope: EXTERNAL parameters have global scope (accessible everywhere) INTERNAL parameters have local scope (accessible in current file and its children) the first set statement within an include creates a new variable new variables created in an include are removed by return statement SOLVER parameters are only accessible between SKBEG and SKEND statements
The following is taken from the OpenCSM.h
file:
Valid operators (in order of precedence): ( ) parentheses, inner-most evaluated first func(a,b) function arguments, then function itself ^ exponentiation (evaluated left to right) * / multiply and divide (evaluated left to right) + - add and subtract (evaluated left to right) Valid function calls: pi(x) 3.14159...*x min(x,y) minimum of x and y max(x,y) maximum of x and y sqrt(x) square root of x abs(x) absolute value of x int(x) integer part of x (3.5 -> 3, -3.5 -> -3) nint(x) nearest integer to x exp(x) exponential of x log(x) natural logarithm of x log10(x) common logarithm of x sin(x) sine of x (in radians) sind(x) sine of x (in degrees) asin(x) arc-sine of x (in radians) asind(x) arc-sine of x (in degrees) cos(x) cosine of x (in radians) cosd(x) cosine of x (in dagrees) acos(x) arc-cosine of x (in radians) acosd(x) arc-cosine of x (in degrees) tan(x) tangent of x (in radians) tand(x) tangent of x (in degrees) atan(x) arc-tangent of x (in radians) atand(x) arc-tangent of x (in degrees) atan2(y,x) arc-tangent of y/x (in radians) atan2d(y,x) arc-tangent of y/x (in degrees) hypot(x,y) hypotenuse: sqrt(x^2+y^2) Xcent(xa,ya,Cab,xb,yb) X-center of circular arc Ycent(xa,ya,Cab,xb,yb) Y-center of circular arc Xmidl(xa,ya,Cab,xb,yb) X-point at midpoint of circular arc Ymidl(xa,ya,Cab,xb,yb) Y-point at midpoint of circular arc turnang(xa,ya,Cab,xb,yb) turning angle of circular arc (in degrees) tangent(xa,ya,Cab,xb,yb,... Cbc,xc,yc) tangent angle at b (in degrees) ifzero(test,ifTrue,ifFalse) if test=0, return ifTrue, else ifFalse ifpos(test,ifTrue,ifFalse) if test>0, return ifTrue, else ifFalse ifneg(test,ifTrue,ifFalse) if test<0, return ifTrue, else ifFalse
The following is taken from the OpenCSM.h
file:
EGADS attributes assigned to Bodys: body Body index (bias-1) brch Branch index (bias-1) EGADS attributes assigned to Faces: body non-unique 2-tuple associated with first Face creation [0] Body index in which Face first existed (bias-1) [1] face-order associated with creation (see above) brch non-unique even-numbered list associated with Branches that are active when the Face is created (most recent Branch is listed first) [2*i ] Branch index (bias-1) [2*i+1] (see below) Branches that contribute to brch attribute are primitive (for which brch[2*i+1] is face-order) grown (for which brch[2*i+1] is face-order) applied (for which brch[2*i+1] is face-order) sketch (for which brch[2*i+1] is sketch primitive if making WIRE Body) patbeg (for which brch[2*i+1] is pattern index) recall (for which brch[2*i+1] is 1) faceID unique 3-tuple that is assigned automatically [0] body[0] [1] body[1] [2] sequence number if multiple Faces have same faceID[0] and faceID[1], then the sequence number is defined based upon the first rule that applies: * Face with smaller xcg has lower sequence number * Face with smaller ycg has lower sequence number * Face with smaller zcg has lower sequence number * Face with smaller area has lower sequence number EGADS attributes assigned to Edges: body non-unique 2-tuple associated with first Edge creation [0] Body index in which Edge first existed (bias-1) [1] 100 * min(body[1][ileft],body[1][irite]) + max(body[1][ileft],body[1][irite]) edgeID unique 5-tuple that is assigned automatically [0] faceID[0] of Face 1 (or 0 if non-manifold) [1] faceID[1] of Face 1 (or 0 if non-manifold) [2] faceID[0] of Face 2 (or 0 if non-manifold) [3] faceID[1] of Face 2 (or 0 if non-manifold) [4] sequence number edgeID[0]/[1] swapped with edge[2]/[3] 100*edgeID[0]+edgeID[1] > 100*edgeID[2]+edgeID[3] if multiple Edges have same edgeID[0], edgeID[1], edgeID[2], and edgeID[3], then the sequence number is defined based upon the first rule that applies: * Edge with smaller xcg has lower sequence number * Edge with smaller ycg has lower sequence number * Edge with smaller zcg has lower sequence number * Edge with smaller length has lower sequence number EGADS attributes assigned to Nodes: nodeID not assigned at this time
.csm
fileThe following is a copy of tutorial1.csm
# tutorial1 # written by John Dannenhoffer # default design parameters despmtr Lbar 6.00 length of bar despmtr Rbar 0.15 radius of bar despmtr T 0.50 thickness of weights despmtr D 2.00 diameter of weights despmtr Rout 1.20 outer radius (for intersection) despmtr Rfil 0.10 fillet radius at end of bar set L Lbar/2 # shaft cylinder -L 0.0 0.0 +L 0.0 0.0 Rbar name shaft attribute shaft 1 # left weight box -L-T/2 -D/4 -D T D/2 2*D name left_weight attribute weight 1 union fillet Rfil # rite weight box +L-T/2 -D/2 -D/2 T D D name rite_weight attribute weight 2 union fillet Rfil # clip weights with outer cylinder cylinder -L-T 0.00 0.00 +L+T 0.00 0.00 Rout attribute clipper 1 intersect end
OpenCSM
performs extensive error checking that can issue the
following error codes:
SUCCESS 0 OCSM_FILE_NOT_FOUND -201 OCSM_ILLEGAL_STATEMENT -202 OCSM_NOT_ENOUGH_ARGS -203 OCSM_NAME_ALREADY_DEFINED -204 OCSM_PATTERNS_NESTED_TOO_DEEPLY -205 OCSM_PATBEG_WITHOUT_PATEND -206 OCSM_PATEND_WITHOUT_PATBEG -207 OCSM_NOTHING_TO_DELETE -208 OCSM_NOT_MODL_STRUCTURE -209 OCSM_DID_NOT_CREATE_BODY -211 OCSM_CREATED_TOO_MANY_BODYS -212 OCSM_EXPECTING_ONE_BODY -213 OCSM_EXPECTING_TWO_BODYS -214 OCSM_EXPECTING_ONE_SKETCH -215 OCSM_EXPECTING_MULTI_SINCE_MARK -216 OCSM_LOFT_WITHOUT_MARK -217 OCSM_RULE_LOFT_OR_BLEND_ERROR -218 OCSM_MODL_NOT_CHECKED -219 OCSM_NEED_TESSELLATION -220 OCSM_FILLET_AFTER_WRONG_TYPE -221 OCSM_CHAMFER_AFTER_WRONG_TYPE -222 OCSM_NO_BODYS_PRODUCED -223 OCSM_NOT_ENOUGH_BODYS_PRODUCED -224 OCSM_TOO_MANY_BODYS_ON_STACK -225 OCSM_FACE_NOT_FOUND -226 OCSM_EDGE_NOT_FOUND -227 OCSM_NODE_NOT_FOUND -228 OCSM_ILLEGAL_VALUE -229 OCSM_SKETCHER_IS_OPEN -231 OCSM_SKETCHER_IS_NOT_OPEN -232 OCSM_COLINEAR_SKETCH_POINTS -233 OCSM_NON_COPLANAR_SKETCH_POINTS -234 OCSM_TOO_MANY_SKETCH_POINTS -235 OCSM_TOO_FEW_SPLINE_POINTS -236 OCSM_SKETCH_DOES_NOT_CLOSE -237 OCSM_ILLEGAL_CHAR_IN_EXPR -241 OCSM_CLOSE_BEFORE_OPEN -242 OCSM_MISSING_CLOSE -243 OCSM_ILLEGAL_TOKEN_SEQUENCE -244 OCSM_ILLEGAL_NUMBER -245 OCSM_ILLEGAL_PMTR_NAME -246 OCSM_ILLEGAL_FUNC_NAME -247 OCSM_ILLEGAL_TYPE -248 OCSM_ILLEGAL_NARG -249 OCSM_NAME_NOT_FOUND -251 OCSM_NAME_NOT_UNIQUE -252 OCSM_PMTR_IS_EXTERNAL -253 OCSM_PMTR_IS_INTERNAL -254 OCSM_FUNC_ARG_OUT_OF_BOUNDS -255 OCSM_VAL_STACK_UNDERFLOW -256 /* probably not enough args to func */ OCSM_VAL_STACK_OVERFLOW -257 /* probably too many args to func */ OCSM_ILLEGAL_BRCH_INDEX -261 /* should be from 1 to nbrch */ OCSM_ILLEGAL_PMTR_INDEX -262 /* should be from 1 to npmtr */ OCSM_ILLEGAL_BODY_INDEX -263 /* should be from 1 to nbody */ OCSM_ILLEGAL_ARG_INDEX -264 /* should be from 1 to narg */ OCSM_ILLEGAL_ACTIVITY -265 /* should OCSM_ACTIVE or OCSM_SUPPRESSED */ OCSM_ILLEGAL_MACRO_INDEX -266 /* should be between 1 and 100 */ OCSM_ILLEGAL_ARGUMENT -267 OCSM_CANNOT_BE_SUPPRESSED -268 OCSM_STORAGE_ALREADY_USED -269 OCSM_NOTHING_PREVIOUSLY_STORED -270 OCSM_SOLVER_IS_OPEN -271 OCSM_SOLVER_IS_NOT_OPEN -272 OCSM_TOO_MANY_SOLVER_VARS -273 OCSM_UNDERCONSTRAINED -274 OCSM_OVERCONSTRAINED -275 OCSM_SINGULAR_MATRIX -276 OCSM_NOT_CONVERGED -277 OCSM_UDP_ERROR1 -281 OCSM_UDP_ERROR2 -282 OCSM_UDP_ERROR3 -283 OCSM_UDP_ERROR4 -284 OCSM_UDP_ERROR5 -285 OCSM_UDP_ERROR6 -286 OCSM_UDP_ERROR7 -287 OCSM_UDP_ERROR8 -288 OCSM_UDP_ERROR9 -289 OCSM_OP_STACK_UNDERFLOW -291 OCSM_OP_STACK_OVERFLOW -292 OCSM_RPN_STACK_UNDERFLOW -293 OCSM_RPN_STACK_OVERFLOW -294 OCSM_TOKEN_STACK_UNDERFLOW -295 OCSM_TOKEN_STACK_OVERFLOW -296 OCSM_UNSUPPORTED -298 OCSM_INTERNAL_ERROR -299
In addition, sometimes EGADS
or CAPRI
will issue an error code. The EGADS
error codes
that may be seen from time to time include:
EGADS_NOTFOUND -1 EGADS_NULLOBJ -2 EGADS_NOTOBJ -3 EGADS_MALLOC -4 EGADS_INDEXERR -5 EGADS_NONAME -6 EGADS_NODATA -7 EGADS_MIXCNTX -8 EGADS_NOTCNTX -9 EGADS_NOTXFORM -10 EGADS_REFERCE -11 EGADS_NOTTOPO -12 EGADS_EMPTY -13 EGADS_NOTTESS -14 EGADS_NOTGEOM -15 EGADS_RANGERR -16 EGADS_NOLOAD -17 EGADS_NOTMODEL -18 EGADS_WRITERR -19 EGADS_NOTBODY -20 EGADS_GEOMERR -21 EGADS_TOPOERR -22 EGADS_CONSTERR -23 EGADS_DEGEN -24 EGADS_NOTORTHO -25 EGADS_BADSCALE -26 EGADS_OCSEGFLT -27 EGADS_TOPOCNT -28 EGADS_ATTRERR -29
All reports of possible 'bugs' and any other feedback should be e-mailed to 'jfdannen@syr.edu' or 'Haimes@mit.edu'. If a bug report, please include the version number you are running (listed in the title bar at the top of the program), what you were doing at the time of the bug, and what happened that you didn't expect. The more information that you include, the better the chances that the bug can be reproduced and hence fixed.
Copyright (C) 2010/2014 John F. Dannenhoffer, III (Syracuse University)
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
activity An attribute of a Branch which tells if the Branch should be executed the next time the Model is re-built. ESP supports 'active' and 'suppressed' activities.
Branch An entity in the Model's feature tree that corresponds to either a primitive solid, transformation, boolean operator, sketch entity, or other item used in the construction of a Model.
browser A computer program with which a user interacts with ESP. ESP currently runs in FireFox and SeaMonkey.
collapse The process of 'closing up' a node in a tree so that its children are not displayed. This is accomplished by pressing the - to the left of an (expanded) tree node.
drag An operation in which a user presses a mouse button and holds it down while moving it to another location on the screen.
Design Velocity A change in an input paramater from which changes in the local surface normals will be computed.
ESP The Engineering Sketch Pad is a browser-based software system that allows users create, modify, (re-)build, and save constructive solid models built via OpenCSM.
expand The process of 'opening up' a node in a tree to see its children nodes. This is accomplished by pressing the + to the left of a (collapsed) tree node.
flying mode A way of panning, zooming, and rotating a display in which the motion of the image in the Graphics Window changes as long as the user holds the mouse button. Use the ! key in the Graphics Window to toggle flying mode on and off.
Graphics window The window on the top-right of the ESP screen that contains a graphical representation of the current configuration.
hostname The name of the computer that is running the server (typically serveCSM). If using a single computer for both the browser and server, use 'Localhost' as the hostname.
journal A file that is written (on the server) that keeps track of the commands that user executed while running ESP. A user (who has access to the server) can copy the journal file to another name and use it to automatically replay the session that was journalled during a future invocation of serveCSM.
Key window The window on the bottom left of the ESP screen that contains a spectrum to indicate sensitivity values. If no sensitivity is active, this window in blank.
Messages window The window on the bottom right of the ESP screen that contains status information and other messages to the user.
Model A container that contains the Parameters and (feature-tree) Branches.
Parameter A two-dimensional array of floating-point numbers that is used during the build process to generate a specific instance of a Model.
port The port number on which the server (typically serveCSM) is listening for requests by the browser. serveCSM uses 7681 as its default port.
server A computer program in which OpenCSM runs and which 'serves' Models and Boundary Representations to ESP. The program 'serveCSM' is the initial server for ESP.
Tree window The window on the top-left of the ESP screen that contains command buttons, a tree-like view of the current Parameters, a tree-like view of the current Branches (of the feature tree), and a tree-like view of the display settings.