GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/catkin/hardware/blmc_drivers/src/motor.cpp Lines: 1 79 1.3 %
Date: 2020-04-15 11:50:02 Branches: 2 184 1.1 %

Line Branch Exec Source
1
/**
2
 * @file motor.cpp
3
 * @author Manuel Wuthrich (manuel.wuthrich@gmail.com)
4
 * @author Maximilien Naveau (maximilien.naveau@gmail.com)
5
 * @brief
6
 * @version 0.1
7
 * @date 2018-11-27
8
 *
9
 * @copyright Copyright (c) 2018
10
 *
11
 */
12
13
#include <blmc_drivers/devices/motor.hpp>
14
15
namespace blmc_drivers
16
{
17
18
Motor::Motor(Ptr<MotorBoardInterface> board, bool motor_id):
19
    board_(board),
20
    motor_id_(motor_id)
21
{
22
23
}
24
25
Motor::Ptr<const Motor::ScalarTimeseries> Motor::get_measurement(
26
  const int& index) const
27
{
28
    if(motor_id_ == 0)
29
    {
30
        switch(index)
31
        {
32
        case current:
33
            return board_->get_measurement(MotorBoardInterface::current_0);
34
        case position:
35
            return board_->get_measurement(MotorBoardInterface::position_0);
36
        case velocity:
37
            return board_->get_measurement(MotorBoardInterface::velocity_0);
38
        case encoder_index:
39
            return board_->get_measurement(
40
                        MotorBoardInterface::encoder_index_0);
41
        }
42
    }
43
    else
44
    {
45
        switch(index)
46
        {
47
        case current:
48
            return board_->get_measurement(MotorBoardInterface::current_1);
49
        case position:
50
            return board_->get_measurement(MotorBoardInterface::position_1);
51
        case velocity:
52
            return board_->get_measurement(MotorBoardInterface::velocity_1);
53
        case encoder_index:
54
            return board_->get_measurement(
55
                        MotorBoardInterface::encoder_index_1);
56
        }
57
    }
58
59
    throw std::invalid_argument("index needs to match one of the measurements");
60
}
61
62
Motor::Ptr<const Motor::ScalarTimeseries> Motor::get_current_target() const
63
{
64
    if(motor_id_ == 0)
65
    {
66
        return board_->get_control(MotorBoardInterface::current_target_0);
67
    }
68
    else
69
    {
70
        return board_->get_control(MotorBoardInterface::current_target_1);
71
    }
72
}
73
74
Motor::Ptr<const Motor::ScalarTimeseries> Motor::get_sent_current_target() const
75
{
76
    if(motor_id_ == 0)
77
    {
78
        return board_->get_sent_control(
79
                    MotorBoardInterface::current_target_0);
80
    }
81
    else
82
    {
83
        return board_->get_sent_control(
84
                    MotorBoardInterface::current_target_1);
85
    }
86
}
87
88
void Motor::set_current_target(const double& current_target)
89
{
90
    if(motor_id_ == 0)
91
    {
92
        board_->set_control(current_target,
93
                            MotorBoardInterface::current_target_0);
94
    }
95
    else
96
    {
97
        board_->set_control(current_target,
98
                            MotorBoardInterface::current_target_1);
99
    }
100
}
101
102
void Motor::print() const
103
{
104
    MotorBoardStatus motor_board_status;
105
    double motor_current = std::nan("");
106
    double motor_position = std::nan("");
107
    double motor_velocity = std::nan("");
108
    double motor_encoder_index = std::nan("");
109
    double motor_sent_current_target = std::nan("");
110
111
    if(board_->get_status()->length() != 0)
112
        {motor_board_status = board_->get_status()->newest_element();}
113
114
    if(get_measurement(current)->length() != 0)
115
        {motor_current = get_measurement(current)->newest_element();}
116
117
    if(get_measurement(position)->length() != 0)
118
        {motor_position = get_measurement(position)->newest_element();}
119
120
    if(get_measurement(velocity)->length() != 0)
121
        {motor_velocity = get_measurement(velocity)->newest_element();}
122
123
    if(get_measurement(encoder_index)->length() != 0)
124
        {motor_encoder_index = get_measurement(encoder_index)->newest_element();}
125
126
    if(get_sent_current_target()->length() != 0)
127
        {motor_sent_current_target = get_sent_current_target()->newest_element();}
128
129
    rt_printf("motor board status: ");
130
    rt_printf("enabled: %d ", motor_board_status.system_enabled);
131
    rt_printf("error_code: %d ", motor_board_status.error_code);
132
    rt_printf("motor status: ");
133
    if(motor_id_ == 0)
134
    {
135
        rt_printf("enabled: %d ", motor_board_status.motor1_enabled);
136
        rt_printf("ready: %d ", motor_board_status.motor1_ready);
137
    }
138
    else
139
    {
140
        rt_printf("enabled: %d ", motor_board_status.motor2_enabled);
141
        rt_printf("ready: %d ", motor_board_status.motor2_ready);
142
    }
143
    rt_printf("motor measurements: ");
144
    rt_printf("current: %8f ", motor_current);
145
    rt_printf("position: %8f ", motor_position);
146
    rt_printf("velocity: %8f ", motor_velocity);
147
    rt_printf("encoder index: %8f ", motor_encoder_index);
148
    rt_printf("target current: %8f ", motor_sent_current_target);
149
    rt_printf("\n");
150
}
151
152
SafeMotor::SafeMotor(
153
  Motor::Ptr<MotorBoardInterface> board,
154
  bool motor_id,
155
  const double& max_current_target,
156
  const size_t& history_length,
157
  const double& max_velocity):
158
      Motor(board, motor_id),
159
      max_current_target_(max_current_target),
160
      max_velocity_(max_velocity)
161
{
162
    current_target_ = std::make_shared<ScalarTimeseries>(history_length);
163
}
164
165
void SafeMotor::set_current_target(const double& current_target)
166
{
167
    current_target_->append(current_target);
168
169
    // limit current to avoid overheating ----------------------------------
170
    double safe_current_target = std::min(current_target,
171
                                          max_current_target_);
172
    safe_current_target = std::max(safe_current_target,
173
                                    -max_current_target_);
174
175
    // limit velocity to avoid breaking the robot --------------------------
176
    if(!std::isnan(max_velocity_) && get_measurement(velocity)->length() > 0 &&
177
            std::fabs(get_measurement(velocity)->newest_element()) > max_velocity_)
178
        safe_current_target = 0;
179
    Motor::set_current_target(safe_current_target);
180
}
181
182

3
} // namespace blmc_drivers