|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#16
|
||||
|
||||
|
Re: Reducing code complexity
Quote:
Like many things in life I didn't really appreciate them until they were denied to me. |
|
#17
|
||||
|
||||
|
Re: Reducing code complexity
Quote:
|
|
#18
|
|||||
|
|||||
|
Re: Reducing code complexity
Quote:
Lookup/Interpolation tables are also my favorites. I'm surprised I don't see them more in FRC. As a note to LV users in this thread, you can make a typedef enum in LV by making a custom control (go to New instead of New VI and it's an option), set it to 'strict type def' and drop an enum. Anywhere you use it, it will auto-update to the type def, so you can change the control (.ctl file) and all of the constants and controls will update. When you create it, the order will define the associated number (it's to the right of the name), which is what you get if you use the enum as a uint. A similar method works for typedef struct, you just need a Cluster full of stuff. |
|
#19
|
||||
|
||||
|
Re: Reducing code complexity
Quote:
We do use static final int and a naming convention to simulate enum, but of course you lose the benefit of syntactic typing constraints. My point was to subtly indicate that some of the earlier suggestions don't translate directly to the current platform due to Java ME limitations. |
|
#20
|
|||
|
|||
|
Re: Reducing code complexity
My Java skills are a bit crusty but this should give you an idea.
Code:
// Enum replacement for State in my previous post
public class State{
public static final State Initializing = new State();
public static final State Waiting = new State();
// and so on
}
State state = State.Initializing;
// No support for instances in switch in Java
if (state == State.Initializing)
{
}
else if (state == State.Waiting)
{
}
// and so on
|
|
#21
|
|||||
|
|||||
|
Re: Reducing code complexity
Quote:
So, what's your beef with command based stuff? |
|
#22
|
||||
|
||||
|
Re: Reducing code complexity
There's nothing saying you can't make your own Command to do it, though. CommandGroups are just Commands implementing a special case of a state machine. Also, an interesting thing to note is that if you use requires(), each Subsystem acts as a state machine with Commands as the states (and it's really easy to add a state for these, as it just involves adding requires() to a Command's constructor).
|
|
#23
|
|||||
|
|||||
|
Re: Reducing code complexity
Quote:
|
|
#24
|
||||
|
||||
|
Re: Reducing code complexity
Quote:
|
|
#25
|
|||
|
|||
|
Re: Reducing code complexity
I highly recommend separating your code into classes per subsystem. In terms of condensing your code you will see the most benefit if you do that - it will also make your code easier to read while some of the other methods will save very little space and make your code more difficult to read.
Last edited by Gigakaiser : 01-05-2013 at 20:52. |
|
#26
|
|||
|
|||
|
Re: Reducing code complexity
Just a hint: take full use of classes and inheritances.
|
|
#27
|
||||
|
||||
|
Re: Reducing code complexity
My major beef with the command based stuff is that it makes it harder to understand the system as a whole. If you have commands that don't complete immediately, it can be hard to know exactly what is happening. You end up at a place with neither a simple set of variables that tells you everything that's going on nor a straightforward callgraph to follow.
Here's a more minor problem: Our autonomous mode became Code:
correct angle -> shooter speed -> shoot Code:
correct angle-\
+--> shoot
shooter speed-/
I get that it's also easier to do the steps linearly in non-command based code, but it's not much different. You'd go from: Code:
switch(mode){
case 0:
run_aim_stuff()
if(aimed) mode=1;
break;
case 1:
turn_on_shooter()
if(up_to_speed) mode=2;
break;
case 2:
shoot()
if(done) mode=3
break;
case 3:
...
}
Code:
switch(mode){
case 0:
if(!aimed) run_aim_stuff()
if(!up_to_speed) turn_on_shooter()
if(aimed && up_to_speed){
shoot()
if(done) mode=3
}
break;
case 3:
...
}
|
|
#28
|
||||
|
||||
|
Re: Reducing code complexity
Quote:
Code:
addParallel(new MoveAngle()); addParallel(new SpinUpShooter()); addSequential(new WaitForChildren()); addSequential(new Shoot()); |
|
#29
|
|||||
|
|||||
|
Re: Reducing code complexity
This thread reminds me why I dislike Java and the command architecture for embedded systems.
I've always designed the code so we can pass desired setpoints in a single auton function then terminate. That way, we send the Set command in the script, and the subsystem listens and controls to that commanded value indefinitely (or until disable->enable transition). This way, the subsystem holds all of the code required to fully run a mechanism, and the rest of the code just is just a button map or auton command. I can test the subsystem individually by commanding setpoint directly, and verify results using all of the data present in the subsystem. In our C code for Vex, each subsystem gets a single C and two H files (since RobotC dosen't exactly work like normal C, the data is in a H with externs in the other H, if we used 'real' C the data would be in a C, code in a C, and externs/prototypes/typedefs in a H). Main (which runs the main task and HMI) gets another C, and Auton has a few files (autosel, routines, psc, nav). All of the code fits easily in a single directory, and totals ~1400 lines (lots of comments and diagnostics). |
|
#30
|
||||||
|
||||||
|
Re: Reducing code complexity
Quote:
1)Send a setpoint and exit immediately while holding the setpoint. 2)Send a setpoint, wait for it to get there, then exit and keep holding. 3)Send a setpoint, wait for it to get there, then exit and stop holding Not sure why you think there's only one way to write things with the command system. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|