Share 
Follow 
AboutDownloadsDocumentsForumsSource CodeIssuesNews
Date:
2013-07-30 16:43
Priority:
3
State:
Open
Submitted by:
Christopher Dembia (chrisdembia)
Assigned to:
Ayman Habib (aymanh)
Summary:
Refinements on converting data in Storage to Controls

Detailed description
I see there are a number of ways in the API to go from a Storage file to a controller; whether it's an actual Controller or a ControlSet to specify control constraints while another controller (CMC) is actually in charge. Despite these great tools, I was not able to easily do what I wanted.

I wanted to take the joint torque output from RRA and apply that torque profile as a CoordinateActuator during CMC. So this is already perhaps a unique case, where the data in the Storage is from OpenSim itself; I presume the typical use case is that the user is making the Storage using their own non-OpenSim data, and they are using Storage just as a data file format (e.g., a CSV file). I was using Jython scripting to do this. I am more focused on converting Storage to ControlSet, but these issues my also be relevant for converting to a Controller.

In any case, here are the issues I ran into:

1) The names of the columns in the RRA-output Storage file containing joint torques (Actuator_force.sto) had column names that were NOT the name of my actuator (my actuators were ankle_robot_r, ankle_robot_l). The API makes the assumption that the Storage column names correspond to an actuator name. It would have been helpful for me if I could rename columns in the Storage file easily; it seems possible (by providing an edited Array of all the Storage column names?). I don't want to have to edit the Storage file (column names) manually.

2) The columns of the Storage file I wanted to use for Control were not necessarily adjacent. So, using '# of columns' and 'index of first column to use' were not sufficient for me to convert Storage directly to ControlSet.

3) I also felt uncomfortable using the default values for the resulting ControlLinear's that the ControlSet(Storage) constructor creates. I wanted to edit default_min/default_max to not be the values used for muscles.

The resolution that solved all 3 of these issues was to do the following:

sto = Storage(sto_fpath)
state_index = sto.getStateIndex('ankle_angle_r')
sto.mutiplyColumn(state_index, 0.5)
cset_r = ControlSet(sto, 1, state_index)

clin_r = ControlLinear.safeDownCast(cset_r.get(0))
clin_r.setName('ankle_robot_r.excitation')
clin_r.setDefaultParameterMin(-1000)
clin_r.setDefaultParameterMax(1000)
clin_r.setUseSteps(True)
clin_r.setExtrapolate(False)

actual_cset.cloneAndAppend(clin_r)

(I believe that having extrapolate as True could lead to unintended behavior.)

As you can see, I am basically using the ControlSet(Storage) constructor to generate a ControlLinear, that I then modify and place into the ControlSet I'm actually going to use. I do this again for the left actuator. So in my particular use case, since I'm using the API/scripting, it was preferable to have a ControlLinear(Storage, index) constructor instead of a ControlSet(Storage) instructor. But this is exactly what ControlSet::ExtractControl() does! So maybe one option is to move ExtractControl() to ControlLinear(Storage), or to a static function ControlLinear::fromStorage(), since the code is there anyway, just as a private function.

Also, why does ControlSet::ExtractControl() start with a capital "E"?

Something that did work well is that I wanted to manipulate the data in the Storage; I wanted to scale down the desired column by a constant number, and the Storage interface allowed me to do this before converting it into a ControlSet. So it's good these methods take a Storage object rather than a filename of a .sto/.mot file.

Add A Comment: Notepad

No Comments Have Been Posted

No Changes Have Been Made to This Item

Feedback