-
Notifications
You must be signed in to change notification settings - Fork 6
/
EcatAdmin.cpp
175 lines (134 loc) · 5.87 KB
/
EcatAdmin.cpp
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
//
// Created by han on 16-12-27.
//
#include "EcatAdmin.h"
ec_master_t* EcatAdmin::master = nullptr;
ec_master_state_t EcatAdmin::master_state = {};
ec_domain_t* EcatAdmin::domain1 = nullptr;
ec_domain_state_t EcatAdmin::domain1_state = {};
uint8_t* EcatAdmin::domain1_pd = nullptr;
EcatAdmin::slaves_map EcatAdmin::slaves_dict;
int EcatAdmin::start_for_ros_control()
{
master = ecrt_request_master(0);
if (!master) {
printf("master init error\n");
goto out_return;
}
domain1 = ecrt_master_create_domain(master);
if (!domain1) {
printf("domain1 init error\n");
goto out_release_master;
}
for(auto & item : slaves_dict){
auto &drive = item.second;
if (!(drive->sc_ = ecrt_master_slave_config(master, drive->get_alias(), drive->get_position(), drive->get_vendor_id(), drive->get_product_code()))) {
printf("Could not get slave configuration for Drive at bus position = %u\n", (unsigned int)drive->get_position());
goto out_release_master;
}
/* Clear RxPdo */
ecrt_slave_config_sdo8( drive->sc_, 0x1C12, 0, 0 ); /* clear sm pdo 0x1c12 */
ecrt_slave_config_sdo8( drive->sc_, 0x1600, 0, 0 ); /* clear RxPdo 0x1600 */
ecrt_slave_config_sdo8( drive->sc_, 0x1601, 0, 0 ); /* clear RxPdo 0x1601 */
ecrt_slave_config_sdo8( drive->sc_, 0x1602, 0, 0 ); /* clear RxPdo 0x1602 */
ecrt_slave_config_sdo8( drive->sc_, 0x1603, 0, 0 ); /* clear RxPdo 0x1603 */
/* Define RxPdo */
ecrt_slave_config_sdo8( drive->sc_, 0x1600, 0, 1 ); /* set number of PDO entries for 0x1600 */
ecrt_slave_config_sdo32( drive->sc_, 0x1600, 1, 0x60400010 ); /* control word */
ecrt_slave_config_sdo8( drive->sc_, 0x1601, 0, 2 ); /* set number of PDO entries for 0x1601 */
ecrt_slave_config_sdo32( drive->sc_, 0x1601, 1, 0x607A0020 ); /* target position*/
ecrt_slave_config_sdo32( drive->sc_, 0x1601, 2, 0x60810020 ); /* profile_velocity */
/* clear TxPdo */
ecrt_slave_config_sdo8( drive->sc_, 0x1C13, 0, 0 ); /* clear sm pdo 0x1c13 */
ecrt_slave_config_sdo8( drive->sc_, 0x1A00, 0, 0 ); /* clear TxPdo 0x1A00 */
ecrt_slave_config_sdo8( drive->sc_, 0x1A01, 0, 0 ); /* clear TxPdo 0x1A01 */
ecrt_slave_config_sdo8( drive->sc_, 0x1A02, 0, 0 ); /* clear TxPdo 0x1A02 */
ecrt_slave_config_sdo8( drive->sc_, 0x1A03, 0, 0 ); /* clear TxPdo 0x1A03 */
/* Define TxPdo */
ecrt_slave_config_sdo32( drive->sc_, 0x1A00, 1, 0x60410010 ); /* 0x6041:0/16bits, status word */
ecrt_slave_config_sdo8( drive->sc_, 0x1A00, 0, 1 ); /* set number of PDO entries for 0x1A00 */
ecrt_slave_config_sdo32( drive->sc_, 0x1A01, 1, 0x606C0020 ); /* 0x606c:0/32bits, act velocity */
ecrt_slave_config_sdo32( drive->sc_, 0x1A01, 2, 0x60640020 ); /* 0x6063:0/32bits, act position */
ecrt_slave_config_sdo8( drive->sc_, 0x1A01, 0, 2 ); /* set number of PDO entries for 0x1A01 */
ecrt_slave_config_sdo8( drive->sc_, 0x6060, 0, 8 );
if (ecrt_slave_config_pdos(drive->sc_, EC_END, cdhd_syncs)) {
printf("Could not configure PDOs for Drive at bus position = %u\n", (unsigned int)drive->get_position());
goto out_release_master;
}
}
if (ecrt_domain_reg_pdo_entry_list(domain1, &(get_pdo_entry_regs_with_terminated()[0]))) {
printf("Could not register PDO entries. \n");
goto out_release_master;
}
printf("Activating the master. \n");
if (ecrt_master_activate(master)) {
printf("Could not activate the ethercat master. \n");
goto out_release_master;
}
domain1_pd = ecrt_domain_data(domain1);
return 0;
out_release_master:
printf("releasing the master\n");
ecrt_release_master(master);
out_return:
printf("error occur!!!\n");
return 1;
}
std::vector<ec_pdo_entry_reg_t> EcatAdmin::get_pdo_entry_regs_with_terminated()
{
std::vector<ec_pdo_entry_reg_t> regs;
for (auto & item : slaves_dict) {
auto &drive = item.second;
for (int i = 0; i < 6; ++i) {
ec_pdo_entry_reg_t entry;
entry.alias = drive->get_alias();
entry.position = drive->get_position();
entry.vendor_id = drive->get_vendor_id();
entry.product_code = drive->get_product_code();
entry.index = drive->pdo_index_[i];
entry.subindex = drive->pdo_subindex_[i];
entry.offset = &Motor::regs[drive->index_to_offset_list_[i]];
entry.bit_position = 0;
regs.push_back(entry);
}
}
ec_pdo_entry_reg_t terminator;
regs.push_back(terminator);
return (regs);
}
void EcatAdmin::add_motor(int joint_no, std::string joint_name, uint16_t alias, uint16_t position, uint32_t vendor_id, uint32_t product_code)
{
std::shared_ptr<Motor> motor_ptr = std::make_shared<Motor>(joint_no, joint_name, alias, position, vendor_id, product_code);
slaves_dict[joint_no] = motor_ptr;
}
void EcatAdmin::shutdown()
{
ecrt_release_master(master);
}
void EcatAdmin::check_domain_state(void)
{
ec_domain_state_t ds = {};
ecrt_domain_state(domain1, &ds);
if (ds.working_counter != domain1_state.working_counter) {
printf("Domain1: WC %u.\n", ds.working_counter);
}
if (ds.wc_state != domain1_state.wc_state) {
printf("Domain1: State %u.\n", ds.wc_state);
}
domain1_state = ds;
}
void EcatAdmin::check_master_state(void)
{
ec_master_state_t ms;
ecrt_master_state(master, &ms);
if (ms.slaves_responding != master_state.slaves_responding) {
printf("%u slave(s).\n", ms.slaves_responding);
}
if (ms.al_states != master_state.al_states) {
printf("AL states: 0x%02X.\n", ms.al_states);
}
if (ms.link_up != master_state.link_up) {
printf("Link is %s.\n", ms.link_up ? "up" : "down");
}
master_state = ms;
}