Is this possible in Vexcode IQ?

I am on VEXcode IQ.
Is there a way in which I can make the code say(in a blocks, not text project):
Set touchLED color to color hue seen on color sensor
Please reply fast

No.

But you could do it in a text project like so:

myTouchLED.on(myColorSensor.value(), 100);
1 Like

what does this mean? what would it do in the code?

I started writing that line of code by consulting my unofficial Doxygen docs for VEXcode IQ C++ – there are a number of functions available that the VEXcode UI doesn’t tell you about but which are present in the doxygen docs.

The function colorsensor::hue is described as follows:

Screen Shot 2021-06-03 at 7.19.35 PM

and touchled::on is described as follows:

Screen Shot 2021-06-03 at 7.20.25 PM

(or at least, one of the versions of touchled::on is described like that, there are several versions of that function with different ways to specify the color you want to show. But hue is the way we want here as specified in your original question.)

So, assuming we have configured a color sensor called myColorSensor and a touch LED called myTouchLED, the line

myTouchLED.on(myColorSensor.value(), 100);

will read the hue seen by the color sensor, and set the touch LED to display that hue at 100% brightness.

5 Likes

ok, thanks a lot! this really helps!
but is there a way to code that in blocks? i use blocks not the text…

In blocks you could do this:

Screen Shot 2021-06-03 at 7.36.40 PM

which would also set the touch LED to the color seen by the color sensor.

But it’s not quite the same thing as doing it by hue – there are only 15 or so distinct color names in VEXcode IQ, so the touch LED would show whichever of those 15 colors is closest to what the color sensor is seeing.

Whereas the hue is an integer in the range 0-360, so the color the Touch LED is showing would be closer to what the color sensor is seeing.

5 Likes

yes, i tried that, but it wasnt accurate.
i guess converting my project to a text project would be best for me?

I think you expecting too much.

The colors that the color sensor “sees”, when converted to values for the touch led, will not give exactly the same perceived color to your eyes.

7 Likes

I think this is a really awesome resource. Thanks for doing this and maintaining this!

1 Like

but it doesn’t look like the color sensor is accurate, even when i go into the robot brain and see what color the brain is seeing so i will probably convert my project to a text one and use the one that @holbrook recommended here

This is really cool. But we cannot do multiple files with vexcode iq c++. I’m having hard time to imagine using this for a larger project.

1 Like

You can do a lot in one file, maybe not as much as some of the caution tape teams (or not as elegantly) but still a lot. Here’s the project I was working on when I first generated the doxygen docs:

Summary
//////////////////////////////////////////////////////////////////////////////
//                                                                            
//    Module:       wv_pico.iqcpp                                                 
//    Author:       John Holbrook & Philip Taylor, WV Robotics Alliance                                                  
//    Created:      August-October 2020                                                   
//    Description:  Control code for the WV Pico Robot.                                                
//                                                                            
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
//
//                       CONFIGURED DEVICES
//
//  +------------+------------------+-------+------------------------+
//  | Name       |  Device          |  Port |  Description           |
//  +------------+------------------+-------+------------------------+
//  | MotorL     |  Motor           |  7    |  Left Drive Motor      |
//  | MotorR     |  Motor           |  1    |  Right Drive Motor     |
//  | AntiTip    |  Motor           |  9    |  Anti-Tip Motor        |
//  | DistanceL  |  Distance Sensor |  11   |  Left Distance Sensor  |
//  | DistanceR  |  Distance Sensor |  5    |  Right Distance Sensor |
//  | Gyro       |  Gyro            |  2    |  Gyro                  |
//  | Controller |  Controller      |  N/A  |  Controller            |
//  +------------+------------------+-------+------------------------+
//
//////////////////////////////////////////////////////////////////////////////

// Include the IQ Library
#include "iq_cpp.h"

// Joystick deadzone radius
#define DEADZONE 30 // percent

//Offset distance from centerline
#define OFFSET_DISTANCE 400 //mm

// Allows for easier use of the VEX Library
using namespace vex;

//////////////////////////////////////////////////////////////////////////////
//
//  MODE TYPES AND GLOBALS
//
//////////////////////////////////////////////////////////////////////////////

//Enum to describe each autonomous operating mode
enum mode{
  betweenWalls,
  macros,
  windString,
  driveStraight
};

//global to indicate the current operating mode
mode currentMode = betweenWalls;

//global thread object to run the current operating mode
thread currentModeThread;

//////////////////////////////////////////////////////////////////////////////
//
//  DISTANCE SENSOR POLLING
//
//////////////////////////////////////////////////////////////////////////////

//globals for the current value seen by each distance sensor
int currLeftDist, currRightDist;

//poll distance sensors one at a time at 100ms intervals to avoid cross-talk
void pollDistSensors(){
  while (true){
    currLeftDist = DistanceL.distance(mm);
    wait(0.1, seconds);
    currRightDist = DistanceR.distance(mm);
    wait(0.1, seconds);
  }
}

//////////////////////////////////////////////////////////////////////////////
//
//  OPERATING MODE FUNCTIONS
//    Each of these functions defines a different operating mode.
//    The correct function will be called by startMode based on the current
//    value of the currentMode global.
//
//////////////////////////////////////////////////////////////////////////////

//navigate using the distance sensors between the walls, either centering between
//them or maintaining an offset from the centerline based on the value of the
//offset global variable
int offset; //offset from the centerline in mm, positive values for left of center
void mode_betweenWalls(){
  const float gain = .6;
  const int base_velocity = 50;
  MotorL.spin(forward);
  MotorR.spin(forward);
  while (true){
    int error = (currLeftDist-currRightDist+offset)*gain;
    MotorL.setVelocity(base_velocity-error, percent);
    MotorR.setVelocity(base_velocity+error, percent);
    wait(0.1, seconds);
  }
}

//turn the robot using the gyro
void gyro_turn(turnType dir, int amount){
  int gyro_start = Gyro.rotation();
  int target;
  if (dir == turnType::left){
    target = gyro_start + amount;
    MotorR.spin(forward);
    MotorL.spin(reverse);
    while (Gyro.rotation() <= target){
      wait(0.1, seconds);
    }
  }
  else{
    target = gyro_start - amount;
    MotorL.spin(forward);
    MotorR.spin(reverse);
    while (Gyro.rotation() >= target){
      wait(0.1, seconds);
    }
  }
  MotorL.stop();
  MotorR.stop();
}

//define various "drive macros" that move the robot pre-determined amounts
#define SM_CREEP_DISTANCE 180 // motor degrees
#define LG_CREEP_DISTANCE 720 //motor degrees
void mode_macros(){
  while (true){
    if (Controller.AxisA.position() > DEADZONE){
      // small creep forward
      MotorL.spinFor(forward, SM_CREEP_DISTANCE, degrees, false);
      MotorR.spinFor(forward, SM_CREEP_DISTANCE, degrees);
    }
    else if (Controller.AxisA.position() < -DEADZONE){
      // small creep backward
      MotorL.spinFor(reverse, SM_CREEP_DISTANCE, degrees, false);
      MotorR.spinFor(reverse, SM_CREEP_DISTANCE, degrees);
    }
    else if (Controller.AxisD.position() > DEADZONE){
      // large creep forward
      MotorL.spinFor(forward, LG_CREEP_DISTANCE, degrees, false);
      MotorR.spinFor(forward, LG_CREEP_DISTANCE, degrees);
    }
    else if (Controller.AxisD.position() < -DEADZONE){
      // large creep backward
      MotorL.spinFor(reverse, LG_CREEP_DISTANCE, degrees, false);
      MotorR.spinFor(reverse, LG_CREEP_DISTANCE, degrees);
    }
    else if (Controller.AxisB.position() > DEADZONE){
      // turn right slightly
      MotorL.spinFor(forward, SM_CREEP_DISTANCE, degrees, false);
      MotorR.spinFor(reverse, SM_CREEP_DISTANCE, degrees);
    }
    else if (Controller.AxisB.position() < -DEADZONE){
      // turn left slightly
      MotorL.spinFor(reverse, SM_CREEP_DISTANCE, degrees, false);
      MotorR.spinFor(forward, SM_CREEP_DISTANCE, degrees);
    }
    else if (Controller.AxisC.position() > DEADZONE){
      // turn right 45 degrees
      gyro_turn(turnType::right, 45);
    }
    else if (Controller.AxisC.position() < -DEADZONE){
      // turn left 45 degrees
      gyro_turn(turnType::left, 45);
    }
    wait(0.1, seconds);
  }
}

void mode_windString(){
  while (true){
    if (Controller.AxisD.position() > DEADZONE){
      MotorL.spin(reverse);
      MotorR.spin(reverse);
    }
    else if (Controller.AxisD.position() < -DEADZONE){
      MotorL.spin(forward);
      MotorR.spin(forward);
    }
    wait(0.1, seconds);
  }
}

//drive straight forward, using the gyro to maintain heading
void mode_driveStraight(){
  int target = Gyro.rotation();
  const int gain = 10;
  const int base_pwr = 50;
  MotorL.spin(forward);
  MotorR.spin(forward);
  while(true){
    int error = (Gyro.rotation() - target)*gain;
    MotorL.setVelocity(base_pwr+error, percent);
    MotorR.setVelocity(base_pwr-error, percent);
    wait(0.1, sec);
  }
}

//////////////////////////////////////////////////////////////////////////////
//
//  MODE MANAGEMENT
//    Functions to start, stop, and change the current operating mode.
//
//////////////////////////////////////////////////////////////////////////////

//call the right function for the current mode
void startMode(){
  switch (currentMode){
    case betweenWalls:
      mode_betweenWalls();
      break;
    case macros:
      mode_macros();
      break;
    case windString:
      mode_windString();
      break;
    case driveStraight:
      mode_driveStraight();
      break;
  }
}

//stop the current mode thread and all motors
void stop(){
  currentModeThread.interrupt();
  MotorL.setVelocity(50, percent);
  MotorR.setVelocity(50, percent);
  MotorL.stop();
  MotorR.stop();
}

//change the current operating mode
void changeMode(mode newMode){
  stop();
  currentMode = newMode;
  currentModeThread = thread(startMode);
}

bool antitip_deployed = false;

int main() {
  //start polling distance sensors
  thread distThread = thread(pollDistSensors);

  AntiTip.setMaxTorque(100, percent);
  AntiTip.setStopping(hold);
  AntiTip.stop();

  //register controller callbacks
  Controller.ButtonEUp.pressed(stop);

  Controller.ButtonEDown.pressed([]{
    offset = 0;
    changeMode(betweenWalls);
  });

  Controller.ButtonLUp.pressed([]{
    offset = OFFSET_DISTANCE;
    changeMode(betweenWalls);
  });

  Controller.ButtonRUp.pressed([]{
    offset = -OFFSET_DISTANCE;
    changeMode(betweenWalls);
  });

  Controller.ButtonFUp.pressed([]{
    changeMode(macros);
  });

  Controller.ButtonFDown.pressed([]{
    changeMode(windString);
  });

  Controller.ButtonRDown.pressed([]{
    changeMode(driveStraight);
  });

  Controller.ButtonLDown.pressed([]{
    if (antitip_deployed){
      AntiTip.spinToPosition(0, degrees, true);
      antitip_deployed = false;
    }
    else{
      AntiTip.spinToPosition(135, degrees, true);
      antitip_deployed = true;
    }
  });
}

The brief was to design a prototype IQ robot to semi-autonomously navigate a cardboard model of a
lunar lava tube, including terrain obstacles such as sand and rocks. The robot had a cell phone onboard which was sending live video back to an operator, who could press buttons on the controller to switch the robot between various autonomous operating modes.

3 Likes

The code looks super clean! I wish my students will be there one day. It’s a slow and painful process to teach them code neatly. LOL.

3 Likes

yes, if i were to convert one of my projects to text, it would be quite a bit long, not as much as yours