@@ -654,3 +654,121 @@ TEST(BlackboardTest, TimestampedInterface)
654654 ASSERT_EQ (stamp_opt->seq , 2 );
655655 ASSERT_GE (stamp_opt->time .count (), nsec_before);
656656}
657+
658+ // Base class
659+ class Greeter
660+ {
661+ public:
662+ typedef std::shared_ptr<Greeter> Ptr;
663+ virtual std::string show_msg () const
664+ {
665+ return " " ;
666+ };
667+ };
668+
669+ // Derived class
670+ class HelloGreeter : public Greeter
671+ {
672+ public:
673+ typedef std::shared_ptr<HelloGreeter> Ptr;
674+ std::string show_msg () const override
675+ {
676+ return " hello" ;
677+ }
678+ void setDerivedParameter (int n){};
679+ };
680+
681+ class CreateHelloGreeter : public SyncActionNode
682+ {
683+ public:
684+ CreateHelloGreeter (const std::string& name, const NodeConfig& config)
685+ : SyncActionNode(name, config)
686+ {}
687+
688+ NodeStatus tick () override
689+ {
690+ auto hello_greeter = std::make_shared<HelloGreeter>();
691+ setOutput (" out_derived" , hello_greeter);
692+
693+ return NodeStatus::SUCCESS;
694+ }
695+
696+ static PortsList providedPorts ()
697+ {
698+ return { BT::OutputPort<HelloGreeter::Ptr>(" out_derived" ) };
699+ }
700+ };
701+
702+ class SetDerivedParameter : public SyncActionNode
703+ {
704+ public:
705+ SetDerivedParameter (const std::string& name, const NodeConfig& config)
706+ : SyncActionNode(name, config)
707+ {}
708+
709+ NodeStatus tick () override
710+ {
711+ int n;
712+ HelloGreeter::Ptr hello_greeter;
713+
714+ getInput (" n" , n);
715+ getInput (" in_derived" , hello_greeter);
716+
717+ hello_greeter->setDerivedParameter (n);
718+
719+ return NodeStatus::SUCCESS;
720+ }
721+
722+ static PortsList providedPorts ()
723+ {
724+ return { BT::InputPort<int >(" n" ), BT::InputPort<HelloGreeter::Ptr>(" in_derived" ) };
725+ }
726+ };
727+
728+ class ShowGreetMessage : public SyncActionNode
729+ {
730+ public:
731+ ShowGreetMessage (const std::string& name, const NodeConfig& config)
732+ : SyncActionNode(name, config)
733+ {}
734+
735+ NodeStatus tick () override
736+ {
737+ Greeter::Ptr greeter;
738+ getInput (" in_base" , greeter);
739+
740+ greeter->show_msg ();
741+
742+ return NodeStatus::SUCCESS;
743+ }
744+
745+ static PortsList providedPorts ()
746+ {
747+ return { BT::InputPort<Greeter::Ptr>(" in_base" ) };
748+ }
749+ };
750+
751+ TEST (BlackboardTest, Upcasting_Issue943)
752+ {
753+ std::string xml_txt = R"(
754+ <root BTCPP_format="4" >
755+ <BehaviorTree ID="Main">
756+ <Sequence>
757+ <CreateHelloGreeter out_derived="{hello_greeter}" />
758+ <SetDerivedParameter in_derived="{hello_greater}" n="2" />
759+ <ShowGreetMessage in_base="{hello_greeter}" />
760+ </Sequence>
761+ </BehaviorTree>
762+ </root>)" ;
763+
764+ BehaviorTreeFactory factory;
765+ factory.registerNodeType <CreateHelloGreeter>(" CreateHelloGreeter" );
766+ factory.registerNodeType <SetDerivedParameter>(" SetDerivedParameter" );
767+ factory.registerNodeType <ShowGreetMessage>(" ShowGreetMessage" );
768+
769+ auto tree = factory.createTreeFromText (xml_txt);
770+
771+ NodeStatus status = tree.tickWhileRunning ();
772+
773+ ASSERT_EQ (status, NodeStatus::SUCCESS);
774+ }
0 commit comments