Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/goktug97/dynamicwindowapproach
The Dynamic Window Approach (DWA) planning algorithm written in C with Python Bindings
https://github.com/goktug97/dynamicwindowapproach
bindings c collision-avoidance cython dwa dynamic-window-approach mobile-robots motion-planning planning-algorithm position-control python python-bindings robot-control robotics
Last synced: about 1 month ago
JSON representation
The Dynamic Window Approach (DWA) planning algorithm written in C with Python Bindings
- Host: GitHub
- URL: https://github.com/goktug97/dynamicwindowapproach
- Owner: goktug97
- License: mit
- Created: 2019-12-23T16:25:39.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-29T08:25:42.000Z (about 2 years ago)
- Last Synced: 2024-12-27T05:05:48.046Z (about 1 month ago)
- Topics: bindings, c, collision-avoidance, cython, dwa, dynamic-window-approach, mobile-robots, motion-planning, planning-algorithm, position-control, python, python-bindings, robot-control, robotics
- Language: Cython
- Homepage: https://goktug97.github.io/dwa/
- Size: 3.45 MB
- Stars: 97
- Watchers: 5
- Forks: 24
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Dynamic Window Approach
===================================2D Dynamic Window Approach [[1]](#ref1) Motion Planning algorithm written in C with Python Bindings.
![Python Demo](https://raw.githubusercontent.com/goktug97/DynamicWindowApproach/master/dwa.gif)
**Table of Contents**
- [Dynamic Window Approach](#dynamic-window-approach)
- [Online Demo](#online-demo)
- [Requirements](#requirements)
- [Python](#python)
- [C Libraries (Optional for the Demo)](#c-libraries-optional-for-the-demo)
- [Installation](#installation)
- [Compile and Install C Library](#compile-and-install-c-library)
- [Install Python Bindings](#install-python-bindings)
- [PyPI](#pypi)
- [Source](#source)
- [Usage](#usage)
- [Documentation](#documentation)
- [Structs and Classes](#structs-and-classes)
- [Rect](#rect)
- [Config](#config)
- [Velocity](#velocity)
- [Point](#point)
- [PointCloud](#pointcloud)
- [Pose](#pose)
- [DynamicWindow](#dynamicwindow)
- [Functions](#functions)
- [planning](#planning)
- [createDynamicWindow](#createdynamicwindow)
- [freeDynamicWindow](#freedynamicwindow)
- [motion](#motion)
- [calculateVelocityCost](#calculatevelocitycost)
- [calculateHeadingCost](#calculateheadingcost)
- [calculateClearanceCost](#calculateclearancecost)
- [createPointCloud](#createpointcloud)
- [freePointCloud](#freepointcloud)
- [References](#references)
- [License](#license)## Online Demo
https://goktug97.github.io/dwa/
## Requirements
### Python
* Python >= 3.6
* cython
* numpy
* cv2 (Optional for the demo)### C Libraries (Optional for the Demo)
* SDL
* OpenGL## Installation
You can directly install Python bindings without compiling the library.
### Compile and Install C Library
```bash
git clone https://github.com/goktug97/DynamicWindowApproach
cd DynamicWindowApproach
mkdir build
cd build
cmake ..
make
make install
# Optional: Build Demo
make demo
```### Install Python Bindings
#### PyPI
```bash
pip3 install dynamic-window-approach --user
```#### Source
```bash
git clone https://github.com/goktug97/DynamicWindowApproach
cd DynamicWindowApproach
python3 setup.py install --user
```## Usage
- Only function you need to run to plan the next move is the
[planning](#planning) function. Rest of the code for both C and
Python examples are just to create simulation environment and GUI.
The 2 examples that you can find in
[examples](https://github.com/goktug97/DynamicWindowApproach/blob/master/examples/)
folder is the same demo but implemented using different libraries for
visualization.- The Python example uses OpenCV and you can run it by executing `python3 demo.py`
in the examples folder.- The C example uses OpenGL and SDL and you can run it by executing `./demo` in
bin folder. The bin folder is created after the compile so if you didn't
compile the demo while installing the library. Go to `build` directory and run
`make demo`.## Documentation
While the [planning](#planning) function is the only function that a user needs
to call for the planning, all of the functions are exposed to the user
for both C and Python for no reasons.### Structs and Classes
If you are using Python bindings, you don't need to use any of these
classes except [Config](#config). The functions accept built-in or
numpy types. The functions create required classes inside for easy
usage. For example a snippet from the [planning](#planning) function;``` cython
cdef float x, y, yaw, v , w, gx, gy
cdef PointCloud _point_cloud = PointCloud(point_cloud)
x, y, yaw = pose
v, w = velocity
gx, gy = goal
cdef Pose _pose = Pose(Point(x, y), yaw)
cdef Velocity _velocity = Velocity(v, w)
cdef Point _goal = Point(gx, gy)
```- Structs are for C
- Classes are for Python#### Rect
- *struct* Rect
* Given center of the robot is (0, 0)
* **Parameters**:
- **xmin** - floating-point minimum x-coordinate of the robot.
- **ymin** - floating-point minimum y-coordinate of the robot.
- **xmax** - floating-point maximum x-coordinate of the robot.
- **ymax** - floating-point maximum y-coordinate of the robot.#### Config
- *struct* Config
* **Parameters**:
- **maxSpeed** - floating-point maximum linear speed robot can reach [m/s]
- **minSpeed** - floating-point minimum linea speed robot can fall [m/s]
- **maxYawrate** - floating-point maximum angular speed robot can reach [yaw/s]
- **maxAccel** - floating-point maximum linear acceleration robot can reach [m/ss]
- **maxdYawrate** - floating-point maximum angular acceleration robot can reach [yaw/ss]
- **velocityResolution** - floating-point linear speed resolution [m/s]
- **yawrateResolution** - floating-point angular speed resolution [m/s]
- **dt** - floating-point time change [s]
- **predictTime** - floating-point simulation time [s]
- **heading** - floating-point heading cost weight
- **clearance** - floating-point clearance cost weight
- **velocity** - floating-point velocity cost weight
- **base** - [Rect](#rect)- *class* Config
``` python
Config(float max_speed, float min_speed,
float max_yawrate, float max_accel, float max_dyawrate,
float velocity_resolution, float yawrate_resolution, float dt,
float predict_time, float heading, float clearance, float velocity,
list base)
```#### Velocity
- *struct* Velocity
* **Parameters**:
- **linearVelocity** - floating-point linear velocity of the robot [m/s]
- **angularVelocity** - floating-point angular velocity of the robot [yaw/s]- *class* Velocity
``` python
Velocity(float linear_velocity, float angular_velocity)
```#### Point
- *struct* Point
* **Parameters**:
- **x** – floating-point x-coordinate of the point.
- **y** – floating-point y-coordinate of the point.- *class* Point
``` python
Point(float x, float y)
```#### PointCloud
- *struct* PointCloud
* int **size**
- Number of points.
* Point ***points**
- Array of [points](#point).- *class* PointCloud
``` python
PointCloud(np.ndarray[np.float32_t, ndim=2] point_cloud)
```#### Pose
- *struct* Pose
* Point **point**
- Coordinate of the robot.
* float **yaw**
- Angle of the robot.- *class* Pose
``` python
Pose(Point point, float yaw)
```#### DynamicWindow
- *struct* DynamicWindow
* int **nPossibleV**:
- Number of linear velocities in the Dynamic Window.
* float ***possibleV**:
- Array of linear velocities with resolution of [Config.velocityResolution](#config)
* int **nPossibleW**:
- Number of angular velocities in the Dynamic Window
* float ***possibleW**:
- Array of angular velocities with resolution of [Config.yawrateResolution](#config)- *class* DynamicWindow
```python
DynamicWindow(tuple velocity, Config config)
```### Functions
#### planning
Calculates best linear and angular velocities given the state. Only
required function to use this library.- C
``` c++
Velocity planning (Pose pose, Velocity velocity, Point goal, PointCloud *pointCloud, Config config);
```* **Parameters:**
- **pose:** [Pose](#pose)
- **velocity:** [Velocity](#velocity)
- **goal:** [Point](#point)
- **pointCloud:** [PointCloud](#pointcloud)
- **config:** [Config](#config)- Python
``` python
linear_velocity, angular_velocity = planning(pose, velocity, goal, point_cloud, config)
```* **Parameters:**
- **pose:** tuple: (x, y, yaw)
- **velocity:** tuple: (Linear Velocity, Angular Velocity)
- **goal:** tuple: (x, y)
- **point_cloud:** Numpy Array of shape (N, 2) and type np.float32
- **config:** [Config](#config)#### createDynamicWindow
Given robot configuration and current velocities, calculates [DynamicWindow](#dynamicwindow).
The memory is allocated dynamically inside of the function and must be freed using
[freeDynamicWindow](#freedynamicwindow) function.- C
``` c++
void createDynamicWindow(Velocity velocity, Config config, DynamicWindow **dynamicWindow);
```* **Parameters:**
- **velocity:** [Velocity](#velocity)
- **config:** [Config](#config)
- **dynamicWindow:** [DynamicWindow](#dynamicwindow)- Python
[DynamicWindow](#dynamicwindow) class is used to create a DynamicWindow instance.
``` python
dw = dwa.DynamicWindow(velocity, config):
print(dw.possible_v, dw.possible_w)
```* **Parameters:**
- **velocity:** tuple: (Linear Velocity, Angular Velocity)
- **config:** [Config](#config) class![Dynamic Window [2]](https://raw.githubusercontent.com/goktug97/DynamicWindowApproach/master/img/dynamic_window.jpg)
#### freeDynamicWindow
Free dynamically allocated memory.
- C
``` c++
void freeDynamicWindow(DynamicWindow *dynamicWindow);
```* **Parameters:**
- **dynamicWindow:** [DynamicWindow](#dynamicwindow)- Python
Handled by the [DynamicWindow](#dynamicwindow) class. See below.
``` python
def __dealloc__(self):
if self.thisptr is not NULL:
cdwa.freeDynamicWindow(self.thisptr)```
#### motion
Given current position and velocities, calculates next position after
given dt using differential drive motion model. Can be used to
simulate motion in a simulated environment.- C
``` c++
Pose motion(Pose pose, Velocity velocity, float dt);
```* **Parameters:**
- **pose:** [Pose](#pose)
- **velocity:** [Velocity](#velocity)
- **dt:** float (seconds)- Python
``` python
x, y, yaw = motion(pose, velocity, dt)
```* **Parameters:**
- **pose:** tuple: (x, y, yaw)
- **velocity:** tuple: (Linear Velocity, Angular Velocity)#### calculateVelocityCost
- C
``` c++
float calculateVelocityCost(Velocity velocity, Config config);
```* **Parameters:**
- **velocity:** [Velocity](#velocity)
- **config:** [Config](#config)- Python
``` python
velocity_cost = calculate_velocity_cost(velocity, config)
```* **Parameters:**
- **velocity:** tuple: (Linear Velocity, Angular Velocity)
- **config:** [Config](#config)#### calculateHeadingCost
- C
``` c++
float calculateHeadingCost(Pose pose, Point goal);
```* **Parameters:**
- **pose:** [Pose](#pose)
- **goal:** [Point](#point)- Python
``` python
heading_cost = calculate_heading_cost(pose, goal)
```* **Parameters:**
- **pose:** tuple: (x, y, yaw)
- **goal:** tuple: (x, y)#### calculateClearanceCost
- C
``` c++
float calculateClearanceCost(Pose pose, Velocity velocity, PointCloud *pointCloud, Config config);
```* **Parameters:**
- **pose:** [Pose](#pose)
- **velocity:** [Velocity](#velocity)
- **pointCloud:** [PointCloud](#pointcloud)
- **config:** [Config](#config)- Python
``` python
clearance_cost = calculate_clearance_cost(pose, velocity, point_cloud, config)
```* **Parameters:**
- **pose:** tuple: (x, y, yaw)
- **velocity:** tuple: (Linear Velocity, Angular Velocity)
- **point_cloud:** Numpy Array of shape (N, 2) and type np.float32
- **config:** [Config](#config)#### createPointCloud
Given a size, creates a [PointCloud](#pointcloud). Must be freed using [freePointCloud](#freepointcloud).
- C
``` c++
PointCloud* createPointCloud(int size);
`````` c++
for (int i = 0; i < pointCloud->size; ++i) {
pointCloud->points[i].x = 0.0
pointCloud->points[i].y = 0.0
}
```* **Parameters:**
- **size:** int- Python
[PointCloud](#pointcloud) class is used to create a PointCloud instance. All
functions in python accepts numpy array instead of PointCloud instance. The
PointCloud instance is created inside of the function.``` python
size = 600
point_cloud = np.zeros((size, 2), dtype=np.float32)
point_cloud = dwa.PointCloud(point_cloud)
```#### freePointCloud
- C
``` c++
void freePointCloud(PointCloud* pointCloud);
```* **Parameters:**
- **pointCloud:** [PointCloud](#pointcloud)- Python
Handled by the [PointCloud](#pointcloud) class. See below.
``` python
def __dealloc__(self):
if self.thisptr is not NULL:
cdwa.freePointCloud(self.thisptr)
```## References
1. D. Fox, W. Burgard and S. Thrun, "The dynamic window approach to
collision avoidance," in IEEE Robotics & Automation Magazine, vol. 4,
no. 1, pp. 23-33, March 1997. doi: 10.1109/100.580977 URL:
http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=580977&isnumber=125892. http://ais.informatik.uni-freiburg.de/teaching/ss19/robotics/slides/19-pathplanning-long.pdf
## License
MIT License.