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

Feature/minimal arbitrator #390

Merged
merged 38 commits into from Oct 21, 2019
Merged

Feature/minimal arbitrator #390

merged 38 commits into from Oct 21, 2019

Conversation

kjrush
Copy link
Contributor

@kjrush kjrush commented Oct 11, 2019

PR Details

Description

Implementation of the minimal Arbitrator and mock Plan Delegator nodes.

Adds the arbitrator package which contains both the arbitrator library (for unit testing) and arbitrator node proper. Arbitrator consists of a skeleton main function delegating execution flow to arbitrator.cpp which is primarily structural code that uses a generic PlanningStrategy to generate plans. TreePlanner is the only existing implementation of PlanningStrategy at present, and is itself generalized over CostFunction, NeighborGenerator, and SearchStrategy for testability and flexibility. The only implementations of these interfaces at present serve to implement a kind of Beam Search that uses the plugins to generate new states, and a list of fixed priorities to derive cost for each state. The search proceeds until a plan reaches the target length or if no new states can be expanded and the length is not reached, the longest plan is returned.

The Plan Delegator implementation is extremely minimalistic as this is not the focus of this task. It simply implements enough functionality to receive a maneuver plan and call the plan_trajectory service on the associated plugin, finally forwarding the new trajectory on to the Trajectory Executor node.

Motivation and Context

These nodes form 2 of the remaining elements of the core CARMA3 planning flow and thus are needed for all future plugin-based planning operation.

How Has This Been Tested?

25 unit tests have been written and passed for all algorithmically relevant components of the Arbitrator (i.e., non-structural, I/O, etc. code). The Plan Delegator node has no unit tests since most of it will be scrapped within the next sprint or two.

Types of changes

  • Defect fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that cause existing functionality to change)

Checklist:

  • I have added any new packages to the sonar-scanner.properties file
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
    CARMA Contributing Guide
  • I have added tests to cover my changes.
  • All new and existing tests passed. (KR: Existing tests which failed prior to this change may still fail)

@kjrush kjrush requested a review from qswawrq October 11, 2019 14:45
@kjrush kjrush self-assigned this Oct 11, 2019
@kjrush
Copy link
Contributor Author

kjrush commented Oct 11, 2019

Note: The dependency on usdot-fhwa-stol/carma-msgs#19 causes unit tests to break when run against develop branch CARMAMsgs. Unit tests for Arbitrator pass locally when run against the correct CARMAMsgs:

  /home/rushk/carma-ws/devel/lib/arbitrator/arbitrator-test --gtest_output=xml:/home/rushk/carma-ws/build/test_results/arbitrator/gtest-arbitrator-test.xml
[==========] Running 25 tests from 5 test cases.
[----------] Global test environment set-up.
[----------] 8 tests from ArbitratorStateMachineTest
[ RUN      ] ArbitratorStateMachineTest.testInitalize
[       OK ] ArbitratorStateMachineTest.testInitalize (0 ms)
[ RUN      ] ArbitratorStateMachineTest.testPlanningCycle
[       OK ] ArbitratorStateMachineTest.testPlanningCycle (0 ms)
[ RUN      ] ArbitratorStateMachineTest.testPauseResumeFromPlanning
[       OK ] ArbitratorStateMachineTest.testPauseResumeFromPlanning (0 ms)
[ RUN      ] ArbitratorStateMachineTest.testPauseResumeFromWaiting
[       OK ] ArbitratorStateMachineTest.testPauseResumeFromWaiting (0 ms)
[ RUN      ] ArbitratorStateMachineTest.testShutdown1
[       OK ] ArbitratorStateMachineTest.testShutdown1 (0 ms)
[ RUN      ] ArbitratorStateMachineTest.testShutdown2
[       OK ] ArbitratorStateMachineTest.testShutdown2 (0 ms)
[ RUN      ] ArbitratorStateMachineTest.testShutdown3
[       OK ] ArbitratorStateMachineTest.testShutdown3 (0 ms)
[ RUN      ] ArbitratorStateMachineTest.testShutdown4
[       OK ] ArbitratorStateMachineTest.testShutdown4 (0 ms)
[----------] 8 tests from ArbitratorStateMachineTest (0 ms total)

[----------] 3 tests from PluginNeighborGeneratorTest
[ RUN      ] PluginNeighborGeneratorTest.testInitalize
[       OK ] PluginNeighborGeneratorTest.testInitalize (0 ms)
[ RUN      ] PluginNeighborGeneratorTest.testGetNeighbors1
[       OK ] PluginNeighborGeneratorTest.testGetNeighbors1 (1 ms)
[ RUN      ] PluginNeighborGeneratorTest.testGetNeighbors2
[       OK ] PluginNeighborGeneratorTest.testGetNeighbors2 (0 ms)
[----------] 3 tests from PluginNeighborGeneratorTest (1 ms total)

[----------] 4 tests from FixedPriorityCostFunctionTest
[ RUN      ] FixedPriorityCostFunctionTest.testSingleManeuver
[       OK ] FixedPriorityCostFunctionTest.testSingleManeuver (0 ms)
[ RUN      ] FixedPriorityCostFunctionTest.testMixedPlanners
[       OK ] FixedPriorityCostFunctionTest.testMixedPlanners (0 ms)
[ RUN      ] FixedPriorityCostFunctionTest.testSingleManeuverUnitDistance
[       OK ] FixedPriorityCostFunctionTest.testSingleManeuverUnitDistance (1 ms)
[ RUN      ] FixedPriorityCostFunctionTest.testUnitDistanceCost
[       OK ] FixedPriorityCostFunctionTest.testUnitDistanceCost (0 ms)
[----------] 4 tests from FixedPriorityCostFunctionTest (1 ms total)

[----------] 7 tests from BeamSearchStrategyTest
[ RUN      ] BeamSearchStrategyTest.testEmptyList
[       OK ] BeamSearchStrategyTest.testEmptyList (0 ms)
[ RUN      ] BeamSearchStrategyTest.testSort1
[       OK ] BeamSearchStrategyTest.testSort1 (0 ms)
[ RUN      ] BeamSearchStrategyTest.testSort2
[       OK ] BeamSearchStrategyTest.testSort2 (0 ms)
[ RUN      ] BeamSearchStrategyTest.testSort3
[       OK ] BeamSearchStrategyTest.testSort3 (0 ms)
[ RUN      ] BeamSearchStrategyTest.testSortAndPrune1
[       OK ] BeamSearchStrategyTest.testSortAndPrune1 (0 ms)
[ RUN      ] BeamSearchStrategyTest.testSortAndPrune2
[       OK ] BeamSearchStrategyTest.testSortAndPrune2 (0 ms)
[ RUN      ] BeamSearchStrategyTest.testSortAndPrune3
[       OK ] BeamSearchStrategyTest.testSortAndPrune3 (0 ms)
[----------] 7 tests from BeamSearchStrategyTest (0 ms total)

[----------] 3 tests from TreePlannerTest
[ RUN      ] TreePlannerTest.testGeneratePlan1
[       OK ] TreePlannerTest.testGeneratePlan1 (1 ms)
[ RUN      ] TreePlannerTest.testGeneratePlan2
[       OK ] TreePlannerTest.testGeneratePlan2 (1 ms)
[ RUN      ] TreePlannerTest.testGeneratePlan3
[       OK ] TreePlannerTest.testGeneratePlan3 (1 ms)
[----------] 3 tests from TreePlannerTest (3 ms total)

[----------] Global test environment tear-down
[==========] 25 tests from 5 test cases ran. (5 ms total)
[  PASSED  ] 25 tests.```

arbitrator/CMakeLists.txt Outdated Show resolved Hide resolved
arbitrator/config/arbitrator_params.yaml Outdated Show resolved Hide resolved
arbitrator/include/arbitrator.hpp Outdated Show resolved Hide resolved
arbitrator/package.xml Outdated Show resolved Hide resolved
arbitrator/package.xml Outdated Show resolved Hide resolved
arbitrator/include/capabilities_interface.tpp Outdated Show resolved Hide resolved
/**
* \brief Virtual destructor provided for memory safety
*/
virtual ~CostFunction(){};
Copy link
Contributor

Choose a reason for hiding this comment

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

You can mark it as pure virtual as well to make sure it will never be called by any child class. This apply to all destructors you have in other abstract class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, defining this as pure virtual seems to remove the ability for my child classes to use the implicit destructor (which seems cleaner to me). I think it'd rather leave this as is, if it's not a big deal.


namespace arbitrator
{
template<typename MSrv>
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I get the reason why you template this class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's just this function that's templated, but it's so it could be used for multiple different kinds of services calls (each needing a different kind of MSrv template parameter for their message type).

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry I meant this template function. Does arbitrator needs to call anything else than STRATEGIC_PLAN service?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not in the present, thought in the future I believe it probably will. For example it'll need to use a different service to interact with the cost plugins to get their costs for a given plan.

arbitrator/src/capabilities_interface.cpp Outdated Show resolved Hide resolved
// Normalize the list and invert into costs
for (auto it = plugin_priorities.begin(); it != plugin_priorities.end(); it++)
{
plugin_costs_[it->first] = 1.0 - (it->second / max_priority);
Copy link
Contributor

Choose a reason for hiding this comment

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

Will be a potential "Divide by Zero" error here if all priorities are not set and default to zero? This also apply to the following compute_cost_per_unit_distance function.

Copy link
Contributor Author

@kjrush kjrush Oct 15, 2019

Choose a reason for hiding this comment

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

Yeah, it would be. The alternative to throwing a divide by zero exception here would be to catch the exception (or check if it would be thrown) and then throw another exception instead, so I'm not clear if that's any better than just throwing a divide by zero.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the easy way to handle it is to check if max_priority == 0 and assign its cost to infinity/maximum.

@kjrush kjrush requested a review from qswawrq October 15, 2019 19:28
Copy link
Contributor

@qswawrq qswawrq left a comment

Choose a reason for hiding this comment

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

Two small comments.

arbitrator/include/arbitrator.hpp Outdated Show resolved Hide resolved
arbitrator/src/arbitrator.cpp Outdated Show resolved Hide resolved
@maefromm
Copy link
Contributor

@qswawrq feel free to merge to develop since freeze has been lifted now. whenever it's ready. thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants