View Single Post
  #2   Spotlight this post!  
Unread 16-03-2010, 10:05
Dave Scheck's Avatar
Dave Scheck Dave Scheck is offline
Registered User
FRC #0111 (WildStang)
Team Role: Engineer
 
Join Date: Feb 2003
Rookie Year: 2002
Location: Arlington Heights, IL
Posts: 574
Dave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond reputeDave Scheck has a reputation beyond repute
Re: Enabling Default Dashboard in C++

I've been meaning to create and release a whitepaper on how we do our dashboard customization, but haven't had time this season. Maybe in our off week next week I'll get around to it.

It sounds like you're in the beginning stages, so lets start there and learn from the example code. Based on your question, I think you did this already, but if not, create a new dashboard sample project if you haven't already (File->New->Example ... Downloadable Kernel Module Sample Project ... FRC Dashboard Data Example) The way packing the data up changed from last year, so you'll want to take a look.

Let's work from the top down and look at the key sections. The RobotMain method makes callse to sendIOPortData() and sendVisionData(). These functions are in DashboardDataFormat.cpp. Calling these functions does everything you need to interface with the default dashboard. So the quick answer to your original question is yes. Make a call to both of these functions every time through your loop. If you're not using vision data, you don't have to make the call, but you have to update the Labview side to not be expecting that data.

So, to dig deeper, lets look at the internals of sendIOPortData(). The first thing it does is get a reference to the low priority dashboard packer. The packer contains the data that will be pushed onto the bit stream. My understanding that the low and high priority packers don't actually have different priorities in the data stream itself. On the receiver side, if the buffer is too large, the low priority packet is truncated.

Once the reference is obtained, it is populated. If you're not familiar with Labview, a Cluster is the equivalent to a structure in C++. Calling AddCluster designates the start of a cluster. It is closed out when FinalizeCluster is called. Calls may be nested to create more complex data types. The AddFloat and AddU8 calls add a float or UINT8 variable type to the packer.

When everything has been added and all clusters have been finalized, Finalize() is called on the dashboard packer. This designates that you are done packing and the data is ready to be sent out the door.

A similar process is done in sendVisionData for the high priority packer.

Once you have that framework in place, you can change it however you like as long as the packet that you're filling in on the C++ side matches what the Labview side is expecting. If it doesn't, you'll get an error on the Labview side that the packet doesn't match the format. This error can be tricky to debug. A few things that I've learned 1. A float comes across as a single precision type. Make sure your orange constants use the "single" representation. 2. Order is critical. You can right click on a cluster to reorder/view its contents.

Once you get the default working I can help you with the customization.

Last edited by Dave Scheck : 16-03-2010 at 10:08.
Reply With Quote