|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||
|
|||
|
How does your team incorporate engineering units?
I'm hoping to get feedback on how teams are already managing engineering units within their code.
Several of the languages used in FRC can provide compile-time checking to verify that units of distance and velocity, for example, are not combined incorrectly within your code. The upside is that you have a compiler watching your back as you make algebraic statements in your code to update an actuator. The downside is that compilers are sticklers and your code may actually become harder to read, or the points at which you connect to WPILib, which doesn't use units, may just become littered with casts and such. Is anyone using unit features within the languages or libraries? Do you have another system that you've adopted? Greg McKaskle |
|
#2
|
||||
|
||||
|
Re: How does your team incorporate engineering units?
Didn't even know this feature existed.
|
|
#3
|
|||
|
|||
|
Re: How does your team incorporate engineering units?
For one, my team (we use LV) does not use this unit feature.
To begin with we weren't aware of the feature at all. (Though most of the senior coders have some cpp experience and know how typedefs can be used in cpp) Also, I don't think it's likely we'll use this feature in the future. My personal opinion is that all our numerical data should be the same data type (ie doubles or rather the LV equivalent.) This makes life easier when coding and debugging since we don't have to cast everything which means 1) the code is less cluttered 2a) We can use LV and WPI libraries more easily since they all take standard numerical inputs 2b) We can ensure our own utility Vis will function for multiple modules of code (which may be using different units) Moreover, the feature seems to be more of a crutch than a solution. Unit confliction can easily be solved with good planning, sanity checks, and testing. ;tldr: we haven't heard of it before, and we probably wont use it since it's easier to code w/o and the issues can be solved with good coding practice |
|
#4
|
|||
|
|||
|
Re: How does your team incorporate engineering units?
Quote:
|
|
#5
|
||||
|
||||
|
Re: How does your team incorporate engineering units?
Quote:
Quote:
|
|
#6
|
|||
|
|||
|
Re: How does your team incorporate engineering units?
Quote:
In the case of the Orbiter, the integration testing obviously didn't include the test case that would have exposed the unit mismatch - or the verification side of the test wasn't properly written, or nobody looked at the results, etc. Would stronger type/unit checking native to the compiler(s) have caught the problem? Would programmers have "fixed" the compiler warnings/errors by littering their code with typecasts to make them "go away", thereby making the coder harder to read/maintain - and possibly causing this exact bug to slip through anyway? We'll never know. |
|
#7
|
||||
|
||||
|
Re: How does your team incorporate engineering units?
Our team's codebase is mostly devoid of values that would be in physical units anyway. Generally, we code to what our sensors provide. Instead of measuring out a path, calculating the number of rotations, then the number of encoder ticks that would take, we take the robot, zero the encoders, and run through the path, recording their values directly. I distrust any assumption (at least in the FIRST timeframe) that a quantity defined in physical units can be cleanly converted to a value from the robot's sensors. If we had the time to create a proper simulation, then perhaps I would use real-world units more, but since our only platform is the robot, we use the values directly from the robot.
As an example, we have this class which allows us to do motion planning from teleop mode. Map this command to a button, and it prints out the lines of code to put into the autonomous mode, using the values from the sensors directly. Last edited by Ginto8 : 27-11-2013 at 14:52. Reason: Added PrintAutonomousMove link for an example |
|
#8
|
||||||
|
||||||
|
Re: How does your team incorporate engineering units?
We typically convert sensor values to a physical unit, if it makes sense to do so. For example, we convert our drivetrain encoders to feet. However, we only use that unit (easy to do on a small development team, harder to do on a large development team that spans multiple companies like the mars orbiter). When there isn't a straight forward conversion, or where that conversion doesn't "help", we leave it in sensor units. We have not used LabVIEW's convert unit feature.
|
|
#9
|
||||
|
||||
|
Re: How does your team incorporate engineering units?
To the discussion of trade-offs between the benefits of unit checking versus adding to the complexity of the code I will add that making the code harder to read has a very serious downside for FRC that does not exist in some other applications. Namely that FRC code often needs to be very quickly modified and tested between rounds. Adding to the difficulty of reading the code can be a real problem. We have generally tried to include sensor calibration information in the comments for each method.
|
|
#10
|
||||
|
||||
|
Re: How does your team incorporate engineering units?
When we used LV, we were aware that LV had lots of useful data types, but we didn't use the feature mentioned above. To solve the problem of inconsistent units we made all of our outputs clusters that we could unbundle, and each element of the bundle would have a meaningful name with units. Having all the bundle/unbundle, index/build array vi's everywhere got confusing, especially while trying to figure out arrays of clusters and clusters of arrays. In order to simplify the block diagrams, we decided to do all of our math in formula nodes, and figure out all of our equations on a piece of paper, while making sure to check units. This system works, but explaining to newer programmers what type defs are, and how 3d arrays are split into 2d arrays was really tough, and was why we switched to java.
|
|
#11
|
|||||
|
|||||
|
Re: How does your team incorporate engineering units?
We always use the same units and are allergic to things like encoder counts, loop counts, magic constants, etc. All public interfaces speak in terms of standard units, with the exception of open loop speed commands which are in the range [-1, 1]. All return values and arguments are named so that the units are explicit, and a common library is used for any necessary conversions.
Generally we use: Distance = inches Time = seconds Angles = degrees (in yaw 0 degrees is robot forward, increasing clockwise) Rates and accelerations are therefore inches/sec, deg/sec, etc. Inches are used because FIRST field drawings are usually spec'd in inches, so it makes for intuitive autonomous mode scripting. We use degrees for angles due to intuition. 0 degrees is north because usually if we care about degrees we are talking about autonomous mode, so the robot's starting orientation defines the coordinate system. I've played with libraries like Boost Units and javax.units, but always found their syntax clunky. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|