Skip to content

Commit 93f0f1a

Browse files
committed
cleanup doc
1 parent 94bb396 commit 93f0f1a

File tree

1 file changed

+11
-119
lines changed

1 file changed

+11
-119
lines changed

docs/PORT_CONNECTION_RULES.md

Lines changed: 11 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,21 @@ InputPort<Position2D>("goal")
2121
### 2. Generic/Weakly Typed Ports (AnyTypeAllowed)
2222

2323
A port is **generic** (not strongly typed) when:
24-
- Declared without a type parameter: `InputPort<>("my_port")`
25-
- Declared with `AnyTypeAllowed`: `InputPort<AnyTypeAllowed>("my_port")`
26-
- Declared with `BT::Any`: `InputPort<BT::Any>("my_port")`
24+
- Declared without a type parameter
25+
- Declared with `AnyTypeAllowed`
26+
- Declared with `BT::Any`
27+
- Declared with `std::string` (**OoutputPort** only)
2728

2829
```cpp
2930
// All of these create generic ports:
3031
InputPort<>("value") // defaults to AnyTypeAllowed
3132
InputPort<AnyTypeAllowed>("value") // explicit AnyTypeAllowed
3233
InputPort<BT::Any>("value") // BT::Any type
34+
OoutputPort<std::string>("value") // Can be connected to strong typed input
3335
```
3436

3537
The `isStronglyTyped()` method returns `false` for these ports:
3638

37-
```cpp
38-
// From basic_types.h
39-
bool isStronglyTyped() const
40-
{
41-
return type_info_ != typeid(AnyTypeAllowed) && type_info_ != typeid(BT::Any);
42-
}
43-
```
4439

4540
## Port Connection Rules
4641

@@ -49,13 +44,9 @@ bool isStronglyTyped() const
4944
Ports of the **exact same type** can always be connected:
5045

5146
```cpp
52-
// Node A
47+
// Connection allowed
5348
OutputPort<int>("value") // writes int
54-
55-
// Node B
5649
InputPort<int>("value") // reads int
57-
58-
// Connection: OK
5950
```
6051

6152
**Test reference:** `gtest_port_type_rules.cpp` - `SameType_IntToInt`, `SameType_StringToString`, `SameType_CustomTypeToCustomType` tests
@@ -65,13 +56,9 @@ InputPort<int>("value") // reads int
6556
A **generic port** (`AnyTypeAllowed` or `BT::Any`) can connect to any other port:
6657

6758
```cpp
68-
// Node A with generic output
59+
// Connection: OK - generic port accepts any type
6960
OutputPort<>("output") // generic, can write anything
70-
71-
// Node B with typed input
7261
InputPort<int>("input_int") // expects int
73-
74-
// Connection: OK - generic port accepts any type
7562
```
7663

7764
**Test reference:** `gtest_port_type_rules.cpp` - `GenericPort_AcceptsInt`, `GenericPort_AcceptsString`, `GenericOutput_ToTypedInput` tests
@@ -80,24 +67,13 @@ InputPort<int>("input_int") // expects int
8067

8168
When a blackboard entry is created as `std::string`, it can be connected to ports of **any type** that has a `convertFromString<T>()` specialization. This is the "string as generic port" rule.
8269

83-
**Source:** `xml_parsing.cpp`
84-
```cpp
85-
// special case related to convertFromString
86-
bool const string_input = (prev_info->type() == typeid(std::string));
87-
88-
if(port_type_mismatch && !string_input)
89-
{
90-
// Error thrown only if NOT a string input
91-
throw RuntimeError("The creation of the tree failed...");
92-
}
93-
```
70+
Note that this may cause a run-time error if the string is not convertible.
9471

9572
**Example:**
9673
```xml
9774
<Sequence>
9875
<!-- Creates blackboard entry "value" as string with value "42" -->
9976
<SetBlackboard value="42" output_key="value" />
100-
10177
<!-- Reads "value" as int - OK because string can convert to int -->
10278
<NodeExpectingInt input="{value}" />
10379
</Sequence>
@@ -113,15 +89,6 @@ if(port_type_mismatch && !string_input)
11389

11490
When using `Blackboard::set<std::string>()`, the entry is created with `AnyTypeAllowed` type, not `std::string`:
11591

116-
**Source:** `blackboard.h`
117-
```cpp
118-
// if a new generic port is created with a string, it's type should be AnyTypeAllowed
119-
if constexpr(std::is_same_v<std::string, T>)
120-
{
121-
entry = createEntryImpl(key, PortInfo(PortDirection::INOUT)); // AnyTypeAllowed
122-
}
123-
```
124-
12592
This allows subsequent writes of different types to the same entry.
12693

12794
**Test reference:** `gtest_port_type_rules.cpp` - `BlackboardSetString_CreatesGenericEntry`, `StringEntry_CanBecomeTyped` tests
@@ -130,37 +97,15 @@ This allows subsequent writes of different types to the same entry.
13097

13198
Once a blackboard entry receives a **strongly typed** value, its type is locked:
13299

133-
**Source:** `blackboard.h`
134-
```cpp
135-
// special case: entry exists but it is not strongly typed... yet
136-
if(!entry.info.isStronglyTyped())
137-
{
138-
// Use the new type to create a strongly typed entry
139-
entry.info = TypeInfo::Create<T>();
140-
// ...
141-
return;
142-
}
143-
```
144-
145-
After this, writing a different type will fail (with exceptions noted below).
100+
After this, writing a different type will fail (with exception).
146101

147102
**Test reference:** `gtest_port_type_rules.cpp` - `TypeLock_CannotChangeAfterTypedWrite`, `TypeLock_XMLTreeCreation_TypeMismatch`, `TypeLock_RuntimeTypeChange_Fails` tests
148103

149104
### Rule 6: BT::Any Bypasses Type Checking
150105

151-
When a blackboard entry is **created with type `BT::Any`**, it can store different types over time. This requires the entry to be explicitly created as `BT::Any` type.
106+
When a blackboard entry is **created with type `BT::Any`**, it can store different types over time.
152107

153-
**Important:** Wrapping a value with `BT::Any()` does **not** bypass type checking - the wrapper is unwrapped and the inner type is used:
154-
155-
```cpp
156-
// This creates an entry of type int, NOT BT::Any
157-
bb->set("key", BT::Any(42));
158-
159-
// This will FAIL - entry is int, not BT::Any
160-
bb->set("key", BT::Any("hello")); // throws LogicError
161-
```
162-
163-
To actually allow different types, create the entry as `BT::Any`:
108+
This requires the entry to be explicitly created as `BT::Any` type.
164109

165110
```cpp
166111
// Create entry explicitly as BT::Any type
@@ -282,56 +227,3 @@ The following names **cannot** be used for ports:
282227
- Names starting with `_` - Reserved for internal use
283228

284229
**Test reference:** `gtest_port_type_rules.cpp` - `ReservedPortName_ThrowsOnRegistration` test
285-
286-
## Common Patterns
287-
288-
### Pattern 1: Type-Safe Port Chain
289-
```xml
290-
<Sequence>
291-
<CalculateGoal goal="{GoalPosition}" /> <!-- Output: Position2D -->
292-
<PrintTarget target="{GoalPosition}" /> <!-- Input: Position2D -->
293-
</Sequence>
294-
```
295-
296-
### Pattern 2: String Literal to Typed Port
297-
```xml
298-
<Sequence>
299-
<SetBlackboard value="1.5;2.5" output_key="pos" />
300-
<MoveToPosition target="{pos}" /> <!-- Converts string to Position2D -->
301-
</Sequence>
302-
```
303-
304-
### Pattern 3: Generic Intermediate Storage
305-
```xml
306-
<Sequence>
307-
<TypedNode output_int="{value}" /> <!-- Writes int to generic entry -->
308-
<GenericNode input="{value}" /> <!-- Generic port reads it -->
309-
<AnotherTypedNode input_int="{value}"/> <!-- Int port reads it -->
310-
</Sequence>
311-
```
312-
313-
## Error Messages
314-
315-
Common type-related errors:
316-
317-
1. **"The creation of the tree failed because the port [X] was initially created with type [A] and, later type [B] was used somewhere else."**
318-
- Cause: Two nodes use same blackboard key with incompatible types
319-
- Solution: Ensure consistent types or use string/generic ports
320-
321-
2. **"Blackboard::set(X): once declared, the type of a port shall not change."**
322-
- Cause: Runtime attempt to change entry type
323-
- Solution: Use consistent types or BT::Any
324-
325-
3. **"The port with name X and value Y can not be converted to Z"**
326-
- Cause: Literal value cannot be parsed to port type
327-
- Solution: Fix value format or add `convertFromString` specialization
328-
329-
## References
330-
331-
- Source: `include/behaviortree_cpp/basic_types.h` - Type system definitions
332-
- Source: `include/behaviortree_cpp/blackboard.h` - Blackboard type checking
333-
- Source: `src/xml_parsing.cpp` - Tree creation validation
334-
- Tests: `tests/gtest_port_type_rules.cpp` - Comprehensive port type rule tests
335-
- Tests: `tests/gtest_ports.cpp` - Port connection tests
336-
- Tests: `tests/gtest_blackboard.cpp` - Blackboard tests
337-
- Tutorial: `examples/t03_generic_ports.cpp` - Custom type example

0 commit comments

Comments
 (0)