Seeed-Studio / ModelAssistant

Seeed SenseCraft Model Assistant is an open-source project focused on embedded AI. 🔥🔥🔥
https://sensecraftma.seeed.cc/
Apache License 2.0
403 stars 46 forks source link

Grove and XIAO-esp32S3 startup for RoboCar #202

Closed hpssjellis closed 7 months ago

hpssjellis commented 7 months ago

@LynnL4 @stevehuang82

image

An old link that steve helped with https://github.com/HimaxWiseEyePlus/Seeed_Grove_Vision_AI_Module_V2/issues/3#issuecomment-1996194780

My Main RoboCar site, for wehich I used the Arduino PortentaH7 is at https://github.com/hpssjellis/robocar

My RoboCar has a few strange effects, that I can probably figure out myself but thought I should share what I am having issues with as they might be bugs in your setup.

  1. On startup there is about a 4 second lag before anything happens.
  2. The car runs full speed after the time lag
  3. Serial monitor shows errors until an object is detected, then the serial monitor prints out correct readings.
  4. When the first object is detected the car stops running at full speed and starts working fairly well
  5. AI.boxes()[0].score seems to keep the last reading instead of getting zeroed each loop.
  6. I am expecting a classification above 85% but I rarely see anything below 78% if I wanted a lower classification value can I set that from the XIAO side or is the lowest acceptable value pre-programmed into the Grove Model?

I am very new to programming the Grove vision AI V2 using the XIAO-esp32s3, can you see if there is anything obviously incorrect with my code. "No worries if you don't have time, I will be debugging over the next few weeks"

The code is fairly obvious it has one servo motor that turns left, center or right. The drive motor simple stops or starts at a preset speed.

/*
 * Connections XIAO-esp32s3 to Grove Vision AI V2 
 * GND to GND
 * 3V3 to 3V3
 * SDA (D4) to SDA grove
 * SCL (D5) to SCL Grove
 * 
 * 
 * Coonections XIAO-esp32S3 to Servo
 * D2 to Orange wire
 * 
 * Connections XIAO-esp32S3 to Big Motor Driver
 * D0 to top left 1   Digital turn
 * D6 to top left 3    PWM motor speed
 * D1 to top left 6     digital turn
 * 3V3 to top left 7
 * GND to top left 8
 * 
 * 
 * 
 * 
 */

#include <Seeed_Arduino_SSCMA.h>
#include <ESP32Servo.h>   // for XIAO-ESP32S3-Sense

SSCMA AI;
Servo myServo_D2;
int myMainSpeed = 37;   // slowest speed that the car moves on a charged battery

void setup(){
    AI.begin();
    Serial.begin(115200);

    // Stay away from pins D4 (SDA) and D5 (SCL) whiuch are used for I2C communication with the Grove board
    // D3 when both are connected is the reset pin so that messes things up.

    myServo_D2.attach(D2); // D2 should do PWM on XIOA
    pinMode(D6, OUTPUT);   // PWM 0 to 255
    pinMode(D1, OUTPUT);   // digital 0 to 1
    pinMode(D0, OUTPUT);   // digital 0 to 1

    analogWrite(D6, 0);      // have car stopped at beginning
                                // both off = glide, both on = brake (if motor can do that)
    digitalWrite(D0, 0);    // not needing to be attached
    digitalWrite(D1, 1);    // set one direction
}

void loop()
{
    if (!AI.invoke() ){

     AI.perf().prepocess;
     AI.perf().inference;
     AI.perf().postprocess;

     if (AI.boxes()[0].score > 85 ){
      Serial.print(String(AI.boxes()[0].score)+", ");
      analogWrite(D6, myMainSpeed);   // go medium  

      if( AI.boxes()[0].x < 100){
            Serial.println("Right");
            myServo_D2.write(110); // turn Right
      }
      else if(AI.boxes()[0].x >= 100 && AI.boxes()[0].x <= 150 ){

            Serial.println("Center");
            myServo_D2.write(90); // turn center
      }

      else if (AI.boxes()[0].x > 150) {
            Serial.println("Left");
            myServo_D2.write(70); // turn left
      }
     }
      else {
        Serial.println(String(AI.boxes()[0].score)+", None");
        analogWrite(D6, 0);   // No objects detected so stop
      }

    }

}
LynnL4 commented 7 months ago

Hi, Which model are you using? I should have the result of clearing the previous one with each invoke, I'll see if I can reproduce your problem https://github.com/Seeed-Studio/Seeed_Arduino_SSCMA/blob/1156339af757641d64258d4781f87f12320444df/src/Seeed_Arduino_SSCMA.cpp#L419

hpssjellis commented 7 months ago

@LynnL4 the model I am using on the Grove board I made using edgeimpulse, exported as an int8 quantized then converted from.lite to tflite for upload.

https://github.com/hpssjellis/robocar/blob/main/v3-0-0-grove-vision-ai-v2-and-xiao-esp32s3/cool-eye-fomo_vela.tflite

It just occured to me that the racing engine issue could be that D6 is being pulled high at startup, I can try a different GPIO for the motor PWM pin.

Thanks for looking into this.

I have tried zeroing AI.boxes()[0].score each loop which does seem promising but causes some other issue of the motor not having time to respond.

I will check the code you linked too, to see if I can access the classification cutoff value.

LynnL4 commented 7 months ago

Hi. Yes D6/D7 are being used as UART interface, so there may be some level changes that cause problems with the PWM control, maybe you can try changing the servo control to the D2

hpssjellis commented 7 months ago

Hi. Yes D6/D7 are being used as UART interface, so there may be some level changes that cause problems with the PWM control, maybe you can try changing the servo control to the D2

The servo is already on D2, it is the drive motor speed that is PWM D6. So in summary which pins are available on the XIAO when using the Grove board? So far I know D3, D6, D7 are in use. Does that mean D0, D1, D2, D4, D8, D9, D10 should be available? I know D8, D9, D10 could be used for SPI to get the image off the Grove board but if I am not using SPI can I use those pins?

By the way if you do try out my model here is the image it was trained on. The eyes can be printed and cut out.

image

LynnL4 commented 7 months ago

Hi If the pins you are using are not connected to the Grove Vision AI V2, then there shouldn't be any issues. As far as I know, all the interfaces on one side of the Grove Vision AI V2 are now occupied except for D2. 😅

hpssjellis commented 7 months ago

@LynnL4 I am still getting the weird errors for 4 to 10 seconds until the first correct reading. I did find out that the XIAO-Grove combination is actually resetting each time. Here is the debug message.

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x420019d4  PS      : 0x00060630  A0      : 0x82006e98  A1      : 0x3fcebd40  
A2      : 0x00000000  A3      : 0x3fc95810  A4      : 0x3fcba2c0  A5      : 0x00000004  
A6      : 0x3fcebf10  A7      : 0x80000001  A8      : 0x00000055  A9      : 0x3fcebd10  
A10     : 0x00000000  A11     : 0x00000001  A12     : 0x00000000  A13     : 0x00000bb8  
A14     : 0x3fcadd08  A15     : 0x3c030268  SAR     : 0x00000017  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x00000008  LBEG    : 0x400554b9  LEND    : 0x400554dd  LCOUNT  : 0x82004839  

Backtrace: 0x420019d1:0x3fcebd40 0x42006e95:0x3fcebd90

ELF file SHA256: dfd0fb4d4d853132

Rebooting...
ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0xa (SPI_FAST_FLASH_BOOT)
Saved PC:0x420274e6
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x44c
load:0x403c9700,len:0xbd8
load:0x403cc700,len:0x2a80
entry 0x403c98d0
hpssjellis commented 7 months ago

@LynnL4 I also found out that given a 9/10 chance for success I still picked the wrong pin for PWM. I tested each pin and here are my results.


    // PWM research on XIAO-ESP32S3 pins with Grove Vision AI V2 board:
    // Note on the grove board we only have PINS 3V3, GND, D4, D5 set

    // D0  PWM works no startup issue
    // D1  PWM works no startup issue
    // D2  PWM works no startup issue
    // D3  JUST don't use! When both boards connected, D3 is the reset pin.    
    // D4 (SDA) which is used for I2C communication with the Grove board
    // D5 (SCL) which is used for I2C communication with the Grove board
    // D6  TX UART pin, PWM works after a brief HIGH, shorter HIGH duration if pins set before AI.begin();

    // D7  RX UART pin  PWM works no startup issue
    // D8  PWM works no startup issue,  SCK SPI connection for Image data if needed from Grove Board
    // D9  PWM works no startup issue,  MISO SPI connection for Image data if needed from Grove Board 
    // D10 PWM works no startup issue,  MOSI SPI connection for Image data if needed from Grove Board
hpssjellis commented 7 months ago

Thank you. I have something that works for me. It still has the weird start where I get reboots until it detects the first object, but that does not really effect my RoboCar.

Here is working code for me and I think I can close this issue.


/*
 * Connections XIAO-esp32s3 to Grove Vision AI V2 
 * GND to GND
 * 3V3 to 3V3
 * SDA (D4) to SDA grove
 * SCL (D5) to SCL Grove
 * 
 * 
 * Coonections XIAO-esp32S3 to Servo
 * D2 to Orange wire
 * 
 * Connections XIAO-esp32S3 to Big Motor Driver
 * D0 to top left 1   Digital turn
 * D6 to top left 3    PWM motor speed
 * D1 to top left 6     digital turn
 * 3V3 to top left 7
 * GND to top left 8
 * 
 * 
 * 
 * 
 */

#include <Seeed_Arduino_SSCMA.h>
#include <ESP32Servo.h>   // for XIAO-ESP32S3-Sense

SSCMA AI;
Servo myServo_D2;
int myMainSpeed = 37;   // slowest speed that the car moves on a charged battery
int myDrivePwmPin = D0;

void setup(){
    Serial.begin(115200);

    pinMode(myDrivePwmPin, OUTPUT);   // PWM 0 to 255

    myServo_D2.attach(D2); // D2 should do PWM on XIOA
    // note the two drive pins on the big motor driver are just connected to GND and 3V3 respectively.

    // PWM research on XIAO-ESP32S3 pins with Grove Vision AI V2 board:
    // Note on the grove board we only have PINS 3V3, GND, D4, D5 set

    // D0  PWM works no startup issue
    // D1  PWM works no startup issue
    // D2  PWM works no startup issue
    // D3  JUST don't use! When both boards connected, D3 is the reset pin.    
    // D4 (SDA) which is used for I2C communication with the Grove board
    // D5 (SCL) which is used for I2C communication with the Grove board
    // D6  TX UART pin, PWM works after a brief HIGH, shorter HIGH duration if pins set before AI.begin();

    // D7  RX UART pin  PWM works no startup issue
    // D8  PWM works no startup issue,  SCK SPI connection for Image data if needed from Grove Board
    // D9  PWM works no startup issue,  MISO SPI connection for Image data if needed from Grove Board 
    // D10 PWM works no startup issue,  MOSI SPI connection for Image data if needed from Grove Board

    // Grove Vision AI V2 and zero at least one value
    AI.begin();
 /*   
    AI.boxes()[0].x      = 0;
    AI.boxes()[0].y      = 0;
    AI.boxes()[0].score  = 0;
    AI.boxes()[0].target = 0;

*/
}

void loop(){
    if (!AI.invoke() ){

     AI.perf().prepocess;
     AI.perf().inference;
     AI.perf().postprocess;

     if (AI.boxes()[0].score > 85 ){
      Serial.print(String(AI.boxes()[0].score)+", ");
      analogWrite(myDrivePwmPin, myMainSpeed);   // go medium  

      // 320 x 320 width and height 
      if( AI.boxes()[0].x < 100){
            Serial.println("Right");
            myServo_D2.write(110); // turn Right
      }
      else if(AI.boxes()[0].x >= 100 && AI.boxes()[0].x <= 150 ){

            Serial.println("Center");
            myServo_D2.write(90); // turn center
      }

      else if (AI.boxes()[0].x > 150) {
            Serial.println("Left");
            myServo_D2.write(70); // turn left
      }

     }
      else {
        Serial.println(String(AI.boxes()[0].score)+", None");
        analogWrite(myDrivePwmPin, 0);   // No objects detected so stop
        delay(500);   //  hmmmm  does not feel like the correct way to deal with this.
      }

     AI.boxes()[0].score = 0;  // pre-zero for next loop

    }

}