BehaviorTree.CPP icon indicating copy to clipboard operation
BehaviorTree.CPP copied to clipboard

Blackboard's set function seems to set variable to type string

Open sven-hoek opened this issue 8 months ago • 2 comments

What I do

After creating a tree, I set blackboard entries from data read in from a JSON string, something like this

{
  "goal_position": 0.0,
  "goal_tolerance": 0.01,
  "serial_port": "/dev/ttyUSB0",
}

I currently restrict to primitive values, setting the parameters with something like this:

const auto parameters = nlohmann::json::parse(json_string);
for (const auto& [key, value] : parameters.items()) {
    if (value.is_string()) {
        // Necessary to avoid having quotes in the string-value
        blackboard->set(key, value.get<std::string>());
    } else if (value.is_primitive()) {
        blackboard->set(key, value.dump());
    } else {
        // discard
    }
}

In my tree, I want to set values according to those set blackboard entries, like so:

<Script code="goal_range_min := goal_position - goal_tolerance" />

What I expect

I expect the script node to succeed, resulting in a blackboard entry goal_range_min, which contains the difference of goal_position and goal_tolerance. In this example, it would be -0.01.

What I get

Error in script [goal_range_min := goal_position - goal_tolerance]

I get a bit more info when I do the calculation in two steps, i.e.

<Script code="goal_range_min := goal_position" />
<Script code="goal_range_min -= goal_tolerance" />

which will result in the following error:

Error in script [goal_range_min -= goal_tolerance]
Operator not supported for strings

Or, when I add a Script node at the beginning of the tree to set/overwrite an entry, i.e.

<Script code="goal_tolerance := 0.03" />

I get

Error in script [goal_tolerance := 0.03]
Error assigning a value to entry [goal_tolerance] with type [std::string]. 
The right operand has type [double] and can't be converted to [std::string]

However, when I delete the goal_tolerance entry from the JSON and only set it through the Script Node, while still setting the goal_position from the JSON, it seems to work.

Thoughts

This hints me that the blackboard entries have the type information to be a string. However, I would expect them to be without type information, according to this line and following: https://github.com/BehaviorTree/BehaviorTree.CPP/blob/3c62813b84fa9b26d8cb88dc38da17deb852f6a7/include/behaviortree_cpp/blackboard.h#L220

So, are mathematical operations between two AnyTypeAlloweds not possible? I assume if both are of unknown type, it is unknown what the operation is supposed to be (addition? string concatenation?).

But is there any solution? I could infer the data type from the JSON entry and use the right template instantiation of Blackboard::set<T>. Any other suggestion?

sven-hoek avatar May 13 '25 00:05 sven-hoek

Hi @sven-hoek , incorrect type

if you want arthimetic operation to be performed just correct this blackboard->set<T>(key,T value)

const auto parameters = nlohmann::json::parse(json_string);
for (const auto& [key, value] : parameters.items()) {
    if (value.is_string()) {
        // Necessary to avoid having quotes in the string-value
        blackboard->set(key, value.get<std::string>());
    } else if (value.is_number_float()()) {   // <=========================== @sven-hoek 
        blackboard->set(key, value.get<float>());
    } else {
        // discard
    }
}

v-snap avatar May 14 '25 07:05 v-snap

Hey @viprob-ai , thanks for your answer. That's what I did for JSON native types (string, int, float). It works fine but I'm worried what will happen once I use more complex types.

I guess for JSON-serialized data, I have to write my own type detection/annotation anyway. But it would be cool if I could have them parsed similarly to when using user-defined Port types.

sven-hoek avatar May 25 '25 10:05 sven-hoek