Movement path drawing

The robot has a distance sensor and if there is an obstacle it will change the path.
This is the code:

   ////////////////////////////////////////////////////////
  //          Arduino Obstacle Avoiding Robot v2.0      //             
 //            By Aarav Garg - 2021                    //
////////////////////////////////////////////////////////

//including the libraries
#include <NewPing.h>
#include <SoftwareSerial.h>
#include <Servo.h>
#include "HCPCA9685.h"

//defining pins and variables
#define TRIG_PIN D3 
#define ECHO_PIN D4 
#define MAX_DISTANCE 200

#define turn_amount 500

//defining motors,servo,sensor
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); 
  
//defining global variables
boolean goesForward=false;
int distance = 100;

#define  I2CAdd_1 0x40
#define  I2CAdd_2 0x41

int pos1 = 200;
int pos2 = 220;
int pos3 = 180;
int pos4 = 0;
int pos5 = 130;
int pos6 = 100;
int pos7=50;
int pos8=260;
int pos9=140;
const float delay1 = 0.5;
int delay2 = 500;

/* Create an instance of the library */
HCPCA9685 HCPCA9685_1(I2CAdd_1);
HCPCA9685 HCPCA9685_2(I2CAdd_2);

void setup() {
       // Initialise both modules
  HCPCA9685_1.Init(SERVO_MODE);
  HCPCA9685_2.Init(SERVO_MODE);
  // Wake both devices up
  HCPCA9685_1.Sleep(false);
  HCPCA9685_2.Sleep(false);
  unsigned int Pos;

/* standing */
  HCPCA9685_1.Servo(2, pos4);
  HCPCA9685_1.Servo(5, pos4);
  HCPCA9685_1.Servo(8, pos4);
  HCPCA9685_1.Servo(11, pos4);
  HCPCA9685_1.Servo(14, pos4);
  HCPCA9685_2.Servo(1, pos4);

  HCPCA9685_1.Servo(1, pos4);
  HCPCA9685_1.Servo(4, pos4);
  HCPCA9685_1.Servo(7, pos4);
  HCPCA9685_1.Servo(10, pos4);
  HCPCA9685_1.Servo(13, pos4);
  HCPCA9685_2.Servo(0, pos4);

  HCPCA9685_1.Servo(0, pos2);
  HCPCA9685_1.Servo(3, pos3);
  HCPCA9685_1.Servo(6, pos2);
  HCPCA9685_1.Servo(9, pos2);
  HCPCA9685_1.Servo(12, pos3);
  HCPCA9685_1.Servo(15, pos2);

  delay(delay2);

  for (int Pos = pos4; Pos < pos5; Pos++)
  {
    HCPCA9685_1.Servo(1, Pos);
    HCPCA9685_1.Servo(4, Pos);
    HCPCA9685_1.Servo(7, Pos);
    HCPCA9685_1.Servo(10, Pos);
    HCPCA9685_1.Servo(13, Pos);
    HCPCA9685_2.Servo(0, Pos);
    delay(delay1);
  }

  delay(delay2);

  for (int Pos = pos4; Pos < pos6; Pos++)
  {
    HCPCA9685_1.Servo(2, Pos);
    HCPCA9685_1.Servo(5, Pos);
    HCPCA9685_1.Servo(8, Pos);
    HCPCA9685_1.Servo(11, Pos);
    HCPCA9685_1.Servo(14, Pos);
    HCPCA9685_2.Servo(1, Pos);
    delay(1);
  }
  /////
  Serial.begin(9600);
  HCPCA9685_2.Servo(2, 220);  
//  myservo.write(90); 
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
}

void loop() {
// moveForward();
// goesForward=false;
// moveForward(); 
 
 int distanceR = 0;
 int distanceL =  0;
 delay(40);
 Serial.println(distance);
 
 if(distance<=15)
 {
  Serial.println("Object Detected");
  moveStop();
  delay(100);
  moveBackward();
  delay(300);
  moveStop();
  delay(200);
  distanceR = lookRight();
  Serial.print("Distance Right = ");
  Serial.println(distanceR);
  delay(1000);
  distanceL = lookLeft();
  Serial.print("Distance Left = ");
  Serial.println(distanceL);
  delay(1000);

  if(distanceR>=distanceL)
  {
    turnRight();
    moveStop();
  }
  else
  {
    turnLeft();
    moveStop();
  }
 }
 else
 {
  moveForward();
 }

 //reseting the variable after the operations
 distance = readPing();
}

int lookRight()
{
    HCPCA9685_2.Servo(2, 130);
//    myservo.write(0); 
    delay(500);
    int distance = readPing();
    delay(100);
    HCPCA9685_2.Servo(2, 220);
//    myservo.write(90); 
    return distance;
}

int lookLeft()
{
    HCPCA9685_2.Servo(2, 310);
//    myservo.write(180); 
    delay(500);
    int distance = readPing();
    delay(100);
    HCPCA9685_2.Servo(2, 220);
//    myservo.write(90); 
    return distance;
    delay(100);
}

int readPing() { 
  delay(70);
  int cm = sonar.ping_cm();
  if(cm==0)
  {
    cm = 250;
  }
  return cm;
}

void moveStop() {

  } 
  
/* Move Forward */
void moveForward() {
  for (int Pos = pos5 ; Pos >= pos7 ; Pos--) {
    HCPCA9685_1.Servo(1, Pos);
    delay(delay1);
  }

      for (int Pos = pos7 ; Pos <= pos5 ; Pos++) {
    HCPCA9685_1.Servo(1, Pos);
    delay(delay1);
  }
}

/* moveBackward */
void move_backward() {
  for (int Pos = pos5 ; Pos >= pos7 ; Pos--) {
    HCPCA9685_1.Servo(4, Pos);
    delay(delay1);
  }

    for (int Pos = pos7 ; Pos <= pos5 ; Pos++) {
    HCPCA9685_1.Servo(4, Pos);
    delay(delay1);
  }
}

/* turn Right */
void turnRight() {
  for (int Pos = pos5 ; Pos >= pos7 ; Pos--) {
    HCPCA9685_1.Servo(7, Pos);
    delay(delay1);
  }

      for (int Pos = pos7 ; Pos <= pos5 ; Pos++) {
    HCPCA9685_1.Servo(7, Pos);
    delay(delay1);
  }
}

/* turn Left */
void turnLeft() {
/////
  for (int Pos = pos5 ; Pos >= pos7 ; Pos--) {
    HCPCA9685_1.Servo(10, Pos);
    delay(delay1);
  }

      for (int Pos = pos7 ; Pos <= pos5 ; Pos++) {
    HCPCA9685_1.Servo(10, Pos);
    delay(delay1);
  }
}

/* Stop Move */
void moveStop() {
}

Sorry I don't know how to collect the moves in to a list. I don't know how to send the data in blocks to arduino for path drawing. I defined four directions for the robot in my code and I can control the robot with buttons but how can I control the robot when I draw a path? Can you edit the blocks or code?

You will need to think up a way to represent the actual movements of your robot as a data stream for it to send the app via BlueTooth.

For simplicity, you might set up a BT BlueTooth stream in the sketch, and add a BT.println() command to each of your 5 turn, move, and stop procedures to send a distinctive code letter to the app each time that procedure is called.

In your app, set up a fast Clock Timer to check for those incoming codes and add them to a global list moves_list, initially create empty list.

Add to your app a Play button to walk the list and move a Sprite or Ball on a Canvas accordingly.

Do you mean some thing like this code? And these blocks that have clock? you sent these blocks in other topic.

  if (BT.available() >0) {
    state = BT.read();
    Serial.print(state);

    if(state == 'F'){
      move_forward();
//      state="";
  }
  
    if(state == 'f'){
      move_stop();
//      state="";
  }
  
    if(state == 'B'){
      move_backward();
//      state="";
  }

    if(state == 'b'){
      move_stop();
//      state="";
  }

    if(state == 'R'){
      turn_right();
//      state="";
  }

    if(state == 'r'){
      move_stop();
//      state="";
  }
  
    if(state == 'L'){
      turn_left();
//      state="";
  }

    if(state == 'l'){
      move_stop();
//      state="";
  }

But How can I use above blocks for developing the below blocks?

ead570f56c554cb5daf9fa604462ec3fac766778_2_178x499

And about the button you said I want to use 'follow path' button for sending data from app to arduino.

I hope you are reading and understanding each piece of code you find, as to its purpose and how it achieves that purpose.

It's likely that you will have to think up new code to achieve your purpose.

This is not a shopping expedition.

Dear ABG thank you for sharing your experience with me. I don't expect you two do all the project. I understand the code and tested it with the robot. And I want to develop it now. But problem is this:
For example when I press forward button, the app sends character 'F' to arduino and it does this with this block:
image

But in path drawing I don't know what should I send to arduino because the robot doesn't move in a specific direction.

It would help to learn the x,y directions of the Canvas and decide on an initial Direction for the robot.

Let's assume North (descending y, constant x) is the direction the robot is initially facing, and that it is at the center of the Canvas.

Work from there.

If the robot then turns right, it will be facing East. Movement East has increasing x, and constant y.

Do you see the pattern?

Yes I understand what you say. assume robot is in this coordinates: X=200 , Y=100. and it wants to go to these coordinates: X=100 , Y=50. And the path is a direct line. And in my code I have four directions(move forward,move backward,turn right,turn left). At first robot should turn 45 degrees to right and then move forward. How can I relate these directions that I have in my arduino code to the coordinates? witch relation is there between them? And I don't know should I send the coordinates or the directions to the arduino? If I send coordinates, How can I define the arduino witch direction should move?

You will need to know How to Work With Lists

1 Like

Thanks

I found a relation between directions and (x,y) coordinates. I made several lists and added the relations to them. and defined the repeating time of each direction with the relations. And at least when the user presses execute button, the app send 50 and (60 or 70). when It sends 50, robot will move forward. And it sends the repeating time of move forward too with start repeating block. And the it sends 60 or 70. if it send 60 robot will turn right and if it send 70 robot will turn left. And it sends the repeating time of turning too. But when I draw the path and then press execute 'run time error' displays in app and the app doesn't work. whats the problem? These are the blocks:


drawRouteForCar2.aia (8.9 KB)

This is the serial monitor:

This is app error:

I see at least two problems

You have empty sockets

You apply text operations to lists and list operations to text

I had no time to examine your logic or data structure

1 Like

Why does your Canvas have obstacles on it? Can't the robot feel collisions?

How do you know the real obstacles match the Canvas obstacles?

Why use dragging for drawing when Turtle Graphic commands match the robot capability closer? (Search this board)

I found Those blocks in app inventor and I didn't change them because they was working correctly. I just added some lists to change the x,y coordinates to my directions in the code and each direction repeataion time And some blocks to bluetooth connection and sending data to arduino.
TIMAI2 sent these blocks here. and they are working correctly:

my problem is after the above blocks where I added new blocks.


about obstacles to begin with I ignore and I want to work on it in my arduino code.

What is global forward repeating time?

It is the time that the robot will execute move forward (move at forward direction).
I edited the blocks and this error is displayed in app. why round block can't round arguments? witch block should I use?


This is the last edition:
drawRouteForCar2(1).aia (8.8 KB)

You can't round a list.

You can only round a number.

A list is not a number.

Got that?

1 Like

But I used round for numbers not lists

The error message says otherwise.

What do you think those [] marks mean?

1 Like

So how can I round the values of a list?

You can round the values before you add them to the list, one by one.

1 Like