If it helps, I generally start with the Pattern Info, and then I set a state differently, usually setting all the parameters (range, start, end).
I will start checking this in my simulations also
![Laughing :lol:](./images/smilies/icon_lol.gif)
Code: Select all
problem.setStateInfo('/jointset/crank_angle/crank_angle/speed', [-100, 0])
problem.setStateInfoPattern('/jointset/.*/.*/speed', [], 0.0, [])
Yeah, I thought so as well, but it is weird.The model with the crank + human will apply forces to enforce the kinematic constraints, but these forces alone shouldn't lead to the crank motion.
I set the joint torques to [-50;50] for the right and left knees and right and left hips. Ankle joints are locked.Are the joint torques much smaller than the crank resistance torque?
Code: Select all
num_mesh: 25
convergence_tol: 1e-1
constraint_tol: 1e-4
osim.MocoFinalTimeGoal('final_time', 10)
osim.MocoControlGoal('min_effort', 1)
I suppose that the forces between the foot and crank could be larger (in order to enforce the constraint), but the joint torques small in the case when the crank resistance is low
Code: Select all
problem.setControlInfo('/tau_hip_flexion_r', [-joint_torque, joint_torque])
problem.setControlInfo('/tau_hip_flexion_l', [-joint_torque, joint_torque])
problem.setControlInfo('/tau_knee_angle_r', [-joint_torque, joint_torque])
problem.setControlInfo('/tau_knee_angle_l', [-joint_torque, joint_torque])
Code: Select all
def create_the_speed_sto_file(name_sto_file, max_speed_deg, duration):
dt = 0.05
max_speed_rad = np.deg2rad(max_speed_deg)#*2*np.pi/60
stoLabels = ['time', '/jointset/crank_angle/crank_angle/speed']
sto = osim.Storage()
col_labels = osim.ArrayStr()
for label in stoLabels:
col_labels.append(label)
sto.setColumnLabels(col_labels)
time_vector = np.arange(0, duration + dt, dt)
speed_vector = - np.minimum(time_vector * (2 * max_speed_rad / duration), max_speed_rad)
data = np.transpose(np.array([time_vector, speed_vector]))
nrow, ncol = data.shape
for i in range(nrow):
row = osim.ArrayDouble()
for j in range(ncol):
row.append(data[i, j])
row_without_time = osim.ArrayDouble(row.getSize() - 1)
for k in range(1, row.getSize()):
row_without_time.setitem(k - 1, row.getitem(k))
sto.append(data[i, 0], row_without_time)
sto.setName(name_sto_file)
sto.setInDegrees(False)
sto.printResult(sto, name_sto_file, os.getcwd(), dt, '.sto')
ref = osim.TableProcessor(name_sto_file + ".sto")
return ref
Code: Select all
def add_speed_goal_control(problem, max_speed, start_time, end_time, weight=None):
# Create the sto file and get the reference
ref = create_the_speed_sto_file("crank_speed", max_speed, end_time)
# Add the goal
tracking = osim.MocoStateTrackingGoal()
tracking.setName('speed_tracking')
tracking.setReference(ref)
tracking.setAllowUnusedReferences(True)
tracking.setWeightForState('/jointset/crank_angle/crank_angle/speed', weight)
problem.addGoal(tracking)
# Set time bonds
problem.setTimeBounds(start_time, end_time)
return problem
Code: Select all
coord_set = model.updCoordinateSet()
actu = osim.CoordinateActuator()
actu.setName('tau_' + coord_name)
actu.setCoordinate(coord_set.get(coord_name))
actu.setOptimalForce(1.0)
model.addComponent(actu)
Code: Select all
problem.setControlInfo('/tau_crank_angle',[-10., 10.])