Skip to content

Commit b75f71c

Browse files
committed
Refactor cl_mission_tracker to pure component base architecture
1 parent 13f239b commit b75f71c

File tree

4 files changed

+148
-11
lines changed

4 files changed

+148
-11
lines changed

smacc2_client_library/cl_foundation_pose/include/cl_foundation_pose/cl_foundation_pose.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ class ClFoundationPose : public smacc2::ISmaccClient
3535

3636
void onInitialize() override
3737
{
38-
//auto subcomponent = this->createComponent<CpTopicSubscriber<vision_msgs::msg::Detection3DArray>>("/detection3d_array");
38+
auto subcomponent =
39+
this->createComponent<CpTopicSubscriber<vision_msgs::msg::Detection3DArray>>(
40+
"/detection3d_array");
3941
}
4042
};
4143

smacc2_client_library/cl_mission_tracker/include/cl_mission_tracker/cl_mission_tracker.hpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,59 @@
2222
#include <smacc2/smacc.hpp>
2323
#include <smacc2/smacc_client.hpp>
2424

25+
#include <cl_mission_tracker/components/cp_decision_manager.hpp>
26+
2527
namespace cl_mission_tracker
2628
{
29+
30+
// Event: Battery load decision
2731
template <typename AsyncCB, typename Orthogonal>
2832
struct EvBatteryLoad : sc::event<EvBatteryLoad<AsyncCB, Orthogonal>>
2933
{
3034
};
3135

36+
// Event: Radial motion decision
3237
template <typename AsyncCB, typename Orthogonal>
3338
struct EvRadialMotion : sc::event<EvRadialMotion<AsyncCB, Orthogonal>>
3439
{
3540
};
3641

42+
// Event: S-pattern decision
3743
template <typename AsyncCB, typename Orthogonal>
3844
struct EvSPattern : sc::event<EvSPattern<AsyncCB, Orthogonal>>
3945
{
4046
};
4147

48+
// Event: F-pattern decision
4249
template <typename AsyncCB, typename Orthogonal>
4350
struct EvFPattern : sc::event<EvFPattern<AsyncCB, Orthogonal>>
4451
{
4552
};
4653

54+
/**
55+
* @brief Client for mission tracking and decision sequencing.
56+
*
57+
* This client follows the pure component-based architecture pattern.
58+
* It acts as an orchestrator that creates and wires components:
59+
*
60+
* - CpDecisionManager: Manages decision counter state
61+
*
62+
* Client behaviors should use requiresComponent() to access the
63+
* decision manager, not direct client fields.
64+
*/
4765
class ClMissionTracker : public smacc2::ISmaccClient
4866
{
49-
private:
50-
int decission_counter = 0;
51-
5267
public:
5368
ClMissionTracker() {}
54-
void nextDecission() { decission_counter++; }
55-
int getDecissionCounter() { return decission_counter; }
69+
70+
virtual ~ClMissionTracker() {}
71+
72+
template <typename TOrthogonal, typename TClient>
73+
void onComponentInitialization()
74+
{
75+
// Create decision manager component
76+
this->createComponent<CpDecisionManager, TOrthogonal, ClMissionTracker>();
77+
}
5678
};
5779

5880
} // namespace cl_mission_tracker

smacc2_client_library/cl_mission_tracker/include/cl_mission_tracker/client_behaviors/cb_battery_decission.hpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,28 @@
1919
******************************************************************************************************************/
2020
#pragma once
2121

22+
#include <cl_mission_tracker/cl_mission_tracker.hpp>
23+
#include <cl_mission_tracker/components/cp_decision_manager.hpp>
2224
#include <smacc2/smacc.hpp>
2325
#include <smacc2/smacc_asynchronous_client_behavior.hpp>
2426

2527
namespace cl_mission_tracker
2628
{
2729

30+
/**
31+
* @brief Behavior that makes mission decisions based on a counter.
32+
*
33+
* This behavior uses requiresComponent() to access:
34+
* - CpDecisionManager: For decision counter state
35+
*
36+
* Based on the current decision count, it posts different events
37+
* to control the mission flow.
38+
*/
2839
class CbBatteryDecission : public smacc2::SmaccAsyncClientBehavior
2940
{
3041
private:
31-
cl_mission_tracker::ClMissionTracker * missionTracker_ = nullptr;
42+
// Component accessed via requiresComponent (NOT direct client!)
43+
CpDecisionManager * decisionManager_ = nullptr;
3244
std::function<void()> postEventFn_;
3345

3446
public:
@@ -45,11 +57,13 @@ class CbBatteryDecission : public smacc2::SmaccAsyncClientBehavior
4557
{
4658
postEventFn_ = [this]()
4759
{
48-
this->requiresClient(missionTracker_);
49-
int decission_count = missionTracker_->getDecissionCounter();
50-
missionTracker_->nextDecission();
60+
// Get component via requiresComponent pattern (NOT requiresClient!)
61+
this->requiresComponent(decisionManager_, true);
5162

52-
switch (decission_count)
63+
// Get current decision and advance counter
64+
int decisionCount = decisionManager_->nextDecision();
65+
66+
switch (decisionCount)
5367
{
5468
case 0:
5569
case 2:
@@ -71,4 +85,5 @@ class CbBatteryDecission : public smacc2::SmaccAsyncClientBehavior
7185
};
7286
}
7387
};
88+
7489
} // namespace cl_mission_tracker
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2021 RobosoftAI Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/*****************************************************************************************************************
16+
*
17+
* Authors: Pablo Inigo Blasco, Brett Aldrich
18+
*
19+
******************************************************************************************************************/
20+
#pragma once
21+
22+
#include <smacc2/component.hpp>
23+
24+
#include <mutex>
25+
26+
namespace cl_mission_tracker
27+
{
28+
29+
/**
30+
* @brief Component that manages mission decision state.
31+
*
32+
* This component tracks the decision counter for mission sequencing.
33+
* It provides thread-safe access to decision state, separating
34+
* mission logic from the client orchestrator.
35+
*/
36+
class CpDecisionManager : public smacc2::ISmaccComponent
37+
{
38+
public:
39+
CpDecisionManager() = default;
40+
41+
virtual ~CpDecisionManager() = default;
42+
43+
void onInitialize() override
44+
{
45+
RCLCPP_INFO(getLogger(), "[CpDecisionManager] Initialized");
46+
}
47+
48+
/**
49+
* @brief Get the current decision counter value.
50+
* @return Current decision count
51+
*/
52+
int getDecisionCounter() const
53+
{
54+
std::lock_guard<std::mutex> lock(mutex_);
55+
return decisionCounter_;
56+
}
57+
58+
/**
59+
* @brief Increment the decision counter and return the previous value.
60+
* @return Decision count before incrementing
61+
*/
62+
int nextDecision()
63+
{
64+
std::lock_guard<std::mutex> lock(mutex_);
65+
int current = decisionCounter_;
66+
decisionCounter_++;
67+
RCLCPP_INFO_STREAM(
68+
getLogger(), "[CpDecisionManager] Decision " << current << " -> " << decisionCounter_);
69+
return current;
70+
}
71+
72+
/**
73+
* @brief Reset the decision counter to zero.
74+
*/
75+
void resetDecisionCounter()
76+
{
77+
std::lock_guard<std::mutex> lock(mutex_);
78+
decisionCounter_ = 0;
79+
RCLCPP_INFO(getLogger(), "[CpDecisionManager] Decision counter reset");
80+
}
81+
82+
/**
83+
* @brief Set the decision counter to a specific value.
84+
* @param value New counter value
85+
*/
86+
void setDecisionCounter(int value)
87+
{
88+
std::lock_guard<std::mutex> lock(mutex_);
89+
decisionCounter_ = value;
90+
RCLCPP_INFO_STREAM(getLogger(), "[CpDecisionManager] Decision counter set to " << value);
91+
}
92+
93+
private:
94+
mutable std::mutex mutex_;
95+
int decisionCounter_ = 0;
96+
};
97+
98+
} // namespace cl_mission_tracker

0 commit comments

Comments
 (0)