-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
204 lines (179 loc) · 4.45 KB
/
main.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#include <ESP8266WiFi.h>
#include <ros.h>
#include<Adafruit_NeoPixel.h>
#include<geometry_msgs/Vector3.h>
#include <Adafruit_PWMServoDriver.h>
#include<math.h>
// motor
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
const int DC_OFF = 0;
const int DC_MIN = 1096;
const int DC_MAX = 4096;
const int DC_DIFF = DC_MAX - DC_MIN;
const int MOTORS = 4;
const int FREQUENCY = 100;
// left to right
const int forward[] = {13, 15, 1, 2};
const int backward[] = {12, 14, 0, 3};
// LED
const int LEDS = 16;
Adafruit_NeoPixel ring = Adafruit_NeoPixel(LEDS, D4, NEO_GRB + NEO_KHZ800);
// WLAN
const char* ssid = "Felsit";
const char* password = "3sUdo#k8-9";
// ROS
IPAddress server(192, 168, 178, 3); // ip of your ROS server
IPAddress ip_address;
WiFiClient client;
bool activated = false;
int timeout = 0;
class WiFiHardware {
public:
WiFiHardware() {};
void init() {
client.connect(server, 11411);
}
// read a byte from the serial port. -1 = failure
int read() {
return client.read(); //will return -1 when it will works
}
// write data to the connection to ROS
void write(uint8_t* data, int length) {
for(int i=0; i<length; i++)
client.write(data[i]);
}
};
void indexwise_add(const double a[],const double b[], double ans[]){
for (int i = 0; i < MOTORS; i++)
ans[i] = a[i] + b[i];
}
void reset_engine(){
for(int i = 0; i < LEDS; i++){
pwm.setPin(i, DC_OFF);
ring.setPixelColor(i, ring.Color(0, 0, 0));
ring.show();
}
}
void breaking(){
//break
for (int i = 0; i < MOTORS; i++){
pwm.setPin(forward[i], DC_OFF);
pwm.setPin(backward[i], DC_OFF);
}
for (int i = 0; i < LEDS; i++)
ring.setPixelColor(i, ring.Color(255, 0, 0));
ring.show();
activated = true;
}
void directional_LEDs(const geometry_msgs::Vector3& directions){
//directional LED
int i = -1;
if(direction.x == 0){
if(direction.y > 0)
i = 8;
else
i = 0;
}
else if (direction.y == 0){
if (direction.x > 0)
i = 4;
else
i = 12;
}
else{
double rad = atan(direction.y/direction.x);
i = ((int)(16 + rad * 16 / (2*M_PI)))%16;
}
// intensity according to aceleration
double l = sqrt(direction.x*direction.x + direction.y*direction.y);
Serial.println(l);
int brightness = 0;
if (l >= 1)
brightness = 255;
else
brightness = 255*l;
ring.setPixelColor(i, ring.Color(0, brightness, 0));
ring.show();
}
void set_acceleration(const double acc[]){
for (int i = 0; i < MOTORS; i++){
if (acc[i] >= 0){
pwm.setPin(forward[i], DC_MIN + acc[i]*DC_DIFF);
pwm.setPin(backward[i], DC_OFF);
}
else{
pwm.setPin(backward[i], DC_MIN - acc[i]*DC_DIFF);
pwm.setPin(forward[i], DC_OFF);
}
}
}
void directionsCallback(const geometry_msgs::Vector3& direction) {
Serial.print("direction");
// led closest to direction
if(direction.x == 0 && direction.y == 0){
breaking();
}
else{
double x = direction.x;
double y = direction.y;
double xy = abs(direction.x) + abs(direction.y);
if(xy > 1){
x = direction.x / xy;
y = direction.y / xy;
}
double acceleration_front[] = {y, y, y, y};
double acceleration_right[] = {x, x, -x, -x};
double acceleration[] = {0, 0, 0, 0};
indexwise_add(acceleration_front, acceleration_right, acceleration);
set_acceleration(acceleration);
directional_LEDs(direction);
}
activated = true;
Serial.printf("activated");
timeout = 2;
}
ros::Subscriber<geometry_msgs::Vector3> sub("directions", &directionsCallback);
ros::NodeHandle_<WiFiHardware> nh;
void setupWiFi()
{
WiFi.begin(ssid, password);
Serial.print("\nConnecting to "); Serial.println(ssid);
while (WiFi.status() != WL_CONNECTED){
delay(1000);
Serial.print("Could not connect to roscore at "); Serial.println(ssid);
}
Serial.println("Connected!");
Serial.print("my address is ");
Serial.println(WiFi.localIP());
}
void setupPWM(){
pwm.begin();
pwm.setPWMFreq(FREQUENCY);
}
void setup() {
Serial.begin(115200);
setupPWM();
ring.begin();
reset_engine();
setupWiFi();
delay(1000);
nh.initNode();
nh.subscribe(sub);
timeout = 2;
}
void loop() {
nh.spinOnce();
Serial.println("post spin");
delay(200);
if (timeout > 0)
timeout -= 1;
Serial.print("timeout = ");
Serial.println(timeout);
if (timeout <= 0 && activated){
for (int i = 0; i < 16; i++)
ring.setPixelColor(i, ring.Color(0, 0, 0));
ring.show();
breaking();
activated = false;
}
}