Skip to content

Commit f71807c

Browse files
committed
Fix fromPython when using python types
1 parent 40a67a4 commit f71807c

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ bt.load_type_converters(
4040
...
4141
```
4242

43+
## Limitations
44+
45+
- Only `register_simple_action`, `register_simple_condition`, and `register_simple_decorator` are supported.
46+
- Due to limitations of `BT::Any` only copy-constructible types are supported.
47+
- Due to how `pybind11` handle memory, mixing `std::shared_ptr` and `std::unique_ptr` between python/c++ is not supported.
48+
4349
## Acknowledgements
4450

4551
- A few functions were based on https://github.com/BehaviorTree/BehaviorTree.CPP/pull/634

include/behaviortree_py/behaviortree_py.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ BTPY_EXPORT BT::Any fromPython(const pybind11::object& bpo);
5151
// Get the name of all registered type converters
5252
std::vector<std::string> get_registered_converters();
5353

54-
/// utility class to register C++ / Python converters for a BT::Any of type T
54+
/// Utility class to register C++ / Python converters for a BT::Any of type T
5555
template <typename T>
5656
class TypeConverter {
5757
public:

src/behaviortree_py.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ bool TypeConverterRegistry::insert(const std::type_index& type_index,
4343

4444
if (!ros_msg_name.empty()) { // is this a ROS msg type?
4545
msg_names_.insert(std::make_pair(ros_msg_name, it_inserted.first));
46+
} else {
47+
msg_names_.insert(std::make_pair(BT::demangle(type_index), it_inserted.first));
4648
}
4749

4850
return true;
@@ -83,9 +85,24 @@ BT::Any fromPython(const py::object& po) {
8385

8486
const std::string& ros_msg_name = rosMsgName(o);
8587
auto it = TypeConverterRegistry::get().msg_names_.find(ros_msg_name);
86-
if (it == TypeConverterRegistry::get().msg_names_.end())
87-
throw py::type_error("No C++ conversion available for type: " + ros_msg_name +
88-
"\n Available conversions : " + fmt::format("{}", get_registered_converters()));
88+
if (it == TypeConverterRegistry::get().msg_names_.end()) {
89+
try {
90+
// Get the Python type object
91+
PyTypeObject* type = po.ptr()->ob_type;
92+
93+
// Check if it's a wrapped C++ type by checking for the type_info holder
94+
if (auto* type_info = pybind11::detail::get_type_info(type)) {
95+
const std::string cpptype = BT::demangle(*type_info->cpptype);
96+
it = TypeConverterRegistry::get().msg_names_.find(cpptype);
97+
if (it == TypeConverterRegistry::get().msg_names_.end()) {
98+
throw py::type_error("No C++ conversion available for type: '" + cpptype +
99+
"'\n Available conversions : " + fmt::format("{}", get_registered_converters()));
100+
}
101+
}
102+
} catch (const std::runtime_error& e) {
103+
throw py::type_error(e.what());
104+
}
105+
}
89106

90107
return it->second->second.from_(po);
91108
}

src/bindings/behaviortree_py.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,12 @@ PYBIND11_MODULE(behaviortree_py, m) {
125125
"output_port",
126126
[](BT::StringView name, BT::StringView description) { return BT::OutputPort<BT::Any>(name, description); },
127127
py::arg("name"),
128+
py::arg("description") = "")
129+
.def(
130+
"bidirectional_port",
131+
[](BT::StringView name, BT::StringView description) {
132+
return BT::BidirectionalPort<BT::Any>(name, description);
133+
},
134+
py::arg("name"),
128135
py::arg("description") = "");
129136
}

0 commit comments

Comments
 (0)