PROS vision sensor code crashing robot

Hello,

Recently I’ve been using PROS with my team’s robot. On a different robot in VCS, I got a vision sensor to track the centermost object (a red or blue flag) and move the robot to get it at most to the center. Now, I have transitioned to PROS and tried recreating that code, but with detecting the green part of the flag as well, and changing the speed of a flywheel on the robot. The code below compiles, but when running on the robot, when I run the autoAim code the robot crashes. I don’t entirely know how exactly PROS vision sensing is supposed to work, but what I need to do is get an array of all visible objects and loop thru the array, looking for green, blue, or red objects, as well as the centermost ones.

Here is the autoAim function, running in opcontrol.cpp:
void autoAim(){

  while(Controller1.get_digital(E_CONTROLLER_DIGITAL_RIGHT) && !Controller1.get_digital(E_CONTROLLER_DIGITAL_LEFT)){
    int len = Bision.get_object_count();
    vision_object_s_t objects[len];
    vision_object_s_t targetObj, altTarget;
    Bision.read_by_size(len, len, objects);
    for(vision_object_s_t object : objects){
      if(object.signature == currentColor.id){
        if(targetObj.x_middle_coord == (int)NULL || abs(targetObj.x_middle_coord) > abs(object.x_middle_coord)) targetObj = object;
      }
      else if(object.signature == GR33N.id){
        if(altTarget.x_middle_coord == (int)NULL || abs(altTarget.x_middle_coord) > abs(object.x_middle_coord))altTarget = object;
      }
    }
    if(!(altTarget.x_middle_coord == (int)NULL || targetObj.x_middle_coord == (int)NULL)){
      //blue flags
      int targetX;
      if(targetObj.x_middle_coord < altTarget.x_middle_coord){
        targetX = (targetObj.left_coord+targetObj.width+altTarget.width)/2;

      }
      //red flags
      else{
        targetX = (altTarget.left_coord+altTarget.width+targetObj.width)/2;
      }

      if(targetX/5 < 0){
        FrontRight.move(127/2);
        FrontLeft.move(-127/2);
        BackRight.move(127/2);
        BackLeft.move(-127/2);
        if(autoSel == 8){
          string out = to_string(timee) + ";0;" + to_string(controllerAToInt(E_CONTROLLER_ANALOG_LEFT_X)) + ";axis;" + to_string(-127/2) + ";\n";
          std::fputs(out.c_str(), file);
        }
      }
      else if(targetX/5 > 0){
        FrontRight.move(127/2);
        FrontLeft.move(-127/2);
        BackRight.move(127/2);
        BackLeft.move(-127/2);
        if(autoSel == 8){
          string out = to_string(timee) + ";0;" + to_string(controllerAToInt(E_CONTROLLER_ANALOG_LEFT_X)) + ";axis;" + to_string(127/2) + ";\n";
          std::fputs(out.c_str(), file);
        }
      }
      else{
        FrontRight.move(0);
        FrontLeft.move(0);
        BackRight.move(0);
        BackLeft.move(0);
        Controller1.rumble("-");
      }
      int realScale = altTarget.height;
      //normScale, flywheelDistK are constant int, arrays
      if(Controller1.get_digital(E_CONTROLLER_DIGITAL_X)){
        flywheelSpeed = (normScale/realScale) * flywheelDistK[0];
      }
      else if(Controller1.get_digital(E_CONTROLLER_DIGITAL_Y)){
        flywheelSpeed = (normScale/realScale) * flywheelDistK[1];
      }
      else if(Controller1.get_digital(E_CONTROLLER_DIGITAL_A)){
        flywheelSpeed = (normScale/realScale) * flywheelDistK[2];
      }
      Flywheel1.move_velocity(flywheelSpeed);
      Flywheel2.move_velocity(flywheelSpeed);
      if(Flywheel1.get_actual_velocity() != Flywheel2.get_actual_velocity()) Bision.set_led(COLOR_RED);
      else Bision.set_led(COLOR_GREEN);
    }
  }
}

Here is the vision signature global initializations, located in initialize.cpp. I retrieved the parameter values from VCS (is this the right thing to do or is there a better way in PROS?)

Vision Bision (10);

//GET FROM V5 UTILITY
  vision_signature_s_t BLU3 =  Vision::signature_from_utility(1, -2745, -1895, -2320, 8191, 11809, 10000, 3.7, 0);
  vision_signature_s_t GR33N =  Vision::signature_from_utility (2, -3013, -2559, -2786, -4681, -4317, -4499, 11, 0);
  vision_signature_s_t R3D =  Vision::signature_from_utility (3, 7061, 7903, 7482, -157, 537, 190, 3.4, 0);

I think you want Bision.read_by_size(0, len, objects);

size_id is the nth object to start reading. That is, if you wanted to skip the largest object the vision sensor sees, then you’d provide 1 as the size_id.

How do you solve environmental problems, such as red, blue, green background or incandescent lamps?

:woman_shrugging: I think that’s a great discussion to be had in a general competition thread. Not sure there’s much you can do about that. It’s a limitation of the vision sensor. Color codes can help (e.g. only look for blobs with green/red or green/blue). If the environment is so poorly configured, it won’t matter.

1 Like

My students don’t understand the document. They have a question.
If I want to create color code for flag :

    RED_FLAG=_visionF.create_color_code(red, green);
    BLUE_FLAG=_visionF.create_color_code(blue, green)
 MYCOLOR=_visionF.create_color_code(red, blue,green);

which one is right?
I tested it and it seemed that both could work.
But if the thread sets a 20MS cycle, it is difficult to detect the color.