-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Class-based loadable agent params #410
Conversation
0965c87
to
72c2aed
Compare
@hidmic for a first pass. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew I left some comments. Most of the new classes seem to be lacking documentation, consider adding some.
backend/automotive_simulator.cc
Outdated
const drake::maliput::api::RoadGeometry* road) { | ||
return AddLoadableAgent(plugin_library_name, "", agent_name, | ||
std::move(initial_state), road, | ||
std::move(std::make_unique<AgentPluginParams>())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew FYI just so that you know, this move is redundant. But there's no need to change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, done
backend/python_bindings.cc
Outdated
#include "../include/delphyne/agent_plugin_base.h" | ||
#include "../src/agents/mobil_car.h" | ||
#include "../src/agents/rail_car.h" | ||
#include "../src/agents/trajectory_car.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew hmmm is this the standard now on Delphyne? It looks.. awkward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We decided to revert this and remove relative imports. Changed.
include/delphyne/agent_plugin_base.h
Outdated
template <typename ConcreteAgentParams> | ||
std::unique_ptr<ConcreteAgentParams> downcast_params( | ||
std::unique_ptr<AgentPluginParams> base_params) { | ||
DELPHYNE_DEMAND(base_params.get() != nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew why aborting if parameters are null? Isn't that a possible condition? I don't see anything enforcing otherwise before calling downcast_params()
. And even then, maybe an exception is a bit less harsh than an abort?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added guards, thanks
include/delphyne/agent_plugin_base.h
Outdated
|
||
class AgentPluginParams { | ||
public: | ||
virtual ~AgentPluginParams() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew consider making the destructor pure virtual so that this class becomes abstract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was a suprise for me too. Though you can have = 0
anyways if I follow that blog correctly (so that you enforce the 'abstractness' of the class).
ASSERT_EQ(0, agent->Configure("testname", 0, params, builder.get(), nullptr, | ||
nullptr)); | ||
auto params = std::make_unique<delphyne::AgentPluginParams>(); | ||
ASSERT_EQ(0, agent->Configure("testname", 0, builder.get(), nullptr, nullptr, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew here and below, consider using kNullNameOfTheThing
instead of nullptr directly to make this a bit more readable. Same thing with regard to the zero id.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks!
src/agents/rail_car.h
Outdated
: lane_direction_(std::move(lane_direction)), | ||
start_params_(std::move(start_params)) {} | ||
|
||
drake::automotive::LaneDirection* get_raw_lane_direction() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew may be const
, both method and returned pointer (I think).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 done
src/agents/rail_car.h
Outdated
return lane_direction_.get(); | ||
} | ||
|
||
drake::automotive::MaliputRailcarParams<double>* get_raw_start_params() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew may be const
, both method and returned pointer (I think).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 done
src/agents/trajectory_car.h
Outdated
std::unique_ptr<drake::automotive::Curve2<double>> curve) | ||
: curve_(std::move(curve)) {} | ||
|
||
drake::automotive::Curve2<double>* get_raw_curve() { return curve_.get(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew may be const
, both method and returned pointer (I think).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 done
src/agents/mobil_car.h
Outdated
bool get_initial_with_s() { return initial_with_s_; } | ||
|
||
private: | ||
bool initial_with_s_{true}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew I'd remove the in-member initialization of initial_with_s_
and delete the default constructor (as you have no way of setting parameters after construction, I presume you've made them immutable on purpose). The same goes for its derived classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forget about above's comment. No default constructor will be implicitly added as there's a constructor defined for the class a few lines above. Had a brain SIGSEGV, sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, thanks for raising it anyway!
include/delphyne/agent_plugin_base.h
Outdated
/// Throws an exception if the provided parameter is not of the expected | ||
/// class | ||
template <typename ConcreteAgentParams> | ||
std::unique_ptr<ConcreteAgentParams> downcast_params( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew I wonder if this should be part of AgentPluginParams
, with an additional check on ConcreteAgentParams
, like:
template<typename ConcreteAgentPluginParams,
typename std::enable_if<std::is_base_of<AgentPluginParams, ConcreteAgentPluginParams>::value>::type>
std::unique_ptr<ConcreteAgentPluginParams> downcast_params(std::unique_ptr<AgentPluginParams> base_params) {...}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+100, like it!
std::unique_ptr<AgentPluginParams> parameters) { | ||
return AddLoadableAgent(plugin_library_name, "", agent_name, | ||
std::move(initial_state), road, | ||
std::move(parameters)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew how do you feel about dropping this method and coercing the user to always specify both plugin_library_name
and plugin_name
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is actually quite handy to have this; as a matter of fact, we are not using the "full" version of it anywhere :). I would vote for leaving it.
backend/automotive_simulator.h
Outdated
@@ -24,6 +24,7 @@ | |||
#include "drake/automotive/simple_car.h" | |||
#include "drake/automotive/trajectory_car.h" | |||
#include "drake/common/drake_copyable.h" | |||
#include "drake/lcm/drake_lcm_interface.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be able to drop this - went away in #408
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, rebase leftovers.
py::class_<linb::any>(m, "Any") | ||
.def(py::init<bool&&>()) | ||
// Keep alive, ownership: `self` keeps `RoadGeometry` alive. | ||
.def(py::init<const RoadGeometry*&&>(), py::keep_alive<1, 2>()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if we go in this direction, you'll probably want to keep anything maliput related (road related) around so that the user can dig into the roads (i.e. world ground truth) in scenario setup, or callback scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow; is this related to the python bindings discussion we were having on slack or is it a different thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was working under the mistaken assumption that the road was instantiated in python. From a look at the PR though, looks like it's getting built by RoadBuilder, which means being instantiated in c++ with ownership transferred to the simulator. This is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, got it.
@hidmic thanks a lot for the detailed review. Ready for another pass when you get a chance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew A few more comments, it's looking great!
backend/automotive_simulator.cc
Outdated
@@ -161,6 +161,8 @@ int AutomotiveSimulator<T>::AddLoadableAgent( | |||
if (plugin_name.empty()) { | |||
agent = delphyne::LoadPlugin<T>(plugin_library_name); | |||
} else { | |||
std::cerr << "Plgin with Name!!!!!" << std::endl; | |||
throw std::runtime_error("Plgin with Name!!!!!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew I like the emphasized panicking, but a few considerations:
- Shouldn't it be
Plgin
->Plugin
? - Since you're throwing, code afterwards in the
else
clause is dead code. - I'd rather not write
stdout
/stderr
from within libraries (I personally hate when libraries do that and I have no control over what my application is going to output).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to @basicNew, this is a testing leftover. Removing.
backend/automotive_simulator.h
Outdated
@@ -98,6 +95,8 @@ class AutomotiveSimulator { | |||
const drake::maliput::api::RoadGeometry* road, | |||
std::unique_ptr<AgentPluginParams> parameters); | |||
|
|||
/// An handy overload for the case that the plugin doesn't require any extra |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew Consider An handy overload for the case that the plugin...
-> A handy overload in case the plugin...
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
include/delphyne/agent_plugin_base.h
Outdated
|
||
class AgentPluginParams { | ||
public: | ||
virtual ~AgentPluginParams() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was a suprise for me too. Though you can have = 0
anyways if I follow that blog correctly (so that you enforce the 'abstractness' of the class).
include/delphyne/agent_plugin_base.h
Outdated
typename std::enable_if<std::is_base_of< | ||
AgentPluginParams, ConcreteAgentPluginParams>::value>::type* = | ||
nullptr> | ||
std::unique_ptr<ConcreteAgentPluginParams> downcast_params( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew +10, though I'd make it static
or move it outside the class (class is just scoping here, there's no access to the current instance).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/agents/rail_car.cc
Outdated
ignerr << "RailCar::Configure(): " | ||
"The provided initial lane is not within this simulation's " | ||
"RoadGeometry." | ||
<< std::endl; | ||
return -1; | ||
} | ||
|
||
if (params_->get_raw_start_params() == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew I can't seem to find where params_->get_raw_start_params()
is used besides here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, it's used near the bottom of the method definition.
ASSERT_EQ(0, agent->Configure("testname", 0, builder.get(), nullptr, nullptr, | ||
nullptr, std::move(params))); | ||
ASSERT_EQ( | ||
0, agent->Configure("testname", 0, builder.get(), kNullPoseAggregator, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew here and below, those 0s could be named too e.g. kSuccessCode
and kDefaultID
respectively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
TEST(AgentPluginLoader, Invalid) { | ||
auto agent = delphyne::LoadPlugin<double>("foo"); | ||
ASSERT_EQ(nullptr, agent); | ||
} | ||
|
||
static const char* env = "DELPHYNE_AGENT_PLUGIN_PATH=agent_plugin"; | ||
static const drake::maliput::api::RoadGeometry* kNullRoad{nullptr}; | ||
|
||
TEST(AgentPluginLoader, SimpleAgent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew I've just noticed that all three tests are identical except for a type. If there're no plans for this to be different, consider using typed tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
TEST(AgentPluginLoader, Invalid) { | ||
auto agent = delphyne::LoadPlugin<double>("foo"); | ||
ASSERT_EQ(nullptr, agent); | ||
} | ||
|
||
static const char* env = "DELPHYNE_AGENT_PLUGIN_PATH=agent_plugin"; | ||
static const drake::maliput::api::RoadGeometry* kNullRoad{nullptr}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew IMHO the last two lines should go like static const type* const name
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
ASSERT_EQ(-1, simulator->AddLoadableAgent("NonExistentPlugin", | ||
"my_test_model", nullptr, nullptr)); | ||
auto state = std::make_unique<SimpleCarState<double>>(); | ||
ASSERT_EQ(-1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@basicNew same as above regarding -1 e.g. kErrorCode
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
7e7d5de
to
82a64dd
Compare
I had to rebase against |
I feel bad approving myself, @basicNew @apojomovsky mind to take a look? |
@hidmic thanks for finishing this one! Couple of minor things/checks:
Aside from that it is good to go! |
82a64dd
to
9bfaa20
Compare
@basicNew Commits and curated and tools run (I wonder if we should have commit hooks, though I bet that was discussed before). Also, it seems that |
@hidmic yup, known issue with pylint. Feel free to merge once tests are green. Thanks! |
Removes the generic dictionary +
linb-any
to pass parameters to agents and replaces them with agent-specific classes for params.Currently WIP.