Skip to content
This repository was archived by the owner on Dec 1, 2020. It is now read-only.

Commit 19dd579

Browse files
author
Olav de Haas
committed
Make Encoder pure abstract
1 parent aa8b5fd commit 19dd579

File tree

9 files changed

+63
-48
lines changed

9 files changed

+63
-48
lines changed

march_hardware/CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ if(CATKIN_ENABLE_TESTING)
110110
test/error/test_hardware_exception.cpp
111111
test/error/test_motion_error.cpp
112112
test/mocks/MockAbsoluteEncoder.cpp
113-
test/mocks/MockIncrementalEncoder.cpp
113+
test/mocks/MockEncoder.cpp
114114
test/mocks/MockIMotionCube.cpp
115+
test/mocks/MockIncrementalEncoder.cpp
115116
test/mocks/MockJoint.cpp
116117
test/mocks/MockTemperatureGES.cpp
117118
test/mocks/MockTemperatureSensor.cpp

march_hardware/include/march_hardware/encoder/AbsoluteEncoder.h

+1-11
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,7 @@ class AbsoluteEncoder : public Encoder
1414
AbsoluteEncoder(size_t number_of_bits, int32_t lower_limit_iu, int32_t upper_limit_iu, double lower_limit_rad,
1515
double upper_limit_rad, double lower_soft_limit_rad, double upper_soft_limit_rad);
1616

17-
/*
18-
* Reads out the encoder from the slave and transforms the result to radians.
19-
* @param actual_position_byte_offset the byte offset in the slave register for the IU position
20-
* @returns The current position of the encoder in radians
21-
*/
22-
double getAngleRad(uint8_t byte_offset) const;
23-
24-
/*
25-
* Converts encoder Internal Units (IU) to radians.
26-
*/
27-
double toRad(int32_t iu) const;
17+
double toRad(int32_t iu) const override;
2818

2919
/*
3020
* Converts radians to encoder Internal Units (IU).

march_hardware/include/march_hardware/encoder/Encoder.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#ifndef MARCH_HARDWARE_ENCODER_H
44
#define MARCH_HARDWARE_ENCODER_H
5-
5+
#include <cmath>
66
#include <cstddef>
77
#include <cstdint>
88

@@ -20,6 +20,20 @@ class Encoder
2020
*/
2121
int32_t getAngleIU(uint8_t byte_offset) const;
2222

23+
/*
24+
* Reads out the encoder from the slave and transforms the result to radians.
25+
* @param byte_offset the byte offset in the slave register for the IU position
26+
* @returns The current position of the encoder in radians
27+
*/
28+
double getAngleRad(uint8_t byte_offset) const;
29+
30+
/*
31+
* Converts encoder Internal Units (IU) to radians.
32+
* This is a pure virtual function and must be implemented by subclasses,
33+
* since each type of encoder has a different way of calculating radians.
34+
*/
35+
virtual double toRad(int32_t iu) const = 0;
36+
2337
size_t getTotalPositions() const;
2438

2539
int getSlaveIndex() const;
@@ -28,6 +42,8 @@ class Encoder
2842
static const size_t MIN_RESOLUTION = 1;
2943
static const size_t MAX_RESOLUTION = 32;
3044

45+
static constexpr double PI_2 = 2 * M_PI;
46+
3147
private:
3248
/*
3349
* Returns the total number of positions possible on an encoder

march_hardware/include/march_hardware/encoder/IncrementalEncoder.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,20 @@ class IncrementalEncoder : public Encoder
1313
public:
1414
IncrementalEncoder(size_t number_of_bits, double transmission);
1515

16-
double getAngleRad(uint8_t byte_offset);
17-
18-
double toRad(int32_t iu);
16+
double toRad(int32_t iu) const override;
1917

2018
/** @brief Override comparison operator */
2119
friend bool operator==(const IncrementalEncoder& lhs, const IncrementalEncoder& rhs)
2220
{
23-
return lhs.getSlaveIndex() == rhs.getSlaveIndex() && lhs.getTotalPositions() == rhs.getTotalPositions();
21+
return lhs.getSlaveIndex() == rhs.getSlaveIndex() && lhs.getTotalPositions() == rhs.getTotalPositions() &&
22+
lhs.transmission_ == rhs.transmission_;
2423
}
2524
/** @brief Override stream operator for clean printing */
2625
friend std::ostream& operator<<(std::ostream& os, const IncrementalEncoder& encoder)
2726
{
2827
return os << "slaveIndex: " << encoder.getSlaveIndex() << ", "
29-
<< "totalPositions: " << encoder.getTotalPositions();
28+
<< "totalPositions: " << encoder.getTotalPositions() << ", "
29+
<< "transmission: " << encoder.transmission_;
3030
}
3131

3232
private:

march_hardware/src/encoder/AbsoluteEncoder.cpp

+4-14
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,17 @@
11
// Copyright 2019 Project March.
22
#include "march_hardware/encoder/AbsoluteEncoder.h"
3-
#include "march_hardware/EtherCAT/EthercatIO.h"
43
#include "march_hardware/error/hardware_exception.h"
54

6-
#include <cmath>
7-
85
#include <ros/ros.h>
96

107
namespace march
118
{
12-
const double PI_2 = 2 * M_PI;
13-
149
AbsoluteEncoder::AbsoluteEncoder(size_t number_of_bits, int32_t lower_limit_iu, int32_t upper_limit_iu,
1510
double lower_limit_rad, double upper_limit_rad, double lower_soft_limit_rad,
1611
double upper_soft_limit_rad)
1712
: Encoder(number_of_bits), lower_limit_iu_(lower_limit_iu), upper_limit_iu_(upper_limit_iu)
1813
{
19-
this->zero_position_iu_ = this->lower_limit_iu_ - lower_limit_rad * Encoder::getTotalPositions() / PI_2;
14+
this->zero_position_iu_ = this->lower_limit_iu_ - lower_limit_rad * this->getTotalPositions() / PI_2;
2015
this->lower_soft_limit_iu_ = this->fromRad(lower_soft_limit_rad);
2116
this->upper_soft_limit_iu_ = this->fromRad(upper_soft_limit_rad);
2217

@@ -42,19 +37,14 @@ AbsoluteEncoder::AbsoluteEncoder(size_t number_of_bits, int32_t lower_limit_iu,
4237
}
4338
}
4439

45-
double AbsoluteEncoder::getAngleRad(uint8_t byte_offset) const
40+
double AbsoluteEncoder::toRad(int32_t iu) const
4641
{
47-
return this->toRad(Encoder::getAngleIU(byte_offset));
42+
return (iu - this->zero_position_iu_) * PI_2 / this->getTotalPositions();
4843
}
4944

5045
int32_t AbsoluteEncoder::fromRad(double rad) const
5146
{
52-
return (rad * Encoder::getTotalPositions() / PI_2) + this->zero_position_iu_;
53-
}
54-
55-
double AbsoluteEncoder::toRad(int32_t iu) const
56-
{
57-
return (iu - this->zero_position_iu_) * PI_2 / Encoder::getTotalPositions();
47+
return (rad * this->getTotalPositions() / PI_2) + this->zero_position_iu_;
5848
}
5949

6050
bool AbsoluteEncoder::isWithinHardLimitsIU(int32_t iu) const

march_hardware/src/encoder/Encoder.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ int32_t Encoder::getAngleIU(uint8_t byte_offset) const
2121
return return_byte.i;
2222
}
2323

24+
double Encoder::getAngleRad(uint8_t byte_offset) const
25+
{
26+
return this->toRad(Encoder::getAngleIU(byte_offset));
27+
}
28+
2429
size_t Encoder::getTotalPositions() const
2530
{
2631
return this->total_positions_;
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
// Copyright 2019 Project March.
22
#include "march_hardware/encoder/IncrementalEncoder.h"
33

4-
#include <cmath>
5-
64
namespace march
75
{
86
IncrementalEncoder::IncrementalEncoder(size_t number_of_bits, double transmission)
97
: Encoder(number_of_bits), transmission_(transmission)
108
{
119
}
1210

13-
double IncrementalEncoder::getAngleRad(uint8_t byte_offset)
14-
{
15-
return this->toRad(Encoder::getAngleIU(byte_offset));
16-
}
17-
18-
double IncrementalEncoder::toRad(int32_t iu)
11+
double IncrementalEncoder::toRad(int32_t iu) const
1912
{
20-
return iu * this->transmission_ * 2 * M_PI / Encoder::getTotalPositions();
13+
return iu * this->transmission_ * PI_2 / this->getTotalPositions();
2114
}
2215
} // namespace march
+14-7
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,43 @@
11
// Copyright 2020 Project March.
2-
#include "march_hardware/encoder/Encoder.h"
2+
#include "../mocks/MockEncoder.cpp"
33
#include "march_hardware/error/hardware_exception.h"
44

55
#include <cmath>
66

77
#include <gtest/gtest.h>
88

9+
/**
10+
* This test fixture uses the MockEncoder to test non virtual methods
11+
* of the Encoder abstract class. Otherwise it is not possible to
12+
* instantiate a pure abstract class. So as long as the non virtual
13+
* methods are tested all is ok.
14+
*/
915
class TestEncoder : public testing::Test
1016
{
1117
protected:
1218
const size_t resolution = 12;
13-
march::Encoder encoder = march::Encoder(this->resolution);
1419
};
1520

1621
TEST_F(TestEncoder, ResolutionBelowRange)
1722
{
18-
ASSERT_THROW(march::Encoder(0), march::error::HardwareException);
23+
ASSERT_THROW(MockEncoder(0), march::error::HardwareException);
1924
}
2025

2126
TEST_F(TestEncoder, ResolutionAboveRange)
2227
{
23-
ASSERT_THROW(march::Encoder(50), march::error::HardwareException);
28+
ASSERT_THROW(MockEncoder(50), march::error::HardwareException);
2429
}
2530

2631
TEST_F(TestEncoder, SetSlaveIndex)
2732
{
33+
MockEncoder encoder(this->resolution);
2834
const int expected = 10;
29-
this->encoder.setSlaveIndex(expected);
30-
ASSERT_EQ(expected, this->encoder.getSlaveIndex());
35+
encoder.setSlaveIndex(expected);
36+
ASSERT_EQ(expected, encoder.getSlaveIndex());
3137
}
3238

3339
TEST_F(TestEncoder, CorrectTotalPositions)
3440
{
35-
ASSERT_EQ(std::pow(2, this->resolution), this->encoder.getTotalPositions());
41+
MockEncoder encoder(this->resolution);
42+
ASSERT_EQ(std::pow(2, this->resolution), encoder.getTotalPositions());
3643
}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "march_hardware/encoder/Encoder.h"
2+
3+
#include <gmock/gmock.h>
4+
5+
class MockEncoder : public march::Encoder
6+
{
7+
public:
8+
MockEncoder(size_t number_of_bits) : Encoder(number_of_bits)
9+
{
10+
}
11+
12+
MOCK_CONST_METHOD1(toRad, double(int32_t));
13+
};

0 commit comments

Comments
 (0)