Deploy Successful, Rio said "No Robot Code"

I have been dealing with code deploying. I deploy the code, consel says Build Successful, & drive station & Rio saying “No Robot Code”.

I did everything: updating WPIlib plugin, updating WPIlib.h, Flashing Rio, checking connections, deploying from other computers. But none of that worked.

But, when I put in a previous version of the robot code, it worked and deployed. The only diffrence between the two versions, is that I used the Timer function inside of WPIlib.h in auto and telop. help?

Click on the only GitHub result inside of the GitHub search results
[https://github.com/search?utf8=%E2%9C%93&q=FRC1662_RobotCode_2017](https://github.com/search?utf8=%E2%9C%93&q=FRC1662_RobotCode_2017)

Thx.

https://github.com/search?utf8=%E2%9C%93&q=FRC1662_RobotCode_2017

here is the link again. didn’t work in

here

Thx.

Can’t guarantee this, but typically successful deploys followed by “no robot code” usually means you’re hitting a null pointer error. My best guess, looking at your code, would be to move:

	double a_timenow = a_timer->Get();
	double s_timenow = s_timer->Get();
	double g_timenow = g_timer->Get();

Into the first lines of both AutonomousPeriodic and TeleopPeriodic (where you use the variables).

Indeed ‘no robot code’ is almost always an indicator that your program crashed on the roboRio. Finding crashes can be frustrating. Suggestions:

  • Inspect the code for using a pointer which you have not yet done a ‘new’ on and so it is invalid or NULL.
  • Use printf() statements to see when you’ve reached certain parts of the code. This can be helpful but can also be troublesome as sometimes printf output doesn’t reach the console over the network before the crash occurs. Beware.
  • The BEST answer is to use the debugger. It’s daunting at first, but an EXCELLENT method. use “Debug As” instead of “Run As” - once in the debugger, you can ‘go’ to run the code and typically the debugger will HALT at the line where the crash occurred and you’re all set. Woohoo! (Your mileage may vary)

bob

I got this when i did debug as ; WPIlib-Deploy
https://i.redd.it/2co15omegwfy.jpg
when i pressed no, it said it could not connect to the Robo Rio.
Is there a specific way to debug using WPIlib-Deploy?

Thx.

I think what you really want to do is ‘Yes’ to that question. It’s a security alert due to the type of secured connection to the roboRio and unfortunately it looks quite ominous. This is, however, not a connection over the internet but a local network connection to a known device and so you’re ok to connect to it.

Good idea in theory, but the code comes back with syntax errors under the code you suggested.
I noticed that when I removed all of the timer functions in the entire code, it deployed and was running perfectly. soo… yea.
I hope that FIRST or WPI fixes their WPIlib.h to work with the RoboRio so that teams are able to use the timer function inside of WPIlib.h

Thx.

It’s really not WPI’s fault.

Lines 30-32 are using a_timer, s_timer, and g_timer BEFORE they are valid objects. You may DECLARE a_timenow, s_timenow, and g_timenow at that point in the class, but you must not assign them until AFTER you do the ‘new’ of your Timers (lines 90-92). Then you can make the assignments you would like.

bob

soo this



#include <iostream>
#include <memory>
#include <string>
#include <IterativeRobot.h>
#include <LiveWindow/LiveWindow.h>
#include <SmartDashboard/SendableChooser.h>
#include <SmartDashboard/SmartDashboard.h>
#include “WPILib.h”
#include “CANTalon.h”
#include “Timer.h”

class Robot: public frc::IterativeRobot
{
public:

//-------------------------------------------------------//
// Other Decorations //
//-------------------------------------------------------//

//-------------------------------------------------------//
// Decoration of Objects //
//-------------------------------------------------------//

//WIP
frc::Timer *s_timer;
frc::Timer *g_timer;
frc::Timer *a_timer;

double a_timenow = a_timer-&gt;Get();
double s_timenow = s_timer-&gt;Get();
double g_timenow = g_timer-&gt;Get();

Joystick *driver;
Joystick *driverV2;
Joystick *op;

CANTalon *drive_right_a, *drive_right_b, *drive_left_a, *drive_left_b;
CANTalon *intake;
CANTalon *aggitater;
CANTalon *shooter;
CANTalon *climber;
CANTalon *hood;
CANTalon *extra;

RobotDrive *drive_base;

Compressor *compressor;

DoubleSolenoid *gear;
DoubleSolenoid *shifter;

//WIP  \/
//Encoder *shooter_encoder;

Robot() {

//-------------------------------------------------------//
//Assigning Objects to Components and Electronics//
//-------------------------------------------------------//
driver = new Joystick(0);
op = new Joystick(1);
driverV2 = new Joystick(2);

	drive_right_a = new CANTalon(8);
	drive_right_b = new CANTalon(9);
	drive_left_a = new CANTalon(1);
	drive_left_b = new CANTalon(2);

	intake = new CANTalon(4);
	shooter = new CANTalon(7);
	climber = new CANTalon(6);
	aggitater = new CANTalon(3);
	hood = new CANTalon(9);

	extra = new CANTalon(5);

	drive_base = new RobotDrive
		(
		drive_right_a,
		drive_right_b,
		drive_left_a,
		drive_left_b
		);

	compressor = new Compressor(0);

	gear = new DoubleSolenoid(0, 2);
	shifter = new DoubleSolenoid(1, 3);



	s_timer = new frc::Timer();
	g_timer = new frc::Timer();
	a_timer = new frc::Timer();



}
void RobotInit() {

//-------------------------------------------------------//
// Robot vision Code //
//-------------------------------------------------------//

	auto cam = frc::CameraServer::GetInstance();
	cam-&gt;StartAutomaticCapture();

//-------------------------------------------------------//
// Robot Compressor //
//-------------------------------------------------------//

	compressor-&gt;SetClosedLoopControl(true);

//-------------------------------------------------------//
// Robot Encoder Code //
//-------------------------------------------------------//

//Quadrature Encoder CPR=1024
	hood-&gt;SetFeedbackDevice
	(
	   CANTalon::QuadEncoder
	 );
	hood-&gt;ConfigEncoderCodesPerRev(1024);




}
void AutonomousInit() override
{
	a_timer-&gt;Reset();
	a_timer-&gt;Start();
}

void AutonomousPeriodic()
{
	if
	(
		a_timenow == 0
	)
	{
		drive_base-&gt;SetSafetyEnabled(false);
		drive_base-&gt;TankDrive(0.5, 0.5, false);
	}

	if
	(
		a_timenow == 3.4	//3.4 second delay until next command
	)
	{

	gear-&gt;Set(
			gear-&gt;Get() ==
			DoubleSolenoid::Value::kReverse ?
			DoubleSolenoid::Value::kForward :
			DoubleSolenoid::Value::kReverse
			  );
	}

	if
	(
		a_timenow == 4.1 //0.5 second delay until next command
	)
	{

	drive_base-&gt;TankDrive(-0.5, -0.5, false);

	}

	if
	(
		a_timenow == 6.1 //2.0 second delay until next command
	)
	{
	gear-&gt;Set(
			gear-&gt;Get() ==
			DoubleSolenoid::Value::kReverse ?
			DoubleSolenoid::Value::kForward :
			DoubleSolenoid::Value::kReverse
			  );
	}

	if
	(
		a_timenow == 9	//3.0 second delay until next command
	)
	{
	drive_base-&gt;TankDrive(0.0, 0.0, false);
	}

	if
	(
		a_timenow == 10 //1.0 second delay until next command
	)
	{
	}

	if
	(
		a_timenow == 15	//end of auto
	)
	{
		a_timer-&gt;Stop(); // Stops auto timer
	}
}
void TeleopInit()
{
	//starting shifter's timer
	s_timer-&gt;Reset();
	s_timer-&gt;Start();

	//starting gear timer
	g_timer-&gt;Reset();
	g_timer-&gt;Start();
}

void TeleopPeriodic()
{

	// drive train; (left joystick; y axis; left drive) (right joystick: y axis; right drive)
	drive_base-&gt;TankDrive(
			-driver-&gt;GetRawAxis(1),
			-driver-&gt;GetRawAxis(5)
						 );

//-------------------------------------------------------//
// Drive Remote //
//-------------------------------------------------------//

	//hood forwards; back button
	if (
		driver-&gt;GetRawButton(7)
	    )
	{
		hood-&gt;Set(1.0);
	}else{
		hood-&gt;Set(0.0);
	}

	//hood backwords; start button
	if (
		driver-&gt;GetRawButton(8)
	    )
	{
		hood-&gt;Set(-1.0);
	}else{
		hood-&gt;Set(0.0);
	}

	//shooter; left bumper
	if(
			driver-&gt;GetRawButton(5)
	  )
	{
		shooter-&gt;Set(0.60);
	}else{
		shooter-&gt;Set(0.0);
	     }

	//intake in; right trigger
	if (
		driver-&gt;GetRawAxis(2)
	   )
	{
		intake-&gt;Set(-1.0);
	}else{
		intake-&gt;Set(0.0);
		  }

	//aggitator; "B" button
	if (
		driver-&gt;GetRawButton(3)
	    )
	{
		aggitater-&gt;Set(1.0);
	}else{
		aggitater-&gt;Set(0.0);
	      }
	//shifters; "A" button
	if (
		driver-&gt;GetRawButton(2)
		)
	{
		if (
				s_timenow &lt; .2
			)
		{
			s_timer-&gt;Reset();
			shifter-&gt;Set(
				shifter-&gt;Get() ==
				DoubleSolenoid::Value::kReverse ?
				DoubleSolenoid::Value::kForward :
				DoubleSolenoid::Value::kReverse
						 );
			driver-&gt;SetRumble
			(
			 GenericHID::RumbleType::kLeftRumble, 1
			 );
		}else{
			s_timer-&gt;Reset();
		     }
	 }

	//Gear open close; "B" button
	if (
			driver-&gt;GetRawButton(1)
		)
	{

		if (
				g_timenow &lt; .2
			)
		{
			g_timer-&gt;Reset();
			gear-&gt;Set(
				gear-&gt;Get() ==
				DoubleSolenoid::Value::kReverse ?
				DoubleSolenoid::Value::kForward :
				DoubleSolenoid::Value::kReverse
					  );
			driver-&gt;SetRumble
			(
					GenericHID::RumbleType::kLeftRumble, 1
			 );
		 }else{
			g_timer-&gt;Start();
		 	   }
	 }

//	climber up; POV UP
//	if (
//		driver-&gt;GetPOV(2)
//		)
//	{
//		climber-&gt;Set(1.0);
//	 }else{
//		climber-&gt;Set(0.0);
//	 }

//	//climber down; POV DOWN
//	if(
//		driver-&gt;GetPOV(6)
//	   )
//	{
//		climber-&gt;Set(-1.0);
//	}else{
//		climber-&gt;Set(0.0);
//	      }

//-------------------------------------------------------//
// Operator Remote //
//-------------------------------------------------------//
//noting here; yeah!!!
}
private:
};
START_ROBOT_CLASS(Robot);

Missed this box when pasting in code. sorry

:ahh:

Not quite…


frc::Timer *s_timer;
frc::Timer *g_timer;
frc::Timer *a_timer;

double a_timenow = a_timer->Get();
double s_timenow = s_timer->Get();
double g_timenow = g_timer->Get();

This (above) is a problem still. You’ve DECLARED s_timer, g_timer, and a_timer, but you have not yet instantiated them. Instantiation happens when you ‘new’ a pointer. If you try to USE those un-instantiated pointers, you’ll crash. And you do that in the subsequent three lines which use the ->Get() function. You EVENTUALLY do instantiate those Timer objects and you should THEN assign a_timenow and the others AFTER instantiating the Timers. Just declare (but don’t assign) until AFTER instantiating…


double a_timenow;
double s_timenow;
double g_timenow;

Then after doing the ‘new Timer’ calls later on, THEN assign a_timenow etc.

bob

soo this (inside of the box this time)


#includes stuff
class Robot: public frc::IterativeRobot
{
public:
	double a_timenow;
	double g_timenow;
	double s_timenow;

	frc::Timer *s_timer;
	frc::Timer *g_timer;
	frc::Timer *a_timer;

//other stuff
	Robot() {
//other stuff again
		s_timer = new frc::Timer();
		g_timer = new frc::Timer();
		a_timer = new frc::Timer();

		double a_timenow = a_timer->Get(); //error:  unused variable 'a_timenow' -Wunused-variable]
		double s_timenow = s_timer->Get(); //error:  unused variable 's_timenow' -Wunused-variable]
		double g_timenow = g_timer->Get(); //error:  unused variable 'g_timenow' -Wunused-variable]

	}

	void RobotInit() { // and all the stuff afterwords.

I do get this error above in the code as a comment

Indeed you are so VERY VERY close to correct. Here’s the issues now which is different than before. You solved the usage of the timers before ‘new’ … so now those are instantiated before you use them. Congrats. Now the issue is that in the class you declare 3 ‘double’ variables and then in Robot() you DECLARE them again. In Robot() you simply want to USE those variables. By putting the ‘double’ in front of them AGAIN, you are re-declaring them for that function and that function alone. The ones declared in the class are being “overridden” in a sense - and become unused. If you remove the ‘double’ from the lower area, you’ll then simply be using the class variables as you intend.

It’s a confusing topic to teach (quickly) to new programmers … in each function, if you declare a variable with a type in front of it:
int i;
double z;
Timer t;
These are variables that live within the confines of that function. That is called their “scope”.

If, instead you declare such variables at the CLASS level:


class AClass {
public:
  int i;
  double z;
  Timer t;
}

Now these variables can be used ANYWHERE in ANY of the class functions defined in “AClass” in my example. Those variables are now “shared” amongst the whole class. This is the beginning of where classes are so powerful - they help keep things organized in the groupings that matter - so the class can use them anywhere and every time you “instantiate” a copy of “AClass”, you’ll get a new set of those variables which are valid for only that instance of the object. So cool. And so clean and elegant too.

I’ve rambled - but that’s the gist - and it’s hard to teach without some great examples and usually some interaction with the student to see the light bulb turn on as the “get it”. And once you get it, it’ll all seem so natural. :slight_smile:

Good luck! You’re doing great!

bob

Thank you bob.wolff68 and all other users who posted, your explnation helped a lot. The Problem has been solved. Thus, this thread can be used to explain to others, who have the same problem, the problem and the solution.

Thx.

Congrats - and you’re quite welcome. It’s hard to learn programming under pressure in a short period of time. But you’re doing well. :slight_smile:

bob