Difference between revisions of "RoCKIn2014PhaseII"
WikiSheriff (talk | contribs) (→FAQ/Problems) |
m |
||
(49 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | + | =Hardware= | |
+ | ==Structure modifications== | ||
− | + | Cover for the screen in order to cover the metallics parts and wires. | |
+ | [[Image:Pantalla1.jpg|center|300px]] | ||
+ | [[Image:Pantalla2.jpg|center|150px]] | ||
+ | Button box in order to host the start and stop button. | ||
− | + | [[Image:botonera.jpg|center|300px]] | |
+ | Bigger space in order to host the computer and the wires. | ||
+ | For this was changed the screws for other longers. | ||
+ | [[Image:modificacionbase1.jpg|center|300px]] | ||
+ | ==Ultrasonic Sensors Belt== | ||
− | + | ===Ultrasonic sensors selecction and microcontroller used=== | |
+ | There are many different kind of ultrasonic sensors and manufacturers, but in this case we have used the Maxbotics [http://www.maxbotix.com] manufacturer . We use these, in order to recycle the ultrasonic sensors of an old watchful robot ( good rattletrap). | ||
+ | This robot use for his navigation system, three different Maxbotics models, the MB1220 [http://www.maxbotix.com/Ultrasonic_Sensors/MB1220.htm], MB 1230 of the XL-Maxsonar-EZ series and the LV-Maxsonar-EZ1 model. | ||
− | + | We will use the model MB1220, because it is the most appropriate for people detection and there are a large quantity of them. | |
+ | [[Image:sensorselection.png|center|600px]] | ||
+ | These sensors will be controller through an Arduino MEGA. | ||
+ | |||
+ | ===First tests and validation sensors=== | ||
+ | |||
+ | Theses sensors have a diode between his outputs PW (anode) and AN (cathode). | ||
+ | |||
+ | After a several test with and without the diode, we come to a conclusion that the sensor only work properly and in the PDF way, using these without diode. | ||
+ | |||
+ | ===Analogical read=== | ||
+ | |||
+ | In order to test the analogical output and his work, we take the process described in the tutorial[http://www.maxbotix.com/articles/016.htm], in which the analogical read (AN) is do it by a voltmeter or using the next program for Arduino: | ||
+ | |||
+ | <pre> | ||
+ | const int anPin = 1; | ||
+ | |||
+ | //variables needed to store values | ||
+ | long anVolt, inches, cm; | ||
+ | int sum=0;//Create sum variable so it can be averaged | ||
+ | int avgrange=60;//Quantity of values to average (sample size) | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | //This opens up a serial connection to shoot the results back to the PC console | ||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | void loop() | ||
+ | { | ||
+ | //MaxSonar Analog reads are known to be very sensitive. See the Arduino forum for more information. | ||
+ | //A simple fix is to average out a sample of n readings to get a more consistant reading.\\ | ||
+ | //Even with averaging I still find it to be less accurate than the pw method.\\ | ||
+ | //This loop gets 60 reads and averages them | ||
+ | |||
+ | for(int i = 0; i < avgrange ; i++) | ||
+ | { | ||
+ | //Used to read in the analog voltage output that is being sent by the MaxSonar device. | ||
+ | //Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in | ||
+ | //Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches | ||
+ | anVolt = analogRead(anPin)/2; | ||
+ | sum += anVolt; | ||
+ | delay(10); | ||
+ | } | ||
+ | inches = sum/avgrange; | ||
+ | cm = inches * 2.54; | ||
+ | Serial.print(inches); | ||
+ | Serial.print("in, "); | ||
+ | Serial.print(cm); | ||
+ | Serial.print("cm"); | ||
+ | Serial.println(); | ||
+ | //reset sample total | ||
+ | sum = 0; | ||
+ | delay(500); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | After this, we know hat the analogical output of the sensor do not work. | ||
+ | |||
+ | ===Digital read PW output. One sensor=== | ||
+ | |||
+ | This output is test using an Arduino and the next code [http://playground.arduino.cc/Main/MaxSonar] | ||
+ | |||
+ | <pre> | ||
+ | const int pwPin = 7; | ||
+ | //variables needed to store values | ||
+ | long pulse, inches, cm; | ||
+ | void setup() { | ||
+ | //This opens up a serial connection to shoot the results back to the PC console | ||
+ | Serial.begin(9600); | ||
+ | } | ||
+ | void loop() { | ||
+ | pinMode(pwPin, INPUT); | ||
+ | //Used to read in the pulse that is being sent by the MaxSonar device. | ||
+ | //Pulse Width representation with a scale factor of 147 uS per Inch. | ||
+ | pulse = pulseIn(pwPin, HIGH); | ||
+ | //147uS per inch | ||
+ | inches = pulse/147; | ||
+ | //change inches to centimetres | ||
+ | cm = inches * 2.54; | ||
+ | Serial.print(inches); | ||
+ | Serial.print("in, "); | ||
+ | Serial.print(cm); | ||
+ | Serial.print("cm"); | ||
+ | Serial.println(); | ||
+ | delay(500); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | ===Using multiple sensors=== | ||
+ | |||
+ | |||
+ | In order to use several sensors [http://www.maxbotix.com/articles/031.htm]at the same time and avoid the cross-talk effect, [http://en.wikipedia.org/wiki/Crosstalk_(electronics)] between them, it is necessary that the sensor work in sequentially way. | ||
+ | |||
+ | ====Sequentially Read Each Sensor 1==== | ||
+ | |||
+ | In order to trigger sequentially the sensors, and use the minimum digital outputs of the microcontroller, the sensors are connected like in the figure, but instead of use the AN output, using the PW ones. | ||
+ | |||
+ | [[Image:Chain sensors.jpg|center|500px]] | ||
+ | |||
+ | The pin BW, is setting to a HIGH logical state , for this. | ||
+ | |||
+ | The program active the first sensor, setting it to RX input to HIGH (for at least 20uS) and take the reading of them, after set it to LOW state and the program continues reading the next sensors, which are activate in a sequentially way. The program read all the sensor in order to know taht when a sensor is activated the others are turn off (0 cm). | ||
+ | |||
+ | <pre> | ||
+ | const int senSor_a = 8; | ||
+ | const int senSor_b = 7; | ||
+ | const int senSor_c = 4; | ||
+ | |||
+ | const int time_Run = 12; | ||
+ | //variables needed to store values | ||
+ | long pulse, inches, cm; | ||
+ | |||
+ | void setup() { | ||
+ | |||
+ | //This opens up a serial connection to shoot the results back to the PC console | ||
+ | Serial.begin(9600); | ||
+ | pinMode(senSor_a, INPUT); | ||
+ | pinMode(senSor_b, INPUT); | ||
+ | pinMode(senSor_c, INPUT); | ||
+ | |||
+ | pinMode(time_Run, OUTPUT); | ||
+ | |||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | |||
+ | |||
+ | digitalWrite(time_Run, HIGH); | ||
+ | |||
+ | //Used to read in the pulse that is being sent by the MaxSonar device. | ||
+ | //Pulse Width representation with a scale factor of 147 uS per Inch. | ||
+ | |||
+ | pulse = pulseIn(senSor_a, HIGH); | ||
+ | //147uS per inch | ||
+ | inches = pulse/147; | ||
+ | //change inches to centimetres | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor a1 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | pulse = pulseIn(senSor_b, HIGH); | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor b1 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | pulse = pulseIn(senSor_c, HIGH); | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor c1 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | delay(20); | ||
+ | |||
+ | digitalWrite(time_Run, LOW); | ||
+ | |||
+ | delay (5); | ||
+ | |||
+ | pulse = pulseIn(senSor_a, HIGH); inch | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor a2 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | pulse = pulseIn(senSor_b, HIGH); | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor b2 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | pulse = pulseIn(senSor_c, HIGH); | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor c2 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | |||
+ | //delay(20); | ||
+ | |||
+ | pulse = pulseIn(senSor_a, HIGH); | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor a3 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | pulse = pulseIn(senSor_b, HIGH); | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor b3 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | pulse = pulseIn(senSor_c, HIGH); | ||
+ | inches = pulse/147; | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor c3 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | |||
+ | |||
+ | delay(100); | ||
+ | |||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | After this test we know that in his way do not work and we can start to think that the sensor were reprogramming in a different way or they are broken. | ||
+ | |||
+ | ====Sequentially Read Each Sensor 2==== | ||
+ | |||
+ | We know that the PW output and in a individually way work properly, for this and in order to trigger sequentially the sensor, the RX pin of each sensor will be connected to a digital output of the microcontroller. | ||
+ | |||
+ | Now, in this way we can activate and deactivate the sensor in a sequentially way. | ||
+ | |||
+ | The code is test for three sensor. It is a really simple code, in order to use the Arduino (microcontroller) like a simple interface to send the data sensor and to be processed by the main computer. | ||
+ | |||
+ | <pre> | ||
+ | // digitals INPUTS for PW read | ||
+ | const int senSor_a = 12; | ||
+ | const int senSor_b = 10; | ||
+ | const int senSor_c = 8; | ||
+ | |||
+ | // digital OUTPUTS to trigger the sensors | ||
+ | const int control_a = 13; | ||
+ | const int control_b = 11; | ||
+ | const int control_c = 9; | ||
+ | //variables needed to store values | ||
+ | long pulse, inches, cm; | ||
+ | int n; | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | |||
+ | //This opens up a serial connection to shoot the results back to the PC console | ||
+ | Serial.begin(9600); | ||
+ | pinMode(senSor_a, INPUT); | ||
+ | pinMode(senSor_b, INPUT); | ||
+ | pinMode(senSor_c, INPUT); | ||
+ | |||
+ | pinMode(control_a, OUTPUT); | ||
+ | pinMode(control_a, OUTPUT); | ||
+ | pinMode(control_a, OUTPUT); | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | |||
+ | ultrasonidos(control_a, senSor_a); | ||
+ | delay (10);// necesario para evitar crostalking y que de resultados validos (sin delay la lectura 764) | ||
+ | |||
+ | ultrasonidos(control_b, senSor_b); | ||
+ | delay (10); | ||
+ | |||
+ | ultrasonidos(control_c, senSor_c); | ||
+ | delay (10); | ||
+ | Serial.println(); | ||
+ | Serial.println(); | ||
+ | //delay (100); | ||
+ | |||
+ | |||
+ | } | ||
+ | |||
+ | void ultrasonidos(const int x, const int y) | ||
+ | { | ||
+ | digitalWrite(x, HIGH); | ||
+ | pulse = pulseIn(y, HIGH); | ||
+ | inches = pulse/147; | ||
+ | //change inches to centimetres | ||
+ | cm = inches * 2.54; | ||
+ | |||
+ | Serial.print(" sensor a1 cm "); | ||
+ | Serial.println(cm); | ||
+ | Serial.println(); | ||
+ | digitalWrite(control_a, LOW); | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | ===ROS and the ultrasonic sensor belt=== | ||
+ | |||
+ | ====Software installation==== | ||
+ | |||
+ | '''''ROS Installation''''' | ||
+ | |||
+ | In this case it was installed ROS Fuerte under Ubuntu [http://wiki.ros.org/fuerte/Installation/Ubuntu]. ( version used on MYRAbot) | ||
+ | In order to communicate ROS and Arduino we have to install the package rosserial: | ||
+ | <syntaxhighlight>sudo apt-get install ros-fuerte-rosserial</syntaxhighlight> | ||
+ | |||
+ | '''''Arduino Intallation''''' | ||
+ | |||
+ | <syntaxhighlight>sudo apt-get update | ||
+ | sudo apt-get install arduino arduino-core</syntaxhighlight> | ||
+ | |||
+ | Now we have to copy the libreries of rosserial_arduino into the directory libreries of Arduino: | ||
+ | <syntaxhighlight>roscd rosserial_arduino/libraries | ||
+ | cp -r ros_lib /home/”directory arduino name”/libraries/ros_lib</syntaxhighlight> | ||
+ | |||
+ | This libreries need only a modification in the case of use ROS Fuerte, because it is a old version, and were developed for old Arduino versions. | ||
+ | We have to modificate the line 35 (#include "WProgram.h") in ArduinoHardware.h (into ros_lib) for #include "Arduino.h". | ||
+ | |||
+ | ====Arduino Sketch==== | ||
+ | |||
+ | <syntaxhighlight> | ||
+ | #include <ros.h> | ||
+ | #include <ros/time.h> | ||
+ | #include <sensor_msgs/Range.h> | ||
+ | |||
+ | ros::NodeHandle nh; | ||
+ | |||
+ | sensor_msgs::Range range_msg; | ||
+ | ros::Publisher pub_range1( "/ultrasound1", &range_msg); | ||
+ | ros::Publisher pub_range2( "/ultrasound2", &range_msg); | ||
+ | ros::Publisher pub_range3( "/ultrasound3", &range_msg); | ||
+ | |||
+ | char frameid[] = "/ultrasound"; | ||
+ | |||
+ | const int senSor_a = 12; | ||
+ | const int senSor_b = 10; | ||
+ | const int senSor_c = 8; | ||
+ | |||
+ | const int control_a = 13; | ||
+ | const int control_b = 11; | ||
+ | const int control_c = 9; | ||
+ | |||
+ | unsigned long timeout = 2000; | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | |||
+ | pinMode(senSor_a, INPUT); | ||
+ | pinMode(senSor_b, INPUT); | ||
+ | pinMode(senSor_c, INPUT); | ||
+ | |||
+ | pinMode(control_a, OUTPUT); | ||
+ | pinMode(control_b, OUTPUT); | ||
+ | pinMode(control_c, OUTPUT); | ||
+ | |||
+ | nh.initNode(); | ||
+ | nh.advertise(pub_range1); | ||
+ | nh.advertise(pub_range2); | ||
+ | nh.advertise(pub_range3); | ||
+ | |||
+ | range_msg.radiation_type = sensor_msgs::Range::ULTRASOUND; | ||
+ | range_msg.header.frame_id = frameid; | ||
+ | |||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | |||
+ | range_msg.range = ultrasonidos(control_a, senSor_a); | ||
+ | range_msg.header.stamp = nh.now(); | ||
+ | pub_range1.publish(&range_msg); | ||
+ | delay (20);// necessario to avoid crostalking | ||
+ | |||
+ | range_msg.range = ultrasonidos(control_b, senSor_b); | ||
+ | range_msg.header.stamp = nh.now(); | ||
+ | pub_range2.publish(&range_msg); | ||
+ | delay (20); | ||
+ | |||
+ | range_msg.range = ultrasonidos(control_c, senSor_c); | ||
+ | range_msg.header.stamp = nh.now(); | ||
+ | pub_range3.publish(&range_msg); | ||
+ | delay (20); | ||
+ | |||
+ | nh.spinOnce(); | ||
+ | |||
+ | } | ||
+ | |||
+ | long ultrasonidos(const int x, const int y) | ||
+ | { | ||
+ | digitalWrite(x, HIGH); | ||
+ | unsigned long pulse = pulseIn(y, HIGH, timeout); | ||
+ | digitalWrite(x, LOW); | ||
+ | return pulse; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Now we only have to start ROS, estar de communication with Arduino (in oher terminal) and see the data take from the sensors: | ||
+ | |||
+ | <syntaxhighlight> | ||
+ | roscore | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight> | ||
+ | rosrun rosserial_python serial_node.py /dev/ttyACM0 | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight> | ||
+ | rostopic echo ultrasound(ultrasound number) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =FAQ/Problems= | ||
+ | |||
+ | == Xtion camera in a PC== | ||
The typical problem with Xtion pro model: | The typical problem with Xtion pro model: | ||
Line 64: | Line 481: | ||
If someone find a better answer I will be happy to know it. | If someone find a better answer I will be happy to know it. | ||
− | + | ==Multiple openni cameras== | |
We have two different cameras Xtion PRo and kinect.This problem is related with the previous configuration, tt makes possible to work with Xtion but now we have problems with kinect. | We have two different cameras Xtion PRo and kinect.This problem is related with the previous configuration, tt makes possible to work with Xtion but now we have problems with kinect. |
Latest revision as of 09:51, 25 June 2014
Contents
- 1 Hardware
- 2 FAQ/Problems
Hardware
Structure modifications
Cover for the screen in order to cover the metallics parts and wires.
Button box in order to host the start and stop button.
Bigger space in order to host the computer and the wires. For this was changed the screws for other longers.
Ultrasonic Sensors Belt
Ultrasonic sensors selecction and microcontroller used
There are many different kind of ultrasonic sensors and manufacturers, but in this case we have used the Maxbotics [1] manufacturer . We use these, in order to recycle the ultrasonic sensors of an old watchful robot ( good rattletrap).
This robot use for his navigation system, three different Maxbotics models, the MB1220 [2], MB 1230 of the XL-Maxsonar-EZ series and the LV-Maxsonar-EZ1 model.
We will use the model MB1220, because it is the most appropriate for people detection and there are a large quantity of them.
These sensors will be controller through an Arduino MEGA.
First tests and validation sensors
Theses sensors have a diode between his outputs PW (anode) and AN (cathode).
After a several test with and without the diode, we come to a conclusion that the sensor only work properly and in the PDF way, using these without diode.
Analogical read
In order to test the analogical output and his work, we take the process described in the tutorial[3], in which the analogical read (AN) is do it by a voltmeter or using the next program for Arduino:
const int anPin = 1; //variables needed to store values long anVolt, inches, cm; int sum=0;//Create sum variable so it can be averaged int avgrange=60;//Quantity of values to average (sample size) void setup() { //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600); } void loop() { //MaxSonar Analog reads are known to be very sensitive. See the Arduino forum for more information. //A simple fix is to average out a sample of n readings to get a more consistant reading.\\ //Even with averaging I still find it to be less accurate than the pw method.\\ //This loop gets 60 reads and averages them for(int i = 0; i < avgrange ; i++) { //Used to read in the analog voltage output that is being sent by the MaxSonar device. //Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in //Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches anVolt = analogRead(anPin)/2; sum += anVolt; delay(10); } inches = sum/avgrange; cm = inches * 2.54; Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println(); //reset sample total sum = 0; delay(500); }
After this, we know hat the analogical output of the sensor do not work.
Digital read PW output. One sensor
This output is test using an Arduino and the next code [4]
const int pwPin = 7; //variables needed to store values long pulse, inches, cm; void setup() { //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600); } void loop() { pinMode(pwPin, INPUT); //Used to read in the pulse that is being sent by the MaxSonar device. //Pulse Width representation with a scale factor of 147 uS per Inch. pulse = pulseIn(pwPin, HIGH); //147uS per inch inches = pulse/147; //change inches to centimetres cm = inches * 2.54; Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println(); delay(500); }
Using multiple sensors
In order to use several sensors [5]at the same time and avoid the cross-talk effect, [6] between them, it is necessary that the sensor work in sequentially way.
Sequentially Read Each Sensor 1
In order to trigger sequentially the sensors, and use the minimum digital outputs of the microcontroller, the sensors are connected like in the figure, but instead of use the AN output, using the PW ones.
The pin BW, is setting to a HIGH logical state , for this.
The program active the first sensor, setting it to RX input to HIGH (for at least 20uS) and take the reading of them, after set it to LOW state and the program continues reading the next sensors, which are activate in a sequentially way. The program read all the sensor in order to know taht when a sensor is activated the others are turn off (0 cm).
const int senSor_a = 8; const int senSor_b = 7; const int senSor_c = 4; const int time_Run = 12; //variables needed to store values long pulse, inches, cm; void setup() { //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600); pinMode(senSor_a, INPUT); pinMode(senSor_b, INPUT); pinMode(senSor_c, INPUT); pinMode(time_Run, OUTPUT); } void loop() { digitalWrite(time_Run, HIGH); //Used to read in the pulse that is being sent by the MaxSonar device. //Pulse Width representation with a scale factor of 147 uS per Inch. pulse = pulseIn(senSor_a, HIGH); //147uS per inch inches = pulse/147; //change inches to centimetres cm = inches * 2.54; Serial.print(" sensor a1 cm "); Serial.println(cm); Serial.println(); pulse = pulseIn(senSor_b, HIGH); inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor b1 cm "); Serial.println(cm); Serial.println(); pulse = pulseIn(senSor_c, HIGH); inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor c1 cm "); Serial.println(cm); Serial.println(); delay(20); digitalWrite(time_Run, LOW); delay (5); pulse = pulseIn(senSor_a, HIGH); inch inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor a2 cm "); Serial.println(cm); Serial.println(); pulse = pulseIn(senSor_b, HIGH); inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor b2 cm "); Serial.println(cm); Serial.println(); pulse = pulseIn(senSor_c, HIGH); inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor c2 cm "); Serial.println(cm); Serial.println(); //delay(20); pulse = pulseIn(senSor_a, HIGH); inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor a3 cm "); Serial.println(cm); Serial.println(); pulse = pulseIn(senSor_b, HIGH); inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor b3 cm "); Serial.println(cm); Serial.println(); pulse = pulseIn(senSor_c, HIGH); inches = pulse/147; cm = inches * 2.54; Serial.print(" sensor c3 cm "); Serial.println(cm); Serial.println(); delay(100); }
After this test we know that in his way do not work and we can start to think that the sensor were reprogramming in a different way or they are broken.
Sequentially Read Each Sensor 2
We know that the PW output and in a individually way work properly, for this and in order to trigger sequentially the sensor, the RX pin of each sensor will be connected to a digital output of the microcontroller.
Now, in this way we can activate and deactivate the sensor in a sequentially way.
The code is test for three sensor. It is a really simple code, in order to use the Arduino (microcontroller) like a simple interface to send the data sensor and to be processed by the main computer.
// digitals INPUTS for PW read const int senSor_a = 12; const int senSor_b = 10; const int senSor_c = 8; // digital OUTPUTS to trigger the sensors const int control_a = 13; const int control_b = 11; const int control_c = 9; //variables needed to store values long pulse, inches, cm; int n; void setup() { //This opens up a serial connection to shoot the results back to the PC console Serial.begin(9600); pinMode(senSor_a, INPUT); pinMode(senSor_b, INPUT); pinMode(senSor_c, INPUT); pinMode(control_a, OUTPUT); pinMode(control_a, OUTPUT); pinMode(control_a, OUTPUT); } void loop() { ultrasonidos(control_a, senSor_a); delay (10);// necesario para evitar crostalking y que de resultados validos (sin delay la lectura 764) ultrasonidos(control_b, senSor_b); delay (10); ultrasonidos(control_c, senSor_c); delay (10); Serial.println(); Serial.println(); //delay (100); } void ultrasonidos(const int x, const int y) { digitalWrite(x, HIGH); pulse = pulseIn(y, HIGH); inches = pulse/147; //change inches to centimetres cm = inches * 2.54; Serial.print(" sensor a1 cm "); Serial.println(cm); Serial.println(); digitalWrite(control_a, LOW); }
ROS and the ultrasonic sensor belt
Software installation
ROS Installation
In this case it was installed ROS Fuerte under Ubuntu [7]. ( version used on MYRAbot) In order to communicate ROS and Arduino we have to install the package rosserial:
sudo apt-get install ros-fuerte-rosserial
Arduino Intallation
sudo apt-get update
sudo apt-get install arduino arduino-core
Now we have to copy the libreries of rosserial_arduino into the directory libreries of Arduino:
roscd rosserial_arduino/libraries
cp -r ros_lib /home/”directory arduino name”/libraries/ros_lib
This libreries need only a modification in the case of use ROS Fuerte, because it is a old version, and were developed for old Arduino versions. We have to modificate the line 35 (#include "WProgram.h") in ArduinoHardware.h (into ros_lib) for #include "Arduino.h".
Arduino Sketch
#include <ros.h>
#include <ros/time.h>
#include <sensor_msgs/Range.h>
ros::NodeHandle nh;
sensor_msgs::Range range_msg;
ros::Publisher pub_range1( "/ultrasound1", &range_msg);
ros::Publisher pub_range2( "/ultrasound2", &range_msg);
ros::Publisher pub_range3( "/ultrasound3", &range_msg);
char frameid[] = "/ultrasound";
const int senSor_a = 12;
const int senSor_b = 10;
const int senSor_c = 8;
const int control_a = 13;
const int control_b = 11;
const int control_c = 9;
unsigned long timeout = 2000;
void setup()
{
pinMode(senSor_a, INPUT);
pinMode(senSor_b, INPUT);
pinMode(senSor_c, INPUT);
pinMode(control_a, OUTPUT);
pinMode(control_b, OUTPUT);
pinMode(control_c, OUTPUT);
nh.initNode();
nh.advertise(pub_range1);
nh.advertise(pub_range2);
nh.advertise(pub_range3);
range_msg.radiation_type = sensor_msgs::Range::ULTRASOUND;
range_msg.header.frame_id = frameid;
}
void loop()
{
range_msg.range = ultrasonidos(control_a, senSor_a);
range_msg.header.stamp = nh.now();
pub_range1.publish(&range_msg);
delay (20);// necessario to avoid crostalking
range_msg.range = ultrasonidos(control_b, senSor_b);
range_msg.header.stamp = nh.now();
pub_range2.publish(&range_msg);
delay (20);
range_msg.range = ultrasonidos(control_c, senSor_c);
range_msg.header.stamp = nh.now();
pub_range3.publish(&range_msg);
delay (20);
nh.spinOnce();
}
long ultrasonidos(const int x, const int y)
{
digitalWrite(x, HIGH);
unsigned long pulse = pulseIn(y, HIGH, timeout);
digitalWrite(x, LOW);
return pulse;
}
Now we only have to start ROS, estar de communication with Arduino (in oher terminal) and see the data take from the sensors:
roscore
rosrun rosserial_python serial_node.py /dev/ttyACM0
rostopic echo ultrasound(ultrasound number)
FAQ/Problems
Xtion camera in a PC
The typical problem with Xtion pro model:
We launch
$ roslaunch openni_launch openni.launch
we get
[ INFO] [1383245066.923739155]: Number devices connected: 1 [ INFO] [1383245066.923896787]: 1. device on bus 002:05 is a PrimeSense Device (601) from PrimeSense (1d27) with serial id '' [ INFO] [1383245066.925020672]: Searching for device with index = 1 [ INFO] [1383245067.026459550]: No matching device found.... waiting for devices. Reason: openni_wrapper::OpenNIDevice::OpenNIDevice(xn::Context&, const xn::NodeInfo&, const xn::NodeInfo&, const xn::NodeInfo&, const xn::NodeInfo&) @ /tmp/buildd/ros-fuerte-openni-camera-1.8.6/debian/ros-fuerte-openni-camera/opt/ros/fuerte/stacks/openni_camera/src/openni_device.cpp @ 61 : creating depth generator failed. Reason: USB interface is not supported!
SOLUTION:
We have to modify global parameters of openni:
$ sudo vi /etc/openni/GlobalDefaults.ini
We go to line and uncomment the UsbInterface parameter:
; USB interface to be used. 0 - FW Default, 1 - ISO endpoints, 2 - BULK endpoints. Default: Arm - 2, other platforms - 1 UsbInterface=2
Reason:
Here and here but I think that the real reason is related to USB port management
From my point of view this is the outline (copy paste from USB port management
ENDPOINT -> The most basic form of USB communication is through something called an endpoint. A USB endpoint can carry data in only one direction, either from the host computer to the device (called an OUT endpoint) or from the device to the host computer (called an IN endpoint). Endpoints can be thought of as unidirectional pipes.
1 ISO-> Isochronous endpoints also transfer large amounts of data, but the data is not always guaranteed to make it through. These endpoints are used in devices that can handle loss of data, and rely more on keeping a constant stream of data flowing. Real-time data collections, such as audio and video devices, almost always use these endpoints.
2 BULK-> Bulk endpoints transfer large amounts of data. These endpoints are usually much larger (they can hold more characters at once) than interrupt endpoints. They are common for devices that need to transfer any data that must get through with no data loss. These transfers are not guaranteed by the USB protocol to always make it through in a specific amount of time. If there is not enough room on the bus to send the whole BULK packet, it is split up across multiple transfers to or from the device. These endpoints are common on printers, storage, and network devices.
0 FW [WARNING, I'm not sure]-> USB interfaces are themselves bundled up into configurations. A USB device can have multiple configurations and might switch between them in order to change the state of the device. For example, some devices that allow firmware to be downloaded to them contain multiple configurations to accomplish this. A single configuration can be enabled only at one point in time. Linux does not handle multiple configuration USB devices very well, but, thankfully, they are rare.
If someone find a better answer I will be happy to know it.
Multiple openni cameras
We have two different cameras Xtion PRo and kinect.This problem is related with the previous configuration, tt makes possible to work with Xtion but now we have problems with kinect.
[ INFO] [1383246210.089689756]: Number devices connected: 1 [ INFO] [1383246210.089891318]: 1. device on bus 001:17 is a Xbox NUI Camera (2ae) from Microsoft (45e) with serial id 'A00366A15277050A' [ INFO] [1383246210.091390182]: Searching for device with index = 1 [ INFO] [1383246210.193031599]: No matching device found.... waiting for devices. Reason: openni_wrapper::OpenNIDevice::OpenNIDevice(xn::Context&, const xn::NodeInfo&, const xn::NodeInfo&, const xn::NodeInfo&, const xn::NodeInfo&) @ /tmp/buildd/ros-fuerte-openni-camera-1.8.6/debian/ros-fuerte-openni-camera/opt/ros/fuerte/stacks/openni_camera/src/openni_device.cpp @ 61 : creating depth generator failed. Reason: USB interface is not supported!
Solution
; USB interface to be used. 0 - FW Default, 1 - ISO endpoints, 2 - BULK endpoints. Default: Arm - 2, other platforms - 1 UsbInterface=0