OCCRA
Go to Post On a side note... "Think outside the robot." - I kinda like that. I'll have to use that in a meeting someday.... - Not2B [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 08-14-2017, 09:10 PM
reddogf5 reddogf5 is offline
Registered User
FRC #0201
 
Join Date: Aug 2017
Location: michigan
Posts: 2
reddogf5 is an unknown quantity at this point
No Robot Code

Can anyone help me figure out why this code returns "no robot code" when enable is pressed on the driver station after successfully compiling and deploying? Most of it is copied from CTRE, and worked when only CANTalon0 was enabled. I am at a loss, as there isn't much here to not work. Any input is appreciated.

Code:
#include "WPILib.h"
#include "CANTalon.h" /* necessary as of FRC2017, comment out for earler seasons */
//#include <RobotDrive.h>

class Robot: public IterativeRobot {
private:
	CANTalon talon0;
	CANTalon talon1;
	CANTalon talon2;
	CANTalon talon3;
	Joystick *joy0;
	int _loops = 0;  //Not needed
public:
	Robot():
		talon0(0), talon1(1), talon2(2), talon3(3), joy0(0)
	{

	}

	void Disabled()
	{
	while(IsDisabled()){}
	}
	void RobotInit() {
        /* first choose the sensor */
		talon0.SetSafetyEnabled(false);
		talon1.SetSafetyEnabled(false);
		talon2.SetSafetyEnabled(false);
		talon3.SetSafetyEnabled(false);
		talon0.SetFeedbackDevice(CANTalon::QuadEncoder);
		talon0.SetSensorDirection(false);
		talon0.ConfigEncoderCodesPerRev(256), // if using FeedbackDevice.QuadEncoder
		talon2.SetFeedbackDevice(CANTalon::QuadEncoder);
		talon2.SetSensorDirection(false);
		talon2.ConfigEncoderCodesPerRev(256), // if using FeedbackDevice.QuadEncoder

		/* set the peak and nominal outputs, 12V means full */
		talon0.ConfigNominalOutputVoltage(+0.0f, -0.0f);
		talon0.ConfigPeakOutputVoltage(+12.0f, -12.0f);
		talon1.ConfigNominalOutputVoltage(+0.0f, -0.0f);
		talon1.ConfigPeakOutputVoltage(+12.0f, -12.0f);
		talon2.ConfigNominalOutputVoltage(+0.0f, -0.0f);
		talon2.ConfigPeakOutputVoltage(+12.0f, -12.0f);
		talon3.ConfigNominalOutputVoltage(+0.0f, -0.0f);
		talon3.ConfigPeakOutputVoltage(+12.0f, -12.0f);

		/* set closed loop gains in slot0 */
		talon0.SelectProfileSlot(0);
		talon0.SetF(0.1097);
		talon0.SetP(0.22);
		talon0.SetI(0.0);
		talon0.SetD(0.0);
		talon2.SelectProfileSlot(0);
		talon2.SetF(0.1097);
		talon2.SetP(0.22);
		talon2.SetI(0.0);
		talon2.SetD(0.0);

		/*set 1 and 3 to slave */
		talon1.SetControlMode(CANSpeedController::kFollower);// Set to follow another
		talon1.Set(0);// follow this talon
		talon3.SetControlMode(CANSpeedController::kFollower);
		talon3.Set(2);
	}
	/**
	 * This function is called periodically during operator control
	 */
	void TeleopPeriodic() {
		/* get gamepad axis */
		double leftYstick = joy0->GetAxis(Joystick::kYAxis);
		double motorOutputR = talon0.GetOutputVoltage() / talon0.GetBusVoltage();
		double motorOutputL = talon2.GetOutputVoltage() / talon2.GetBusVoltage();

		/* while button1 is held down, closed-loop on target velocity */
		if (joy0->GetRawButton(1)) {
        	/* Speed mode */
			double targetSpeed = leftYstick * 1500.0; /* 1500 RPM in either direction */
			talon0.SetControlMode(CANSpeedController::kSpeed);
        		talon0.Set(targetSpeed); /* 1500 RPM in either direction */
			talon2.SetControlMode(CANSpeedController::kSpeed);
        		talon2.Set(targetSpeed); /* 1500 RPM in either direction */

        } else {
			/* Percent voltage mode */
			talon0.SetControlMode(CANSpeedController::kPercentVbus);
			talon0.Set(leftYstick);
			talon2.SetControlMode(CANSpeedController::kPercentVbus);
			talon2.Set(leftYstick);
		}
		/* print every ten loops, printing too much too fast is generally bad for performance */
		if (++_loops >= 10) {
			_loops = 0;
			SmartDashboard::PutNumber("RMotor Out", motorOutputR);
			SmartDashboard::PutNumber("LMotor Out", motorOutputL);
			SmartDashboard::PutNumber("RMotor Speed", talon0.GetSpeed());
			SmartDashboard::PutNumber("LMotor Speed", talon2.GetSpeed());
			SmartDashboard::PutNumber("RMotor Error", talon0.GetClosedLoopError());
			SmartDashboard::PutNumber("LMotor Error", talon2.GetClosedLoopError());
		}

	}
};

START_ROBOT_CLASS(Robot)
Reply With Quote
  #2   Spotlight this post!  
Unread 08-15-2017, 10:56 AM
Jjmase123's Avatar
Jjmase123 Jjmase123 is offline
Registered User
AKA: JJ Mase
FRC #1661 (Griffitrons)
Team Role: Mentor
 
Join Date: Oct 2016
Rookie Year: 2014
Location: Los Angeles
Posts: 16
Jjmase123 is a jewel in the roughJjmase123 is a jewel in the roughJjmase123 is a jewel in the roughJjmase123 is a jewel in the rough
Re: No Robot Code

I'm no expert in C here, but I know in Java you should have a "if isEnabled() && isOperatorControl()" and I think this may be causing the error. Here's a link to the WPILib page and I do see it there also. Seems a little strange thought that that would throw a no code error.

https://wpilib.screenstepslive.com/s...g-a-base-class
__________________
Reply With Quote
  #3   Spotlight this post!  
Unread 08-15-2017, 11:25 AM
firecrafty's Avatar
firecrafty firecrafty is offline
Registered User
AKA: Ryan Blue
FRC #1018 (Pike RoboDevils)
Team Role: Programmer
 
Join Date: Feb 2017
Rookie Year: 2016
Location: Indianapolis
Posts: 101
firecrafty will become famous soon enoughfirecrafty will become famous soon enough
Re: No Robot Code

Do you have any logs you could show us? Anything going on in the DS console?
__________________

"Programming is a science. Writing beautiful code is an art."
Any views I express are my own and do not necessarily reflect those of my team.
Reply With Quote
  #4   Spotlight this post!  
Unread 08-15-2017, 11:27 AM
AustinShalit's Avatar
AustinShalit AustinShalit is offline
Registered User
AKA: אוסטין
no team (WPILib Suite Developer)
 
Join Date: Dec 2013
Rookie Year: 2008
Location: Los Angeles/Worcester/Israel
Posts: 201
AustinShalit is a glorious beacon of lightAustinShalit is a glorious beacon of lightAustinShalit is a glorious beacon of lightAustinShalit is a glorious beacon of lightAustinShalit is a glorious beacon of lightAustinShalit is a glorious beacon of light
Re: No Robot Code

Quote:
Originally Posted by reddogf5 View Post
Can anyone help me figure out why this code returns "no robot code" when enable is pressed on the driver station after successfully compiling and deploying? Most of it is copied from CTRE, and worked when only CANTalon0 was enabled. I am at a loss, as there isn't much here to not work. Any input is appreciated.
I would take a look at the most up to date version of this example from CTRE.

https://github.com/CrossTheRoadElec/.../src/Robot.cpp




Quote:
Originally Posted by Jjmase123 View Post
I'm no expert in C here, but I know in Java you should have a "if isEnabled() && isOperatorControl()" and I think this may be causing the error. Here's a link to the WPILib page and I do see it there also. Seems a little strange thought that that would throw a no code error.

https://wpilib.screenstepslive.com/s...g-a-base-class
You only need the `if (isEnabled() && isOperatorControl())` if you are using SampleRobot. Please do not use SampleRobot. Here is a copy of the warning text in the SampleRobot template:

Quote:
WARNING: While it may look like a good choice to use for your code if you're inexperienced, don't. Unless you know what you are doing, complex code will be much more difficult under this system. Use IterativeRobot or Command-Based instead if you're new.
__________________
Reply With Quote
  #5   Spotlight this post!  
Unread 08-15-2017, 12:06 PM
NotInControl NotInControl is offline
Controls Engineer/Team Lead Mentor
AKA: Kevin Harrilal
FRC #2168 (Aluminum Falcons)
Team Role: Engineer
 
Join Date: Oct 2011
Rookie Year: 2004
Location: Groton, CT
Posts: 285
NotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond reputeNotInControl has a reputation beyond repute
Re: No Robot Code

Didn't look at your code indepth, but if you look at your Driverstation output console, most likely you will see Null pointer errors.

Which means you are not instantiating the Talon controllers and Joysticks.

You need to use the "new" operator to instantiate each motor controller and joystick

something like
Code:
talon0 = new CANTalon(0); 
joy = new Joystick(0);
for each controller, and similarly for the joystick.

"Robot Code" green while in disabled, then "No Robot Code" while enabled means the code crashed during run-time. So you have a run-time error crashing your code.

In this case, most likely a null pointer since the Motor controllers and Joysticks are not instantiated before using the dot operator on them.

The console will give you a trace to where this error is occurring.

Hope this helps
__________________
Lead Mentor/Controls Engineer Team 2168 -Aluminum Falcons
[2016 Season] - World Championship Controls Award, District Controls Award, 3rd BlueBanner
-World Championship- #45 seed in Quals, World Championship Innovation in Controls Award - Curie
-NE Championship- #26 seed in Quals, winner(195,125,2168)
[2015 Season] - NE Championship Controls Award, 2nd Blue Banner
-NE Championship- #26 seed in Quals, NE Championship Innovation in Controls Award
-MA District Event- #17 seed in Quals, Winner(2168,3718,3146)
[2014 Season] - NE Championship Controls Award & Semi-finalists, District Controls Award, Creativity Award, & Finalists
-NE Championship- #36 seed in Quals, SemiFinalist(228,2168,3525), NE Championship Innovation in Controls Award
-RI District Event- #7 seed in Quals, Finalist(1519,2168,5163), Innovation in Controls Award
-Groton District Event- #9 seed in Quals, QuarterFinalist(2168, 125, 5112), Creativity Award
[2013 Season] - WPI Regional Winner - 1st Blue Banner
Reply With Quote
  #6   Spotlight this post!  
Unread 08-15-2017, 12:48 PM
RufflesRidge RufflesRidge is offline
Registered User
no team
 
Join Date: Jan 2012
Location: USA
Posts: 1,004
RufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant futureRufflesRidge has a brilliant future
Re: No Robot Code

Quote:
Originally Posted by NotInControl View Post
if you look at your Driverstation output console, most likely you will see Null pointer errors.
Not in C++. This code will just segfault with no error message.

Quote:
You need to use the "new" operator to instantiate each motor controller and joystick
This is not 100% correct. While this is one way of doing things (and the right way if using pointers), it is not the only valid way. The OP is using an initializer list to instantiate the motor controllers and joystick which, if done correctly, is perfectly valid.

The issue is that joy0 is a pointer not a reference. So initializing it to 0 is not creating a joystick object for "Joystick 0" it is initializing to a null pointer. When this pointer is accessed the code crashes.

joy0 should be changed to a reference and the pointer dereferences on it (->) should be changed to dot operators (.) for the minimal changes to make this code not crash.

Having said that, I would take a look at the updated CTRE examples as referenced above.
Reply With Quote
  #7   Spotlight this post!  
Unread 08-15-2017, 12:49 PM
Andrew Lobos Andrew Lobos is offline
Registered User
FRC #0225 (TechFire)
Team Role: Mentor
 
Join Date: Feb 2011
Rookie Year: 2011
Location: Lancaster, PA
Posts: 65
Andrew Lobos is just really niceAndrew Lobos is just really niceAndrew Lobos is just really niceAndrew Lobos is just really nice
Re: No Robot Code

In your Robot constructor, you're creating the talons as normal objects, but creating the joystick as a pointer

Code:
	CANTalon talon0;
	CANTalon talon1;
	CANTalon talon2;
	CANTalon talon3;
	Joystick *joy0;
	int _loops = 0;  //Not needed
public:
	Robot():
		talon0(0), talon1(1), talon2(2), talon3(3), joy0(0)
	{

	}
As-is, this calls the constructor for the CANTalon objects with the parameter you give it. But - joy0 is not a Joystick object, it's a pointer (memory address) to a Joystick object. When you initialize joy0 with 0 in your constructor, you're setting that pointer to memory address 0. Since your program doesn't own that memory, the operating system kills it when you try to access joy0.

If you want to continue to use a pointer, you can initialize the Joystick using the new operator as NotInControl said. Alternatively, you could just remove the * (which makes that Joystick variable a pointer), and reference the Joystick as a normal object (dot vs -> ). This changes how the instance gets allocated in memory (stack vs heap) - either way will work the same for a single class robot program.

Edit: RufflesRidge beat me to it by a minute
__________________

2015-?: 225 Programming Mentor
2012-2014: 225 Driver, Programmer & Co-Captain
2012-2014: FTC 4977 Driver, Programmer, & Team Captain
2011: 225 Operator & Programmer

2013: FRC: Springside-Chestnut Hill Winner (w/341 & 1495), Midknight Mayhem Winner (w/316, 369, & 869), Battle O' Baltimore Winner (w/1640, 2914 & 339), Duel on the Delaware Finalist (w/816 & 369), Ramp Riot Winner (w/341, 304, & 4637) FTC: PA State Finalist
2014: FRC: Springside-Chestnut Hill Winner (w/316 & 1495), Greater DC Winner (w/1731 & 4464), Midknight Mayhem Winner (w/25, 1626 & 329) FTC: PA State Champion
Reply With Quote
  #8   Spotlight this post!  
Unread 08-16-2017, 06:26 AM
reddogf5 reddogf5 is offline
Registered User
FRC #0201
 
Join Date: Aug 2017
Location: michigan
Posts: 2
reddogf5 is an unknown quantity at this point
Re: No Robot Code

Thanks, I got it working both with a pointer and a "normal" object.

Bigger question, why use one over the other?

I'm not a C++ programmer, and the resource I used to learn didn't explain why to use pointers, only that you can create a variable, or a pointer to one, which sounds like bypassing some functionality of the language. But in researching this problem yesterday, it seems pointers versus normal objects also determine which memory space the object is in (probably does not matter on a robot), and how long and where it exists - normal objects don't exist outside the entity that created them. This probably doesn't matter much on a robot, at least one using iterative robot. Command based might be a different story.
So it would appear the "safe" method is to create objects with pointers, to ensure they don't blink out of existence just when you need them. Is this reasonable, or is there a better answer?

Thanks again!
Reply With Quote
  #9   Spotlight this post!  
Unread 08-16-2017, 07:56 AM
Jaci's Avatar
Jaci Jaci is offline
http://imjac.in/ta/name
AKA: Jaci R Brunning
FRC #5333 (Can't C#) #5663 (Ground Control) | (OpenRIO, FRC West Aus)
Team Role: Mentor
 
Join Date: Jan 2015
Rookie Year: 2015
Location: Perth, Western Australia
Posts: 446
Jaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond reputeJaci has a reputation beyond repute
Re: No Robot Code

Quote:
Originally Posted by reddogf5 View Post
Thanks, I got it working both with a pointer and a "normal" object.

Bigger question, why use one over the other?

I'm not a C++ programmer, and the resource I used to learn didn't explain why to use pointers, only that you can create a variable, or a pointer to one, which sounds like bypassing some functionality of the language. But in researching this problem yesterday, it seems pointers versus normal objects also determine which memory space the object is in (probably does not matter on a robot), and how long and where it exists - normal objects don't exist outside the entity that created them. This probably doesn't matter much on a robot, at least one using iterative robot. Command based might be a different story.
So it would appear the "safe" method is to create objects with pointers, to ensure they don't blink out of existence just when you need them. Is this reasonable, or is there a better answer?

Thanks again!
A pointer allocates in Heap Space, while a normal old variable allocates in the Scoped Stack Space.

In the Heap Space, the pointer is allocated some memory on the large heap (where most of the system memory is most of the time), and the system is told not to give that memory to anyone else until it is free'd, meaning it will stay there until you call free(), or until your program exits (the OS has some safety to not leave dangling heap memory). In this case, the pointer is just saying "I've got your memory, it's over there, go use it".

In the Stack Space, your variables are allocated into something called a stack frame. Stack frames start when your program does, starting with constants and static variables, and each time a new scope is called (usually entering a function, for example), a new stack frame is added. When that stack frame is exited (i.e. returning from a function), the stack frame is popped off, and its memory is free to be written over by the next stack frame.

When you call new <yourobject>(), you're allocating on heap space. This is much more expensive than allocating on the stack, since the system has to find memory that isn't taken up yet (allocating the memory is practical 0 time, but finding memory to allocate takes a while).

As long as the scope the variables were initialised in still exists, your variables won't disappear.
__________________
Jacinta R

Curtin FRC (5333+5663) : Senior Mentor
OpenRIO : Owner

Website | Github
jaci.brunning@gmail.com
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 04:02 PM.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi