Fridge Presets:
- Added calls to profiles to implement presets.
Final cleanup by Austin and Brian.
Change-Id: Id706acd5dc3d382a68e3c609a760c2be89b60924
diff --git a/aos/common/actions/action_test.cc b/aos/common/actions/action_test.cc
index 0db4b29..423769e 100644
--- a/aos/common/actions/action_test.cc
+++ b/aos/common/actions/action_test.cc
@@ -17,31 +17,51 @@
namespace actions {
namespace testing {
+class TestActorIndex
+ : public aos::common::actions::ActorBase<actions::TestActionQueueGroup> {
+ public:
+ explicit TestActorIndex(actions::TestActionQueueGroup *s)
+ : aos::common::actions::ActorBase<actions::TestActionQueueGroup>(s) {}
+
+ bool RunAction(const uint32_t &new_index) override {
+ index = new_index;
+ return true;
+ }
+
+ uint32_t index = 0;
+};
+
+::std::unique_ptr<
+ aos::common::actions::TypedAction<actions::TestActionQueueGroup>>
+MakeTestActionIndex(uint32_t index) {
+ return ::std::unique_ptr<
+ aos::common::actions::TypedAction<actions::TestActionQueueGroup>>(
+ new aos::common::actions::TypedAction<actions::TestActionQueueGroup>(
+ &actions::test_action, index));
+}
+
class TestActorNOP
: public aos::common::actions::ActorBase<actions::TestActionQueueGroup> {
public:
- explicit TestActorNOP(actions::TestActionQueueGroup* s)
+ explicit TestActorNOP(actions::TestActionQueueGroup *s)
: actions::ActorBase<actions::TestActionQueueGroup>(s) {}
- bool RunAction() { return true; }
+ bool RunAction(const uint32_t &) override { return true; }
};
::std::unique_ptr<
aos::common::actions::TypedAction<actions::TestActionQueueGroup>>
MakeTestActionNOP() {
- return ::std::unique_ptr<
- aos::common::actions::TypedAction<actions::TestActionQueueGroup>>(
- new aos::common::actions::TypedAction<actions::TestActionQueueGroup>(
- &actions::test_action));
+ return MakeTestActionIndex(0);
}
class TestActorShouldCancel
: public aos::common::actions::ActorBase<actions::TestActionQueueGroup> {
public:
- explicit TestActorShouldCancel(actions::TestActionQueueGroup* s)
+ explicit TestActorShouldCancel(actions::TestActionQueueGroup *s)
: aos::common::actions::ActorBase<actions::TestActionQueueGroup>(s) {}
- bool RunAction() {
+ bool RunAction(const uint32_t &) override {
while (!ShouldCancel()) {
LOG(FATAL, "NOT CANCELED!!\n");
}
@@ -52,10 +72,25 @@
::std::unique_ptr<
aos::common::actions::TypedAction<actions::TestActionQueueGroup>>
MakeTestActionShouldCancel() {
+ return MakeTestActionIndex(0);
+}
+
+class TestActor2Nop
+ : public aos::common::actions::ActorBase<actions::TestAction2QueueGroup> {
+ public:
+ explicit TestActor2Nop(actions::TestAction2QueueGroup *s)
+ : actions::ActorBase<actions::TestAction2QueueGroup>(s) {}
+
+ bool RunAction(const actions::MyParams &) { return true; }
+};
+
+::std::unique_ptr<
+ aos::common::actions::TypedAction<actions::TestAction2QueueGroup>>
+MakeTestAction2NOP(const actions::MyParams ¶ms) {
return ::std::unique_ptr<
- aos::common::actions::TypedAction<actions::TestActionQueueGroup>>(
- new aos::common::actions::TypedAction<actions::TestActionQueueGroup>(
- &actions::test_action));
+ aos::common::actions::TypedAction<actions::TestAction2QueueGroup>>(
+ new aos::common::actions::TypedAction<actions::TestAction2QueueGroup>(
+ &actions::test_action2, params));
}
class ActionTest : public ::testing::Test {
@@ -65,11 +100,15 @@
// test.
actions::test_action.goal.Clear();
actions::test_action.status.Clear();
+ actions::test_action2.goal.Clear();
+ actions::test_action2.status.Clear();
}
virtual ~ActionTest() {
actions::test_action.goal.Clear();
actions::test_action.status.Clear();
+ actions::test_action2.goal.Clear();
+ actions::test_action2.status.Clear();
}
// Bring up and down Core.
@@ -88,8 +127,8 @@
// Tests that the queues are properly configured for testing. Tests that queues
// work exactly as used in the tests.
TEST_F(ActionTest, QueueCheck) {
- actions::TestActionQueueGroup* send_side = &actions::test_action;
- actions::TestActionQueueGroup* recv_side = &actions::test_action;
+ actions::TestActionQueueGroup *send_side = &actions::test_action;
+ actions::TestActionQueueGroup *recv_side = &actions::test_action;
send_side->goal.MakeMessage();
send_side->goal.MakeWithBuilder().run(1).Send();
@@ -280,6 +319,76 @@
EXPECT_FALSE(action_queue_.Running());
}
+// Tests that we do get an index with our goal
+TEST_F(ActionTest, ActionIndex) {
+ TestActorIndex idx_act(&actions::test_action);
+
+ // Tick an empty queue and make sure it was not running.
+ action_queue_.Tick();
+ EXPECT_FALSE(action_queue_.Running());
+
+ // Enqueue action to post index.
+ action_queue_.EnqueueAction(MakeTestActionIndex(5));
+ EXPECT_TRUE(actions::test_action.goal.FetchLatest());
+ EXPECT_EQ(5u, actions::test_action.goal->params);
+ EXPECT_EQ(0u, idx_act.index);
+
+ idx_act.WaitForActionRequest();
+ action_queue_.Tick();
+
+ // Check the new action is the right one.
+ uint32_t test_id = 0;
+ EXPECT_TRUE(action_queue_.GetCurrentActionState(nullptr, nullptr, nullptr,
+ nullptr, &test_id, nullptr));
+
+ // Run the next action so it can accomplish signal completion.
+ idx_act.RunIteration();
+ action_queue_.Tick();
+ idx_act.WaitForStop(test_id);
+ EXPECT_EQ(5u, idx_act.index);
+
+ // Enqueue action to post index.
+ action_queue_.EnqueueAction(MakeTestActionIndex(3));
+ EXPECT_TRUE(actions::test_action.goal.FetchLatest());
+ EXPECT_EQ(3u, actions::test_action.goal->params);
+
+ // Run the next action so it can accomplish signal completion.
+ idx_act.RunIteration();
+ action_queue_.Tick();
+ idx_act.WaitForStop(test_id);
+ EXPECT_EQ(3u, idx_act.index);
+}
+
+// Tests that an action with a structure params works.
+TEST_F(ActionTest, StructParamType) {
+ TestActor2Nop nop_act(&actions::test_action2);
+
+ // Tick an empty queue and make sure it was not running.
+ action_queue_.Tick();
+ EXPECT_FALSE(action_queue_.Running());
+
+ actions::MyParams p;
+ p.param1 = 5.0;
+ p.param2 = 7;
+
+ action_queue_.EnqueueAction(MakeTestAction2NOP(p));
+ nop_act.WaitForActionRequest();
+
+ // We started an action and it should be running.
+ EXPECT_TRUE(action_queue_.Running());
+
+ // Tick it and make sure it is still running.
+ action_queue_.Tick();
+ EXPECT_TRUE(action_queue_.Running());
+
+ // Run the action so it can signal completion.
+ nop_act.RunIteration();
+ action_queue_.Tick();
+
+ // Make sure it stopped.
+ EXPECT_FALSE(action_queue_.Running());
+}
+
} // namespace testing.
} // namespace actions.
} // namespace common.
diff --git a/aos/common/actions/actions.h b/aos/common/actions/actions.h
index 08d94f7..15054d2 100644
--- a/aos/common/actions/actions.h
+++ b/aos/common/actions/actions.h
@@ -44,13 +44,13 @@
bool Running();
// Retrieves the internal state of the current action for testing.
- // See comments on the private members of TypedAction<T> for details.
+ // See comments on the private members of TypedAction<T, S> for details.
bool GetCurrentActionState(bool* has_started, bool* sent_started,
bool* sent_cancel, bool* interrupted,
uint32_t* run_value, uint32_t* old_run_value);
// Retrieves the internal state of the next action for testing.
- // See comments on the private members of TypedAction<T> for details.
+ // See comments on the private members of TypedAction<T, S> for details.
bool GetNextActionState(bool* has_started, bool* sent_started,
bool* sent_cancel, bool* interrupted,
uint32_t* run_value, uint32_t* old_run_value);
@@ -76,7 +76,7 @@
void WaitUntilDone() { DoWaitUntilDone(); }
// Retrieves the internal state of the action for testing.
- // See comments on the private members of TypedAction<T> for details.
+ // See comments on the private members of TypedAction<T, S> for details.
void GetState(bool* has_started, bool* sent_started, bool* sent_cancel,
bool* interrupted, uint32_t* run_value,
uint32_t* old_run_value) {
@@ -95,7 +95,7 @@
// Blocks until complete.
virtual void DoWaitUntilDone() = 0;
// For testing we will need to get the internal state.
- // See comments on the private members of TypedAction<T> for details.
+ // See comments on the private members of TypedAction<T, S> for details.
virtual void DoGetState(bool* has_started, bool* sent_started,
bool* sent_cancel, bool* interrupted,
uint32_t* run_value, uint32_t* old_run_value) = 0;
@@ -107,16 +107,19 @@
public:
// A convenient way to refer to the type of our goals.
typedef typename std::remove_reference<decltype(
- *(static_cast<T*>(NULL)->goal.MakeMessage().get()))>::type GoalType;
+ *(static_cast<T*>(nullptr)->goal.MakeMessage().get()))>::type GoalType;
+ typedef typename std::remove_reference<
+ decltype(static_cast<GoalType*>(nullptr)->params)>::type ParamType;
- TypedAction(T* queue_group)
+ TypedAction(T* queue_group, const ParamType ¶ms)
: queue_group_(queue_group),
goal_(queue_group_->goal.MakeMessage()),
// This adds 1 to the counter (atomically because it's potentially
// shared across threads) and then bitwise-ORs the bottom of the PID to
// differentiate it from other processes's values (ie a unique id).
run_value_(run_counter_.fetch_add(1, ::std::memory_order_relaxed) |
- ((getpid() & 0xFFFF) << 16)) {
+ ((getpid() & 0xFFFF) << 16)),
+ params_(params) {
LOG(INFO, "Action %" PRIx32 " created on queue %s\n", run_value_,
queue_group_->goal.name());
// Clear out any old status messages from before now.
@@ -173,6 +176,9 @@
// The value we're going to use for goal.run etc.
const uint32_t run_value_;
+ // flag passed to action in order to have differing types
+ const ParamType params_;
+
// The old value for running that we may have seen. If we see any value other
// than this or run_value_, somebody else got in the way and we're done. 0 if
// there was nothing there to start with. Only valid after sent_started_
@@ -282,6 +288,7 @@
if (goal_) {
LOG(INFO, "Starting action %" PRIx32 "\n", run_value_);
goal_->run = run_value_;
+ goal_->params = params_;
sent_started_ = true;
if (!goal_.Send()) {
LOG(ERROR, "sending goal for action %" PRIx32 " failed\n", run_value_);
diff --git a/aos/common/actions/actions.q b/aos/common/actions/actions.q
index 8950dd1..8b75ee7 100644
--- a/aos/common/actions/actions.q
+++ b/aos/common/actions/actions.q
@@ -24,6 +24,9 @@
// The unique value to put into status.running while running this instance or
// 0 to cancel.
uint32_t run;
+ // Default parameter. The more useful thing to do would be to define your own
+ // goal type to change param to a useful structure.
+ double param;
};
interface ActionQueueGroup {
diff --git a/aos/common/actions/actor.h b/aos/common/actions/actor.h
index b64051a..2193ea1 100644
--- a/aos/common/actions/actor.h
+++ b/aos/common/actions/actor.h
@@ -17,12 +17,17 @@
template <class T>
class ActorBase {
public:
+ typedef typename std::remove_reference<decltype(
+ *(static_cast<T*>(nullptr)->goal.MakeMessage().get()))>::type GoalType;
+ typedef typename std::remove_reference<
+ decltype(static_cast<GoalType*>(nullptr)->params)>::type ParamType;
+
ActorBase(T* acq) : action_q_(acq) {}
// Will return true if finished or asked to cancel.
// Will return false if it failed accomplish its goal
// due to a problem with the system.
- virtual bool RunAction() = 0;
+ virtual bool RunAction(const ParamType& params) = 0;
// Runs action while enabled.
void Run();
@@ -110,7 +115,7 @@
.Send()) {
LOG(ERROR, "Failed to send the status.\n");
}
- abort_ = !RunAction();
+ abort_ = !RunAction(action_q_->goal->params);
LOG(INFO, "Done with action %" PRIx32 "\n", running_id);
// If we have a new one to run, we shouldn't say we're stopped in between.
diff --git a/aos/common/actions/test_action.q b/aos/common/actions/test_action.q
index c46e182..3451c04 100644
--- a/aos/common/actions/test_action.q
+++ b/aos/common/actions/test_action.q
@@ -7,7 +7,24 @@
message Goal {
uint32_t run;
- double test_value;
+ uint32_t params;
+ };
+
+ queue Goal goal;
+ queue aos.common.actions.Status status;
+};
+
+struct MyParams {
+ double param1;
+ int32_t param2;
+};
+
+queue_group TestAction2QueueGroup {
+ implements aos.common.actions.ActionQueueGroup;
+
+ message Goal {
+ uint32_t run;
+ MyParams params;
};
queue Goal goal;
@@ -15,3 +32,4 @@
};
queue_group TestActionQueueGroup test_action;
+queue_group TestAction2QueueGroup test_action2;