programming for autonomous pick and place robot

for this semester i am required to build an autonomous pick and place robot, where it must pick up a 1 N load at point A and place it at another point which is point B. I'm lost on how i am going to program the robot to travel from point A to point B while carrying a load. the sensor that we are allowed to use are only IR sensor and the hc-sr04 ultrasonic sensor. the track does not have any line to follow and i could only rely on the ultrasonic sensor. Are there any suggestion or tips on how i should program the robot?

jimbeet: for this semester i am required to build an autonomous pick and place robot, where it must pick up a 1 N load at point A and place it at another point which is point B. I'm lost on how i am going to program the robot to travel from point A to point B while carrying a load. the sensor that we are allowed to use are only IR sensor and the hc-sr04 ultrasonic sensor. the track does not have any line to follow and i could only rely on the ultrasonic sensor. Are there any suggestion or tips on how i should program the robot?

Can we then assume you have already built the robot? What makes the robot move? What makes the robot pick up something? Can your robot hold something after it has been picked up? How far apart ore points A and B? Are they in a straight line? You could be a lot more forthcoming with information. Paul

Those things called code tags and using them to put your formatted code into will go a long way towards getting help on your subject of interest. If you do not use code tags this topic will devolve into a bunch of messages on how to use this forum and not much to do with addressing your issue.

In the reply box or edit box, you’ll see a </> thingy. That’s a code tag.

How about looking at links like this: https://forum.arduino.cc/index.php?topic=97455.0, and putting your code into code tags?

Help us help you.

duration = pulseIn(frontechoPin, HIGH);
duration = pulseIn(leftechoPin, HIGH);
duration = pulseIn(rightechoPin, HIGH);

A very obvious problem. You need separate variables for the duration of each direction

Please follow the advice on posting a programming question given in Read this before posting a programming question

In particular note the advice to Auto format code in the IDE and to use code tags when posting code here as it prevents some combinations of characters in code being interpreted as HTML commands such as italics, bold or a smiley character, all of which render the code useless

no i haven’t built it yet because there’s been a changed of plan regarding the project. I am required to only do the programming for the robot and not build the robot physically. because of this it is hard for me to identify whether my code is functioning or not. for the robot movement, I’m using 4 6v dc gearmotor and the robot will also have an arm and a gripper which is for the pick and place part. the arm and gripper will consists of 3 servo motor to control the claw angle movement. there will also be an IR sensor at the gripper to detect the load. this is a code i came up with, I’m not sure if it works, please comment on which part I need to improve. i have attached a file which contains the picture of the track. The must be picked up at point 1 and placed at point 2.

int fronttrigPin = 7;
int frontechoPin = 6;
int righttrigPin = 9;
int rightechoPin = 8;
int lefttrigPin = 3;
int leftechoPin = 5;
int IRsensorC = A0;
int SensorvalueC = 0;
int E1 = 10;
int M1 = 11;
int E2 = 12;
int M2 = 13;
int leftdistance=0,rightdistance=0,frontdistance=0;
#include <Servo.h>
Servo gripper;
Servo arm;
Servo arm2;
char incoming_byte = 0;
int value = 0;
int pos = 0;
#define MAX_DISTANCE = 200;
long duration, distance;

  


void setup() {
  pinMode(fronttrigPin, OUTPUT);       
pinMode(frontechoPin, INPUT);  
pinMode(righttrigPin, OUTPUT);         
pinMode(rightechoPin, INPUT);  
pinMode(lefttrigPin, OUTPUT);         
pinMode(leftechoPin, INPUT);
pinMode(M1, OUTPUT);
pinMode (M2, OUTPUT);
Serial.begin(9600);
  gripper.attach(A3);
  arm.attach(A4);
  arm2.attach(A5);
  pinMode(IRsensorC, INPUT);
    
}

void loop() 
{
duration = pulseIn(frontechoPin, HIGH);
duration = pulseIn(leftechoPin, HIGH);
duration = pulseIn(rightechoPin, HIGH);
distance = duration / 58.2; 
delay(10);
SensorvalueC = analogRead (IRsensorC);
  
  if (SensorvalueC <= 250) // gripping the load
  {
  gripper.write(90);
  }
  if ((frontdistance <10 )&(leftdistance <20)&(rightdistance <20)) // pick and place part
  {
    digitalWrite (M1, HIGH); // turn right facing the load
    analogWrite (E1,80);
    digitalWrite (M2, LOW);
    analogWrite (E2, 80);
    delay(500);
 digitalWrite (M1, HIGH); // stop to pickup load
    analogWrite (E1,0);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 0);
    arm.write (50);
    arm2.write (50);
    delay(10000);
    digitalWrite (M1, HIGH); //turn right after picking up load
    analogWrite (E1,80);
    digitalWrite (M2, LOW);
    analogWrite (E2, 80);
    arm.write (0);
    arm2.write (0);
    delay(500);
     digitalWrite (M1, HIGH); // go straight
    analogWrite (E1,80);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 80);
    delay (1000);
     digitalWrite (M1, LOW); // left turn
    analogWrite (E1,80);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 80);
    delay(500);
    digitalWrite (M1, HIGH); // go straight to place load
    analogWrite (E1,80);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 80);
    delay(10000);
      digitalWrite (M1, LOW); // left turn
    analogWrite (E1,80);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 80);
    delay(500);
     digitalWrite (M1, HIGH); // go straight
    analogWrite (E1,80);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 80);
    delay (1000);
    digitalWrite (M1, HIGH); // stop to place load
    analogWrite (E1,0);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 0);
    arm.write (50);
    arm2.write (50);
    gripper.write (0);
    delay(10000);
  } 
    
    
    
  }

TRACK.png

how do I separate the variable for each direction? @UKHeliBob

jimbeet: no i haven't built it yet because there's been a changed of plan regarding the project. I am required to only do the programming for the robot and not build the robot physically. because of this it is hard for me to identify whether my code is functioning or not

If you are not required to build the robot it's not at all clear to me why you would write the code - not least because you can't test it. I suspect you could count on the fingers of one hand the number of non-trivial programs in the world that were right first time.

I suggest you start with an English language description of all of the detailed decisions and actions that need to happen. Write one action on each line. It will be easier than writing code because you don't have to worry about syntax. And it will make it easier to think about the problem because it is in normal language.

If you do need to write actual code then it should be very straightforward to turn the detailed description into code - much easier than trying to invent code before the detailed description has been written.

...R

Could you use the new ping library for the untrasonics? By using the library to run the ultrasonics you'll get ultrasonic code that is a known good and will improve your chances of success.

As this project seems to be a school project, I'd expect there to be more comments in the code to explain the things.

The description given is frustratingly incomplete.

Where does the robot start? Does the robot have to search for the object or is the object placed neatly between the grippers?

What are the colored regions in the map? What is the significance of the dashed-line? What does '3' represent?

What is kinematic relationship between the "arm" servos and the gripper?

Looking at the code you provided I get the feeling you're not considering that loop() runs repeatedly. If "SensorvalueC" is less than or equal to "250" you close the gripper and proceed but what if the value is great than 250? You proceed without closing the gripper. And when the whole of loop() has run, it runs again, and again, and again etc.

Unless I'm misunderstanding something you need to consider the use of discrete operating "states";

  • robot is searching for the payload or waiting for the payload to be placed within its gripper space
  • robot closes gripper and raises (?) arm
  • robot backs away from pickup point
  • robot navigates to drop off point
  • robot lowers arm and opens gripper
  • robot backs away from placed load to safe standoff distance
  • robot idles

Each of these states would need to be a separate block of code executed in a "state machine"; very crudely, something like:

void RobotStateMachine( void )
{
    switch( stateRobot )
    {
        case    WAIT_FOR_PAYLOAD:
            //wait for IR sensor to detect object
            //allow some time for object to stop moving/person's hand to move away
        break;

        case    CLOSE_GRIPPER_RAISE:
            //close the gripper and raise the arm
        break;

        case    BACK_AWAY_FROM_PICKUP_POINT:
            //if necessary, back out of pickup point
            //run motors as required for short time and/or measure distances or use odometry if available
        break;

        case    NAVIGATE_TO_DROPOFF_POINT:
            //use sonar and odometry if available to navigate to drop-off point
        break;

        case    LOWER_GRIPPER_RELEASE:
            //at drop-off point, lower the arm and release the gripper
            //wait some time for object release and settle
        break;

        case    BACK_TO_STANDOFF_DISTANCE:
            //after release, move off some distance away from just-released payload
        break;

        case    ROBOT_IDLE:
            //task complete and robot is at safe backoff distance
            //do nothing (maybe blink some lights etc; robot movement is stopped)
        break;

    }//switch
    
}//RobotStateMachine

jimbeet: how do I separate the variable for each direction? @UKHeliBob

Use a different variable for each of them

frontDuration = pulseIn(frontechoPin, HIGH);
leftDuration = pulseIn(leftechoPin, HIGH);
rightDuration = pulseIn(rightechoPin, HIGH);

If you are not involved in building the robot then:

You don't know if the gear motors have any end stop indication. You don't know if the gear motors send any position feedback. You don't know if the gripper is open, closed or somewhere in between. You don't know if the gripper is gripping anything. You don't know how far the robot has traveled. You don't know if the robot is moving.

And so much more.

As an example of Robin's statement about writing programs that cannot be tested as they are being written, I wrote perhaps 1,000 programs for various computers and various commercial applications over 35 years . Only ONE time did a program work correctly the first time. This was a report printing program and due to the computer not being available, I had to "desk check" the program for at least a week. Any more complex program takes many iterations of fix and test. Yours will too.

Paul

@paul@robin I could not agree more with you guys .Actually ,at first, we were required to build the robot physically but the situation has changed due to the pandemic. right now we are in a lockdown in our home and our class are fully online. because of this we can not go to campus to get the materials or use the appliance to build the robot. this is why the school told us to do only the programming instead. they expect us students to try the codes using a simulator online but to me its quite hard to do so because we’ re building a robot that requires physical evaluation in order to know the functioning of it.

@blackfin the robot will start at the space left to point 1. there will be a 1N load there and the robot need to travel there to pick up the load . then travel all the way to point 2 to place the load. Point 3 is just a space for the robot to self park.

@UKHeliBob I have separated the variable as you advice me to. this is my updated code

int fronttrigPin = 7;
int frontechoPin = 6;
int righttrigPin = 9;
int rightechoPin = 8;
int lefttrigPin = 3;
int leftechoPin = 5;
int IRsensorC = A0;
int SensorvalueC = 0;
int E1 = 10;
int M1 = 11; //left motot
int E2 = 12;
int M2 = 13; // right motor
int leftdistance=0,rightdistance=0,frontdistance=0;
#include <Servo.h>
Servo gripper;
Servo arm;
Servo arm2;
char incoming_byte = 0;
int value = 0;
int pos = 0;
#define MAX_DISTANCE = 200;
long frontduration;
long leftduration;
long rightduration;
long distance;

  


void setup() {
  pinMode(fronttrigPin, OUTPUT);       
pinMode(frontechoPin, INPUT);  
pinMode(righttrigPin, OUTPUT);         
pinMode(rightechoPin, INPUT);  
pinMode(lefttrigPin, OUTPUT);         
pinMode(leftechoPin, INPUT);
pinMode(M1, OUTPUT);
pinMode (M2, OUTPUT);
Serial.begin(9600);
  gripper.attach(A3);
  arm.attach(A4);
  arm2.attach(A5);
  pinMode(IRsensorC, INPUT);
}
  void forward()
  {
    digitalWrite (M1, HIGH); // go straight
    analogWrite (E1,80);
    digitalWrite (M2, HIGH);
    analogWrite (E2, 80);  
  }
void reverse ()
{
  digitalWrite (M1, LOW); 
  analogWrite (E1,80);
  digitalWrite (M2, LOW);
  analogWrite (E2, 80);  
}
void rightturn ()
{
  digitalWrite (M1, HIGH); // turn right facing the load
  analogWrite (E1,80);
  digitalWrite (M2, LOW);
  analogWrite (E2, 80);
}
void leftturn()
{
  digitalWrite (M1, LOW); // left turn
  analogWrite (E1,80);
  digitalWrite (M2, HIGH);
  analogWrite (E2, 80); 
}
void stop ()
{
 digitalWrite (M1, HIGH); // stop to pickup load
 analogWrite (E1,0);
 digitalWrite (M2, HIGH);
}
void pickup()
{
 digitalWrite (M1, HIGH); // stop to pickup load
 analogWrite (E1,0);
 digitalWrite (M2, HIGH);
 analogWrite (E2, 0);
 arm.write (50);
 arm2.write (50); 
} 
void place ()
{
 digitalWrite (M1, HIGH); // stop to place load
 analogWrite (E1,0);
 digitalWrite (M2, HIGH);
 analogWrite (E2, 0);
 arm.write (50);
 arm2.write (50);
 gripper.write (0);

}
void loop() 
{
frontduration = pulseIn(frontechoPin, HIGH);
leftduration = pulseIn(leftechoPin, HIGH);
rightduration = pulseIn(rightechoPin, HIGH);
frontdistance = frontduration / 58.2; 
leftdistance = leftduration / 58.2;
rightdistance = rightduration / 58.2;
delay(10);
SensorvalueC = analogRead (IRsensorC);
  
 if (frontdistance >20)
 {
  void forward();
 }
 if ((frontdistance < 5)&(leftdistance <10)&(rightdistance < 10))
 {
  void rightturn ();
  delay(500);
  void forward ();
  delay (200);
  void pickup ();
  delay (5000);
  void rightturn ();
  delay(500);
  void forward ();
  delay (500);
  void leftturn ();
  delay (500);
  void forward ();
  delay (10000);
  void lefturn ();
  delay (500);
  void forward ();
  delay (200);
  void place ();
  delay (5000);
  void reverse ();
  delay (500);
  void leftturn ();
  delay (500);
  void stop ();
  
  
 }
    
  }

jimbeet: this is why the school told us to do only the programming instead. they expect us students to try the codes using a simulator online but to me its quite hard to do so because we' re building a robot that requires physical evaluation in order to know the functioning of it.

If you write the the English language description that I suggested you will, at least, have a specification against which the code can be reviewed. And if you are working as part of a team the description would make it much easier to get input from other team members as no knowledge of coding is required.

Writing that sort of description is an essential prerequisite for any non-trivial program.

I've spent most of yesterday and today writing a description for changes I want to make to a project. Once I had the description set out clearly changing the code was straightforward. Writing the description also brought to light some alternative approaches and allowed me to consider them and choose between them.

...R

alright i will do that thank you for the suggestion :slight_smile: @Robin2

the robot will start at the space left to point 1. there will be a 1N load there and the robot need to travel there to pick up the load

Even that sounds like a non-trivial task.

Consider starting with a simulator, like the free MobotSim 2D robot simulator package (downloadable at various sites), which allows you to write code for a virtual differential drive robot with ultrasonic sensors.

It is not trivial to navigate from point A to B, especially if there are obstacles, so solve that problem first.