Chief Delphi

Chief Delphi (http://www.chiefdelphi.com/forums/index.php)
-   C/C++ (http://www.chiefdelphi.com/forums/forumdisplay.php?f=183)
-   -   Dashboard-Driver Station Help Please (http://www.chiefdelphi.com/forums/showthread.php?t=80526)

sircedric4 18-01-2010 19:04

Dashboard-Driver Station Help Please
 
I need help getting the dashboard on the driver station to show me what the robot is doing. I tried to get the dashboard working last year on C++ to no avail, and had hoped that FIRST had got it functioning this year, or at least made it easy that those of us still learning C++ can figure it out.

I have started from the SimpleTemplate code, and the only change I made was to goto TankDrive. I have added the DashboardDataFormat.h and DashboardDataFormat.cpp from the DashboardDataExample and I am posting the code in myRobot.cpp. The robot works fine, it drives around and is definitely talking to the driver station and everything is updated, but the dashboard will not reflect what the PWM's are doing.

Can someone enlighten me on what I am doing wrong. I expect with this code the way it is to see the PWM sliders on the driver station to move up and down as the joysticks are moved, but it doesn't do that. I have not included the sendVisionData because we aren't using the camera. Am I misunderstanding how the dashboard is supposed to work, is it not supposed to update the charts with the PWM positions?

Help me please with this code:

Code:

#include "WPILib.h"
#include "DashboardDataFormat.h"

/**
 * This is a demo program showing the use of the RobotBase class.
 * The SimpleRobot class is the base of a robot application that will automatically call your
 * Autonomous and OperatorControl methods at the right time as controlled by the switches on
 * the driver station or the field controls.
 */
class RobotDemo : public SimpleRobot
{
        RobotDrive myRobot; // robot drive system
        Joystick leftstick; // left joystick
        Joystick rightstick; //right joystick

public:
        RobotDemo(void):
                myRobot(1, 3, 2, 4),        // PWMs for drive
                                //1,3 - Left Motors
                                //2,4 - Right Motors
                leftstick(1),                // Left Joystick.
                rightstick(2)                // Right Joystick.
        {
                myRobot.SetInvertedMotor(RobotDrive::kFrontLeftMotor, false);
                myRobot.SetInvertedMotor(RobotDrive::kFrontRightMotor, false);
                myRobot.SetInvertedMotor(RobotDrive::kRearLeftMotor, false);
                myRobot.SetInvertedMotor(RobotDrive::kRearRightMotor, false);
                GetWatchdog().SetExpiration(0.1);
        }

        /**
        * Drive left & right motors for 2 seconds then stop
        */
        void Autonomous(void)
        {
                GetWatchdog().SetEnabled(false);
                myRobot.Drive(0.5, 0.0);        // drive forwards half speed
                Wait(2.0);                                //    for 2 seconds
                myRobot.Drive(0.0, 0.0);        // stop robot
        }

        /**
        * Runs the motors with tank steering.
        */
        void OperatorControl(void)
        {
                GetWatchdog().SetEnabled(true);
                while (IsOperatorControl())
                {
                        GetWatchdog().Feed();
                        myRobot.TankDrive(leftstick, rightstick); // drive
                        sendIOPortData();
                        Wait(0.005);                                // wait for a motor update time
                }
        }
};

START_ROBOT_CLASS(RobotDemo);


auk 18-01-2010 21:25

Re: Dashboard-Driver Station Help Please
 
The default DashboardDataFormat.cpp file has a bunch of fake values plugged in for the PWMs and Analog inputs, with the real stuff commented out. Not sure why they did this...

sircedric4 19-01-2010 07:23

Re: Dashboard-Driver Station Help Please
 
Thank you auk, I see the comments you referred to, and can figure out which lines I should replace the comments with, except a couple of the lines look like they might be doing something I don't understand.

Are there any examples that do work? (2010 Vision Demo isn't) Can someone point me to the document that details what the format that the dashboard is expecting so I know what I need to fill it. I'm gonna try the changes I just made, on the robot tonight, but don't be surprised if you find me asking for a working Dashboard example if someone is feeling gracious so I can see what I need to do to get my driver station updating with robot information.


-------------------------------------------------------------------------------------------------------------
This is just general venting, you can skip this unless you want to commiserate or as the students today say: tl,dr
-------------------------------------------------------------------------------------------------------------

So FIRST once again purposely torpedos the rookies and those just starting to learn, which isn't very graciously professional if you ask me. Not exactly setting a good example I think. I suppose now that I know that they are false advertising and are not actually providing working examples to learn from, I will be more careful. As a consulation at least they only commented out the code that makes it work.

I suppose their torpedos are also in the 2010 Vision Demo as well which would explain why I could not get it to work either. I keep getting an error on the driver station about a watchdog not being fed. With the Vision Demo I just threw it away since I couldn't get it to work, eventhough I put the GetWatchDog().Feed(); in the teleoperated section and it still didn't work. I just assumed that like the rest of the coding and updating that something was broken and that a new example would be coming out soon. I spent the last 3 days just trying to get the systems to talk together because of all the errors in the manual and getting all the proper updates talking.

It's not like the game and building a robot isn't difficult enough without maliciously providing red herrings and wrong turns. I understand showing the students how harsh the real world is, but I expect the simple examples to be actually functional, or at least for FIRST not to say that they have sample functioning code for you to learn on. What happened to the good old days of FIRST just 2 years ago, when a default code was provided that would at least have your robot work out of the box if you put your PWM's to the right places?

TheDominis 19-01-2010 09:10

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by sircedric4 (Post 902090)
Thank you auk, I see the comments you referred to, and can figure out which lines I should replace the comments with, except a couple of the lines look like they might be doing something I don't understand.

Are there any examples that do work? (2010 Vision Demo isn't) Can someone point me to the document that details what the format that the dashboard is expecting so I know what I need to fill it. I'm gonna try the changes I just made, on the robot tonight, but don't be surprised if you find me asking for a working Dashboard example if someone is feeling gracious so I can see what I need to do to get my driver station updating with robot information.


-------------------------------------------------------------------------------------------------------------
This is just general venting, you can skip this unless you want to commiserate or as the students today say: tl,dr
-------------------------------------------------------------------------------------------------------------

So FIRST once again purposely torpedos the rookies and those just starting to learn, which isn't very graciously professional if you ask me. Not exactly setting a good example I think. I suppose now that I know that they are false advertising and are not actually providing working examples to learn from, I will be more careful. As a consulation at least they only commented out the code that makes it work.

I suppose their torpedos are also in the 2010 Vision Demo as well which would explain why I could not get it to work either. I keep getting an error on the driver station about a watchdog not being fed. With the Vision Demo I just threw it away since I couldn't get it to work, eventhough I put the GetWatchDog().Feed(); in the teleoperated section and it still didn't work. I just assumed that like the rest of the coding and updating that something was broken and that a new example would be coming out soon. I spent the last 3 days just trying to get the systems to talk together because of all the errors in the manual and getting all the proper updates talking.

It's not like the game and building a robot isn't difficult enough without maliciously providing red herrings and wrong turns. I understand showing the students how harsh the real world is, but I expect the simple examples to be actually functional, or at least for FIRST not to say that they have sample functioning code for you to learn on. What happened to the good old days of FIRST just 2 years ago, when a default code was provided that would at least have your robot work out of the box if you put your PWM's to the right places?

You mad?

http://www.youtube.com/watch?v=CnhUYWbW3jQ around ~6:00

sircedric4 19-01-2010 11:06

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by TheDominis (Post 902136)

Mad is a good word, although I would say I am unusually annoyed. I have found the internet forum to be a good pressure relief for when stupid stuff isn't working out, which is why I prefaced my vent above. :-)

That way folks having the same issue can see they aren't the only ones having their problem.

It honestly never occured to me to read and check every line of the code they said worked and used as an example. I just assumed that I was messing up when calling it in my code. I wonder if I should have to check every line of the WPIlib souce code as well? Where does that mentality stop?

slavik262 19-01-2010 11:20

Re: Dashboard-Driver Station Help Please
 
The lack of functionality in the examples is rather annoying. If you're still having watchdog issues. Try calling GetWatchdog().SetEnabled(false) to shut it off completely. This should stop the issues (with the watchdog at least).

Mark McLeod 19-01-2010 11:27

Re: Dashboard-Driver Station Help Please
 
The Watchdog issues may be due to the System Watchdog which no user code affects. There is a Driver station efficency issue that NI has mentioned in other threads that they are working on correcting. When communication between the DS and the cRIO lags too much, the System Watchdog error message comes up.

heydowns 19-01-2010 12:30

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by sircedric4 (Post 902090)
I suppose their torpedos are also in the 2010 Vision Demo as well which would explain why I could not get it to work either. I keep getting an error on the driver station about a watchdog not being fed. With the Vision Demo I just threw it away since I couldn't get it to work, eventhough I put the GetWatchDog().Feed(); in the teleoperated section and it still didn't work. I just assumed that like the rest of the coding and updating that something was broken and that a new example would be coming out soon.

The vision example is obviously broken with respect to the Watchdog usage. It clearly enables the watchdog, sets expiration to some time (let's say t seconds, since I don't have it in front of me) and then proceeds to sleep significantly longer than that expiration (t + x).
You will always get a watchdog not fed at the start of this example if left unmodified.

I do understand your frustration with the quality of the examples.

sircedric4 19-01-2010 17:38

Re: Dashboard-Driver Station Help Please
 
Ok I am desperate now, I just tried uncommenting the code in the dashboard format and I still don't get anything on my driver station dashboard. Can someone please help me.

I have tried the same code that you saw in the first post above, and I also tried this code for my myRobot.cpp.

Code:

#include "WPILib.h"
#include "DashboardDataFormat.h"

/**
 * This is a demo program showing the use of the RobotBase class.
 * The SimpleRobot class is the base of a robot application that will automatically call your
 * Autonomous and OperatorControl methods at the right time as controlled by the switches on
 * the driver station or the field controls.
 */
class RobotDemo : public SimpleRobot
{
        RobotDrive myRobot; // robot drive system
        Joystick leftstick; // left joystick
        Joystick rightstick; //right joystick
        DashboardDataFormat DataPlease;
       
public:
        RobotDemo(void):
                myRobot(1, 3, 2, 4),        // PWMs for drive
                                //1,3 - Left Motors
                                //2,4 - Right Motors
                leftstick(1),                // Left Joystick.
                rightstick(2)                // Right Joystick.
        {
                myRobot.SetInvertedMotor(RobotDrive::kFrontLeftMotor, false);
                myRobot.SetInvertedMotor(RobotDrive::kFrontRightMotor, false);
                myRobot.SetInvertedMotor(RobotDrive::kRearLeftMotor, false);
                myRobot.SetInvertedMotor(RobotDrive::kRearRightMotor, false);
                GetWatchdog().SetExpiration(0.1);
        }

        /**
        * Drive left & right motors for 2 seconds then stop
        */
        void Autonomous(void)
        {
                GetWatchdog().SetEnabled(false);
                myRobot.Drive(0.5, 0.0);        // drive forwards half speed
                Wait(2.0);                                //    for 2 seconds
                myRobot.Drive(0.0, 0.0);        // stop robot
        }

        /**
        * Runs the motors with tank steering.
        */
        void OperatorControl(void)
        {
               
                // Create and set up a camera instance. first wait for the camera to start
                // if the robot was just powered on. This gives the camera time to boot.
                //Wait(10.0);
                //printf("Getting camera instance\n");
                //AxisCamera &camera = AxisCamera::getInstance();
                //printf("Setting camera parameters\n");
                //camera.writeResolution(k320x240);
                //camera.writeBrightness(0);

                // set watchdog
                GetWatchdog().SetExpiration(1.0);
                GetWatchdog().SetEnabled(true);
               
                while (IsOperatorControl())
                {
                        GetWatchdog().Feed();
                        myRobot.TankDrive(leftstick, rightstick); // drive

                        // send the dashboard data associated with the I/O ports
                        DataPlease.sendIOPortData();
                       
                        Wait(0.005);                                // wait for a motor update time
                }
        }
};

START_ROBOT_CLASS(RobotDemo);

And to top things off here is my DashboardDataFormat.cpp code where I uncommented the things that should have polled the cRio I thought.

Code:

#include "DashboardDataFormat.h"

void sendVisionData() {
        Dashboard &dash = DriverStation::GetInstance()->GetHighPriorityDashboardPacker();
        dash.AddCluster(); // wire (2 elements)
        {
                dash.AddCluster(); // tracking data
                {
                        dash.AddDouble(1.0); // Joystick X
                        dash.AddDouble(135.0); // angle
                        dash.AddDouble(3.0); // angular rate
                        dash.AddDouble(5.0); // other X
                }
                dash.FinalizeCluster();
                dash.AddCluster(); // target Info (2 elements)
                {
                        dash.AddCluster(); // targets
                        {
                                dash.AddDouble(100.0); // target score
                                dash.AddCluster(); // Circle Description (5 elements)
                                {
                                        dash.AddCluster(); // Position (2 elements)
                                        {
                                                dash.AddDouble(30.0); // X
                                                dash.AddDouble(50.0); // Y
                                        }
                                        dash.FinalizeCluster();
                                }
                                dash.FinalizeCluster(); // Position
                                dash.AddDouble(45.0); // Angle
                                dash.AddDouble(21.0); // Major Radius
                                dash.AddDouble(15.0); // Minor Radius
                                dash.AddDouble(324.0); // Raw score
                        }
                        dash.FinalizeCluster(); // targets
                }
                dash.FinalizeCluster(); // target Info
        }
        dash.FinalizeCluster(); // wire
        dash.Finalize();
}

void sendIOPortData() {
        Dashboard &dash = DriverStation::GetInstance()->GetLowPriorityDashboardPacker();
        dash.AddCluster();
        {
                dash.AddCluster();
                { //analog modules
                        dash.AddCluster();
                        {
                                for (int i = 1; i <= 8; i++) {
                                        dash.AddFloat((float) AnalogModule::GetInstance(1)->GetAverageVoltage(i));
                                        //dash.AddFloat((float) i * 5.0 / 8.0);
                                }
                        }
                        dash.FinalizeCluster();
                        dash.AddCluster();
                        {
                                for (int i = 1; i <= 8; i++) {
                                        dash.AddFloat((float) AnalogModule::GetInstance(2)->GetAverageVoltage(i));
                                }
                        }
                        dash.FinalizeCluster();
                }
                dash.FinalizeCluster();

                dash.AddCluster();
                { //digital modules
                        dash.AddCluster();
                        {
                                dash.AddCluster();
                                {
                                        int module = 4;
                                        dash.AddU8(DigitalModule::GetInstance(module)->GetRelayForward());
                                        dash.AddU8(DigitalModule::GetInstance(module)->GetRelayReverse());
                                        dash.AddU16((short)DigitalModule::GetInstance(module)->GetDIO());
                                        //dash.AddU16((short) 0xAAAA);
                                        dash.AddU16((short)DigitalModule::GetInstance(module)->GetDIODirection());
                                        //dash.AddU16((short) 0x7777);
                                        dash.AddCluster();
                                        {
                                                for (int i = 1; i <= 10; i++) {
                                                        dash.AddU8((unsigned char) DigitalModule::GetInstance(module)->GetPWM(i));
                                                        //dash.AddU8((unsigned char) (i-1) * 255 / 9);
                                                }
                                        }
                                        dash.FinalizeCluster();
                                }
                                dash.FinalizeCluster();
                        }
                        dash.FinalizeCluster();

                        dash.AddCluster();
                        {
                                dash.AddCluster();
                                {
                                        int module = 6;
                                        dash.AddU8(DigitalModule::GetInstance(module)->GetRelayForward());
                                        dash.AddU8(DigitalModule::GetInstance(module)->GetRelayForward());
                                        dash.AddU16((short)DigitalModule::GetInstance(module)->GetDIO());
                                        dash.AddU16(DigitalModule::GetInstance(module)->GetDIODirection());
                                        dash.AddCluster();
                                        {
                                                for (int i = 1; i <= 10; i++) {
                                                        dash.AddU8((unsigned char) DigitalModule::GetInstance(module)->GetPWM(i));
                                                        //dash.AddU8((unsigned char) i * 255 / 10);
                                                }
                                        }
                                        dash.FinalizeCluster();
                                }
                                dash.FinalizeCluster();
                        }
                        dash.FinalizeCluster();
                }
                dash.FinalizeCluster();

                // Can't read solenoids without an instance of the object
                dash.AddU8((char) 0);
        }
        dash.FinalizeCluster();
        dash.Finalize();
}

I'm not too proud to beg, can someone give me a hint here please. It shouldn't be this hard. Another two hours gone so far with different variations now. And I still don't know what the dashboard is expecting and in what order, how do you guys know? Is there documentation of that somewhere, and I would prefer a direct page reference please instead of just telling me to read the manual, because I don't know what manual to even look in.

sircedric4 19-01-2010 20:36

Re: Dashboard-Driver Station Help Please
 
Well I got it to work finally but in a weird way. I basically took the Dashboard Code with the torpedo comments removed and moved it over to the IterativeRobot example which we're gonna use for our robot long term and it started to work.

The only difference is that I am calling it in Iterative only every 0.50 seconds, versus the way I had it, which was calling it every loop. The only thing I can figure is that it wasn't getting enough time to finish its packing and update the dashboard. So if you are having trouble like I was, remove the commented stuff and change the code to only poll the data at specific period. I don't know what the minimum is, but 1/2 second is good enough for me. Thanks to those that helped and hopefully this experience will help someone else.

byteit101 20-01-2010 15:40

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by heydowns (Post 902232)
The vision example is obviously broken with respect to the Watchdog usage. It clearly enables the watchdog, sets expiration to some time (let's say t seconds, since I don't have it in front of me) and then proceeds to sleep significantly longer than that expiration (t + x).
You will always get a watchdog not fed at the start of this example if left unmodified.

I do understand your frustration with the quality of the examples.

But it still feeds it
Quote:

Originally Posted by 2010ImageDemo
...
// set watchdog
GetWatchdog().SetExpiration(1.0);

Wait(3.0);


// keep track of the previous joystick trigger value
bool lastTrigger = false;

// loop getting images from the camera and finding targets
printf("Starting operator control loop\n");
while (IsOperatorControl()) {
bool trigger;
GetWatchdog().Feed();
...


heydowns 20-01-2010 15:52

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by byteit101 (Post 903201)
But it still feeds it

Of course, but at a point when its already too late and it will have tripped, thus showing a "Watchdog not fed" error message on the DS.
I point this out so that people will not be alarmed when they see it.

Abrakadabra 21-01-2010 02:39

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by sircedric4 (Post 902511)
... I still don't know what the dashboard is expecting and in what order, how do you guys know? Is there documentation of that somewhere, and I would prefer a direct page reference please instead of just telling me to read the manual, because I don't know what manual to even look in.

Check out the WPI Robotic's Library User's Guide on page 51 - "Sending data to the dashboard". (Best bet is to follow the hyperlink from the PDF's table of contents, because someone forgot to put page numbers in the thing :rolleyes:). There is a two-column table on the next page that describes two different LabView data "clusters" - these are essentially the documentation for the data packages that the C++ example code is building up in preparation for sending it to the DS Dashboard that was written (of course) in LabView.

HTH.

jhersh 21-01-2010 02:53

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by sircedric4 (Post 902631)
Well I got it to work finally but in a weird way. I basically took the Dashboard Code with the torpedo comments removed and moved it over to the IterativeRobot example which we're gonna use for our robot long term and it started to work.

The only difference is that I am calling it in Iterative only every 0.50 seconds, versus the way I had it, which was calling it every loop. The only thing I can figure is that it wasn't getting enough time to finish its packing and update the dashboard. So if you are having trouble like I was, remove the commented stuff and change the code to only poll the data at specific period. I don't know what the minimum is, but 1/2 second is good enough for me. Thanks to those that helped and hopefully this experience will help someone else.

Packets go back to the dashboard every 20ms, so it's pointless to update faster than that.

jhersh 21-01-2010 03:12

Re: Dashboard-Driver Station Help Please
 
Quote:

Originally Posted by Abrakadabra (Post 903713)
Check out the WPI Robotic's Library User's Guide on page 51 - "Sending data to the dashboard". (Best bet is to follow the hyperlink from the PDF's table of contents, because someone forgot to put page numbers in the thing :rolleyes:). There is a two-column table on the next page that describes two different LabView data "clusters" - these are essentially the documentation for the data packages that the C++ example code is building up in preparation for sending it to the DS Dashboard that was written (of course) in LabView.

This structure is only an example, though. It's true that it does match the default data structures in the Dashboard that is generated when you create a new Dashboard project in LabVIEW, but there is nothing blessed about that format. Delete anything you don't want and make space for data that will actually help you to debug or to drive.

It's meant to get you to a good starting point with some examples... not to mandate that you use that data format, cause quite frankly, the data is too low level to be terribly useful (certainly in a driving situation) and reading all that data from the FPGA wastes lots of processor time. The fact that this was intended to be replaced by you with relevant data is even more evident since the real data isn't populated!

Sorry it was confusing and that you guys had different expectations. This part is supposed to be highly customized.

I have a feeling people would like it even less if it was all just a blank slate giving you no idea how to handle interesting data types, but at least their expectations would be fitting.


All times are GMT -5. The time now is 13:39.

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