Skip to content

Commit e1a4a13

Browse files
authored
Add BNO055 IMU code (#66)
File is unchanged (to encoder.ino) except for addition of code for Adafruit BNO055 IMU
1 parent e7b6c8c commit e1a4a13

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/* Encoder Library - TwoKnobs Example
2+
* http://www.pjrc.com/teensy/td_libs_Encoder.html
3+
*
4+
* This example code is in the public domain.
5+
*/
6+
// Adafruit BNO055 code added by Russ76
7+
// Red to 3.3V, Black GRND, Yellow SCL 19, Blue SDA 18
8+
/*
9+
* rosserial PubSub Example
10+
* Prints "hello world!" and toggles led
11+
*/
12+
13+
#include <ros.h>
14+
#include "ros/time.h"
15+
//#include <std_msgs/Int32.h>
16+
#include <diffbot_msgs/Encoders.h>
17+
#include <std_msgs/Empty.h>
18+
#include <Wire.h>
19+
#include <Adafruit_Sensor.h>
20+
#include <Adafruit_BNO055.h>
21+
#include <utility/imumaths.h>
22+
#include "sensor_msgs/Imu.h"
23+
#include <Encoder.h>
24+
25+
// Encoder setup
26+
// Change these pin numbers to the pins connected to your encoder.
27+
// Best Performance: both pins have interrupt capability
28+
// Good Performance: only the first pin has interrupt capability
29+
// Low Performance: neither pin has interrupt capability
30+
Encoder encoderLeft(5, 6); // Default pins 5, 6
31+
Encoder encoderRight(7, 8); // Default pins 7, 8
32+
// avoid using pins with LEDs attached
33+
char imu_link[] = "imu";
34+
35+
ros::NodeHandle nh;
36+
37+
// Check I2C device address and correct line below (by default address is 0x29 or 0x28)
38+
// id, address
39+
Adafruit_BNO055 bno = Adafruit_BNO055(55, 0x28);
40+
sensor_msgs::Imu Imu_msg;
41+
ros::Publisher imu_pub("imu/data_raw", &Imu_msg);
42+
43+
// ROS Subscriber setup to reset both encoders to zero
44+
void resetCallback( const std_msgs::Empty& reset)
45+
{
46+
//digitalWrite(13, HIGH-digitalRead(13)); // blink the led
47+
// reset both back to zero.
48+
encoderLeft.write(0);
49+
encoderRight.write(0);
50+
nh.loginfo("Reset both wheel encoders to zero");
51+
}
52+
53+
ros::Subscriber<std_msgs::Empty> sub_reset("reset", resetCallback);
54+
55+
// ROS Publisher setup to publish left and right encoder ticks
56+
// This uses the custom encoder ticks message that defines an array of two integers
57+
diffbot_msgs::Encoders encoder_ticks;
58+
ros::Publisher pub_encoders("encoder_ticks", &encoder_ticks);
59+
60+
void setup()
61+
{
62+
nh.initNode();
63+
nh.advertise(pub_encoders);
64+
nh.subscribe(sub_reset);
65+
nh.advertise(imu_pub);
66+
while (!nh.connected())
67+
{
68+
nh.spinOnce();
69+
}
70+
nh.loginfo("Initialize DiffBot Wheel Encoders");
71+
std_msgs::Empty reset;
72+
resetCallback(reset);
73+
delay(1);
74+
75+
/* Initialise the sensor */
76+
if (!bno.begin())
77+
{
78+
/* There was a problem detecting the BNO055 ... check your connections */
79+
Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
80+
while (1);
81+
}
82+
83+
delay(100);
84+
bno.setExtCrystalUse(true);
85+
}
86+
87+
long positionLeft = -999;
88+
long positionRight = -999;
89+
90+
void loop() {
91+
long newLeft, newRight;
92+
newLeft = encoderLeft.read();
93+
newRight = encoderRight.read();
94+
95+
encoder_ticks.ticks[0] = newLeft;
96+
encoder_ticks.ticks[1] = newRight;
97+
pub_encoders.publish(&encoder_ticks);
98+
nh.spinOnce();
99+
100+
101+
imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);
102+
imu::Vector<3> gyro = bno.getVector(Adafruit_BNO055::VECTOR_GYROSCOPE);
103+
imu::Quaternion quat = bno.getQuat();
104+
105+
//nh.loginfo("In main loop now.");
106+
107+
// http://docs.ros.org/kinetic/api/sensor_msgs/html/msg/Imu.html
108+
sensor_msgs::Imu imu_msg;
109+
imu_msg.header.frame_id = imu_link;
110+
imu_msg.header.stamp = nh.now();
111+
imu_msg.orientation.x = quat.w();
112+
imu_msg.orientation.y = quat.x();
113+
imu_msg.orientation.z = quat.y();
114+
imu_msg.orientation.w = quat.z();
115+
imu_msg.linear_acceleration.x = (euler.x());
116+
imu_msg.linear_acceleration.y = (euler.y());
117+
imu_msg.linear_acceleration.z = (euler.z());
118+
imu_msg.angular_velocity.x = (gyro.x());
119+
imu_msg.angular_velocity.y = (gyro.y());
120+
imu_msg.angular_velocity.z = (gyro.z());
121+
// https://github.com/Russ76/ros_mpu6050_node-1/blob/master/src/mpu6050_node.cpp
122+
imu_pub.publish(&imu_msg);
123+
124+
125+
// Use at least a delay of 3 ms on the work pc and 5 ms on the Raspberry Pi
126+
// Too low delay causes errors in rosserial similar to the following:
127+
// [INFO]: wrong checksum for topic id and msg
128+
// [INFO]: Wrong checksum for msg length, length 4, dropping message.
129+
// [ERROR]: Mismatched protocol version in packet (b'\x00'): lost sync or rosserial_python is from different ros release than the rosserial client
130+
// [INFO]: Protocol version of client is unrecognized, expected Rev 1 (rosserial 0.5+)
131+
// [INFO]: wrong checksum for topic id and msg
132+
// [WARN]: Last read step: message length
133+
// [WARN]: Run loop error: Serial Port read failure: Returned short (expected 3 bytes, received 2 instead).
134+
// [INFO]: Requesting topics...
135+
// [ERROR]: Lost sync with device, restarting...
136+
// [INFO]: Requesting topics...
137+
delay(10);
138+
// Note that https://www.arduino.cc/reference/en/language/functions/time/delay/:
139+
// Certain things do go on while the delay() function is controlling the Atmega chip,
140+
// however, because the delay function does not disable interrupts.
141+
// Serial communication that appears at the RX pin is recorded, PWM (analogWrite) values and pin states are maintained,
142+
// and interrupts will work as they should.
143+
144+
if (newLeft != positionLeft || newRight != positionRight) {
145+
//String str = "Left = " + String(newLeft) + ", Right = " + String(newRight);
146+
//nh.loginfo(str);
147+
positionLeft = newLeft;
148+
positionRight = newRight;
149+
}
150+
}

0 commit comments

Comments
 (0)