Click here to Skip to main content
6,629,885 members and growing! (21,576 online)
Email Password   helpLost your password?
Web Development » Applications & Tools » Tools with source code     Advanced License: A Public Domain dedication

2D LUA Based Robot Simulator

By auralius

An article on designing your own robot simulator
VC6, Windows, MFC, GDI, VS2008, Dev
Version:3 (See All)
Posted:22 Feb 2009
Updated:8 Mar 2009
Views:9,947
Bookmarked:33 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
6 votes for this article.
Popularity: 3.68 Rating: 4.73 out of 5

1

2

3
2 votes, 33.3%
4
4 votes, 66.7%
5

Introduction

Here I would like to introduce a self-made 2D robot simulator. With this simulator, we can design how a robot will navigate in a 2D world by using a set of rules that we design. The rules are designed by using Lua script. For the world editor, we use GDI Device Context programming. Here are the overall features:

  • Differential steering robot
  • Laser beam type distance sensor
  • Embedded Lua script for the robot code
  • Graphical world editor
  • Code editor with syntax colorization

A little knowledge in Lua is necessary. You can check Lua website.

The Robot Theory

The robot that we have here is a wheeled robot. It has two wheels. It navigates with a differentially steered drive system. Differentially steered drive system is like a wheeled chair. Steering a wheeled chair can be done by varying the speed of its wheels. If one wheel is rotating faster, the wheeled chair will make a curved path. If both wheels are on the same speed, it will make a straight path.

The Robot Mathematics

I am not good at math. It gives me quite a headache. Better you check on G.W. Lucas tutorial. Let's make it simple. Here are the equations that I am using to model differential steering behaviour.

Now if the left wheel and the right wheel are at the same speed? The equation above cannot be implemented since it will result in division by zero error. Using L'Hospital's rule, it can be shown that the equation has limits approaching straight line (check again on G.W. Lucas tutorial). So, when the left wheel and the right wheel are at the same speed, use this equation. Please notice that dx/dt means the difference between current x position and previous x position.

To get the current position of the robot, we only need to input time, left wheel speed and right wheel speed to the equation above. Robot angle is something that we also need to calculate. Here is the equation to calculate the robot angle.

Finally, here is the implementation code of those equations:

void CRobot::goRobotGo(double *t){
    if (canResetTime){
        *t = 0;
        canResetTime = false;
    }

    int plusFactor = m_robot.rWheelSpeed + m_robot.lWheelSpeed;
    int minusFactor = m_robot.lWheelSpeed - m_robot.rWheelSpeed;

    if (m_robot.lWheelSpeed - m_robot.rWheelSpeed != 0.0){
        m_robot.pos.x = m_puos0.x + m_robot.size / 2 * plusFactor / minusFactor /
                        2 *(sin(minusFactor * (*t) / m_robot.size / 2 + m_robot.theta)
                        - sin(m_robot.theta));
        m_robot.pos.y = m_pos0.y - m_robot.size / 2 * plusFactor / minusFactor /
                        2 *(cos(minusFactor * (*t) / m_robot.size / 2 + m_robot.theta)
                        - cos(m_robot.theta));
        m_robot.theta = m_theta0 + minusFactor * (*t) / m_robot.size ;

    }
    else{
        m_robot.pos.x = plusFactor / 2 * cos(m_robot.theta) * (*t) + m_pos0.x;
        m_robot.pos.y = plusFactor / 2 * sin(m_robot.theta) * (*t) + m_pos0.y;
    }
}

All things related to the robot are put in class CRobot in file Robot.h and Robot.cpp.

The World Editor

The world editor is simply an implementation of GDI device context programming. We use simple graphs such as rectangle, ellipse, and line to create rooms and obstacles. With a little math, we can make those graphs selectable, moveable, and resizable. This world editor is based on my own previous work. I know it is very simple and also not good since I received several bad responses on it. I will make it better if I have time. All things related to the world editor are in CCanvas in files Canvas.h and Canvas.cpp.

The Code Editor

For the code editor, I use Scintilla library. With Scintilla library, we can make an editor that supports syntax colorization easily. I learned about this library from an article I found on CodeProject. Check here and here. All things related to the world editor are in the file EditorDlg.h and EditorDlg.cpp.

The Embedded Lua

Lua is a very nice programming language. It is a light-weight, small footprint programming language designed for extending applications. Here I embed four C++ functions to Lua by using Lua script C++ wrapper created by RhicadS. Lua is a very nice programming language. It is a light-weight, small footprint programming language designed for extending applications.

  • initsensor() accepts nothing; returns nothing. You must issue at the very beginning of your code.
  • readsensor(int index) accepts sensor index; returns measured distance.
  • setspeed(int left, int right) accepts left and right wheel speed; returns nothing.
  • getangle() accepts nothing; returns current angular position of the robot (in radians).
  • debug(char *msg) accepts message to be displayed on log; returns nothing.
  • debug(char *msg or function) accepts message or another function to be displayed on log; returns nothing.

How To Use

You can display code editor window by clicking View >> Editor or by clicking View code editor on toolbar. Output log is where all error and debug messages are displayed. It can be loaded from menu View >> Output Log or View output log on toolbar. A world file is saved with *.wrl extension while code file is saved with *.lua extension. Loading and saving them are done separately.

Let's try. First draw a big ellipse on the world editor. Then drag the robot so that the right side of the robot is close to the inner side of the ellipse. Load code editor and paste the following code. Run the simulation. When the robot disappears, click menu Robot >> Reset Position.

function this.main(this)
    this:initsensor()
    this:setspeed(20,20)
    while true do
        a = this:readsensor(1)
        b = this:readsensor(2)
        if (a - b > 2) then
            this:setspeed(30,20)
        end

        if (a - b < -2) then
            this:setspeed(20,30)
        end

        if( (a - b > -2)  and (a - b < 2) ) then
            this:setspeed(20,20)
        end
    end
end

The above code is to make the robot move forward following the right wall. See how it reads the sensor value. There are six sensors in the robot (by default). You can modify the number of sensors from menu Robot >> Set properties. They are all laser beam type distance. As we know there are also sonar type distance sensor. Take a look at the picture. Sensor numbering starts from the right side and the index is increasing in clockwise direction.

Let's try another. Within the demo, I included two files trinity.wrl and trinity.lua. Load the two files. Copy and paste the following code:

function this.moveforward(this)
    -- to much to the left, so turn right
    while(this:readsensor(1) - this:readsensor(5) > 20) do
        this:setspeed(30,20);
    end

    --to much to the right, so turn left
    while(this:readsensor(1) - this:readsensor(5) < -20) do
        this:setspeed(20,30);
    end

    this:setspeed(30,30);
end

function this.sharpturnright(this)
    th = this:getangle()
    while(this:getangle() < th + 3.14 / 2) do
        this:setspeed(30,0);
    end
end

function this.sharpturnleft(this)
    th = this:getangle()
    while(this:getangle() > th - 3.14 / 2) do
        this:setspeed(0,30);
    end
end

-----------------------------------------------------------
--main function
function this.main(this)
    this:initsensor()
    while(true) do
        while(this:readsensor(0) > 50) do
            this:moveforward()
        end

        if (this:readsensor(1) - this:readsensor(5) > 0) then
            this:sharpturnright()
        else
            this:sharpturnleft()
        end

    end
end

Let's take a closer look. The function this.main(this) will always be first called. It's the main function. Function is always written with something like this: function this.functionname(this) and we call it with: this:functionname(parameterifexisit). In the code above, function this.moveforward(this) will read the difference between right front and left front sensor. If they show a big difference (more than 20 units), it will turn the robot to the proper direction. If the robot senses a wall at the front, it will check which direction is free. Finally, it will turn sharply in that direction.

Points Of Interest

There have been plenty of improvements I made since the first release. In the first release, there was an issue that the sensors didn't read right. That's why now we have initsensor command. I also added the debug command so that you can print sensor value in runtime mode. However I still need feedback so that I can make it better. For your information, now this simulator is developed with Visual Studio 2008. If you want to try the demo, you may need to install VS2008 Redistributable package. I hope you like it and it can be helpful for you.

References

History

  • 22nd February, 2009: Initial post
  • 6th March, 2009: Article updated

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

auralius


Member
from Indonesia with love... Smile
Occupation: Software Developer (Junior)
Location: Indonesia Indonesia

Other popular Applications & Tools articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 8 of 8 (Total in Forum: 8) (Refresh)FirstPrevNext
GeneralMaths? PinmemberMember 40308895:05 11 Sep '09  
GeneralRe: Maths? Pinmemberauralius3:41 15 Sep '09  
Generalbugs... Pinmemberauralius13:34 1 Apr '09  
GeneralRe: bugs... PinmemberMember 150845222:29 29 Jul '09  
GeneralRe: bugs... PinmemberMember 150845222:38 29 Jul '09  
GeneralRe: bugs... Pinmemberauralius23:22 30 Jul '09  
GeneralFrom a fellow robotics developer. PinmemberJonathan Davies3:21 23 Feb '09  
GeneralRe: From a fellow robotics developer. Pinmemberauralius16:55 23 Feb '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 8 Mar 2009
Editor: Deeksha Shenoy
Copyright 2009 by auralius
Everything else Copyright © CodeProject, 1999-2009
Web19 | Advertise on the Code Project