Embedded Motion Control 2014 Group 3: Difference between revisions

From Control Systems Technology Group
Jump to navigation Jump to search
Line 36: Line 36:
'''strategy:''' This node does multiple things. First it detects openings where it assigns a target to, if no openings are found the robot finds itself in a dead end. Secondly it reads the topic ''/arrow'' and if an arrow is present it overrides the preferred direction. Finally the robot determines the direction of the velocity of the robot using the Potential Field Method (PFM) and sends the velocity to the topic ''/pico/cmd_vel''.   
'''strategy:''' This node does multiple things. First it detects openings where it assigns a target to, if no openings are found the robot finds itself in a dead end. Secondly it reads the topic ''/arrow'' and if an arrow is present it overrides the preferred direction. Finally the robot determines the direction of the velocity of the robot using the Potential Field Method (PFM) and sends the velocity to the topic ''/pico/cmd_vel''.   


The approach is very simple and easy to implement. The strategy node for example has approximately only 100 lines of code this is why there has not been chosen to subdivide all the elements in different nodes. The benefit of easy code is the easiness to tackle bugs and that bugs are less likely to occur. Another benefit of this 'simple' code is the easiness to optimize for performance.
The approach is very simple and easy to implement. The strategy node for example has approximately only 100 lines of code. This is the reason why there has not been chosen to divide all elements over different nodes. The benefit of easy code is the easiness to tackle bugs and that bugs are less likely to occur. Another benefit of this 'simple' code is the easiness to optimize for performance.


[[File:softarch2.png]]
[[File:softarch2.png]]

Revision as of 12:29, 25 June 2014

Group Members

Name: Student id:
Jan Romme 0755197
Freek Ramp 0663262
Kushagra 0873174
Roel Smallegoor 0753385
Janno Lunenburg - Tutor -


Software architecture and used approach

A schematic overview of the software architecture is shown in the figure below. The software basically consists only of 3 nodes, laserProcessor, arrowDetection and strategy. A short elaboration of the nodes:

laserProcessor: This node reads the /pico/laser topic which sends the laser data in polar coordinates. All this node does is converting the polar coordinates to cartesian coordinates and filters out points closer than 10 cm. The cartesian coordinate system is preferred over the polar coordinate system because it feels more intuitive. Finally once the conversion and filtering is done it publishes the transformed coordinates onto topic /cloud.

arrowDetection: This node reads the camera image from topic /pico/asusxtion/rgb/image_color and detects red arrows. If it detects an arrow the direction is determined and posted onto topic /arrow.

strategy: This node does multiple things. First it detects openings where it assigns a target to, if no openings are found the robot finds itself in a dead end. Secondly it reads the topic /arrow and if an arrow is present it overrides the preferred direction. Finally the robot determines the direction of the velocity of the robot using the Potential Field Method (PFM) and sends the velocity to the topic /pico/cmd_vel.

The approach is very simple and easy to implement. The strategy node for example has approximately only 100 lines of code. This is the reason why there has not been chosen to divide all elements over different nodes. The benefit of easy code is the easiness to tackle bugs and that bugs are less likely to occur. Another benefit of this 'simple' code is the easiness to optimize for performance.

Softarch2.png

Applied methods description

Arrow detection

The following steps describe the algorithm to find the arrow and determine the direction:

1. Read rgb image from "/pico/asusxtion/rgb/image_color" topic.

2. Convert rgb image to hsv color space.

Rgbtohsv1.png

3. Filter out the red color using cv::inRange

Inrange.png

4. Find contours and convex hulls and filter it

The filter removes all contours where the following relationship does not hold: [math]\displaystyle{ 0.5 \lt \frac{Contour \ area}{Convex \ hull \ area} \lt 0.65 }[/math]. This removes some of the unwanted contours. The contour and convex hull of the arrow:

Convex.png

5. Use cv::approxPolyDP over the contours

The function cv::approxPolyDP is used to fit polylines over the resulting contours. The arrow should have approximately 7 lines per polyline. The polylines fitted over the contours with [math]\displaystyle{ 5 \ \lt \ number \ of \ lines \ in \ polyline \ \lt \ 10 }[/math] is the arrow candidate.

Polylines.png

6. Determine if arrow is pointing left or right

First the midpoint of the arrow is found using [math]\displaystyle{ x_{mid} = \frac{x_{min}+x_{max}}{2} }[/math]. When the midpoint is known the program iterates over all points of the arrow contour. Two counters are made which count the number of points left and right of [math]\displaystyle{ x_{mid} }[/math]. If the left counter is greater than the right counter the arrow is pointing to the left, otherwise the arrow is pointing to the right.

7. Making the detection more robust As last an effort is made to make the arrow detection more robust, for example when at one frame the arrow is not detected the program still knows there is an arrow. This is done by taking the last 5 iterations, check if in all these iterations the arrow is detected then publish the direction of the arrow onto the topic "/arrow". If in the last 5 iterations no arrow is seen the arrow is not visible anymore thus publish that there is no arrow onto the topic "/arrow".

Strategy

Target

In the approach used a targed is needed for Pico to drive to. In this section the determination of the target point is explained. In the code a loop is made through all data points, which are in order from right to left. Only the points within 1.4 meter from pico are encountered. If the distance between two following points is bigger than a determined threshold, the presence of a door is assumed. This will be further explained with the following figure.

Base setpointPointWIKI.png

In the figure the vision of pico is illustrated by the dotted black arc and the detected points within this marge by red dots. In the left figure two distances between following points are bigger than the given threshold and thus two doors are present. The targets are set in the middle of the line between the two points. In the figure in the middle a problem is illustrated which occured during testing. When Pico looks past a corner it sometimes sees points where no walls are, the so called ghostpoints. This is a problem because in the case of ghostpoints the distance between two points becomes smaller than the threshold. To filter this effect the distance is not taken between two points, but over five. By testing and tuning the value of five was found as an optimal. A downside of this method is that points far ahead of pico give the possibility of false positives. But because in this case Pico only looks at a relative short distance, this will not occur. In the figure on the rightside the filter is applied and the door is found again.

PFM

Dead-end

Safety

The importance of safety and the requirement that pico should not hit an obstacle under any circumstances was realized. For this reason a safety feature was introduced. In ideal situation, pico should never need to use this safety feature. The program was designed in such a way that the robot could complete its task without using safety. But there are many variables in real world, all of which are difficult to account particularly in the given time frame. It is always a possibility that for some unforeseen reason, pico gets too close to an object and might hit it. Safety was designed to prevent this. The first version of Safety was designed to stop pico if it moves very close to any object it detects. This version was, of course, not very effective as the robot would come to a stand-still once Safety was invoked which prevented it from finishing its task. Safety was later upgraded. When too close, pico needs to move away from the obstacle and this movement should not interfere with path-detection and space orientation of the robot. In the latest version, a sophisticated safety design was incorporated. Two circles, critical circle and safety circle are considered. The program first counts the number of points detected within the critical circle. If more than 10 points are counted, Safety mode is started. This is done for noise filtering. Safety is given highest priotity and overrides decisions for movement of pico. The program now calculates average x and y position of all points within safety circle (safety circle is larger than critical circle). Without changing the direction it is facing, pico moves in direction directly opposite to the average obstacle point. Since there is no turning involved, spacial orientation of pico remains unaffected. This point is updated with every cycle and pico keeps moving away until the point moves out of safety circle. Safety mode is then turned off and normal operation is resumed.

End of maze

First software approach

Obstacle Detection

Finding Walls from PointCloud data

The node findWalls reads topic "/cloud" which contains laserdata in x-y coordinates relative to the robot. The node findWalls returns a list containing(xstart,ystart) and (xend, yend) of each found wall (relative to the robot). The following algorithm is made:

- Create a cv::Mat object and draw cv::circle on the cv::Mat structure corresponding to the x and y coordinates of the laserspots.

- Apply Probabilistic Hough Line Transform cv::HoughLinesP

In the picture shown below one can see the laserspots at the left side of the picture. At the right side the lines of the cv::HoughLinesP are shown.

Emc03wall.png

The cv::HoughLinesP algorithm gives multiple lines per wall. In the end we want 1 line per wall. To solve this first the all the lines are sorted into lists by their angle they make, for example if a line makes angle of [math]\displaystyle{ 27^\circ }[/math] it is stored in a list where all lines lie between [math]\displaystyle{ 20^\circ }[/math] and [math]\displaystyle{ 30^\circ }[/math]. Once all lines have been sorted the two most common directions are plotted which is shown in the following pictures:

Mostcommon.png

Secondmostcommon.png

Finally to extract 1 line per wall the outer points of the contour are taken to get 1 line per wall. The result is shown in the following figure:

Finalwallok.png

Finding Doors from found Walls

Now that the walls are given as lines doors are fitted between the walls. The result is shown in the following figure:

Deurtjes.png

Why this method doesn't work in real life

The method described in how to find walls and doors did not work properly in real life. We experienced some serious robustness problems due to the fact that in some of the iterations complete walls and/or doors were not detected, thus the robot couldn't steer in a proper fashion to the target. Secondly this method required some serious computation power which is not preferable (one cpu core ran at 80% cpu when the refresh rate of the algorithm was only 5 Hz).

Evaluation of the maze competetion