Skip to content
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

Python bound agents Part II #425

Merged
merged 17 commits into from
May 31, 2018
Merged

Python bound agents Part II #425

merged 17 commits into from
May 31, 2018

Conversation

stonier
Copy link
Collaborator

@stonier stonier commented May 28, 2018

  • python bound rail car agent
  • rail car tests
  • python bound mobil car agent
  • mobil car tests
  • unwind loadable agents methods

Additionally:

  • simulator now responsible for passing the ground truth road object at Configure() time
  • started a maliput utilities library for maliput convenience methods (see Readme.md)
  • move FindLane from AutomotiveSimulator to a maliput utilities library so agents can use it (see Readme.md there)
  • bugfix errors in the python add_rail_car introduced in Added railcar_and_mobilcar_in_multilane demo #418
  • AutomotiveSimulator::road_road_geometry_, there are other road components coming soon

@basicNew
Copy link

Adding @hidmic for style review

Copy link
Contributor

@hidmic hidmic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier Wow, this a large PR. First pass, PTAL. Overall documentation needs a bit of polish.

* ready this agent for use in the simulation.
*
* @param agent
* @return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier documentation is missing a few bits.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

/**
* @brief Adds an agent to the simulation.
*
* The user should have custom constructed this agent from
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier consider using Doxygen's @details command for this.

Copy link
Collaborator Author

@stonier stonier May 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed if you have the blank line (as per the doxygen documentation). Do you have a persuasive argument for wanting to do so?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm no argument, I guess I'm just used to it. Dismiss it.

@@ -249,8 +214,7 @@ class AutomotiveSimulator {
// with static id counters since they may run into threading problems)
int unique_system_id_{0};

// Maps an agent id to a pointer to the system that implements the agent.
std::map<int, std::unique_ptr<delphyne::AgentPluginBase<T>>> loadable_agents_;
// Maps an agent id to a the agents
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier consider Maps agent ids to agents. instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check.

///
/// Creators of scenarios need never to call this method.
///
/// @param id: a unique id
/// @param road_geometry: the ground truth road information
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier missing trailing period on both sentences above.

///
/// Creators of scenarios need never to call this method.
///
/// @param id: a unique id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier whose unique id? the agent's?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. Am trying to unwind this particular id as I don't think it's necessary. Will come in a future PR though.

system_context->get_mutable_continuous_state().get_mutable_vector();
drake::systems::BasicVector<double>* const state =
dynamic_cast<drake::systems::BasicVector<double>*>(&context_state);
DELPHYNE_ASSERT(state);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier a comment stating why it is reasonable to make this assumption would be nice.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, asserts. This was from the previous classes. I could second-guess the implications and write something here, but I'll unwind this entire method in Part III so that context retrieval and the subsequent assertion is not necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a TODO then?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, across all the agents.

*/
MobilCar(const std::string& name, const bool& direction_of_travel,
const double& x, const double& y, const double& heading,
const double& speed);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier same as above regarding const references to POD types.

std::make_unique<drake::automotive::PriusVis<double>>(id_, name));

return 0;
if (initial_parameters_.lane.segment()->junction()->road_geometry()->id() !=
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier we're making several assumptions regarding Lane state. We should have checks/assertions for each level of indirection, or state why that's not necessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

offset(offset),
speed(speed),
nominal_speed(nominal_speed) {}
} initial_parameters_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier what's the rationale/advantage of having this struct, as opposed to just defining those parameters as class fields?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Communicates to the user that these parameters are only for initial construction of the object and not used thereafter. I also hope to drop in streaming operators for the agents and some infrastructure so that it's easy to see what the running agents have been configured with at runtime. This is a great means of debugging simple configuration mistakes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen this pattern much, but I like it, especially if it will allow some sort of introspection in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, fair enough.

typedef drake::automotive::MaliputRailcarParams<double>
RailCarContextParameters;
typedef std::unique_ptr<RailCarContextParameters> RailCarContextParametersPtr;
typedef drake::automotive::MaliputRailcar2<double> RailCarSystem;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier I'm fine with most typedefs, but obscuring pointers like this is not common in Drake. Not that I haven't seen it on other codebases, but I'd rather avoid it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

@stonier
Copy link
Collaborator Author

stonier commented May 30, 2018

@hidmic ready for re-review. Aside from the individual comments I've gone over the public headers (agent_base.h and find_lane.h - they're the most visible) to sync more closely with yourself and @basicNew.

Copy link

@basicNew basicNew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a couple of comments, most of them are just trivial fixes.

@@ -36,6 +38,15 @@ PYBIND11_MODULE(agents, m) {

py::class_<delphyne::Agent>(m, "AgentBase");

py::class_<delphyne::MobilCar, delphyne::Agent>(m, "MobilCar")
.def(py::init<const std::string&, const bool&, const double&,
const double&, const double&, const double&>());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change const double& to double and similar. I think all the methods in this file use that notation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

x, # scene x-coordinate (m)
y, # scene y-coordinate (m)
heading, # heading (radians)
speed, # speed in the s-direction (m/s)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra comma at the end. Plus I think pylint doesn't like the parenthesis alone in the bottom.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check, fixed for the others too.

add_maliput_railcar(simulator, car_id, dragway, railcar_s, railcar_speed)
add_rail_car(simulator,
name=str(car_id),
lane = dragway.junction(0).segment(0).lane(1),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra space around =

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

position=railcar_s,
offset=0.0,
speed=railcar_speed
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, I think that parenthesis should be in line 82

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

y=0.0 + y_offset * (i % 3),
heading=0.0,
speed=velocity_base * i
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above wrt parenthesis

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

position=railcar_s,
offset=0.0,
speed=railcar_speed
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parens

add_maliput_railcar(simulator, car_id, dragway, railcar_s, railcar_speed)
add_rail_car(simulator,
name=str(car_id),
lane = dragway.junction(0).segment(0).lane(1),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space around =

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

y=0.0 + y_offset * (i % 3),
heading=0.0,
speed=velocity_base * i
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parens

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

* @param direction_of_travel: designates whether the car will travel
* with or against the flow specified by the lane's rules
* @param longitudinal_position: initial position on the lane's track
* (maliput lane coordinate, 's' (m))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 on the clarification in terms of maliput coordinate system, thanks!

offset(offset),
speed(speed),
nominal_speed(nominal_speed) {}
} initial_parameters_;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen this pattern much, but I like it, especially if it will allow some sort of introspection in the future.

Copy link
Contributor

@hidmic hidmic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier I left some more comments. It's looking good (and bigger?).


/// @brief Prepare the backgroudn context(s) for the agent in this method.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier typo in background.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

/// Access the system, currently used internally by
/// @ref delphyne::AutomotiveSimulator "AutomotiveSimulator" to feed
///
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier spurious extra line.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

* Systems
*********************/
// driving
drake::automotive::MobilPlanner<double>* mobil_planner =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. Good that you've added then.

system_context->get_mutable_continuous_state().get_mutable_vector();
drake::systems::BasicVector<double>* const state =
dynamic_cast<drake::systems::BasicVector<double>*>(&context_state);
DELPHYNE_ASSERT(state);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a TODO then?

*********************/
// TODO(daniel.stonier): This is a very repeatable pattern for vehicle
// agents, reuse?
auto ports = aggregator->AddSinglePoseAndVelocityInput(name_, id);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier should be specific about type here too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, across agents.

EXPECT_LT(id2, 0);
// sim is using a different road geometry
simulator->SetRoadGeometry(std::move(dragway));
auto different_dragway = CreateDragway("DifferentDragway", 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier should be specific about type here too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

0.0, // offset
0.0, // speed
0.0 // nominal_speed
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier here and below, missing units.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

@@ -578,7 +537,7 @@ TEST_F(AutomotiveSimulatorTest, TestLcmOutput) {
viewer_draw_callback);

// Plus one to include the world.
const int expected_num_links = PriusVis<double>(0, "").num_poses() * 2 + 1;
const int expected_num_links = PriusVis<double>(0, "").num_poses() * 2 + 2;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier why the change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exercising the system with the road geometry added as well. Updated the comment to reflect that.

There definitely is some wierdness in the link count checks here and the test above though. That is out of the scope of this PR though.

}

// Verifies that exceptions are thrown if a vehicle with a non-unique name is
// added to the simulation.
TEST_F(AutomotiveSimulatorTest, TestDuplicateVehicleNameException) {
auto simulator = std::make_unique<AutomotiveSimulator<double>>();
auto road_geometry =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier should be specific about type here too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check

simulator->AddLoadableAgent("rail-car", "decoy1", std::move(decoy_state1),
road, std::move(railcar_params1));
auto decoy_1 = std::make_unique<delphyne::RailCar>(
"decoy1", *(road_geometry->junction(0)->segment(0)->lane(0)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stonier missing assert to ensure road_geometry is not nullptr.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I understand that we trust that these chained indirections will not cause a SIGSEGV because road_geometry is supposed to be a dragway. Still, I'd add a comment stating it.

Copy link
Collaborator Author

@stonier stonier May 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, getting out of scope of this actual PR and hitting alot of existing code. I think in this case we can say safe by construction (since it's explicit in a method at the top of the file and assumes such a Dragway construction is ok). That should and is tested elsewhere, so arguably we shouldn't need to repeat that here. If we did, I'd isolate that to a single test somewhere.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree. That's why I suggested a comment.

Copy link
Collaborator Author

@stonier stonier May 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aye, added in the last commit an hour ago, b65eb3d

stonier added 10 commits May 30, 2018 19:20
Also added a convenience maliput library to play around with and
for common patterns, push upstream. This means FindLane has disappeared
from AutomotiveSimulator's interface.

AgentBase added RoadGeometry to the Configure() call, necessary
for checks against the road network, but in general, the principle is
this is the point where the simulator passes to the agent the actual
ground truth world entities.
@stonier
Copy link
Collaborator Author

stonier commented May 30, 2018

More fixes in.

@hidmic / @basicNew I know this is a relatively large PR, though technically it was merely a mechanical follow-on from #417 which I'd kept tightly scoped to address those technical concerns. Style's important, but in such a large PR, it's probably not the best place to address that in meticulous detail, especially given that so much of it is covering existing code and there was significant shuffling of code here. This is not a 'delphyne' style makeover PR.

Note: starting to get difficult working through conflicts as other PR's go in.

Copy link

@basicNew basicNew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (and sorry for all the back and forth, just trying to keep the code consistent with Drake)

@hidmic
Copy link
Contributor

hidmic commented May 31, 2018

@stonier LGTM! I checked out your branch locally, tests are passing and demos are working fine. Sorry for the scope creeping, I had no way to tell what used to be there already and what not based on the PR diff only.

@stonier
Copy link
Collaborator Author

stonier commented May 31, 2018

Thanks lads for helping close the gaps!

@stonier stonier merged commit 65611b2 into master May 31, 2018
@stonier stonier deleted the stonier/other_cars branch May 31, 2018 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants