Skip to content

Commit 449a9f6

Browse files
committed
Added clear to motion queues
1 parent 355a1a0 commit 449a9f6

13 files changed

+72
-21
lines changed

src/determine-print-stats.cc

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ class StatsSegmentQueue : public SegmentQueue {
117117
void WaitQueueEmpty() final {}
118118
bool GetPhysicalStatus(PhysicalStatus *status) final { return false; }
119119
void SetExternalPosition(int axis, int pos) final {}
120+
bool Clear() final { return false; }
120121

121122
private:
122123
BeagleGPrintStats *const print_stats_;

src/gcode-machine-control_test.cc

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class MockMotorOps final : public SegmentQueue {
5959
void MotorEnable(bool on) final {}
6060
bool GetPhysicalStatus(PhysicalStatus *status) final { return false; }
6161
void SetExternalPosition(int axis, int steps) final {}
62+
bool Clear() final { return false; }
6263

6364
int call_count_wait_queue_empty = 0;
6465

src/gcode2ps.cc

+1
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ class SegmentQueuePrinter final : public SegmentQueue {
10371037
void MotorEnable(bool on) final {}
10381038
void WaitQueueEmpty() final {}
10391039
bool GetPhysicalStatus(PhysicalStatus *status) final { return false; }
1040+
bool Clear() final { return false; }
10401041
void SetExternalPosition(int motor, int pos) final {
10411042
current_pos_[motor] = pos;
10421043
if (pass_ == ProcessingStep::GenerateOutput) {

src/motion-queue-motor-operations.cc

+7
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,13 @@ bool MotionQueueMotorOperations::Enqueue(const LinearSegmentSteps &segment) {
337337
return ret;
338338
}
339339

340+
bool MotionQueueMotorOperations::Clear() {
341+
const bool ret = backend_->Clear();
342+
shadow_queue_->clear();
343+
shadow_queue_->push_front({});
344+
return ret;
345+
}
346+
340347
void MotionQueueMotorOperations::MotorEnable(bool on) {
341348
backend_->WaitQueueEmpty();
342349
backend_->MotorEnable(on);

src/motion-queue-motor-operations.h

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class MotionQueueMotorOperations : public SegmentQueue {
3737
void WaitQueueEmpty() final;
3838
bool GetPhysicalStatus(PhysicalStatus *status) final;
3939
void SetExternalPosition(int axis, int position_steps) final;
40+
bool Clear() final;
4041

4142
private:
4243
bool EnqueueInternal(const LinearSegmentSteps &param,

src/motion-queue-motor-operations_test.cc

+38-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,15 @@ class MockMotionQueue final : public MotionQueue {
3636
if (head_item_progress) *head_item_progress = remaining_loops_;
3737
return queue_size_;
3838
}
39-
bool EmergencyReset() final { return true; }
39+
40+
bool Clear() final {
41+
clear_calls_count++;
42+
remaining_loops_ = 0;
43+
queue_size_ = 0;
44+
return true;
45+
}
46+
47+
int clear_calls_count = 0;
4048

4149
void SimRun(const uint32_t executed_loops, const unsigned int buffer_size) {
4250
assert(buffer_size <= queue_size_);
@@ -203,6 +211,35 @@ TEST(RealtimePosition, zero_loops_edge) {
203211
EXPECT_THAT(expected, ::testing::ContainerEq(status.pos_steps));
204212
}
205213

214+
// Clear motion queue motor operations.
215+
// The physical status should be reset and motion_backend.Clear() called.
216+
TEST(RealtimePosition, clear_queue) {
217+
HardwareMapping hw;
218+
MockMotionQueue motion_backend = MockMotionQueue();
219+
MotionQueueMotorOperations motor_operations(&hw, &motion_backend);
220+
221+
// Enqueue a segment
222+
LinearSegmentSteps segment = {
223+
0 /* v0 */,
224+
0 /* v1 */,
225+
0 /* aux */,
226+
{10, 20, 30, 40, 50, 60, 70, 80} /* steps */
227+
};
228+
int expected[BEAGLEG_NUM_MOTORS] = {10, 20, 30, 40, 50, 60, 70, 80};
229+
230+
motor_operations.Enqueue(segment);
231+
motion_backend.SimRun(0, 1);
232+
233+
PhysicalStatus status;
234+
motor_operations.GetPhysicalStatus(&status);
235+
EXPECT_THAT(expected, ::testing::ContainerEq(status.pos_steps));
236+
EXPECT_TRUE(motor_operations.Clear());
237+
EXPECT_EQ(motion_backend.clear_calls_count, 1);
238+
motor_operations.GetPhysicalStatus(&status);
239+
memset(expected, 0, sizeof(expected));
240+
EXPECT_THAT(expected, ::testing::ContainerEq(status.pos_steps));
241+
}
242+
206243
int main(int argc, char *argv[]) {
207244
Log_init("/dev/stderr");
208245
::testing::InitGoogleTest(&argc, argv);

src/motion-queue.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ class MotionQueue {
119119
// of not yet executed loops in the item currenly being executed.
120120
virtual int GetPendingElements(uint32_t *head_item_progress) = 0;
121121

122-
// Perform an immediate shutdown, even if motors are still moving, and
123-
// reset the queue to its initial state.
124-
virtual bool EmergencyReset() = 0;
122+
// Perform an immediate reset of the queue,
123+
// even if motors are still moving.
124+
virtual bool Clear() = 0;
125125
};
126126

127127
// Standard implementation.
@@ -141,7 +141,7 @@ class PRUMotionQueue final : public MotionQueue {
141141
void MotorEnable(bool on) final;
142142
void Shutdown(bool flush_queue) final;
143143
int GetPendingElements(uint32_t *head_item_progress) final;
144-
bool EmergencyReset() final;
144+
bool Clear() final;
145145

146146
private:
147147
bool Init();
@@ -166,7 +166,7 @@ class DummyMotionQueue final : public MotionQueue {
166166
if (head_item_progress) *head_item_progress = 0;
167167
return 1;
168168
}
169-
bool EmergencyReset() final { return true; }
169+
bool Clear() final { return true; }
170170
};
171171

172172
#endif // _BEAGLEG_MOTION_QUEUE_H_

src/planner_test.cc

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class FakeMotorOperations : public SegmentQueue {
124124
void WaitQueueEmpty() final {}
125125
bool GetPhysicalStatus(PhysicalStatus *status) final { return false; }
126126
void SetExternalPosition(int axis, int steps) final {}
127+
bool Clear() final { return false; }
127128

128129
int SegmentsCount() const { return collected_.size(); }
129130
const std::vector<LinearSegmentSteps> &segments() { return collected_; }

src/pru-motion-queue.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ void PRUMotionQueue::Shutdown(bool flush_queue) {
177177
MotorEnable(false);
178178
}
179179

180-
bool PRUMotionQueue::EmergencyReset() {
181-
Shutdown(false);
180+
bool PRUMotionQueue::Clear() {
181+
pru_interface_->Shutdown();
182182
return Init();
183183
}
184184

src/pru-motion-queue_test.cc

+7-13
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,8 @@ class MockPRUInterface : public PruHardwareInterface {
3030
public:
3131
MockPRUInterface() : execution_index_(QUEUE_LEN - 1) {
3232
mmap = NULL;
33-
ON_CALL(*this, Init).WillByDefault([]() {
34-
return true;
35-
});
36-
ON_CALL(*this, Shutdown).WillByDefault([]() {
37-
return true;
38-
});
33+
ON_CALL(*this, Init).WillByDefault([]() { return true; });
34+
ON_CALL(*this, Shutdown).WillByDefault([]() { return true; });
3935
}
4036
~MockPRUInterface() override { free(mmap); }
4137

@@ -45,6 +41,7 @@ class MockPRUInterface : public PruHardwareInterface {
4541
MOCK_METHOD(bool, Shutdown, (), ());
4642

4743
bool AllocateSharedMem(void **pru_mmap, const size_t size) final {
44+
if (mmap != NULL) return true;
4845
mmap = (struct MockPRUCommunication *)malloc(size);
4946
*pru_mmap = (void *)mmap;
5047
memset(*pru_mmap, 0x00, size);
@@ -141,9 +138,8 @@ TEST(PruMotionQueue, one_round_queue) {
141138
EXPECT_EQ(motion_backend.GetPendingElements(NULL), QUEUE_LEN);
142139
}
143140

144-
// Check emergency reset shutsdowns the motors and
145-
// the PRU and sets to zero the whole queue.
146-
TEST(PruMotionQueue, emergency_stop) {
141+
// Check the PRU is reset and no elements are pending.
142+
TEST(PruMotionQueue, clear_queue) {
147143
MotorsRegister absolute_pos_loops;
148144
NiceMock<MockPRUInterface> pru_interface;
149145
HardwareMapping hmap = HardwareMapping();
@@ -164,11 +160,9 @@ TEST(PruMotionQueue, emergency_stop) {
164160
EXPECT_CALL(pru_interface, Shutdown())
165161
.Times(1)
166162
.WillRepeatedly(testing::Return(true));
167-
EXPECT_CALL(pru_interface, Init())
168-
.Times(1)
169-
.WillOnce(testing::Return(true));
163+
EXPECT_CALL(pru_interface, Init()).Times(1).WillOnce(testing::Return(true));
170164
}
171-
EXPECT_TRUE(motion_backend.EmergencyReset());
165+
EXPECT_TRUE(motion_backend.Clear());
172166
EXPECT_EQ(motion_backend.GetPendingElements(NULL), 0);
173167
}
174168

src/segment-queue.h

+6
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,12 @@ class SegmentQueue {
7777
// source (e.g. homing). This will allow accurate reporting of the
7878
// PhysicalStatus.
7979
virtual void SetExternalPosition(int axis, int position_steps) = 0;
80+
81+
// Clear the queue and reset it to its initial state.
82+
// This action is immediate and will discard any running or
83+
// enqueued and not yet executed segment.
84+
// Current physical status will be lost.
85+
virtual bool Clear() = 0;
8086
};
8187

8288
#endif // _BEAGLEG_MOTOR_OPERATIONS_H_

src/sim-audio-out.h

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class SimFirmwareAudioQueue : public MotionQueue {
3232
void WaitQueueEmpty() final {}
3333
void MotorEnable(bool on) final {}
3434
void Shutdown(bool flush_queue) final {}
35+
bool Clear() final { return false; }
3536
int GetPendingElements(uint32_t *head_item_progress) final {
3637
if (head_item_progress) *head_item_progress = 0;
3738
return 1;

src/sim-firmware.h

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class SimFirmwareQueue : public MotionQueue {
3131
void WaitQueueEmpty() final {}
3232
void MotorEnable(bool on) final {}
3333
void Shutdown(bool flush_queue) final {}
34+
bool Clear() final { return false; }
3435
int GetPendingElements(uint32_t *head_item_progress) final {
3536
if (head_item_progress) *head_item_progress = 0;
3637
return 1;

0 commit comments

Comments
 (0)