# How to set up a new item A new node, object, marker, load or sensor. Short: **write the definition, generate, write the `.cpp`, build, test.** The details of each part are in the documents linked here; this page says what to do in which order. ## 0. First in Python Try the model with the generic items and user functions: `ObjectGenericODE2`/`ODE1` with user functions for a body or a system, `ObjectConnectorCoordinateVector` for a constraint, a spring-damper with a force user function for a connector, `SensorUserFunction` for a sensor. A C++ item is worth it when that prototype works **and is too slow**. ## 1. How it works An item is one `ItemDefinition(...)` in `definitions/itemDefs.py`. The generators read it and write everything that follows from it; the computation is hand-written C++. | written | for item `ObjectMyBody` of kind `Object` | by | |---|---|---| | the definition | `definitions/itemDefsObjects.py` | you | | C++ headers: parameters, the three classes | `src/Autogenerated/objects/CObjectMyBody.h`, `MainObjectMyBody.h`, `VisuObjectMyBody.h` | generator | | registration in the object factory: `mbs.AddObject({'objectType':'MyBody', ...})` creates the three | `src/Autogenerated/objectFactoryAutoReg.h` ([ARCHITECTURE.md](ARCHITECTURE.md)) | generator | | the Python class `ObjectMyBody` (and its short name) and the typed stub | `python/exudyn/itemInterface.py`, `python/exudyn/types/items.py` | generator | | the reference manual page, and the item in the index of its kind | `docs/generated/items/ObjectMyBody.md` | generator | | the MiniExample file and its entry in the list the test suite runs | `python/MiniExamples/ObjectMyBody.py`, `miniExamplesFileList.py` | generator | | the computation, the output variables and the drawing (`UpdateGraphics`) | `src/ImplObjects/CObjectMyBody.cpp`; loads in `src/System/CLoad.cpp`, sensors in `src/System/CSensor.cpp` | you | | the checks before assembly, if the definition declares `CheckPreAssembleConsistency` | `src/System/checkPreAssembleConsistencies.cpp` | you | | a new `.cpp` in the build | `msvc/cppsrc.vcxproj`, then `python tools/gen_sources.py` writes `sources.json` | you | | the reference value of the MiniExample | `python/testing/runTestSuiteRefSol.py`, `MiniExamplesReferenceSolution` | you | Never edit a generated file; a hand edit is overwritten by the next generation. ## 2. The definition Copy the definition of the item that is most like yours, in the same file, and change it. The vocabulary is in [definitions/README.md](../../definitions/README.md). - **Header**: `className`, `classType`, `objectType` (objects), the parents `cParentClass`, `mainParentClass`, `visuParentClass`, `pythonShortName`. - **Parameters**: `ItemParameter(type=..., destination=..., pythonName=..., defaultValue=..., description=...)`. A description that starts with a symbol in `$...$` puts the symbol into the table, `(symbol: ...)`. - **Functions**: `ItemFunctionDef('Name')` for a function that overrides a base-class function - the declaration comes from the library; `implementation=` for a one-line body, otherwise the body is in your `.cpp`. `ItemFunction(...)` for a function new in this item. Each with a `description` where it is not obvious. - **Types**: what the item provides and needs - `ItemTypes`, `ItemRequestedTypes`, `ItemAccessFunctionTypes()` (objects: the types are derived from the access functions the object provides; `ownMarkers=` for a super element or kinematic tree with markers of its own), `requestedNodeTypes` (node markers). They decide which items fit together; `Assemble()` checks them, and the page lists the fitting items from them. - **`outputVariables`**: `ItemOutputVariable(OVPosition, r"""$symbol$description""")` for every output variable; the generator writes `GetOutputVariableTypes` from the list, you implement `GetOutputVariable...` for exactly these. - **`overallDescription`**: one or two sentences, what it is and what for. - **`detailedDescription`**: the equations - headings and contents by kind in [definitions/README.md](../../definitions/README.md) §*The page of an item*, the rules of the text in §*Writing a description*. - **`miniExample`**: a short model that uses the item and sets `exu.sys['testResult']`; rules in §*The mini example*. - optional: `createFunctions`, `examples` (§*The page of an item*). ## 3. Generate In `venvExuP313`: ``` python tools/regenerate.py --check # validates the definitions, generates, reports what changed exudev generate --all-checks # the same with all checks ``` The validator fails on a function that overrides nothing, a wrong type, a description that breaks the text rules. Then read the page, `docs/generated/items/.md`. ## 4. The C++ Copy the `.cpp` of the same item as in step 2 and rewrite its functions; the class declarations are in the generated headers. | kind | functions to implement | |---|---| | body | `ComputeMassMatrix`, `ComputeODE2LHS`, the access functions `GetPositionJacobian`, `GetRotationJacobian`, `GetMassWeightedPositionJacobian`, `GetJacobianTransposedTimesVectorDerivative` (how a force or torque reaches the body; each gives the body its access function type, derived by `ItemAccessFunctionTypes()`) and `IsValidLocalPosition` where they are defined at restricted local positions only, `GetOutputVariableBody`, `GetPosition`, `GetVelocity`, ... as far as they apply, `GetAvailableJacobians` | | connector | `ComputeODE2LHS` (the forces on the markers), `ComputeJacobianODE2_ODE2` unless `GetAvailableJacobians` says it is not a function, `GetOutputVariableConnector` | | constraint | `ComputeAlgebraicEquations`, `ComputeJacobianAE`, `GetOutputVariableConnector` | | node | `GetPosition`, `GetVelocity`, ..., `GetOutputVariable` | | marker | `ComputeMarkerData` (values and Jacobians), `GetPosition`, ... | | load | `GetLoadVector` or `GetLoadValue` | | sensor | `GetSensorValues` | | every item | `UpdateGraphics` of `Visualization`, in the same `.cpp` | Checks of parameters and of the items it is attached to go into `CheckPreAssembleConsistency`, with a message that names the parameter; errors raised from C++ follow [CODING_STYLE.md](CODING_STYLE.md) §10. ## 5. Build and test ``` exudev build --env venvExuP313 exudev test --env venvExuP313 # runs the MiniExample; add its value to runTestSuiteRefSol.py ``` A test model in `python/TestModels/` for what the MiniExample does not cover ([WORKFLOW.md](WORKFLOW.md) §*What a test model looks like*); then the four gates of [WORKFLOW.md](WORKFLOW.md).