Getting Values FROM Shuffleboard?

So our team has been able to output color sensor data to Smartboard and Shuffleboard. We also noticed we can edit the values of these “widgets.” Is it possible to get the value of a widget and use it as a variable in our code? Say we have a widget called “Motor Speed” based on a percentage to change the speed of the robot through the dashboards. Our robot is programmed in C++.

Yes, absolutely. The SmartDashboard class provides Get functions as well as Set functions.

How would you go about doing so?

You could just assign the variable equal to SmartDashboard.getDataType with the location and default value as arguements. This ends up looking like

SmartDashboard.getString("Location/location", "Default String");

This works exactly like putting a number on SmartDashboard.

Hello, after a few days of trying to get our code working, we cannot get the following to work properly:

/*----------------------------------------------------------------------------*/

/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */

/* Open Source Software - may be modified and shared by FRC teams. The code   */

/* must be accompanied by the FIRST BSD license file in the root directory of */

/* the project.                                                               */

/*----------------------------------------------------------------------------*/

#include <frc/GenericHID.h>

#include <frc/Spark.h>

#include <frc/TimedRobot.h>

#include <frc/XboxController.h>

#include <frc/drive/DifferentialDrive.h>

#include <cameraserver/CameraServer.h>

#include <frc/TimedRobot.h>

#include <frc/smartdashboard/smartdashboard.h>

#include <frc/util/color.h>

#include "rev/ColorSensorV3.h"

#include "rev/ColorMatch.h"

#include <string>

double round(double var) { 

    double value = (int)(var * 100 + .5); 

    return (float)value / 100;}

class Robot : public frc::TimedRobot {

  int speedMultiplier;

  frc::Spark m_leftMotor{0};

  frc::Spark m_rightMotor{1};

  frc::DifferentialDrive m_robotDrive{m_leftMotor, m_rightMotor};

  frc::XboxController m_driverController{0};

    

  static constexpr auto i2cPort = frc::I2C::Port::kOnboard;

  rev::ColorSensorV3 m_colorSensor{i2cPort};

  rev::ColorMatch m_colorMatcher;

  static constexpr frc::Color kBlueTarget = frc::Color(0.143, 0.427, 0.429);

  static constexpr frc::Color kGreenTarget = frc::Color(0.197, 0.561, 0.240);

  static constexpr frc::Color kRedTarget = frc::Color(0.561, 0.232, 0.114);

  static constexpr frc::Color kYellowTarget = frc::Color(0.361, 0.524, 0.113);

 public:

  void TeleopPeriodic() {

    int speedMultiplier;

    m_robotDrive.ArcadeDrive(

        m_driverController.GetY(frc::GenericHID::JoystickHand::kLeftHand)*-1*speedMultiplier/100,

        m_driverController.GetY(frc::GenericHID::JoystickHand::kLeftHand)*speedMultiplier/100);

        frc::Color detectedColor = m_colorSensor.GetColor();

    std::string colorString;

    double confidence = 0.0;

    frc::Color matchedColor = m_colorMatcher.MatchClosestColor(detectedColor, confidence);

    if (matchedColor == kBlueTarget) {

      colorString = "Blue";

    } else if (matchedColor == kRedTarget) {

      colorString = "Red";

    } else if (matchedColor == kGreenTarget) {

      colorString = "Green";

    } else if (matchedColor == kYellowTarget) {

      colorString = "Yellow";

    } else {

      colorString = "Unknown";

    }

    

    frc::SmartDashboard::PutString("Confidence", std::to_string(round(confidence)*100) + "%");

    frc::SmartDashboard::PutString("Detected Color", colorString);

    frc::SmartDashboard::GetNumber("Drive Speed", speedMultiplier);

    frc::SmartDashboard::PutNumber("Speed", speedMultiplier);

  }

  private:

  void RobotInit()

  {

    frc::CameraServer::GetInstance()->StartAutomaticCapture();

    m_colorMatcher.AddColorMatch(kBlueTarget);

    m_colorMatcher.AddColorMatch(kGreenTarget);

    m_colorMatcher.AddColorMatch(kRedTarget);

    m_colorMatcher.AddColorMatch(kYellowTarget);

  }

};

#ifndef RUNNING_FRC_TESTS

int main() {

  return frc::StartRobot<Robot>();

#endif

}

According to the documentation for GetNumber, GetNumber takes as a parameter the default value and returns either the value from NetworkTables (if it’s present there) or the default value. For example:

speedMultiplier = frc::SmartDashboard::GetNumber("Drive Speed", 1.0);

That may have been an issue I had, but whenever I run the code and enter a value into Drive Speed, the robot disables itself.

Why do you declare speedMultiplier again in the TeleopPeriodic loop?

Great point, had forgotten to remove that. However, removing it does not solve our issue.

You should name the get/put dashboard variables the same so they will reference each other. The second thing is to put the putNumber function in an init function instead of being in a perodic function. For example:

void RobotInit() {
    frc::SmartDashboard::PutNumber("Drive Speed", speedMultiplier);
}

void TeleopPeriodic() {
    speedMultiplier = frc::SmartDashboard::GetNumber("Drive Speed", 1.0);
}

With that, I get these errors:
C:\Users\Public\Desktop\FRC\Emmet2.0\src\main\cpp\Robot.cpp: In member function ‘virtual void Robot::TeleopPeriodic()’:
C:\Users\Public\Desktop\FRC\Emmet2.0\src\main\cpp\Robot.cpp:47:5: error: ‘speedMultiplier’ was not declared in this scope
speedMultiplier = frc::SmartDashboard::GetNumber(“Drive Speed”, 1.0);
^~~~~~~~~~~~~~~
C:\Users\Public\Desktop\FRC\Emmet2.0\src\main\cpp\Robot.cpp: In member function ‘virtual void Robot::RobotInit()’:
C:\Users\Public\Desktop\FRC\Emmet2.0\src\main\cpp\Robot.cpp:77:51: error: ‘speedMultiplier’ was not declared in this scope
frc::SmartDashboard::PutNumber(“Drive Speed”, speedMultiplier);

Declare speedMultiplier as a static variable: static int speedMultiplier

Still the same error.

Here’s the updated code, for reference:

    /*----------------------------------------------------------------------------*/
/* Copyright (c) 2017-2019 FIRST. All Rights Reserved.                        */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

#include <frc/GenericHID.h>
#include <frc/Spark.h>
#include <frc/PWMVictorSPX.h>
#include <frc/TimedRobot.h>
#include <frc/XboxController.h>
#include <frc/drive/DifferentialDrive.h>
#include <cameraserver/CameraServer.h>
#include <frc/TimedRobot.h>
#include <frc/smartdashboard/smartdashboard.h>
#include <frc/util/color.h>
#include "rev/ColorSensorV3.h"
#include "rev/ColorMatch.h"
#include <string>

double round(double var) { 
    double value = (int)(var * 100 + .5); 
    return (float)value / 100;}

class Robot : public frc::TimedRobot {
  frc::Spark m_leftMotor{0};
  frc::Spark m_rightMotor{1};
  frc::PWMVictorSPX intake{2};
  frc::PWMVictorSPX shooter{3};
  frc::DifferentialDrive m_robotDrive{m_leftMotor, m_rightMotor};
  frc::XboxController m_driverController{0};
    
  static constexpr auto i2cPort = frc::I2C::Port::kOnboard;

  rev::ColorSensorV3 m_colorSensor{i2cPort};

  rev::ColorMatch m_colorMatcher;

  static constexpr frc::Color kBlueTarget = frc::Color(0.143, 0.427, 0.429);
  static constexpr frc::Color kGreenTarget = frc::Color(0.197, 0.561, 0.240);
  static constexpr frc::Color kRedTarget = frc::Color(0.561, 0.232, 0.114);
  static constexpr frc::Color kYellowTarget = frc::Color(0.361, 0.524, 0.113);

 public:
  void TeleopPeriodic() {
    m_robotDrive.ArcadeDrive(
        m_driverController.GetY(frc::GenericHID::JoystickHand::kLeftHand)*-1*speedMultiplier/100,
        m_driverController.GetY(frc::GenericHID::JoystickHand::kLeftHand)*speedMultiplier/100);
        frc::Color detectedColor = m_colorSensor.GetColor();

    std::string colorString;
    double confidence = 0.0;
    frc::Color matchedColor = m_colorMatcher.MatchClosestColor(detectedColor, confidence);

    if (matchedColor == kBlueTarget) {
      colorString = "Blue";
    } else if (matchedColor == kRedTarget) {
      colorString = "Red";
    } else if (matchedColor == kGreenTarget) {
      colorString = "Green";
    } else if (matchedColor == kYellowTarget) {
      colorString = "Yellow";
    } else {
      colorString = "Unknown";
    }
    
    frc::SmartDashboard::PutString("Confidence", std::to_string(round(confidence)*100) + "%");
    frc::SmartDashboard::PutString("Detected Color", colorString);
    static int speedMultiplier = frc::SmartDashboard::GetNumber("Drive Speed", 1.0);

  }
  private:
  void RobotInit()
  {
    frc::CameraServer::GetInstance()->StartAutomaticCapture();
    frc::SmartDashboard::PutNumber("Drive Speed", speedMultiplier);
    m_colorMatcher.AddColorMatch(kBlueTarget);
    m_colorMatcher.AddColorMatch(kGreenTarget);
    m_colorMatcher.AddColorMatch(kRedTarget);
    m_colorMatcher.AddColorMatch(kYellowTarget);
  }
};

#ifndef RUNNING_FRC_TESTS
int main() {
  return frc::StartRobot<Robot>();
#endif
}

Shouldn’t you be doing it like this?:

static int speedMultiplier = 1;

void RobotInit() {
    frc::SmartDashboard::PutNumber("Drive Speed", speedMultiplier);
}

void TeleopPeriodic() {
    speedMultiplier = (int) frc::SmartDashboard::GetNumber("Drive Speed", 1.0);
}

That has lead to a successful build and probably solved my issue. I will get back to you if it I have any further issues. Thanks.