Embedded Motion Control 2012 Group 2

From Control Systems Technology Group
Jump to navigation Jump to search

Group Members

Name ID number e-mail
T.H.A. Dautzenberg0657673 T.H.A. Dautzenberg
V.J.M. Holten0655090 V.J.M. Holten
D.H.J.M. v.d. Hoogen0662522 D.H.J.M. v.d. Hoogen
B. Sleegers0658013 B. Sleegers
Mail to all


Tutor: Janno Lunenburg

Project Progress


Week 1

  • Installation of Ubuntu, ROS and Eclipse
  • C++ tutorial


Week 2

  • ROS tutorial
  • Meeting 1 with tutor
  • Read Chapter 1 and 4 of Real-Time Concepts for Embedded Systems
  • Made a presentation of Ch. 4 for lecture 2 [Slides]
  • Prepared the lecture about Ch. 4


Week 3

  • ROS tutorials continued
  • Looking up useful information and possible packages on the ros website
  • Formulating an idea to tackle the problem
  • Trying to run and create new packages but running into some problems
  • Presented Ch. 4
  • Extra research regarding the API and Linux scheduler, as requested by Molengraft


Week 4

  • Created a node which makes sure Jazz doesn't collide with the walls
  • Created a node which enables Jazz to make the first left corner
  • Research on different maze solving algorithm's
  • Presented extra research regarding the API and the Linux scheduler briefly


Week 5

  • Trying to create the path detection and autonomously cornering
  • Made a start regarding arrow detection (strategy follows)


Week 6

  • Further work on arrow detection
  • Created a program with which we are able to accomplish the corridor competition
  • First test with Jazz, Thursday 13:00 - 14:00
  • The test turned out very well. We first had to rewrite some things in order to take the larger laser data array into account (1081 points instead of a lot less). But when this was fixed our first test immediately had the hoped result. The corner was detected and the robot drove through the corner properly without bumping into any walls. A link in the movies section was added where the result of a test is shown.


Week 7

  • Corridor competition! Unfortunately Pico didn't succeed. At the first run the gain for the center drive controller wasn't tuned well resulting in an emergency stop. At the second run Pico drove quite well through the center of the corridor. Furthermore the left corner was detected and Pico drove to the setpoint correctly. Then the problem occured, Pico didn't turn enough which resulted in another emergency stop.



Components

  • Wall detection
    • Laser scan data
  • Arrow detection
    • Camera data
  • Path detection (openings in wall and possible driving directions)
    • Laser scan data
  • Control center (handels data provided by nodes above and determines the commands sent to the Jazz robot)

Software Design

The software design is based on two nodes: one for arrow recognition and one Core node for all other operations. The camera node processes the images from the camera and will send 'left', 'right' or 'no arrow detected' over a topic. The Core node listens to the topics 'scan', 'odom', and the topic from the camera node. Publishing is done over the 'cmd_vel' topic. To maintain structure within the node, several structures and classes are used:

Structures

  • Laserdata: a structure housing all information that is needed from the laser data provided by the robot. This also includes some data that has been manipulated.
  • Odomdata: odometry data is stored in this structure as x- and y-position and the rotation around the z-vector.
  • Corner: This struct contains parameters (mainly boolean) used in the discretization of making a corner over several stages that are identified during this process.
  • Cornerdata: a variable of this type is used to store information needed in corner detection.


Classes

  • Laser: this class contains functions needed to process the laser data from the robot. Upon extraction, the data is immediately manipulated i.e. relative x- and y-distances are computed using the range and the angle w.r.t. the robot and a number of minimum values from specific ranges are extracted from the data. A public function can be used to return a pointer to the instance of the structure 'Laserdata' where all the information is stored.
  • Odometry: the basic functionality is analogous to the Laser class. The only manipulation of the data is done upon calculation of the angle (is provided in quaternions).
  • Motion: A public function can be used to send movement commands. This function has the forward velocity and the angular velocity as inputs. Also, a check is conducted that will limit both velocities to a predetermined maximum value.
  • Drive: This class is used to group the functions for the driving algorithm. Here, a drive command can be given by using a function where a distance can be entered that should be traveled in a forward direction. Contained in this class is a function to make a setpoint and a function that returns a boolean that is used to 'keep driving' as long as the setpoint has not yet been reached.
  • Turn: Equal to the Drive class, this class is used to make a setpoint for an angular motion and to check whether this setpoint is already reached.

Apart from the classes, functions are used for corner detection and for the centering whilst driving through a corridor.

The 'main' loop is where the real program runs. It starts with the declaration of variables and a few initialization commands of ROSS. Hereafter, the subscribers and publishers are assigned their respective topics. A while loop is used to run the node in combination with the condition 'ros::ok()', a rate definition of the form 'ros::Rate', and 'ros::SpinOnce()' to refresh the subscribers and publishers.


Strategy scheme.jpg

Strategy

  • Use the laser pointing forward to detect dead-ends, then turn 180 degrees.
  • Use lasers pointing left & right to keep the robot in the middle of the path.
  • Use lasers pointing 45 degrees left and right to detect corners. If there is a 'jump' in the data, there is a corner. The new and old laserdata are then used to create a setpoint in the middle of the corner to which it will drive. It will then turn left/right 90 degrees and start driving again until it detects a new corner.
  • Use 2 nodes. One for the camera (which is only partly done) and the other node for the rest (corner detection, decision making, etc.). This is because the arrow detection should run at a much lower frequency due to the large amount of data.
  • We use the right turn algorithm.
    • A right turn (if possible) is preferred above going straight ahead (if possible), and going straight ahead (if possible) is preferred above going left (if possible).
    • It is certainly not the most efficient technique, but relatively easy to implement.
    • A problem that might occur with this algorithm is that the robot will be circling around an 'island' for infinite time and never find the exit when his start position is at this 'island'.
      • Possible solution: The Pledge algorithm. The Pledge algorithm requires an arbitrarily chosen direction to go toward. When an obstacle is met, the right hand is kept along the obstacle while the angles turned are counted. When the solver is facing the original direction again, and the angular sum of the turns made is 0, the solver leaves the obstacle and continues moving in its original direction. The hand is removed from the wall when both 'sum of turns made' and 'current heading' are at zero. This allows the algorithm to avoid traps like starting at an 'island'. Note that this algorithm will not work when the robot has to find the way from an entrance on the outside of the maze to some goal within it.
      • When we heard we will start outside of the maze and have to find an exit outside of the maze we decided to halt implementing the Pledge algorithm. Since the denoted problem can not occur in this setting. The right turn algorithm will be safe.


File:Pledge algorithm.jpg

Path detection and corner setpoint creation
Path detection2.jpg

Robustness in laser detection

In order to make the software robust against holes in the wall or things like this, a small fan of laser points is used. While testing the robot detected a corner at a location where this really wasn’t possible, the reason turned out to be a small gap between the plates of the maze. So instead of basing the corner detection and path centering algorithms on a single point of the laser array, a number of points are now used. For the algorithms that determine the corner detection and the centering of the robot in the corridor, specific angles in the array of laser data points are used. Around this angle, we now use a series of points and determine the minimum of this series. This point is then used as before as the distance at that angle. In the picture below, this is the marked point. The series will consist of 15 points for a specific angle, which for a total of 1081 data points around 270 degrees, comes down to a fan of about 3 degrees. So when the corridor has a diameter of 1m, the robot can handle a gap of up to about 3cm.


Gap detection.jpg

Arrow detection

Arrow recognition
Arrow recog.jpg
Left the original image with detected green dots, right the HSV thresholded image. We still have to figure out how to convert these green dots to whether or not the arrow is pointing left or right. (we're also using the 2.x API (cv::Mat) instead of OpenCV 1.x API (CvArr))

Movies

Corridor competition test: Corridor_test_1 <br\> Arrow recognition: Arrow recognition



[[[File:youtube_arrow.png|thumb|400px|Arrow recognition http://youtu.be/tgMa_HOL0Mo]]

Possible improvements

In this section we present future recommendations, which we were not able to implement anymore.

Arrow detection

  • Convert the image to HSV.
  • Use the "k-means algorithm" to cluster nearby objects.
  • Use "connected compenents labelling" to find the different objects.
  • Use "region filling" to fill in any gaps due to lightning.
  • Calculate the inertia/covariance matrices for each object and find its eigenvalues and eigenvectors.
  • Divide both eigenvalues of each object and extract the arrow which is the object with the same heigth/width ratio as the arrow. The largest eigenvalue is longitudinal with the arrow.
  • Make a line move perpendicalur over the corresponding eigenvector. Where the line is maximal, is where the head of the arrow is.

This way the direction of the arrow can be detected more robustly than the algorithm we used. This can also detect if the arrow is pointing in the drive straight arrow direction.


...

  • ...