Skip to content

Commit cfac1aa

Browse files
ineskhouyudataguyMikefly123Copilot
authored
Antenna Deployer (#14)
* added burnwire component (2) * impl from sdd * appease linter * Readme with notes to the connecty stuff to be refined and edited and appease linter * added rate group * appease linter * added design review feedback * add antenna deployer component * increase packet size to 8 * fix burnwire test * fix test label * appease linter * resolved conflicts with the radio * Apply suggestions from code review Mostly spelling corrections! Co-authored-by: Copilot <[email protected]> * appease linter * fixing restting of tests * fixed <- * fixed time conversoin test * dploy * changed the defualt * clear history to not get caught in 1 twice * updated sdd * Updated Naming of DeployCount --------- Co-authored-by: Sam S. Yu <[email protected]> Co-authored-by: Michael Pham <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent 68fa004 commit cfac1aa

File tree

12 files changed

+831
-3
lines changed

12 files changed

+831
-3
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
#include "FprimeZephyrReference/Components/AntennaDeployer/AntennaDeployer.hpp"
2+
3+
namespace Components {
4+
5+
// ----------------------------------------------------------------------
6+
// Component construction and destruction
7+
// ----------------------------------------------------------------------
8+
9+
AntennaDeployer ::AntennaDeployer(const char* const compName) : AntennaDeployerComponentBase(compName) {}
10+
11+
AntennaDeployer ::~AntennaDeployer() {}
12+
13+
// ----------------------------------------------------------------------
14+
// Handler implementations for typed input ports
15+
// ----------------------------------------------------------------------
16+
17+
void AntennaDeployer ::schedIn_handler(FwIndexType portNum, U32 context) {
18+
(void)portNum;
19+
(void)context;
20+
21+
switch (this->m_state) {
22+
case DeploymentState::IDLE:
23+
// Nothing to do
24+
break;
25+
case DeploymentState::QUIET_WAIT:
26+
this->handleQuietWaitTick();
27+
break;
28+
case DeploymentState::BURNING:
29+
this->handleBurningTick();
30+
break;
31+
case DeploymentState::RETRY_WAIT:
32+
this->handleRetryWaitTick();
33+
break;
34+
}
35+
}
36+
37+
void AntennaDeployer ::distanceIn_handler(FwIndexType portNum, F32 distance, bool valid) {
38+
(void)portNum;
39+
40+
this->m_lastDistance = distance;
41+
this->m_lastDistanceValid = valid && this->isDistanceWithinValidRange(distance);
42+
43+
if (!this->m_lastDistanceValid) {
44+
this->log_WARNING_LO_InvalidDistanceMeasurement(distance);
45+
return;
46+
}
47+
48+
this->tlmWrite_LastDistance(distance);
49+
50+
if (this->m_state == DeploymentState::IDLE) {
51+
return;
52+
}
53+
54+
if (this->isDistanceDeployed(distance)) {
55+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_SUCCESS);
56+
}
57+
}
58+
59+
// ----------------------------------------------------------------------
60+
// Command handler implementations
61+
// ----------------------------------------------------------------------
62+
63+
void AntennaDeployer ::DEPLOY_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
64+
if (this->m_state != DeploymentState::IDLE) {
65+
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::BUSY);
66+
return;
67+
}
68+
69+
this->enterQuietWait();
70+
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
71+
}
72+
73+
void AntennaDeployer ::DEPLOY_STOP_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
74+
if (this->m_state == DeploymentState::IDLE) {
75+
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
76+
return;
77+
}
78+
79+
this->m_stopRequested = true;
80+
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
81+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_ABORT);
82+
}
83+
84+
// ----------------------------------------------------------------------
85+
// Internal helpers
86+
// ----------------------------------------------------------------------
87+
88+
void AntennaDeployer ::enterQuietWait() {
89+
this->resetDeploymentState();
90+
this->m_state = DeploymentState::QUIET_WAIT;
91+
this->m_ticksInState = 0;
92+
this->m_successDetected = false;
93+
this->m_stopRequested = false;
94+
95+
Fw::ParamValid valid;
96+
const U32 quietTime = this->paramGet_QUIET_TIME_SEC(valid);
97+
if (quietTime == 0U) {
98+
this->startNextAttempt();
99+
}
100+
}
101+
102+
void AntennaDeployer ::startNextAttempt() {
103+
this->m_currentAttempt++;
104+
105+
// Emit quiet time expired event if we're transitioning from QUIET_WAIT state
106+
// Do this before resetting m_ticksInState so we capture the actual elapsed time
107+
if (this->m_state == DeploymentState::QUIET_WAIT) {
108+
this->log_ACTIVITY_HI_QuietTimeExpired(this->m_ticksInState);
109+
}
110+
111+
this->m_ticksInState = 0;
112+
this->m_successDetected = false;
113+
114+
this->log_ACTIVITY_HI_DeployAttempt(this->m_currentAttempt);
115+
116+
this->m_totalAttempts++;
117+
this->tlmWrite_DeployAttemptCount(this->m_totalAttempts);
118+
119+
if (this->isConnected_burnStart_OutputPort(0)) {
120+
this->burnStart_out(0);
121+
}
122+
123+
this->m_state = DeploymentState::BURNING;
124+
}
125+
126+
void AntennaDeployer ::handleQuietWaitTick() {
127+
this->m_ticksInState++;
128+
129+
if (this->m_stopRequested) {
130+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_ABORT);
131+
return;
132+
}
133+
134+
Fw::ParamValid valid;
135+
const U32 quietTime = this->paramGet_QUIET_TIME_SEC(valid);
136+
if (this->m_ticksInState >= quietTime) {
137+
this->startNextAttempt();
138+
}
139+
}
140+
141+
void AntennaDeployer ::handleBurningTick() {
142+
this->m_ticksInState++;
143+
144+
if (this->m_stopRequested) {
145+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_ABORT);
146+
return;
147+
}
148+
149+
if (this->m_state != DeploymentState::BURNING) {
150+
return;
151+
}
152+
153+
Fw::ParamValid valid;
154+
const U32 burnDuration = this->paramGet_BURN_DURATION_SEC(valid);
155+
if (this->m_ticksInState >= burnDuration) {
156+
this->ensureBurnwireStopped();
157+
158+
if (this->m_successDetected) {
159+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_SUCCESS);
160+
return;
161+
}
162+
163+
Fw::ParamValid attemptsValid;
164+
const U32 maxAttempts = this->paramGet_MAX_DEPLOY_ATTEMPTS(attemptsValid);
165+
if (this->m_currentAttempt >= maxAttempts) {
166+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_FAILED);
167+
return;
168+
}
169+
170+
this->m_state = DeploymentState::RETRY_WAIT;
171+
this->m_ticksInState = 0;
172+
}
173+
}
174+
175+
void AntennaDeployer ::handleRetryWaitTick() {
176+
this->m_ticksInState++;
177+
178+
if (this->m_stopRequested) {
179+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_ABORT);
180+
return;
181+
}
182+
183+
if (this->m_successDetected) {
184+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_SUCCESS);
185+
return;
186+
}
187+
188+
Fw::ParamValid valid;
189+
const U32 retryDelay = this->paramGet_RETRY_DELAY_SEC(valid);
190+
if (retryDelay == 0U || this->m_ticksInState >= retryDelay) {
191+
Fw::ParamValid attemptsValid;
192+
const U32 maxAttempts = this->paramGet_MAX_DEPLOY_ATTEMPTS(attemptsValid);
193+
if (this->m_currentAttempt >= maxAttempts) {
194+
this->finishDeployment(Components::DeployResult::DEPLOY_RESULT_FAILED);
195+
return;
196+
}
197+
198+
this->startNextAttempt();
199+
}
200+
}
201+
202+
void AntennaDeployer ::finishDeployment(Components::DeployResult result) {
203+
if (this->m_state == DeploymentState::IDLE) {
204+
return;
205+
}
206+
207+
this->ensureBurnwireStopped();
208+
209+
if (result == Components::DeployResult::DEPLOY_RESULT_SUCCESS) {
210+
this->log_ACTIVITY_HI_DeploySuccess(this->m_currentAttempt);
211+
}
212+
213+
this->log_ACTIVITY_HI_DeployFinish(result, this->m_currentAttempt);
214+
215+
this->resetDeploymentState();
216+
}
217+
218+
void AntennaDeployer ::resetDeploymentState() {
219+
this->m_state = DeploymentState::IDLE;
220+
this->m_currentAttempt = 0;
221+
this->m_ticksInState = 0;
222+
this->m_stopRequested = false;
223+
this->m_successDetected = false;
224+
this->m_lastDistanceValid = false;
225+
}
226+
227+
bool AntennaDeployer ::isDistanceWithinValidRange(F32 distance) {
228+
Fw::ParamValid topValid;
229+
const F32 top = this->paramGet_INVALID_THRESHOLD_TOP_CM(topValid);
230+
231+
Fw::ParamValid bottomValid;
232+
const F32 bottom = this->paramGet_INVALID_THRESHOLD_BOTTOM_CM(bottomValid);
233+
234+
return (distance <= top) && (distance >= bottom);
235+
}
236+
237+
bool AntennaDeployer ::isDistanceDeployed(F32 distance) {
238+
Fw::ParamValid valid;
239+
const F32 threshold = this->paramGet_DEPLOYED_THRESHOLD_CM(valid);
240+
241+
if (distance <= threshold) {
242+
this->m_successDetected = true;
243+
return true;
244+
}
245+
246+
return false;
247+
}
248+
249+
void AntennaDeployer ::ensureBurnwireStopped() {
250+
if (this->isConnected_burnStop_OutputPort(0)) {
251+
this->burnStop_out(0);
252+
}
253+
}
254+
255+
} // namespace Components
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
module Components {
2+
enum DeployResult {
3+
DEPLOY_RESULT_SUCCESS @< Deployment completed successfully
4+
DEPLOY_RESULT_ABORT @< Deployment aborted via command
5+
DEPLOY_RESULT_FAILED @< Deployment failed after exhausting retries
6+
}
7+
}
8+
9+
module Components {
10+
port DistanceUpdate(
11+
distance: F32 @< Latest measured distance in centimeters
12+
valid: bool @< Flag indicating the distance value is considered valid
13+
)
14+
}
15+
16+
module Components {
17+
@ Component that deploys the antenna, activates the burnwire, checks the distance sensor
18+
passive component AntennaDeployer {
19+
######################################################################
20+
# Commands
21+
######################################################################
22+
@ DEPLOY starts the deployment procedure
23+
sync command DEPLOY()
24+
25+
@ DEPLOY_STOP stops the deployment procedure
26+
sync command DEPLOY_STOP()
27+
28+
######################################################################
29+
# Telemetry
30+
######################################################################
31+
@ Counts the number of deployment attempts across boots
32+
telemetry DeployAttemptCount: U32
33+
34+
@ Tracks the last observed distance reading
35+
telemetry LastDistance: F32 format "{.2f}cm"
36+
37+
######################################################################
38+
# Events
39+
######################################################################
40+
@ Emitted at the start of each deployment attempt
41+
event DeployAttempt(
42+
attempt: U32 @< The attempt number (starting at 1)
43+
) severity activity high \
44+
format "Antenna deployment attempt {} started"
45+
46+
@ Emitted when the antenna deployment is considered successful
47+
event DeploySuccess(
48+
attempt: U32 @< Attempt number that succeeded
49+
) severity activity high \
50+
format "Antenna deployment succeeded on attempt {}"
51+
52+
@ Emitted when the deployment procedure finishes
53+
event DeployFinish(
54+
result: Components.DeployResult @< Final deployment outcome
55+
attempts: U32 @< Number of attempts completed
56+
) severity activity high \
57+
format "Antenna deployment finished with result {} after {} attempts"
58+
59+
@ Emitted when a distance reading is ignored because it is invalid
60+
event InvalidDistanceMeasurement(
61+
distance: F32 @< Distance provided
62+
) severity warning low \
63+
format "Ignoring invalid antenna distance measurement: {.2f} cm"
64+
65+
@ Emitted when the quiet wait period expires and deployment attempt begins
66+
event QuietTimeExpired(
67+
elapsedTime: U32 @< Time elapsed in seconds during quiet wait
68+
) severity activity high \
69+
format "Quiet time expired after {} seconds, starting deployment attempt"
70+
71+
######################################################################
72+
# Ports
73+
######################################################################
74+
@ Port receiving calls from the rate group
75+
sync input port schedIn: Svc.Sched
76+
77+
@ Port receiving latest distance measurements
78+
sync input port distanceIn: Components.DistanceUpdate
79+
80+
@ Port signaling the burnwire component to start heating
81+
output port burnStart: Fw.Signal
82+
83+
@ Port signaling the burnwire component to stop heating
84+
output port burnStop: Fw.Signal
85+
86+
######################################################################
87+
# Parameters
88+
######################################################################
89+
@ Quiet time (seconds) to wait after DEPLOY before the first burn attempt
90+
param QUIET_TIME_SEC: U32 default 120
91+
92+
@ Delay (seconds) between burn attempts
93+
param RETRY_DELAY_SEC: U32 default 30
94+
95+
@ Maximum number of burn attempts before giving up
96+
param MAX_DEPLOY_ATTEMPTS: U32 default 3
97+
98+
@ Duration (seconds) for which to hold each burn attempt before issuing STOP
99+
param BURN_DURATION_SEC: U32 default 8
100+
101+
@ Distance threshold (cm) under which the antenna is considered deployed
102+
param DEPLOYED_THRESHOLD_CM: F32 default 5.0
103+
104+
@ Distance readings above this value (cm) are considered invalid
105+
param INVALID_THRESHOLD_TOP_CM: F32 default 500.0
106+
107+
@ Distance readings below this value (cm) are considered invalid
108+
param INVALID_THRESHOLD_BOTTOM_CM: F32 default 0.1
109+
110+
########################################################################
111+
# Standard AC Ports: Required for Channels, Events, Commands, Parameters
112+
########################################################################
113+
@ Port for requesting the current time
114+
time get port timeCaller
115+
116+
@ Port for sending command registrations
117+
command reg port cmdRegOut
118+
119+
@ Port for receiving commands
120+
command recv port cmdIn
121+
122+
@ Port for sending command responses
123+
command resp port cmdResponseOut
124+
125+
@ Port for sending textual representation of events
126+
text event port logTextOut
127+
128+
@ Port for sending events to downlink
129+
event port logOut
130+
131+
@ Port for sending telemetry channels to downlink
132+
telemetry port tlmOut
133+
134+
@ Port to return the value of a parameter
135+
param get port prmGetOut
136+
137+
@ Port to set the value of a parameter
138+
param set port prmSetOut
139+
}
140+
}

0 commit comments

Comments
 (0)