Lab Experiments: Robotics
Lab Experiments: Robotics
Lab Experiments
Robotics
Prof. Prashant Upadhyay
Contents
Experiment No. 1 .................................................................................................................................... 2
Control of One Degree of Freedom Revolute Type Robot Arm ......................................................... 2
Experiment No. 2 .................................................................................................................................... 4
To study the open loop characteristics of DC motor and experiment it with Matlab simulation File. 4
Experiment No. 3 .................................................................................................................................... 7
Controlling directions of the Motor .................................................................................................... 7
Theory: .................................................................................................................................................... 7
Experiment No. 4- Position Control of Motor using PID algorithm ........................................................ 9
Aim: Study of Position Control of Motor using PID algorithm ............................................................ 9
Experiment No. 5 .................................................................................................................................. 16
Reading Rotary Encoder for position control application................................................................. 16
Experiment No. 6 .................................................................................................................................. 20
Reading Potentiometer as Encoder for position control application in Robotic ARM. .................... 20
Experiment No.7 ................................................................................................................................... 21
Servo Motor Control ......................................................................................................................... 21
Experiment No.8 ................................................................................................................................... 23
AIM: Study of ROS Basics and creation of CATKIN workspace .................................................... 23
ROS Workspace ................................................................................................................................ 23
Experiment 9: Study of ROS NODES .................................................................................................. 25
Create a ROS Node ........................................................................................................................... 25
Experiment No: 10 ................................................................................................................................ 33
Aim: to move the turtle inside the window in a vertical D shape of radius 1 unit. ........................... 33
Procedure .......................................................................................................................................... 33
Output ............................................................................................................................................... 35
In this system the robot the DC motor moves the robot arm to the proper angular position
according to the input. In this system the robot the DC motor moves the robot arm to the
proper angular position according to the in
TORQUE
Thetam = motor shaft angle position J= All inertia connected to the motor shaft. D= All
friction connected to motor shaft.
Equation 1: Torque Equation
>> v=10;
>> angle=90;
>> Kp=v/angle;
>>G=tf([1],[0.4177 1.11 0]);
>> sysclose=feedback(G,Kp);
>> step(sysclose);
Experiment No. 2
To study the open loop characteristics of DC motor and experiment it with
Matlab simulation File.
Theory
The electric circuit of the armature and the free body diagram of the rotor for the DC motor
are shown in the following figure:
From the figure above we can write the following equations based on Newton's law
combined with Kirchhoff's law:
The impulse response and step response for an open loop dc motor system is given below.
The dc motor is assumed to have the following parameters:
moment of inertia of the rotor (J) =0.75e-07 Kg m2
damping ratio of the mechanical system (b) = 1e-08 Nm/rad/s
electromotive force constant ( Kt = Km= K ) = 0.0033 (in SI units)
armature resistance (R)= 1.27 ohm
armature inductance (L)= 0.000035 H
Reference:
https://www.numerade.com/ask/question/1-a-three-link-manipulator-with-rotational-joints-and-
prismatic-joint-is-shown-in-figure-calculate-the-velocity-of-the-tip-of-the-arm-as-a-jacobian-give-the-
answer-in-two-froms-in-terms-of-frame-3-and/
Experiment No. 3
Controlling directions of the Motor
Apparatus: Battery Pack, Motor Driver, MD10, Arduino Board, Connecting wires
Theory:
Procedure: 1) Read MD10 data sheet shared in repository and identify name of input signals,
name of output port and power signals name and other required details
2 Output Port
Theory: Closed loop control system is an essential topic for embedded systems, bringing together
actuators and sensors with the control algorithm in software. For example, motor speed can be
controlled by varying the PWM duty cycle used to drive the motor. This is the open-loop control.
However, due to the lack of feedback, the actual motor speed could not be verified. This is important
because driving the motor with the same PWM duty cycle does not guarantee the motor to run at the
same speed under all circumstances. A motor will run faster in load free condition than under load
with the same PWM signal. In order to control the motor speed, we need to close the loop by adding
feedback of the actual motor speed to the controller.
Besides speed control, PID control system can also be used to control other parameters such as
position, temperature, water level, stability, etc.
Reference:1) https://github.com/Aklant-sahu/Embedded-Programming/blob/main/pid4/pid4.ino
2) https://softwareengineering.stackexchange.com/questions/186124/programming-pid-loops-in-c
int temp, counter1
=0,counter2=0,
prev_count1=0,prev_c
ount2=0;
int setpoint1=0,setpoint2=0;
double kp=0,ki=0,kd=0;
float error1=0,val1=0,prev_error1=0,cum_error1=0;
float error2=0,val2=0,prev_error2=0,cum_error2=0;
double curr_time1=0,prev_time1=0,dt1=0,rate1=0;
double curr_time2=0,prev_time2=0,dt2=0,rate2=0;
int inc=0;
double pii = 22/7;
double k_encoder = 200*pii/658;
double sp, rpm;
double prev_speed_time1=0,count_diff1=0;
#define dir1 4
#define pwm1 5
#define dir2 6
#define pwm2 7
#define wheel 100 // size in mm
#define gear 47
#define count_per_rev gear*7*4 // count per revolution
int motor1dir=LOW,motor2dir=HIGH;
int refdir1=LOW,refdir2=HIGH;
void setup() {
pinMode(2, INPUT_PULLUP); // internal pullup input pin 2
pinMode(3, INPUT_PULLUP); // internal pullup input pin 3
pinMode(18, INPUT_PULLUP); // internal pullup input pin 2
pinMode(19, INPUT_PULLUP);
//Setting up interrupt
//A rising pulse from encodenren activated A(). AttachInterrupt 0
is DigitalPin nr 2 on moust Arduino.
attachInterrupt(digitalPinToInterrupt(2), a1, CHANGE);
// attachInterrupt(digitalPinToInterrupt(3), b1, RISING);
attachInterrupt(digitalPinToInterrupt(18), a2, CHANGE);
// attachInterrupt(digitalPinToInterrupt(19), b2, RISING);
kp=1.5;
ki=0.00006;
kd=0;
setpoint1=2000;
prev_error1=0;
prev_time1=millis();
prev_speed_time1=millis();
setpoint2=2000;
prev_error2=0;
prev_time2=millis();
digitalWrite(dir1,LOW);
digitalWrite(dir2,HIGH);
Serial.begin (9600);
}
void loop() {
//
val1=Pidinc(counter1,prev_error1,prev_time1,cum_error1,kp,ki,kd,set
point1,1,dir1,motor1dir);
val2=Pidinc(counter2,prev_error2,prev_time2,cum_error2,kp,ki,kd,set
point2,1,dir2,motor2dir);
float valspeed=rpm(counter2,prev_speed_time2,count_diff);
// digitalWrite(dir1,LOW);
// digitalWrite(dir2,HIGH);
// analogWrite(pwm1,val1);
digitalWrite(dir2,motor2dir);
analogWrite(pwm2,val2);
}
void a1() {
// A is activated if DigitalPin nr 2 is going from LOW to HIGH
// Check pin 3 to determine the direction
if(digitalRead(3)==LOW) {
counter1++;
}else{
counter1--;
}
}
void b1() {
// ai1 is activated if DigitalPin nr 3 is going from LOW to HIGH
// Check with pin 2 to determine the direction
if(digitalRead(2)==LOW) {
counter1--;
}else{
counter1++;
}
}
void a2() {
// A is activated if DigitalPin nr 2 is going from LOW to HIGH
// Check pin 3 to determine the direction
if(digitalRead(19)==LOW) {
counter2++;
}else{
counter2--;
}
}
void b2() {
// ai1 is activated if DigitalPin nr 3 is going from LOW to HIGH
// Check with pin 2 to determine the direction
if(digitalRead(18)==LOW) {
counter2--;
}else{
counter2++;
}
}
float bound(float x, float x_min, float x_max) {
if (x < x_min) { x = x_min; }
if (x > x_max) { x = x_max; }
return x;
}
double Pidinc (double inp,float &prev_err,double &prev_ti,float
&cum_err,double kp,double ki,double kd,double setp,int flag,int
dirpin,int &dir,int refdir){
double err=setp-inp;
double crr=millis();
double dt=crr-prev_ti;
prev_ti=crr;
double rate=(err-prev_err)/dt;
prev_err=err;
if(abs(err)<0.1*setp ){
cum_err +=(err*dt);
}
else{
ki=0;
}
double out=kp*err + ki*cum_err + kd*rate;
// Serial.print(out);
//
// Serial.print(',');
if(inp>setp && out<0){
if(out<-255){
out=255;
}
else{
out=abs(out);
}
if(refdir==HIGH){
dir=LOW;
}
else if(refdir==LOW){
dir=HIGH;
}
}
else if(inp<setp && out<0){
if(out<-255){
out=255;
}
else{
out=abs(out);
}
if(refdir==HIGH){
dir=HIGH;
}
else if(refdir==LOW){
dir=LOW;
}
}
else{
dir=refdir;
out= bound(out, 0, 255);
}
if (flag==1){
Serial.print(inp);
Serial.print(',');
Serial.print(setp);
// Serial.print(',');
// Serial.print(out);
Serial.println();
}
return out;
}
float rpm(double inp,float &prev_count,double &prev_ti){
double time1 = millis() - prev_ti;
prev_ti=millis();
if(prev_count != inp){
count_diff = prev_count - inp;
}
if(count_diff <0){
count_diff = abs(count_diff) ;
sp = count_diff/time1;
}
sp = sp * k_encoder;
sp = sp * 60000; //distance travelled in 1 minute
sp = sp/(200*(22/7)); //Revolutions per minute
return sp;
}
Experiment No. 5
Reading Rotary Encoder for position control application.
Aim: To study the waveform generated by rotary encoder, and generate the logic to read and
interpret using Microcontroller/Arduino.
Experimental Setup:
Theory: Inside the encoder is a slotted disc that is connected to the common ground pin C. It
also contains two contact pins A and B, as shown below. When you turn the knob, A and B
come into contact with the common ground pin C in a particular order according to the
direction in which you are turning the knob.
When they come into contact with common ground, signals are generated. These signals are
90° out of phase with each other as one pin comes into contact with the common ground
before the other pin. This is called quadrature encoding.
From the generated waveform Logic can be generated to find out the direction of rotation of
Motion.
Procedure:
Resulting waveform:
int counter = 0;
int currentStateCLK;
int lastStateCLK;
String currentDir ="";
unsigned long lastButtonPress = 0;
void setup() {
void loop() {
// If last and current state of CLK are different, then pulse occurred
// React to only 1 state change to avoid double count
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
}
Reference:
1) https://lastminuteengineers.com/rotary-encoder-arduino-tutorial/
2) Arduino Cookbook by Michael Margolis
3) ROTARY ENCODER WITH INTERRUPTS - Arduino tutorial #12--https://youtu.be/gPLpPFmv-Zc
4) https://github.com/jumejume1/dc-motor-encoder/blob/master/dc_encoder.ino
Experiment No. 6
Reading Potentiometer as Encoder for position control application in Robotic
ARM.
Aim: To study the Potentiometer, and generate the logic to read and interpret using
Microcontroller/Arduino.
Program 1
#include <Servo.h>
Servo servo;
void setup() {
servo.attach(7); // put your setup code here, to run once:
servo.write(0);
delay(2000);
}
void loop() {
// put your main code here, to run repeatedly:
servo.write(90);
delay(1000);
servo.write(0);
delay(1000);
}
Program 2
#include <Servo.h>
Servo servo;
int angle=10;
void setup() {
// put your setup
servo.attach(8);
servo.write(angle);//code here, to run once:
void loop() {
// for(angle = 10; angle < 180; angle++)
{
servo.write(angle);
delay(15);
}
// now scan back from 180 to 0 degrees
for(angle = 180; angle > 10; angle--)
{
servo.write(angle);
delay(15); //put your main code here, to run repeatedly:
}
}
Experiment No.8
AIM: Study of ROS Basics and creation of CATKIN workspace.
Theory:
Linux Resources
CodeChef (Closed) 641
ROS Basics-
o ROS Workspace
Create Catkin Workspace 210
o ROS Package
o ROS Nodes
ROS Workspace
Catkin Workspace
catkin is the official build system of ROS and the successor to the original ROS build system,
rosbuild.
catkin combines CMake macros and Python scripts to provide some functionality on top of
CMake‟s normal workflow.
catkin was designed to be more conventional than rosbuild, allowing for better distribution of
packages, better cross-compiling support, and better portability.
1. Open up a terminal.
2. Create the root workspace directory. You can name your directory anything but by ROS
convention we will use catkin_ws as the name.
3. mkdir -p ~/catkin_ws/src
o Move to the newly created workspace
4. cd ~/catkin_ws/src
5. Initialize the catkin workspace.
6. catkin_init_workspace
Look for the statement “Workspace configuration appears valid”, showing that your catkin
workspace was created successfully. If you forgot to create the src directory or did not
run catkin init from the workspace root (both common mistakes), you‟ll get an error message
like “WARNING: Source space does not yet exist”.
OR
cd ~/catkin_ws
o Finish the creation of the workspace by building it. Note: Build your workspace after every
change in C++ scripts. Changes in the Python scripts don‟t need rebuilding.
catkin_make
9. Now your catkin workspace will have additional directories build, devel.
10. ls
11. Now to make your workspace visible to ROS. Source the setup file in the devel directory.
12. source ~/catkin_ws/devel/setup.bash
By doing this, all the packages that you create inside the src folder will be visible to ROS.
13. This setup.bash file of your workspace must be the source every time when you want to use
ROS packages created inside this workspace.
1. gedit ~/.bashrc
2. Add to the end: source ~/catkin_ws/devel/setup.bash
3. Save and close the editor.
Experiment 9: Study of ROS NODES
Theory:
A ROS Node is a piece of software/executable that uses ROS to communicate with other
ROS Nodes.
1. Navigate to pkg_ros_basics.
cd ~/catkin_ws/src/pkg_ros_basics
OR
roscd pkg_ros_basics
NOTE: roscd will work only if you have sourced setup.bash of your catkin workspace.
2. Create a scripts folder for your Python scripts and navigate into the folder.
mkdir scripts
cd scripts
touch node_hello_ros.py
5. The First line of all your Python ROS scripts should be the following shebang:
#!/usr/bin/env python3
#!/usr/bin/env python3
import rospy
def main():
if __name__ == '__main__':
try:
main()
except rospy.ROSInterruptException:
pass
chmod +x node_hello_ros.py
roscore
2. Once the roscore is up running, open a new termminal and run the ROS Node.
http://wiki.ros.org/ROS/Tutorials/UnderstandingNodes
References: http://wiki.ros.org/ROS/Tutorials/UnderstandingNodes
About rosrun
rosrun allows you to run an executable in an arbitrary package from anywhere without having to
give its full path or cd/roscd there first.
Usage:
<package> is nothing but the name of the package which you have created
using catkin_create_pkg command. This could also be the name of any other pre existing
package.
After creating a package, make a new scripts folder to store all the python files.
cd ~/catkin_ws/src/<package>
mkdir scripts
To create a python script, first, navigate inside the scripts folder using the cd command, and then
create the script using the touch command.
cd scripts
touch filename.py
Before running a new python file, you have to make it executable by running the following
command-
cd ~/catkin_ws/src/<package>/scripts
chmod +x filename.py
After creating a package, create a src folder to store all the cpp files in that folder.
cd ~/catkin_ws/src/<package>
mkdir src
To create a cpp file, first, navigate inside the src folder using the cd command, and then create the
file using the touch command.
cd src
touch filename.cpp
Now you can edit your cpp file, but for making it executable we have to edit
the CMakeLists.txt file which is present in the package.
add_executable(filename src/filename.cpp)
target_link_libraries(filename ${catkin_LIBRARIES})
cd ~/catkin_ws
catkin build
About
rosnode contains the rosnode command-line tool for displaying debug information about ROS
Nodes 16.
Note: For quick information about any command, be that outside of ROS, simply type the
command along with suffix --h or -help. This is a widely used concept among other Linux
commands for quick references. Here‟s an example for rosnode --h command
1. list
Let‟s figure out the arguments for the list sub-command. In a new terminal start the rosmaster:
roscore
rosnode list
Now the node named talker (node with word talker in it) will be printed on the terminal.
2. info
rosnode info /node_name displays information about a node, including publications and
subscriptions.
Let‟s figure out the arguments for the info sub-command. In a new terminal start the rosmaster:
roscore
3. kill
roscore
Note 1: Turtle should first cover the semicircle from the start point moving in counter-clockwise
motion with radius of 1 unit and finally move straight back to its initial location as shown above.
Any other orientation/order will result in partial score.
Procedure
Create package
First, create a workspace, Once done, compile and source the packages.
Navigate inside your catkin_ws/src directory. If your catkin workspace‟s name is catkin_ws &
is addressed at home location in your system, use-
cd ~/catkin_ws/src
For users who do not have git installed. Enter the following command for installation-
Krishi Bot package might take some time to clone, depending on your internet speed.
Install additional packages-
Finally, build the catkin workspace using catkin_make command. The setup is now complete!
NOTE: To build the package in the system, ensure that the terminal is pointing
at ~/catkin_ws directory and not in ~/catkin_ws/src. Furthermore, once
within ~/catkin_ws location, enter catkin_make.
After the package has been successfully built, do not forget to source it
source devel/setup.bash
For every new package cloned or created within the src of your catkin workspace, you
should build & source the workspace to proceed.
IMPORTANT NOTE:
The referred documentation about ROS packages, is in Python 2, but remember, ROS Noetic
runs on python 3. You should follow the resources given and implement your solution in Python
3.
Launch file can run multiple nodes, unlike a python/cpp script, at least in ROS. While in ROS2,
this is not the case. Do explore it. Please note that resources related to ROS 2 are not a part of
this competition.
Implementation
Now edit the task_0.py file (navigate the clones repo to find where it is) and implement your
logic. Do not forget to refer the learning resources 199 section.
3. Hints
1. The turtle needs to move in a vertical „D‟ shape with a radius of 1 unit during its sem-circular
motion.
o This radius should be sufficient to fit within the turtlesim window. However, making it rotate
circularly, with only velocities to control, is something to think about.
2. Use linear velocity as well as angular velocity with some combination to get this done.
3. Keep tracking the distance travelled to know when to stop. But do not limit yourself to this.
Feel free to use any methods as you wish, as far as it‟s a valid submission. You can refer
to Overview of rospy 190 for more hints.
Output
#! /usr/bin/env python3
import rospy
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
def pose_tell(pose:Pose):
rospy.loginfo(f"x {pose.x} y {pose.y}")
global count
msg=Twist()
if 7.52<pose.y<7.55 and 5.52<pose.x<5.55:
rospy.loginfo("Straight sequence started")
count=1
if count==1:
if 5.52<pose.x<5.55 and 5.55>pose.y>5.52:
msg.linear.x=0
msg.angular.z=0
else:
msg.linear.y=0.5
else:
msg.linear.x=1
msg.angular.z=1
pub.publish(msg)
if __name__=="__main__":
global count
count=0
rospy.init_node("task0")
pub=rospy.Publisher("/turtle1/cmd_vel",Twist,queue_size=10)
sub=rospy.Subscriber("/turtle1/pose",Pose,callback=pose_tell)
rospy.loginfo('node started')
rospy.spin()