Skip to content

Commit

Permalink
RSDK-8592 Make single encoder tick even without motor (viamrobotics#4332
Browse files Browse the repository at this point in the history
)
  • Loading branch information
oliviamiller committed Sep 3, 2024
1 parent 4d3b913 commit 55ac5e3
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 5 deletions.
8 changes: 5 additions & 3 deletions components/encoder/single/single_encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ func (e *Encoder) Reconfigure(
if e.workers != nil {
e.workers.Stop() // Shut down the old interrupt stream
}
e.start(ctx, board) // Start up the new interrupt stream
e.start(board) // Start up the new interrupt stream
return nil
}

// start starts the Encoder background thread. It should only be called when the encoder's
// background workers have been stopped (or never started).
func (e *Encoder) start(ctx context.Context, b board.Board) {
func (e *Encoder) start(b board.Board) {
e.workers = utils.NewBackgroundStoppableWorkers()

encoderChannel := make(chan board.Tick)
Expand Down Expand Up @@ -207,7 +207,9 @@ func (e *Encoder) start(ctx context.Context, b board.Board) {
atomic.AddInt64(&e.position, dir)
}
} else {
e.logger.CDebug(ctx, "received tick for encoder that isn't connected to a motor; ignoring")
// if no motor is attached to the encoder, increase in positive direction.
e.logger.Debug("no motor is attached to the encoder, increasing ticks count in the positive direction only")
atomic.AddInt64(&e.position, 1)
}
}
})
Expand Down
39 changes: 37 additions & 2 deletions components/encoder/single/single_encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ func TestEncoder(t *testing.T) {
})
})

// this test ensures that digital interrupts are ignored if AttachDirectionalAwareness
// is never called
// this test ensures that position goes forward if motor not attached.
t.Run("run no direction", func(t *testing.T) {
enc, err := NewSingleEncoder(ctx, deps, rawcfg, logging.NewTestLogger(t))
test.That(t, err, test.ShouldBeNil)
Expand All @@ -128,6 +127,42 @@ func TestEncoder(t *testing.T) {
// by the encoder worker
time.Sleep(50 * time.Millisecond)

ticks, _, err := enc.Position(context.Background(), encoder.PositionTypeUnspecified, nil)
test.That(t, err, test.ShouldBeNil)
test.That(t, ticks, test.ShouldEqual, 1)
})

// Taking off directional awareness makes encoder tick forward.
t.Run("run motor then no motor", func(t *testing.T) {
enc, err := NewSingleEncoder(ctx, deps, rawcfg, logging.NewTestLogger(t))
test.That(t, err, test.ShouldBeNil)
enc2 := enc.(*Encoder)
defer enc2.Close(context.Background())

m := &FakeDir{-1} // backward
enc2.AttachDirectionalAwareness(m)

err = ii.Tick(context.Background(), true, uint64(time.Now().UnixNano()))
test.That(t, err, test.ShouldBeNil)

testutils.WaitForAssertion(t, func(tb testing.TB) {
tb.Helper()
ticks, _, err := enc.Position(context.Background(), encoder.PositionTypeUnspecified, nil)
test.That(tb, err, test.ShouldBeNil)
test.That(tb, ticks, test.ShouldEqual, -1)
})

// take off directional awareness.
enc2.m = nil

err = ii.Tick(context.Background(), true, uint64(time.Now().UnixNano()))
test.That(t, err, test.ShouldBeNil)

// Give the tick time to propagate to encoder
// Warning: theres a race condition if the tick has not been processed
// by the encoder worker
time.Sleep(50 * time.Millisecond)

ticks, _, err := enc.Position(context.Background(), encoder.PositionTypeUnspecified, nil)
test.That(t, err, test.ShouldBeNil)
test.That(t, ticks, test.ShouldEqual, 0)
Expand Down

0 comments on commit 55ac5e3

Please sign in to comment.