-
Notifications
You must be signed in to change notification settings - Fork 1
/
CANMotor.h
197 lines (174 loc) · 4.91 KB
/
CANMotor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
* This software includes the work that is distributed in the Apache License 2.0
*/
#ifndef CAN_MOTOR_H
#define CAN_MOTOR_H
#include "Motor.h"
#include "mbed.h"
#include "CANMotorManager.h"
class CANMotorManager;
/** An CAN Motor is used to controll CAN motor driver
*
* You can use as many separate CANMotor objects as you require.
*
* Example:
* @code
* #include "mbed.h"
* #include "CANMotor.h"
*
* static const int total_motor = 4;
*
* CAN can(p9, p10);
* CANMotorManager motor_mng(can);
*
* CANMotor motor[total_motor] = {
* CANMotor(can, motor_mng, 0, 0);
* CANMotor(can, motor_mng, 0, 1);
* CANMotor(can, motor_mng, 1, 0);
* CANMotor(can, motor_mng, 1, 1);
* }
*
* int main() {
* // モーター0のデューティー比の変化具合を設定
* motor[0].rise_level(Motor::Low);
* motor[0].fall_level(Motor::High);
*
* // motor_mng.connect_all(); // 下のfor文とほぼ同じ
* for (int i = 0; i < total_motor; i++)
* {
* int j = 0;
* while ((motor[i].connect() == false) && (j++ < 5))
* {
* wait_us(20000);
* }
* }
*
* while(true) {
* // 下のように、それぞれ設定したいモーターに
* // デューティー比と回転方向を入力していく(モーターには書き込まれない)
* motor[3].duty_cycle(0.42);
* motor[3].state(Motor::CW);
*
* // motor_mng.write_all(); // 下のfor文とほぼ同じ
* for (int i = 0; i < total_motor; i++)
* {
* // motor[x].write() が実行されて初めてモータードライバに設定値が書き込まれる
* int result = motor[i].write(); // motor[x].write() が実行されて初めてモータードライバに設定値が書き込まれる
*
* debug_if(!result, "Couldn't write to can bus.\r");
* wait_us(1000);
* }
* }
* }
* @endcode
*/
class CANMotor : public Motor
{
public:
/** Create a CAN Motor interface
*
* @param can connect to can pins
* @param dip Slave DPI value
* @param number Slave motor number
*/
CANMotor(CAN &can, CANMotorManager &mng, int dip, int number);
/** Create a CAN Motor interface
*
* @param can connect to can pins
* @param id Slave id
*/
CANMotor(CAN &can, CANMotorManager &mng, int id);
~CANMotor();
/** Set CAN id
*
* @param id Slave id
*/
void id(int value);
/** Return the CAN id
*
* @returns
* the slave id
*/
int id() const;
/** Connect MotorDriver
*
* @returns
* 0 if connect failed,
* 1 if connect successful
*/
int connect();
/** parse can message
*
* @param data The data to parse
* @returns
* 0 if parse failed,
* 1 if get initialization data request
* 2 if get ack
*/
int parse(unsigned char *data);
/** Set the frequency of the CAN bus
*
* @param hz The bus frequency in hertz
*/
void can_frequency(int hz);
/** Return the CAN frequency
*
* @returns
* the bus frequency in hertz
*/
int can_frequency() const;
/** Write a CANMessage to the bus.
*
* @param msg The CANMessage to write.
*
* @returns
* 0 if write failed,
* 1 if write successful
*/
virtual int write(void);
static const int offset_id_number;
protected:
CAN &_can;
CANMotorManager &_mng;
CANMessage _normal_msg;
CANMessage _initial_msg;
int _number;
int _hz;
int _has_received_ack;
/** Update the duty cycle to MotorDriver
*
* @param duty_cycle duty cycle to update
*/
void update_duty_cycle_data();
/** Update the state to MotorDriver
*
* @param type state to update
*/
void update_state_data();
/** Update the extention data to MotorDriver
*/
void update_extention_data();
/** Embed integers at specified locations in data
*
* @param value Value to embed
* @param size Size of value to embed
* @param data Write destination data
* @param bit_nubmer to start writing
* @returns
* 0 if failed
* 1 if successful
*/
int int_encode(int value, int size, unsigned char *data, int bit_number);
/** Embed floating point data at specified location in data (convert float to bfloat16)
*
* @param value Value to embed
* @param size Size of value to embed
* @param data Write destination data
* @param bit_nubmer to start writing
* @returns
* 0 if failed
* 1 if successful
*/
int float_to_bfloat16_encode(float value, unsigned char *data, int bit_number);
};
#endif