Design, Program
Design, Program
SANA’A UNIVERSITY
FACULTY OF ENGINEERING
MECHATRONICS ENGINEERING DEPARTMENT
BY:
Supervised by:
Dr. Hatem Al-Dois
JANUARY 2018
CANDIDATE’S DECLARATION
We hereby certify that the work which is being presented in the thesis entitled “Design,
program and fabrication of autonomous mobile SCARA” in partial fulfilment of the requirement
for the award of the degree of Bachelor of Engineering and submitted in Sana’a University (Faculty
of Engineering) Mechatronics Engineering Department an authentic record of our own work, under
the supervision of:
The matter presented in this thesis has not been submitted by us for the award of any other degree
of this University or any other University.
This is to certify that the above statement made by the candidates is correct to the best of our
knowledge.
Dr. Hatem Al-Dois.
i
ACKNOWLEDGEMENT
It is always a pleasure to mention the fine people in this graduation project for their sincere
guidance we received to raise our practical as well as theoretical skills in mechatronics
engineering.
We would like to express our special thanks to Dr.Hatem Al-Dois who gave us this golden
opportunity to do a wonderful project on robotics. This opportunity helped us to do a lot of research
and came to know about many new aspects in the field. We are really thankful to him. We also
want to thank the Mechatronics department staff and the workers in the faculty for their efforts
that helped us reaching this success.
ii
ABSTRACT
The project consists of two main parts; the manipulator and the mobile robot. The
manipulator is of type SCARA and mounted on the platform of a mobile robot. The function of
the manipulator is to take stuff from and onto the platform of the mobile robot. The mobile robot
has for wheels and is able to move autonomously to the specified position. The motion of the car
is programmed using A* search technique which finds the shortest path between the initial and
final positions and avoids any obstacles. The path is followed using PID control scheme. A
Raspberry-pi controller programmed in python along with several motor drivers are used. The
controller is programmed to receive the motion command wirelessly for a remote location. The
robot is equipped with different sensors to ensure the correct executive of the commanded motion
and to prevent the robot from damage in case of collision with surrounding objects or itself. A GUI
is developed in MATLAB for the manipulator and in python for the car to simulate the
performance of the robot. Finally, the mobile robot motion and manipulator functionally are tested
and the results are reported.
iii
LIST OF FIGURES
iv
Fig. (3.24) The Car of the Project 26
Fig. (3.25) Inner Construction of the Car 26
Fig. (3.26) The Final Project 27
Fig. (4.1) SCARA Robot Coordinate Assignment 28
Fig. (4.2) Grid Based Algorithm 31
Fig. (4.3) A* Search Algorithm 32
Fig. (4.4) Path Smoothing 32
Fig. (4.5) Bicycle Model of the Car 33
Fig. (4.6) GUI Simulation for the SCARA Manipulator 34
Fig. (4.7) Inverse Kinematic Simulation 34
Fig. (4.8) Torque Comparison Simulation 35
Fig. (4.9) Trajectory Simulation 35
Fig. (4.10) Mobile Robot Simulation 36
Fig. (5.1) Raspberry pi Desktop 37
Fig. (5.2) Project Flow Chart 39
Fig. (5.3) Grids of the Workspace 47
Fig. (6.1) Steering Angle and Distance Error 54
v
LIST OF TABLES
Table Title Page No.
3.1 Raspberry pi 3 Specifications 15
3.2 Linear Motor Specifications 16
3.3 Savox Servo Motor Specifications 18
4.1 Link Coordinate Parameters 29
vi
CONTENTS
Page No.
CANDIDATE’S DECLARATION. i
ACKNOWLEDGEMENT. ii
ABSTRACT. iii
LIST OF FIGURES. iv
LIST OF TABLES. vi
CHAPTER 1
1
“INTRODUCTION”
1.1 Background. 1
1.2 Problem Definition. 2
1.3 Motivation. 2
1.4 Goals of the Project. 2
1.5 Project Overview. 2
1.5.1 Project out lines. 3
CHAPTER 2
4
“ROBOTICS TECHNOLOGY”
2.1 Introduction. 4
2.2 Classes of Manipulators. 4
2.3 Robot Configurations. 6
2.4 Robots Locomotion. 7
2.5 Mechanics and Control of Robotics. 8
CHAPTER3
14
“HARDWARE DESIGN”
CHAPTER 6
54
“PRACTICAL RESULTS”
6.1 Introduction. 54
6.2 Testing the manipulator positioning accuracy. 54
6.3 Testing the mobile robot positioning accuracy. 54
CHAPTER 7
56
“CONCLUSION AND FUTURE DEVELOPMENT”
REFRENCES. 57
1.1 Background
Robotics can be described as the current pinnacle of technical development. Robotics is a
confluence science using the continuing advancements of mechanical engineering, material science,
sensor fabrication, manufacturing techniques, and advanced algorithms. The study and practice of
robotics will expose a dabbler or professional to hundreds of different avenues of study. For some,
the romanticism of robotics brings forth an almost magical curiosity of the world leading to creation
of amazing machines. A journey of a lifetime awaits in robotics. Robotics can be defined as the
science or study of the technology primarily associated with the design, fabrication, theory, and
application of robots. While other fields contribute the mathematics, the techniques, and the
components, robotics creates the magical end product. The practical applications of robots are to
drive development of robotics and drive advancements in other sciences in turn. Crafters and
researchers in robotics study more than just robotics. The promise of robotics is easy to describe but
hard for the mind to grasp. Robots hold the promise of moving and transforming materials with the
same lean and ease as a computer program transforms data. Today, robots mine minerals, assemble
semi-processed materials into automobile components, and assemble those components into
automobiles. On the immediate horizon are self-driving cars, robotics to handle household chores,
and assemble specialized machines on demand. It is not unreasonable to imagine robots that are
given some task, such as reclaim desert into photovoltaic cells and arable land, and left to make their
own way. Then the promise of robotics exceeds the minds grasp .
Robotics has achieved its greatest success to date in the world of industrial manufacturing. A
fixed manipulator has a limited range of motion that depends on where it is bolted down. In contrast,
a mobile robot would be able to travel throughout the manufacturing plant, flexibly applying its
talents wherever it is most effective. This Project focuses on the technology of mobility: how can a
mobile robot move unsupervised through real-world environments to fulfill its tasks? The first
challenge is locomotion itself. How a mobile robot moves, and what should be, is it about a
particular locomotion mechanism that makes it superior to alternative locomotion mechanisms?
These robots are compelling not for reasons of mobility but because of their autonomy, and so their
ability to maintain a sense of position and to navigate without human intervention is paramount. The
1
dynamics and control theory must be understood beside the mechanism and kinematics for solving
the locomotion problem. [1]
1.3 Motivation
Robotics is one of the most interesting since nowadays, there are international competitions
between the greatest countries in the world in producing the highest intelligence robots with high
technologies. Yemen as one country of the third world this kind of completion is not there because of
the limitation of the technology. However, lately with the appearance of mechatronics engineering in
Sana’a University and other universities in the capital of Yemen and other big cities such as Emirates
University and Malaysian university, students started to make a good starting robotics projects.
1. To apply mechatronics concepts that, we studied during five years in a real project.
2. Improve the transmission of objects in the industries of our county.
3. To open the gate of robotics competition inside Yemen.
2
processing to produce all the links and the mechanical parts such as the shafts, gears, pulley and
bearings holders. The same thing with the mobile robot we produced it by mechanical operation, the
design of the project will be shown in chapter 3. The robot can move easily to the required places
autonomously depending on the application that will be chosen to. Manipulator, mobile robot,
electrical devices such as servo motors, dc motors, some drivers, shields and microcontroller are the
main hardware parts of this project. In general robotics arms are needed to be used in industrial areas
and some other areas. The locomotion characteristic makes the robot’s scope too much larger. The
project is an autonomous mobile manipulator with a large scope which can be used in different areas
of human life. Industrial factories, hospitals restaurants, cafeterias, homes, schools and companies. In
general, it is multi-functional robot depends on its gripper. The project contains a small hand as its
gripper which make its scope clearly identified. Taking small things from nearby places to required
positions is the main job for this robot with high intelligence and autonomous locomotion.
Chapter 2 Covers a general overview about robotics, mobile robot and applications.
Chapter 3 Describes the project hardware including design and kits used in the project.
Chapter 4 Describes the modeling and simulation for this project in details.
Chapter 5 Describes the software design for this project in details.
Chapter 6 Presents the results obtained for practical test
Chapter 7 Presents the conclusion and future development.
3
CHAPTER 2
ROBOTICS TECHNOLOGY
2.1 Introduction
The term robot means different things to different people. Science fiction books and movies
have strongly influenced what many people expect a robot to be or what it can do. Sadly, the practice
of robotics is far behind this popular conception. One thing is certain though – robotics will be an
important technology in this century. Products such as vacuum cleaning robots are the vanguard of a
wave of smart machines that will appear in our homes and workplaces. [2]
Another formal definitions of robot is: "A robot is a mechanical device with links and joints, guided
by sensors, driven by actuators and controlled through a programmed software, to handle and
manipulate parts, materials, tools and devices for performing various tasks in variety of work
environments". The definition stated above answers the question like-what type of device is the
robot. What are its elements? How is it moved? How is it made to function? What does it do? And
where can it work? [4]
4
robot consists of a number of rigid links connected with joints. Simplicity considerations in
manufacturing and control have led to robots with only revolute or prismatic joints and orthogonal,
parallel and/or intersecting joint axes (instead of arbitrarily placed joint axes). [5]
In the Stewart platform, the actuators are paired together on both the basis and the platform.
These systems are articulated robots that use similar mechanisms for the movement of either the
robot on its base, or one or more manipulator arms. Their 'parallel' distinction, as opposed to a serial
manipulator, is that the end effector (or 'hand') of this linkage (or 'arm') is connected to its base by a
number of (usually three or six) separate and independent linkages working in parallel. 'Parallel' is
used here in the computer science sense, rather than the geometrical; these linkages act together, but
it is not implied that they are aligned as parallel lines; here parallel means that the position of the end
point of each linkage is independent of the position of the other linkages. [7]
5
2.3 Robot Configurations
The possible types of movements that a robot can provide define the configuration of a
particular robot. The different configurations of different robots help in positioning of the robot hand
in the defined co-ordinate of the work-envelope. If 'P' represents the prismatic joint and 'R' represents
the revolute joint, then a robot with three prismatic and 2 revolute joints is configured as 3P2R robot.
The different robot configuration are as follows. [8]
2.3.1 SCARA (Selective Compliance Assembly Robot Arm):
This is a specially configured robot which has two horizontal and parallel revolute joints with
the axis vertical and one prismatic joint which can move the arm vertically up and down. This gives
high stiffness due to the vertical axis and dexterity in the horizontal points due to the rotary joints.
This finds use in assembly operations. Figure 2.2(a) shows schematic of the SCARA robots.
6
(a) SCARA (b) Cartesian (c) Cylindrical
7
2.4.2 Mobile robot:
An autonomous robot acts as a stand-alone system, complete with its own computer (called the
controller). The most advanced example is the smart robot, which has a built-in artificial intelligence
(AI) system that can learn from its environment and its experience and build on its capabilities based
on that knowledge Mobile robot category includes wheeled robots, legged robots, flying robots,
swimming robots, rolling robotic, swarm robots, modular robots, micro robots, Nano robots and soft
elastic robots. [10]
8
and orientation of a body, so we often think of transforming or changing the description of these
attributes of a body from one frame to another see figure (2.4). [11]
2.5.2 Kinematics:
Kinematics is the science of motion that treats motion without regard to the forces which cause
it. Within the science of kinematics, one studies position, velocity, acceleration, and all higher order
derivatives of the position variables (with respect to time or any other variable(s)). Hence, the study
of the kinematics of manipulators refers to all the geometrical and time-based properties of the
motion. The dimensions of the robot and its kinematics equations define the volume of space
reachable by the robot, known as its workspace. This science covers many topics such as forward
kinematics, inverse kinematics, and velocities.
▪ Forward Kinematics:
Forward kinematics specifies the joint parameters and computes the configuration of the chain.
For serial manipulators this is achieved by direct substitution of the joint parameters into the forward
kinematics equations for the serial chain. For parallel manipulators substitution of the joint
parameters into the kinematics equations requires solution of a set of polynomial constraints to
determine the set of possible end-effector locations. [12]
▪ Inverse Kinematics:
Inverse kinematics specifies the end-effector location and computes the associated joint angles.
For serial manipulators this requires solution of a set of polynomials obtained from the kinematics
equations and yields multiple configurations for the chain. The case of a general 6R serial
9
manipulator (a serial chain with six revolute joints) yields sixteen different inverse kinematics
solutions, which are solutions of a sixteenth-degree polynomial. For parallel manipulators, the
specification of the end-effector location simplifies the kinematics equations, which yields formulas
for the joint parameters. [13]
2.5.3 Dynamics:
Dynamics is the study of motion taking into account the forces and torques that cause it.
Analogous to the notions of a robot’s forward and inverse kinematics, the forward dynamics problem
seeks to determine the resulting joint trajectory for a given input joint torque profile. The inverse
dynamics problem is concerned with determining the input joint torque profile for a desired joint
trajectory. The dynamic equations relating the forces and torques to the motion of the robot’s links
are given by a set of second-order ordinary differential equations. [14]
10
▪ Path Planning:
Path planning problem is a sub-problem of the general motion planning problem, and seeks to
determine a collision-free path between a start and goal configuration. Path planning methodologies
are often computationally expensive and require a relatively accurate map of the environment in
order to determine the optimal path. The frequency of re-planning is dependent on the efficiency of
the algorithm. Some popular techniques to accomplish path planning include the A* Search
algorithm, the Wavefront algorithm and having the user manually input a desired path. [15]
1. A* Search Algorithm: The A* algorithm is a best first tree search algorithm which uses
a combination of the path cost and a heuristic function to determine the order in which
it visits the tree nodes. The path cost is associated with the cost moving from one
position to another and the heuristic function provides an estimate of the desirability of
visiting a given node. This algorithm guarantees to find the optimal path to the goal
position if one exists.
2. Wavefront: The wave front algorithm (also referred to as Distance Transform Path
Planning) is unique in the way that it determines the optimal path by traversing
backwards from the goal position towards the robot start position. This method is
guaranteed to offer an optimal path provided that the given environment map is
accurate.
3. User-defined: In terms of determining an acceptable path; having the end user manually
determine the path is perhaps the simplest methodology. However, in terms of
implementation complexity it is not the best solution because it requires a relatively
complex Graphic User Interface (GUI) to be built in order to obtain the desired path
from the user. Furthermore, manually inputted paths are not guaranteed to be optimal
even though they may be acceptable to the end user; usually such solutions are offered
as a secondary option.
▪ Path Smoothing:
In order to avoid wheel slippage or mechanical damage during the mobile robot navigation, it
is necessary to smoothly change driving velocity or direction of the mobile robot. This means that
dynamic constraints of the mobile robot should be considered in the design of path smoothing
algorithm.
11
2.5.6 Robot Control:
Robotic control can be seen as a mixture of engineering and cognitive science and as such it
presents unusual challenges to the programmer. Robotic control methodologies have tended to move
from simplistic, predefined actuator actions based on specific input criteria to tight feedback loops
with input from the environment, giving more robust solutions.
Robots are classified by control method into servo and non-servo robots. The earliest robots were
non-servo robots. These robots are essentially open-loop devices whose movement is limited to
predetermined mechanical stops, and they are useful primarily for materials transfer. Servo robots
use closed-loop computer control to determine their motion and are thus capable of being truly
multifunctional, reprogrammable devices. [16]. A mostly used closed loop control in robotics is the
PID controller.
- PID Controller:
In Control Theory, a PID controller is a feedback based control loop used in industrial systems.
It is used in more than half the industrial controllers in use nowadays, which has led to the
development of a variety of systems to adjust the tuning of the control parameters. One main
advantage of this type of controllers is that they can be applied in many different systems, which
makes them very versatile, especially when a mathematical model of the system to be controlled
cannot be known.
𝑡
𝑑
𝑢(𝑡) = 𝐾𝑝 𝑒(𝑡) + 𝑇𝑖 (∫ 𝑒(𝑡) 𝑑𝑡) + 𝑇𝑑 ( 𝑒(𝑡)) … … . . (1)
0 𝑑𝑡
A PID controller works by calculating the error between the output of the plant and a given set point.
With this error, an output is calculated based on equation (1). This output is then given as input to the
controlled system as shown in Figure (2.5). Equation (1) can be divided in three parts, which are the
three actions of the PID controller:
12
• Proportional: the actual error is multiplied by a gain of Kp, which means that the bigger the
error, the bigger the output. This action defines the response speed of the controller: ideally,
this constant should be as large as possible in order to get a perfect response. However,
increasing the gain too much can cause oscillation and overshooting in output values.
• Integral: the error is integrated over time and multiplied by Ti, making it possible to correct
the constant error that the proportional part can have. The integral action allows to eliminate
the steady-state error, as it will increase its output over time when a constant deviation
happens. In digital controllers, the integration is often approximated as the sum of errors in
each time step. This approach can cause the errors introduced by sensors or noise to
accumulate, which can distort the output if the gain is set too high.
• Derivative: the error is derived with respect to time in order to get the error change rate, and
is then multiplied by Td. This way, the controller can predict future error based on the way
the actual error is changing. The derivative action is sensitive to noise, which could cause
spikes in the output if not filtered correctly.
13
CHAPTER 3
HARDWARE DESIGN
3.1.1 Raspberry pi 3:
The controller of the robot is a single board computer Raspberry Pi 3. Figure (3.1) shows
Raspberry Pi 3 B architecture with GPIO connectors. CPU performance can be compared to a
Pentium II 300 MHz processor. It has a variety of interfacing peripherals, including Wi-Fi, HDMI
port, USB port, SD card storage and 40 pin GPIO port for expansion, table (3.1) shows Raspberry pi
3 specifications. Monitor, keyboard, and mouse can be connected to the Raspberry Pi 3 through
HDMI and USB connectors and it can be used like a desktop computer. It supports many of
operating systems like a Debian based Linux distort, Raspbian which is used in this project.
Raspberry Pi 3 can be connected to a local area network by using an Ethernet cable, and then it can
be accessed through remote login. Raspberry bi is a small computer that is used for control the input
(as sensors) and the output (as servo and dc motor) of robot. [17]
14
Table (3.1) Raspberry pi 3 model B specifications
Characteristic Raspberry Pi 3
CPU Quad cortex A53 @ 1.2GHz
GPU 400MHz Video Core IV
RAM 1GB SDRAM
Storage Micro SD
Ethernet Port Yes
Wireless 802.11n/Bluetooth 4.0
GPIO 40 pins
▪ It's an i2c-controlled PWM driver with a built-in clock. Which means we can control up
to 16 servos using only 2 pins.
▪ It is 5V compliant, which means you can control it from a 3.3V microcontroller and
still safely drive up to 6V outputs.
▪ 6addresses select pins so you can wire up to 62 of these on a single i2c bus, a total of
992 outputs - that's a lot of servos.
▪ Adjustable frequency PWM up to about 1.6 KHz.
▪ 12-bit resolution for each output - for servos, that means about 4us resolution at 60Hz
update rate
▪ Output enable pin to quickly disable all the outputs.
15
3.1.3 Dc linear motor:
Linear motors are electromagnetic direct drives in tubular form as shown in Figure (3.3). The
linear motion is produced purely electrically and wear-free, without any intermediate coupling of
mechanical gearboxes, spindles, or belts. The linear motor consists of just two parts: the slider and
the stator. Table (3.2) shows its specifications. Linear motor is used to move the gripper of the arm
vertically.
Voltage 12 VDC
16
3.1.5 ADC 16-bit:
Raspberry pi doesn't have analog-to-digital converter, so we used the ADS1115 to provide 16-
bit precision at 860 samples/second over I2C. The chip can be configured as 4 single-ended input
channels, or two differential channels. As a nice bonus, it even includes a programmable gain
amplifier, up to x16, to help boost up smaller single/differential signals to the full range. We like this
ADC because it can run from 2V to 5V power/logic, can measure a large range of signals and its
super easy to use. It is a great general purpose 16-bit converter [20]. The analog to digital converter
is shown in Figure (3.5).
17
Figure (3.6) SAVOX servo motor
Gear Steel
18
3.1.8 Servo to shaft Coupler:
A Servo to Shaft Coupler shown on Figure (3.8), it offers a simple and solid way to attach a
shaft in line with the output spline of a servo. Once installed onto the servo the coupler is then
fastened to the servo using a servo screw. The shaft can then be slid into place and clamped using the
supplied socket head screw. [22]
Three IR sharp sensor IR Sensor are used in our project for the car in avoiding obstacles while the
mobile robot is moving. They are connected to the analog-to-digital converter then the ADC send the
signal to the raspberry pi via I2C.
19
3.1.10 Pulley:
We used two Toothed-pulleys for the second link as shown in Figure (3.10). The Pulley is
used to transmit the motion from the servo motor to the second link by the belt which is connected to
the pulley of the servo shaft in one end and the other end is connected to the pulley of the shaft that
fixed to the second link.
They are fixed in the rear tires of the car. It is shown in Figure (3.11).
20
HC-SR04 Ultrasonic Specifications are as follows: [24]
1. 12V battery used to supply power to the DC-motors (linear motor, gripper, and the rear
motors).
2. 6V battery used to supply power to the three servo motors.
3. 5V power bank used to supply power to the raspberry pi.
21
3.2 Mechanical Construction
3.2.1 Shafts and bearings:
We start with the shafts and bearings that will connect the links of the arm with each other. The
dimensions of the shafts are 12-cm long and 2.5-cm diameter, see Figure (3.14c). Two shafts are
used; one to connect the first link with the base and the other is connected between first links and
second, the shaft is shown in Figure (3.14a).
Four bearings are used, two for the first link and two for the second. The bearing is shown in Figure
(3.14b). The material of the shafts and bearings is aluminum.
22
Figure (3.15a) Link dimension
The movement of the second link is by using toothed pulleys and belt to transform the motion from
the servo to the second link. The movement mechanisms are shown in Figure (3.18).
23
Figure (3.17) Gear mechanism of the first link
It is used for mounting the links of the arm on it. The base of the arm is shown in Figure (3.19).
24
3.2.7. Steering mechanism of the cart:
The steering mechanism is shown in Figure (3.21). The maximum steering angle of the mobile
robot is from (+30 to -30 degrees) controlled by a servo motor.
25
Figure (3.23) SCARA robotic arm after the assembly process
26
3.2.11. The final project:
After assembling the robotic arm and the cart of the mobile robot, we reach our final step by
putting the arm on the straight platform. That makes the final project accurately balanced as shown
in Figure (3.26).
27
CHAPTER 4
MODELING AND SIMULATION
In this chapter, the models of the robot are derived and the simulation process is illustrated.
28
Table (4.1) Link coordinate parameters
1 0 0 0 𝜃1
2 0 0.28 0.05 𝜃2
3 𝜋 0.22 𝑑3 + 0.05 0
Since
if
cos(ϕ) sin(ϕ) 0 X
sin(ϕ) −cos(ϕ) 0 Y
0T3 =[ ]
0 0 −1 Z
0 0 0 1
Then
Z = d2 − d3 – d4
So
d3 = d2 − d4 − Z ..................................... (1)
29
𝑋 2 + 𝑌 2 −𝑎1 2 − 𝑎2 2
Cos(q2) =
2∗𝑎1 ∗𝑎2
X = k1*cos(q1) - k2*sin(q1),
Y = k1*sin(q1) + k2*cos(q1),
Where
k1 = α1 + α2 *cos(q2),
k2 = α2 * sin(q2).
If
r = +√𝑘1 2 + 𝑘2 2
and
γ = atan2(k2, k1),
then
k1 = r * cos(γ),
k2 = r * sin(γ).
𝑋
= cos(𝛾) ∗ cos(𝑞1) − sin(𝛾) ∗ sin(𝑞1)
𝑟
𝑌
= cos(𝛾) ∗ sin(𝑞1) + sin(𝛾) ∗ cos(𝑞1)
𝑟
So
𝑋
cos(γ+q1) = 𝑟
𝑌
sin(γ + q1) = 𝑟
γ + q1 = atan2(y, x)
30
and so
31
Figure (4.3) A* search algorithm
Figure (4.4a) Original path generated from A* search Figure (4.4b) Smoothed path
32
Figure (4.5) Bicycle model of the car
We might wish to follow a path that is defined as some locus on the xy-plane. The path come
from a sequence of coordinates generated by a motion planner, such as discussed above.
The robot maintains a distance d* behind the path and we formulate an error:
That we regulate to zero by controlling the robot’s velocity using a proportional integral (PI)
controller. The integral term is required to provide a finite velocity demand v* when the following
error is zero.
𝑣 ∗ = 𝑘𝑣 ∗ 𝑒 + 𝑘𝑖 ∗ ∫ 𝑒 𝑑𝑡…………………………………….(5)
The second controller steers the robot toward the target which is at the relative angle
𝑦 ∗ −𝑦
𝛩 ∗ = 𝑡𝑎𝑛−1 𝑥 ∗−𝑥 ……………………………………………....(6)
and a simple proportional controller turns the steering wheel so as to drive the robot toward the
target.
33
4.3 SCARA Robotic Arm Simulation
A software developed in MATLAB is equipped with a GUI for simulating the performance of
SCARA manipulator motion. The interface panel includes entries for different analyses, such as
forward kinematics, inverse kinematics, path construction by teach through and joints/Cartesian
space trajectories. Figure (4.6) below shows a screenshot for the developed software GUI.
The developed software can a coronate any 6 DOF or less serial manipulator. It has the
following capabilities:
1. Plotting the robot from D-H table inputs as shown in the Figure (4.6) above.
2. Calculating the inverse kinematics as shown in Figure (4.7).
Figure (4.7) (a) Inverse Kinematic GUI program (b) right solution (c) left solution.
34
3. Comparing joints torques between right and left solutions, Figure (4.8) shows a torque
comparison between the joints of the robot when it moves through a predefined trajectory.
4. Generating Trajectory in joint space and Cartesian space, Figure (4.9) shows the generated
trajectory. The user just enters the initial and final position of the robot and the trajectory will
be generated automatically.
The simulation analysis for SCARA manipulator using the developed software in MATLAB
could give a clear picture of the arm characteristics with respect to the proposed application.
35
4.4 Mobile Robot Simulation
The mobile robot simulation is implemented using Anaconda software. Anaconda is a
freemium open source distribution of the Python and R programming languages for large-scale data
processing, predictive analytics, and scientific computing, that aims to simplify package management
and deployment. Package versions are managed by the package management system conda. [26]
The simulation of the mobile car is shown in Figure (4.10). The red circles are the obstacles, the
black curve is the original path generated by A* search, and the blue curve is the mobile robot
motion trial to follow the original curve. The performance of the mobile robot is enhanced by
changing the values of the PID parameters of its control scheme.
The simulation showed the correction of the proposed A*search algorithm to move the mobile
robot from given points to a destination which obstacles are avoided. It also illustrated the effect of
changing the PID parameters on the path following task and helped in choosing the most appropriate
gain values.
36
CHAPTER 5
SOFTWARE DESIGN AND IMPLEMENTATION
5.1 Introduction
The main controller of the project is raspberry pi 3 model B. It is a general-purpose computer,
usually with a Linux operating system as shown in Figure (5.1), with the ability to run multiple
programs. It is more complicated to use than an Arduino. It can run a full Linux based operating
system and has hardware support for SPI, I2C and UART.
Many programming languages can be used, including Python, C/C++, Java, Ruby and more.
This allows to implement a powerful control for systems, such as the autonomous mobile robots,
while keeping low-level access to the GPIO pins, used to read digital information from sensors, or to
control motors.
The programming language used in the project is Python. It has the following advantages:
37
▪ Artificial intelligence: Python is widely used for artificial intelligence, with packages for a
number of applications including General AI, Machine Learning, Natural Language
Processing and Neural Networks.
The algorithm also applies the required smoothen to the generated path. Having the smoothed path
generated, the robot starts moving along the path. At each grid point the controller checks if the goal
point is reached, otherwise the motion is continued.
If the mobile robot has reached its goal points, the controller starts moving the arm motors to move
and grasp or release the object based on the inverse kinematics algorithm and trajectory estimated.
If the mobile robot is programmed to another points, the cycle is repeated, otherwise, the motion is
ended and the program stops.
While the mobile robot is in motion, if it receives a signal the attached sensors about the proximity of
an object, the motion stops and wouldn’t be continued unless the path is clear. A flowchart summary
for the project is shown in Figure (5.2).
38
Figure (5.2) Flow chart summary
39
5.3 SCARA robotic arm software
The software that runs the motion of the SCARA manipulator is briefly as follows:
1. The user inters the position of the object in [x, y, z], then the joints angles are
calculated using the inverse kinematic equations (explained in chapter 4). The inverse
kinematic code is shown below:
if sqrt(X**2 + Y**2) > 50 or sqrt(X**2 + Y**2) < 31.2 or Z > (d2-d4) or Z < -30:
return
else:
#Calculation of Theta(2)
Cos_q2 = ((X**2)+(Y**2)-(a1**2)-(a2**2))/(2*a1*a2)
Sin_q2a = 0
Sin_q2b = 0
else:
Sin_q2a = sqrt(1-(Cos_q2**2))
Sin_q2b = -sqrt(1-(Cos_q2**2))
Theta2_a = atan2(Sin_q2a,Cos_q2)
Theta2_b = atan2(Sin_q2b,Cos_q2)
#Calculation of Theta(1)
K1 = a1+(a2*Cos_q2)
K2_a = a2*Sin_q2a
K2_b = a2*Sin_q2b
40
Theta1_a = atan2(Y, X)-atan2(K2_a, K1)
#Calculation of d3
d3 = d2 - d4 - Z
#----------------------
if angle == 'r':
if (Config=='R'):
T[0] = b
elif (Config=='L'):
T[0] = b
if (Config=='R'):
T[0] = b
elif (Config=='L'):
T[0] = b
return T
41
2. A trajectory is generated from initial to final position. The trajectory code is shown
below; the user can choose the type of trajectory (cubic or quadratic):
tf = max(t)
if space == 'cart':
# Quadratic
if traj == 5:
a0_1 = q0[0]
a3_1 = (10*(qf[0]-q0[0]))/(tf**3)
a4_1 = (-15*(qf[0]-q0[0]))/(tf**4)
a5_1 = (6*(qf[0]-q0[0]))/(tf**5)
42
q1 = a0_1 + (a3_1*(t**3)) + (a4_1*(t**4)) + (a5_1*(t**5))
q1 = q1*deg
a0_2 = q0[1];
a3_2 = (10*(qf[1]-q0[1]))/(tf**3)
a4_2 = (-15*(qf[1]-q0[1]))/(tf**4)
a5_2 = (6*(qf[1]-q0[1]))/(tf**5)
q2 = q2*deg
a0_3 = q0[2];
a3_3 = (10*(qf[2]-q0[2]))/(tf**3)
a4_3 = (-15*(qf[2]-q0[2]))/(tf**4)
a5_3 = (6*(qf[2]-q0[2]))/(tf**5)
43
qf[2] = myMap(qf[2], 30, 0, 0, 30)
q3 = (len(q2)) * [qf[2]]
q = q.transpose()
q = np.around(q, decimals = 1)
v = np.array([v1, v2])
v = v.transpose()
v = np.around(v, decimals = 4)
a = np.array([a1, a2])
a = a.transpose()
a = np.around(a, decimals = 4)
# Cuibic
elif traj == 3:
a0_1 = q0[0]
a2_1 = (qf[0]-q0[0])*(3/(tf*tf))
a3_1 = -(qf[0]-q0[0])*(2/(tf*tf*tf))
44
q1 = q1 * deg
v1 = (2*a2_1*t) + (3*a3_1*t**2)
a1 = (2*a2_1) + (6*a3_1*t)
a0_2 = q0[1]
a2_2 = (qf[1]-q0[1])*(3/(tf*tf));
a3_2 = -(qf[1]-q0[1])*(2/(tf*tf*tf));
q2 = q2*deg
v2 = (2*a2_2*t) + (3*a3_2*t**2)
a2 = (2*a2_2) + (6*a3_2*t)
a0_3 = q0[2]
a2_3 = (qf[2]-q0[2])*(3/(tf*tf));
a3_3 = -(qf[2]-q0[2])*(2/(tf*tf*tf));
q3 = (len(q2)) * [qf[2]]
45
q = q.transpose()
q = np.around(q, decimals = 1)
v = np.array([v1, v2])
v = v.transpose()
v = np.around(v, decimals = 4)
a = np.array([a1, a2])
a = a.transpose()
a = np.around(a, decimals = 4)
self.coord_update(x, y, z)
return (q, v, a)
46
5.4 The Mobile Robot Code
The code that runs the mobile robot motion based on the A* search is explained as follows:
1. The workspace is divided into grids using grid-based algorithm as shown in Figure
(5.3a). The user inters a matrix of the workspace with zeros and ones, one means there
is obstacle in that grid as shown in Figure (5.3b) or zero means there is no obstacle.
Figure (5.3a) Girds of the workspace Figure (5.3b) Grids matrix example
2. The path from initial to final position is generated using the technic of Artificial
intelligence (A* Search). The path planning code is shown below:
#class plan: used for finding the best and cheap path from start to goal
#By the use of A star Search (Artificail Inteligence)
class plan:
def __init__(self, grid, init, goal, cost = 1):
self.cost = cost
self.grid = grid
self.init = init
self.goal = goal
self.make_heuristic(grid, goal, self.cost)
self.path = []
self.spath = []
# --------
# make heuristic function for a grid
47
abs(j - self.goal[1])
# ------------------------------------------------
# A* for searching a path to the goal
def astar(self):
if self.heuristic == []:
raise ValueError("Heuristic must be defined to run A*")
# internal motion parameters
delta = [[-1, 0], # go up
[ 0, -1], # go left
[ 1, 0], # go down
[ 0, 1]] # do right
closed[self.init[0]][self.init[1]] = 1
x = self.init[0]
y = self.init[1]
h = self.heuristic[x][y]
g=0
f=g+h
open = [[f, g, h, x, y]]
found = False # flag that is set when search complete
resign = False # flag set if we can't find expand
count = 0
else:
# remove node from list
open.sort()
open.reverse()
48
next = open.pop()
x = next[3]
y = next[4]
g = next[1]
else:
# expand winning element and add to new open list
for i in range(len(delta)):
x2 = x + delta[i][0]
y2 = y + delta[i][1]
if x2 >= 0 and x2 < len(self.grid) and y2 >= 0 \
and y2 < len(self.grid[0]):
if closed[x2][y2] == 0 and self.grid[x2][y2] == 0:
g2 = g + self.cost
h2 = self.heuristic[x2][y2]
f2 = g2 + h2
open.append([f2, g2, h2, x2, y2])
closed[x2][y2] = 1
action[x2][y2] = i
count += 1
invpath = []
x = self.goal[0]
y = self.goal[1]
invpath.append([x, y])
while x != self.init[0] or y != self.init[1]:
x2 = x - delta[action[x][y]][0]
y2 = y - delta[action[x][y]][1]
x = x2
y = y2
invpath.append([x, y])
self.path = []
49
for i in range(len(invpath)):
self.path.append(invpath[len(invpath) - 1 - i])
# ------------------------------------------------
# this is the smoothing function
if self.path == []:
raise ValueError("Run A* first before smoothing path")
change = tolerance
while change >= tolerance:
change = 0.0
for i in range(1, len(self.path)-1):
for j in range(len(self.path[0])):
aux = self.spath[i][j]
self.spath[i][j] += weight_data * \
(self.path[i][j] - self.spath[i][j])
self.spath[i][j] += weight_smooth * \
(self.spath[i-1][j] + self.spath[i+1][j]
- (2.0 * self.spath[i][j]))
if i >= 2:
self.spath[i][j] += 0.5 * weight_smooth * \
(2.0 * self.spath[i-1][j] - self.spath[i-2][j]
- self.spath[i][j])
if i <= len(self.path) - 3:
self.spath[i][j] += 0.5 * weight_smooth * \
(2.0 * self.spath[i+1][j] - self.spath[i+2][j]
- self.spath[i][j])
50
3. The robot moves along the generated path using PID control. The control code is
shown below:
def run(grid, init, orientation, goal, spath, params, printflag = False, distance =
1, timeout = 100):
myrobot = robot()
myrobot.set(init[0], init[1], orientation)
myrobot.set_noise(steering_noise, distance_noise, measurement_noise)
robotPos_x = []
robotPos_y = []
robot_orientation = []
steeringAngles = []
cte = 0.0
err = 0.0
N =0
index = 0 # index into the path
else:
diff_cte = - cte
inti_cte = 0.0
# ----------------------------------------
# compute the CTE
robotPose = [myrobot.x, myrobot.y, myrobot.orientation]
51
#u is the robot estimate projectes onto the path segment:
u = (drx * dx + dry * dy) / (dx**2 + dy**2)
# spath_x = spath[index][0]
# spath_y = spath[index][1]
if u >1.0 :
index += 1
# ---------------------------------------
#PID
steer = - params[0] * cte - params[1] * diff_cte - params[2] * inti_cte
robotPos_x.append(myrobot.x)
robotPos_y.append(myrobot.y)
robot_orientation.append(myrobot.orientation * 180/pi)
steeringAngles.append(steeringAngle)
if not myrobot.check_collision(grid):
print('##### Collision ####')
err += (cte ** 2)
N += 1
if printflag:
print(myrobot, cte, index, u)
print([myrobot.check_goal(goal), myrobot.num_collisions,
myrobot.num_steps])
return [myrobot.check_goal(goal), robotPos_x, robotPos_y,
robot_orientation, steeringAngles]
52
4. The robot checks for goal at every step or grid point, the check_goal code is shown
below:
def check_goal(self, goal, threshold = 1.0):
dist = sqrt((float(goal[0]) - self.x) ** 2 + (float(goal[1]) - self.y) ** 2)
return dist < threshold
The full code of the mobile robot is given in appendix B.
53
CHAPTER 6
PRACTICAL RESULTS
6.1 Introduction
Engineering projects usually have a difference between real behavior and simulation
because of errors caused by environment and hardware equipment so the practical tests are necessary
to evaluate the system performance and improve until getting the best match between simulated and
real results.
54
6.3.1 Analysis the Errors
1. The error of the distance is mostly caused by the variance of the battery voltage. This affects
the motor speed and results eventually in a deviation from the given path.
2. A considerable reason for the error in the steering angle is the inequality of mass distribution
of the vehicle components that results in an inequality of the moment of inertia about the
vehicle axes.
55
CHAPTER 7
CONCLUSION AND FUTURE DEVELOPMENT
This report described the design and fabrication processes of an autonomous mobile SCARA
manipulator. A mobile car equipped with PID control was developed to carry a 3 DOF SCARA
manipulator and move autonomously on the floor. A*search algorithm was implemented to allow the
car to choose the best possible path in terms of the shortest distance. The manipulator was designed
grip and release objects on a certain height. A raspberry-pi controller was programmed via python to
coordinate the overall motion of the car and the manipulator. The kinematic and dynamic models for
the car and the manipulator were derived and the performance was simulated in MATLAB and
python environments. In practical experimentation, the overall performance was tested and found
satisfactory. We hope this graduation project will open a wide door for the potential research
capabilities in robotics available in our department and serve a forward step towards the development
of the industrial society surrounding us.
1- Equipping the robot with a camera, stationary or attached to the robot, to extract the map
instead of entering the data manually.
2- The accuracy of the movement of the car can be enhanced by adding encoders to the
motors of the car.
Finally, it is our wished that the project may get developed further and finds an upcoming group to
work on it.
56
REFRENCES
[1] Introduction to robotics, [https://en.wikibooks.org/wiki/Robotics/Introduction] accessed October-
15-2017.
[4] Ganesh S. Hegde, (2006), A Text Book On Industrial Robotics,1st Edition, Laxim Publication.
[11] John J. Craig, 2005. Introduction to Robotics Mechanics and Control, 3rd Edition. Boston, Ma:
Addison Wesley.
[12] Forward Kinematics, [online] available at: https://en.m.wikipedia.org, accessed January 4 2018.
[13] Inverse Kinematics, [online] available at: https://en.m.wikipedia.org, accessed January 4 2018.
[14] F. C. Park and K. M. Lynch, 2012. Introduction to Robotics Mechanics, Planning, And Control,
Cambridge University Press.
[15] Firebots: autonomous Fire Detecting Robots report, Waterloo university, [online] available at:
https://eng.uwaterloo.ca/~smasiada/FirebotsReport.
[16] Mark W. Spong, Seth Hutchinson, And M. Vidyas,1989, Robot Dynamics and Control 2nd
Edition, Wiley and Sons.
57
[17] Introducing the raspberry pi 3 [https://hackaday.com/2016/02/28/introducing-the-raspberry-pi
3/]
58
Appendix A
Robotics Arm Codes
import math
import numpy as np
np.set_printoptions(threshold=np.nan)
pi = math.pi
cos = math.cos
sin = math.sin
sqrt = math.sqrt
atan2 = math.atan2
deg = 180/pi
rad = pi/180
a1 = 28
a2 = 32 #link = 22 , gripper = 10
d2 = 5
d4 = 5
class RobotArm:
59
self.q1 = q1
self.q2 = q2
self.d3 = d3
self.x = T[0]
self.y = T[1]
self.z = T[2]
self.q1 = q1
self.q2 = q2
self.d3 = d3
self.x = x
self.y = y
self.z = z
q1 = q1 * rad
q2 = q2 * rad
d3 = d3 * rad
DH = np.matrix([[0, 0, 0, q1],
Y = DH[2, :]
60
Z = DH[1, :]
C = DH[0, :]
[sin(Y[0, 3])*cos(Y[0, 0]), cos(Y[0, 3])*cos(Y[0, 0]), -sin(Y[0, 0]), -sin(Y[0, 0])*Y[0, 2]],
[sin(Y[0, 3])*sin(Y[0, 0]), cos(Y[0, 3])*sin(Y[0, 0]), cos(Y[0, 0]), cos(Y[0, 0])*Y[0, 2]],
[0, 0, 0, 1]])
[sin(Z[0, 3])*cos(Z[0, 0]), cos(Z[0, 3])*cos(Z[0, 0]), -sin(Z[0, 0]), -sin(Z[0, 0])*Z[0, 2]],
[sin(Z[0, 3])*sin(Z[0, 0]), cos(Z[0, 3])*sin(Z[0, 0]), cos(Z[0, 0]), cos(Z[0, 0])*Z[0, 2]],
[0, 0, 0, 1]])
[sin(C[0, 3])*cos(C[0, 0]), cos(C[0, 3])*cos(C[0, 0]), -sin(C[0, 0]), -sin(C[0, 0])*C[0, 2]],
[sin(C[0, 3])*sin(C[0, 0]), cos(C[0, 3])*sin(C[0, 0]), cos(C[0, 0]), cos(C[0, 0])*C[0, 2]],
[0, 0, 0, 1]])
Tr = Tr1*Tr2*Tr3
Roll = q1+q2
Roll = Roll*deg
Tr = np.around(Tr, decimals=4)
return T
if sqrt(X**2 + Y**2) > 50 or sqrt(X**2 + Y**2) < 31.2 or Z > (d2-d4) or Z < -30:
61
return
else:
#Calculation of Theta(2)
Cos_q2 = ((X**2)+(Y**2)-(a1**2)-(a2**2))/(2*a1*a2)
Sin_q2a = 0
Sin_q2b = 0
else:
Sin_q2a = sqrt(1-(Cos_q2**2))
Sin_q2b = -sqrt(1-(Cos_q2**2))
Theta2_a = atan2(Sin_q2a,Cos_q2)
Theta2_b = atan2(Sin_q2b,Cos_q2)
#Calculation of Theta(1)
K1 = a1+(a2*Cos_q2)
K2_a = a2*Sin_q2a
K2_b = a2*Sin_q2b
#Calculation of d3
d3 = d2 - d4 - Z
62
if angle == 'r':
if (Config=='R'):
T[0] = b
elif (Config=='L'):
T[0] = b
if (Config=='R'):
T[0] = b
elif (Config=='L'):
T[0] = b
return T
tf = max(t)
63
if space == 'cart':
if traj == 5:
a0_1 = q0[0]
a3_1 = (10*(qf[0]-q0[0]))/(tf**3)
a4_1 = (-15*(qf[0]-q0[0]))/(tf**4)
a5_1 = (6*(qf[0]-q0[0]))/(tf**5)
q1 = q1*deg
64
a1 = (6*a3_1*t) + (12*a4_1*(t**2)) + (20*a5_1*(t**3))
a0_2 = q0[1];
a3_2 = (10*(qf[1]-q0[1]))/(tf**3)
a4_2 = (-15*(qf[1]-q0[1]))/(tf**4)
a5_2 = (6*(qf[1]-q0[1]))/(tf**5)
q2 = q2*deg
a0_3 = q0[2];
a3_3 = (10*(qf[2]-q0[2]))/(tf**3)
a4_3 = (-15*(qf[2]-q0[2]))/(tf**4)
a5_3 = (6*(qf[2]-q0[2]))/(tf**5)
q3 = (len(q2)) * [qf[2]]
q = q.transpose()
65
q = np.around(q, decimals = 1)
v = np.array([v1, v2])
v = v.transpose()
v = np.around(v, decimals = 4)
a = np.array([a1, a2])
a = a.transpose()
a = np.around(a, decimals = 4)
elif traj == 3:
a0_1 = q0[0]
a2_1 = (qf[0]-q0[0])*(3/(tf*tf))
a3_1 = -(qf[0]-q0[0])*(2/(tf*tf*tf))
q1 = q1 * deg
v1 = (2*a2_1*t) + (3*a3_1*t**2)
a1 = (2*a2_1) + (6*a3_1*t)
a0_2 = q0[1]
a2_2 = (qf[1]-q0[1])*(3/(tf*tf));
a3_2 = -(qf[1]-q0[1])*(2/(tf*tf*tf));
66
q2 = a0_2 + (a2_2*(t**2)) + (a3_2*(t**3))
q2 = q2*deg
v2 = (2*a2_2*t) + (3*a3_2*t**2)
a2 = (2*a2_2) + (6*a3_2*t)
a0_3 = q0[2]
a2_3 = (qf[2]-q0[2])*(3/(tf*tf));
a3_3 = -(qf[2]-q0[2])*(2/(tf*tf*tf));
q3 = (len(q2)) * [qf[2]]
q = q.transpose()
q = np.around(q, decimals = 1)
v = np.array([v1, v2])
v = v.transpose()
v = np.around(v, decimals = 4)
a = np.array([a1, a2])
a = a.transpose()
a = np.around(a, decimals = 4)
67
# Update the current pos and joint angle
self.coord_update(x, y, z)
return (q, v, a)
def __repr__(self):
2. Servo Code:
import time
import math
import Adafruit_PCA9685
pwm = Adafruit_PCA9685.PCA9685()
frequency = 60
pwm.set_pwm_freq(frequency)
68
#%%%%%%%%%%%
#Finding the min and max pulse length for the servo by (Mohammed Rizq)
t = 1/frequency
time_per_tic = t/4096
#So, the min and max pulse length can be found as follows:
#%%%%%%%%%%%
pwm.set_pwm(channel, 0, int(pulseWidth))
69
3. Ultrasonic Code:
#Libraries
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO_TRIGGER = 16
GPIO_ECHO = 20
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
def getDistance():
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
70
StartTime = time.time()
StopTime = time.time()
# save StartTime
while GPIO.input(GPIO_ECHO) == 0:
StartTime = time.time()
while GPIO.input(GPIO_ECHO) == 1:
StopTime = time.time()
#get 10 results and find the avarage to reduce the random error
Ultrasonic_Resolution = 10
distMatrix = []
for i in range(Ultrasonic_Resolution):
dist = distance
distMatrix.append(dist)
time.sleep(0.04)
dist = sum(distMatrix)/Ultrasonic_Resolution
return dist
71
4. DC-Motor Code:
GPIO.setmode(GPIO.BCM)
#Linear
IN_1 = 24
IN_2 = 25
#gripper
IN_3 = 18
IN_4 = 23
GPIO.setwarnings(False)
GPIO.setup(IN_1, GPIO.OUT)
GPIO.setup(IN_2, GPIO.OUT)
GPIO.setup(IN_3, GPIO.OUT)
GPIO.setup(IN_4, GPIO.OUT)
GPIO.output(IN_1, GPIO.LOW)
GPIO.output(IN_2, GPIO.LOW)
GPIO.output(IN_3, GPIO.LOW)
GPIO.output(IN_4, GPIO.LOW)
72
def forward():
GPIO.output(IN_1, GPIO.HIGH)
GPIO.output(IN_2, GPIO.LOW)
def reverse():
GPIO.output(IN_2, GPIO.HIGH)
GPIO.output(IN_1, GPIO.LOW)
def motorStop():
GPIO.output(IN_1, GPIO.LOW)
GPIO.output(IN_2, GPIO.LOW)
GPIO.output(IN_3, GPIO.HIGH)
GPIO.output(IN_4, GPIO.LOW)
GPIO.output(IN_4, GPIO.HIGH)
GPIO.output(IN_3, GPIO.LOW)
GPIO.output(IN_4, GPIO.LOW)
GPIO.output(IN_3, GPIO.LOW)
def linearMotion(goal):
init = getDistance()
73
if goal < init:
init = getDistance()
print(init)
sleep(0.5)
forward()
motorStop()
init = getDistance()
print(init)
sleep(0.5)
reverse()
motorStop()
motorStop()
74
5. Raspberry piCode for the Robotics Arm:
import servoLibrary
import DC_Motor
#Linear
IN_1 = 24
IN_2 = 25
#gripper
IN_3 = 18
IN_4 = 23
#car
IN_5 = 22
IN_6 = 27
GPIO.setwarnings(False)
GPIO.setup(IN_1, GPIO.OUT)
GPIO.setup(IN_2, GPIO.OUT)
GPIO.setup(IN_3, GPIO.OUT)
GPIO.setup(IN_4, GPIO.OUT)
GPIO.setup(IN_5, GPIO.OUT)
GPIO.setup(IN_6, GPIO.OUT)
75
#Function(1)
if moduleType == 'pick':
print("module is pick")
DC_Motor.gripper('Open')
sleep(1)
print("gripper Stop...")
DC_Motor.gripper('Stop')
DC_Motor.linearMotion(desiredHigh)
DC_Motor.gripper('Close')
sleep(1)
print("gripper Stop...")
DC_Motor.gripper('Stop')
DC_Motor.reverse()
76
sleep(3)
print("module is drop")
DC_Motor.linearMotion(desiredHigh)
DC_Motor.gripper('Open')
sleep(1)
print("gripper Stop...")
DC_Motor.gripper('Stop')
DC_Motor.reverse()
sleep(6)
#Function(2)
77
sleep(servoSpeed)
armModule(desiredPos_1[2], 'pick')
## sleep(15)
sleep(servoSpeed)
armModule(desiredPos_2[2], 'drop')
#Function
78
servoLibrary.moveServo(q[i-1, 1], motor_2_Channel)
sleep(servoSpeed)
armModule(7, 'pick')
## sleep(15)
sleep(servoSpeed)
armModule(7, 'drop')
#Function(3)
def cartMotion():
79
q,v,a = scara.moveRobot('cart', x, y, z, time, 5, 'L')
## print(q[i-1, 0])
sleep(servoSpeed)
## print(q[len(q)-1, 2])
DC_Motor.linearMotion(q[len(q)-1, 2])
#Function(5)
def linearTest():
DC_Motor.linearMotion(desiredHigh)
#Function(6)
def robotLinearMotion():
z = input("Enter Z: ")
for i in range(len(q)):
80
servoLibrary.moveServo(q[i-1, 0], 15)
DC_Motor.linearMotion(z)
sleep(servoSpeed)
for i in range(len(q2)):
sleep(servoSpeed)
servoSpeed = 0.02
81
## servoLibrary.moveServo(q[i-1, 0], 15)
## sleep(servoSpeed)
#main loop
try:
while True:
## cartMotion()
## linearTest()
print(scara)
except KeyboardInterrupt:
GPIO.output(IN_1, GPIO.LOW)
GPIO.output(IN_2, GPIO.LOW)
GPIO.output(IN_3, GPIO.LOW)
GPIO.output(IN_4, GPIO.LOW)
GPIO.cleanup()
82
Appendix B:
Mobile Robot Codes
#class plan: used for finding the best and cheap path from start to goal
#By the use of A star Search (Artificail Inteligence)
class plan:
# --------
# init:
# creates an empty plan
#
# --------
#
# make heuristic function for a grid
83
def make_heuristic(self, grid, goal, cost):
self.heuristic = [[0 for row in range(len(grid[0]))]
for col in range(len(grid))]
for i in range(len(self.grid)):
for j in range(len(self.grid[0])):
self.heuristic[i][j] = abs(i - self.goal[0]) + \
abs(j - self.goal[1])
# ------------------------------------------------
#
# A* for searching a path to the goal
#
#
def astar(self):
if self.heuristic == []:
raise ValueError("Heuristic must be defined to run A*")
closed[self.init[0]][self.init[1]] = 1
84
x = self.init[0]
y = self.init[1]
h = self.heuristic[x][y]
g=0
f=g+h
else:
# remove node from list
open.sort()
open.reverse()
next = open.pop()
x = next[3]
y = next[4]
g = next[1]
85
else:
# expand winning element and add to new open list
for i in range(len(delta)):
x2 = x + delta[i][0]
y2 = y + delta[i][1]
if x2 >= 0 and x2 < len(self.grid) and y2 >= 0 \
and y2 < len(self.grid[0]):
if closed[x2][y2] == 0 and self.grid[x2][y2] == 0:
g2 = g + self.cost
h2 = self.heuristic[x2][y2]
f2 = g2 + h2
open.append([f2, g2, h2, x2, y2])
closed[x2][y2] = 1
action[x2][y2] = i
count += 1
self.path = []
for i in range(len(invpath)):
self.path.append(invpath[len(invpath) - 1 - i])
86
# this is the smoothing function
if self.path == []:
raise ValueError("Run A* first before smoothing path")
change = tolerance
while change >= tolerance:
change = 0.0
for i in range(1, len(self.path)-1):
for j in range(len(self.path[0])):
aux = self.spath[i][j]
self.spath[i][j] += weight_data * \
(self.path[i][j] - self.spath[i][j])
self.spath[i][j] += weight_smooth * \
(self.spath[i-1][j] + self.spath[i+1][j]
- (2.0 * self.spath[i][j]))
if i >= 2:
self.spath[i][j] += 0.5 * weight_smooth * \
(2.0 * self.spath[i-1][j] - self.spath[i-2][j]
- self.spath[i][j])
if i <= len(self.path) - 3:
self.spath[i][j] += 0.5 * weight_smooth * \
(2.0 * self.spath[i+1][j] - self.spath[i+2][j]
87
- self.spath[i][j])
class robot:
# init:
# creates robot and initializes location/orientation to 0, 0, 0
self.x = float(new_x)
self.y = float(new_y)
self.orientation = float(new_orientation) % (2.0 * pi)
# set_noise:
# sets the noise parameters
#
88
def set_noise(self, new_s_noise, new_d_noise, new_m_noise):
# makes it possible to change the noise parameters
# this is often useful in particle filters
self.steering_noise = float(new_s_noise)
self.distance_noise = float(new_d_noise)
self.measurement_noise = float(new_m_noise)
# --------
# check:
# checks of the robot pose collides with an obstacle, or
# is too far outside the plane
# apply noise
steering2 = random.gauss(steering, self.steering_noise)
distance2 = random.gauss(distance, self.distance_noise)
steerAngle = 90 + steering2*180/pi
steerAngle = (steerAngle - 60) * (60 - 120) / (120 - 60) + 120
print(steerAngle)
# Execute motion
turn = tan(steering2) * distance2 / res.length #from corke equation 4.2
## print(res)
return res, steerAngle
# --------
# sense:
#
def sense(self):
# --------
# measurement_prob
# computes the probability of a measurement
#
# calculate Gaussian
error = exp(- (error_x ** 2) / (self.measurement_noise ** 2) / 2.0) \
/ sqrt(2.0 * pi * (self.measurement_noise ** 2))
error *= exp(- (error_y ** 2) / (self.measurement_noise ** 2) / 2.0) \
/ sqrt(2.0 * pi * (self.measurement_noise ** 2))
return error
def __repr__(self):
return '[x=%.5f y=%.5f orient=%.5f]' % (self.x, self.y, self.orientation * 180 / pi)
## return '[%.5f, %.5f]' % (self.x, self.y)
#__________________________________
#------------------------------------------
def run(grid, init, orientation, goal, spath, params, printflag = False, distance = 1, timeout =
100):
myrobot = robot()
myrobot.set(init[0], init[1], orientation)
myrobot.set_noise(steering_noise, distance_noise, measurement_noise)
robotPos_x = []
robotPos_y = []
robot_orientation = []
steeringAngles = []
92
cte = 0.0
err = 0.0
N =0
index = 0 # index into the path
cte = 0.0
err = 0.0
N =0
else:
diff_cte = - cte
inti_cte = 0.0
# ----------------------------------------
# compute the CTE
# spath_x = spath[index][0]
# spath_y = spath[index][1]
if u >1.0 :
index += 1
# ----------------------------------------
#PID
steer = - params[0] * cte - params[1] * diff_cte - params[2] * inti_cte
robotPos_x.append(myrobot.x)
robotPos_y.append(myrobot.y)
robot_orientation.append(myrobot.orientation * 180/pi)
steeringAngles.append(steeringAngle)
if not myrobot.check_collision(grid):
print('##### Collision ####')
err += (cte ** 2)
94
N += 1
if printflag:
print(myrobot, cte, index, u)
accuracy = 0.1
95
2. Raspberry pi Code for the mobile robot:
GPIO.setmode(GPIO.BCM)
IN_1 = 22
IN_2 = 27
GPIO.setwarnings(False)
GPIO.setup(IN_1, GPIO.OUT)
GPIO.setup(IN_2, GPIO.OUT)
GPIO.output(IN_1, GPIO.LOW)
GPIO.output(IN_2, GPIO.LOW)
f = GPIO.PWM(IN_1, 50)
r = GPIO.PWM(IN_2, 50)
f.start(0)
r.start(0)
def moveForward(maxSpeed = 30):
f.start(0)
print("Moving")
f.ChangeDutyCycle(maxSpeed)
##___________________##
def pause():
print("Pause")
f.ChangeDutyCycle(0)
r.ChangeDutyCycle(0)
96
##__________________##
def stop():
print("Stoping")
f.stop()
r.stop()
##_________________##
def moveReverse(speed):
r.start(0)
print("Reverse")
r.ChangeDutyCycle(speed)
##_________________##
def check_obstacles(channel_1, channel_2, channel_3, threshold = 15):
dist_1 = IRreading(channel_1)
if dist_1 <= threshold:
return True
else:
dist_2 = IRreading(channel_2)
if dist_2 <= threshold:
return True
else:
dist_3 = IRreading(channel_3)
if dist_3 <= threshold:
return True
##_________________##
def returnTo(Angles, maxSpeed, delay):
Angles.reverse()
for i in range(len(Angles)):
print(Angles[i])
servoLibrary.moveServo(Angles[i] - 10, 13)
moveReverse(maxSpeed-15)
sleep(delay)
if i == len(Angles) -1:
97
stop()
##_________________##
def chooseNextAction():
print("___________________________________")
print("Choose the next action: ")
print(" 1 - Return to previous point")
print(" 2 - Go to new postion")
print(" 3 - nothing")
x = input("Enter the number of the action : ")
return x
##____________________##
steering_noise = 0.0
distance_noise = 0.1
measurement_noise = 0.3
weight_data = 0.1
weight_smooth = 0.2
p_gain = 2.0
d_gain = 6.0
i_gain = 0.0
distance = 0.1
speed = 0.18/1 # 0.12 m/sec
delay = distance/speed
maxSpeed = 30
98
try:
x=2
while x == 2:
init = []
goal = []
xi = input("Enter initial x : ")
init.append(xi)
yi = input("Enter initial y : ")
init.append(yi)
xf = input("Enter final x : ")
goal.append(xf)
yf = input("Enter final y : ")
goal.append(yf)
myPath = plan(grid, init, goal)
myPath.astar()
myPath.smooth(weight_data, weight_smooth)
mySmothPath = myPath.spath
slop = ((mySmothPath[1][1]) - (mySmothPath[0][1])) / ((mySmothPath[1][0]) -
(mySmothPath[0][0])+0.0000001)
print(steeringAngles[i])
print("[x=%.5f y=%.5f orient=%.5f]" % (robotPos_x[i], robotPos_y[i], orint[i]))
# servoLibrary.moveServo(steeringAngles[i] - 10, 13)
moveForward(maxSpeed)
sleep(delay)
if i == len(steeringAngles) -1:
stop()
x = chooseNextAction()
if(x == 1):
returnTo(steeringAngles, maxSpeed, delay)
100