Ok, so after googling and fiddling around, I found a solution to having a super class (BaseRobot) and 2 different controllers that subclass it (Solitary and LocalBroadcaster). I was making a number of mistakes before, this is how it should be:
In controllers/CMakeLists.txt:
Code: Select all
add_library(baseRobot SHARED baseRobot.h baseRobot.cpp)
target_link_libraries(
baseRobot
${GSL_LIBRARIES}
argos3core_simulator
argos3plugin_simulator_actuators
argos3plugin_simulator_footbot
argos3plugin_simulator_genericrobot
argos3plugin_simulator_sensors)
add_library(solitary SHARED solitary.h solitary.cpp)
target_link_libraries(
solitary
baseRobot
${GSL_LIBRARIES}
argos3core_simulator
argos3plugin_simulator_actuators
argos3plugin_simulator_footbot
argos3plugin_simulator_genericrobot
argos3plugin_simulator_sensors)
add_library(localBroadcaster SHARED localBroadcaster.h localBroadcaster.cpp)
target_link_libraries(
localBroadcaster
baseRobot
${GSL_LIBRARIES}
argos3core_simulator
argos3plugin_simulator_actuators
argos3plugin_simulator_footbot
argos3plugin_simulator_genericrobot
argos3plugin_simulator_sensors)
Then, at the end of each cpp file for the subclassed controllers, add lines like:
Code: Select all
REGISTER_CONTROLLER(Solitary, "solitaryController")
To register the classes with argos. The 2nd argument is the name of the node in the xml config file.
You can then make a config file like:
Code: Select all
...
<controllers>
<localBroadcasterController id="localBroadcasterController" library="build/controllers/liblocalBroadcaster.dylib">
...
</localBroadcasterController>
<solitaryController id="solitaryController" library="build/controllers/libsolitary.dylib">
...
</solitaryController>
</controllers>
and use any of the controllers later in the config file to instantiate robots, e.g.:
Code: Select all
<distribute>
<position method="uniform" min="-2,-2,0" max="2,2,0" />
<orientation method="uniform" min="0,0,0" max="360,0,0" />
<entity quantity="2" max_trials="100">
<foot-bot id="robot">
<controller config="solitaryController" />
</foot-bot>
</entity>
</distribute>
The fact that in the make file, a separate library is created for the base class and for the subclasses means that you can e.g. loop through the robots in a loop function, no matter their class. To do that, add the baseRobot library in the loop functions/CMakeLists.txt:
Code: Select all
...
add_library(mainLoopFunctions MODULE ${mainLoopFunctions_SOURCES})
target_link_libraries(mainLoopFunctions
baseRobot
argos3core_simulator
argos3plugin_simulator_actuators
argos3plugin_simulator_dynamics2d
argos3plugin_simulator_entities
argos3plugin_simulator_footbot
argos3plugin_simulator_genericrobot
argos3plugin_simulator_media
argos3plugin_simulator_sensors)
...
This allows you to do things like this in your loop function:
Code: Select all
CSpace::TMapPerType& m_cFootbots = GetSpace().GetEntitiesByType("foot-bot");
for(CSpace::TMapPerType::iterator it = m_cFootbots.begin(); it != m_cFootbots.end(); ++it) {
CFootBotEntity& footBotEntity = *any_cast<CFootBotEntity*>(it->second);
BaseRobot& footBot = dynamic_cast<BaseRobot&>(footBotEntity.GetControllableEntity().GetController());