Skip to content

Commit

Permalink
Merge pull request google-deepmind#56 from hartikainen/restructure-hu…
Browse files Browse the repository at this point in the history
…manoid-task-files

Restructure humanoid task files
  • Loading branch information
nimrod-gileadi authored Jan 24, 2023
2 parents 15b4385 + 152f914 commit 67af331
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 112 deletions.
2 changes: 1 addition & 1 deletion docs/OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ The swimmer's cost has two terms:
The repository includes additional example tasks:
- Humanoid [Stand](../mjpc/tasks/humanoid/task_stand.xml) | [Walk](../mjpc/tasks/humanoid/task_walk.xml)
- Humanoid [Stand](../mjpc/tasks/humanoid/stand/task.xml) | [Walk](../mjpc/tasks/humanoid/walk/task.xml)
- Quadruped [Terrain](../mjpc/tasks/quadruped/task_hill.xml) | [Flat](../mjpc/tasks/quadruped/task_flat.xml)
- [Walker](../mjpc/tasks/walker/task.xml)
- [In-Hand Manipulation](../mjpc/tasks/hand/task.xml)
Expand Down
6 changes: 4 additions & 2 deletions mjpc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,10 @@ add_library(
tasks/cartpole/cartpole.h
tasks/hand/hand.cc
tasks/hand/hand.h
tasks/humanoid/humanoid.cc
tasks/humanoid/humanoid.h
tasks/humanoid/stand/task.cc
tasks/humanoid/stand/task.h
tasks/humanoid/walk/task.cc
tasks/humanoid/walk/task.h
tasks/panda/panda.cc
tasks/panda/panda.h
tasks/particle/particle.cc
Expand Down
9 changes: 7 additions & 2 deletions mjpc/planners/ilqg/backward_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ int iLQGBackwardPass::RiccatiStep(
boxqp.H.data(), boxqp.g.data(), m, boxqp.lower.data(),
boxqp.upper.data());
if (mFree < 0) {
// printf("backward_pass failure\n");
printf("backward_pass failure\n");
return 0;
}

Expand Down Expand Up @@ -198,7 +198,12 @@ int iLQGBackwardPass::RiccatiStep(
} else {
// Quut^-1
mju_copy(tmp3, Quu_reg, m * m);
mju_cholFactor(tmp3, m, 0.0);
int rank = mju_cholFactor(tmp3, m, 0.0);

if (rank < m) {
printf("backward pass failure\n");
return 0;
}

// Kt = - Quut \ Qxut
for (int i = 0; i < n; i++) {
Expand Down
101 changes: 101 additions & 0 deletions mjpc/tasks/humanoid/stand/task.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2022 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tasks/humanoid/stand/task.h"

#include <iostream>

#include <mujoco/mujoco.h>
#include "utilities.h"


namespace mjpc {

// ------------------ Residuals for humanoid stand task ------------
// Number of residuals: 6
// Residual (0): Desired height
// Residual (1): Balance: COM_xy - average(feet position)_xy
// Residual (2): Com Vel: should be 0 and equal feet average vel
// Residual (3): Control: minimise control
// Residual (4): Joint vel: minimise joint velocity
// Number of parameters: 1
// Parameter (0): height_goal
// ----------------------------------------------------------------
void humanoid::Stand::Residual(const double* parameters, const mjModel* model,
const mjData* data, double* residual) {
int counter = 0;

// ----- Height: head feet vertical error ----- //

// feet sensor positions
double* f1_position = mjpc::SensorByName(model, data, "sp0");
double* f2_position = mjpc::SensorByName(model, data, "sp1");
double* f3_position = mjpc::SensorByName(model, data, "sp2");
double* f4_position = mjpc::SensorByName(model, data, "sp3");
double* head_position = mjpc::SensorByName(model, data, "head_position");
double head_feet_error =
head_position[2] - 0.25 * (f1_position[2] + f2_position[2] +
f3_position[2] + f4_position[2]);
residual[counter++] = head_feet_error - parameters[0];

// ----- Balance: CoM-feet xy error ----- //

// capture point
double* com_position = mjpc::SensorByName(model, data, "torso_subtreecom");
double* com_velocity = mjpc::SensorByName(model, data, "torso_subtreelinvel");
double kFallTime = 0.2;
double capture_point[3] = {com_position[0], com_position[1], com_position[2]};
mju_addToScl3(capture_point, com_velocity, kFallTime);

// average feet xy position
double fxy_avg[2] = {0.0};
mju_addTo(fxy_avg, f1_position, 2);
mju_addTo(fxy_avg, f2_position, 2);
mju_addTo(fxy_avg, f3_position, 2);
mju_addTo(fxy_avg, f4_position, 2);
mju_scl(fxy_avg, fxy_avg, 0.25, 2);

mju_subFrom(fxy_avg, capture_point, 2);
double com_feet_distance = mju_norm(fxy_avg, 2);
residual[counter++] = com_feet_distance;

// ----- COM xy velocity should be 0 ----- //
mju_copy(&residual[counter], com_velocity, 2);
counter += 2;

// ----- joint velocity ----- //
mju_copy(residual + counter, data->qvel + 6, model->nv - 6);
counter += model->nv - 6;

// ----- action ----- //
mju_copy(&residual[counter], data->ctrl, model->nu);
counter += model->nu;

// sensor dim sanity check
// TODO: use this pattern everywhere and make this a utility function
int user_sensor_dim = 0;
for (int i = 0; i < model->nsensor; i++) {
if (model->sensor_type[i] == mjSENS_USER) {
user_sensor_dim += model->sensor_dim[i];
}
}
if (user_sensor_dim != counter) {
mju_error_i(
"mismatch between total user-sensor dimension "
"and actual length of residual %d",
counter);
}
}

} // namespace mjpc
44 changes: 44 additions & 0 deletions mjpc/tasks/humanoid/stand/task.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2022 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef MJPC_TASKS_HUMANOID_STAND_TASK_H_
#define MJPC_TASKS_HUMANOID_STAND_TASK_H_

#include <mujoco/mujoco.h>

namespace mjpc {
namespace humanoid {

struct Stand {

// ------------------ Residuals for humanoid stand task ------------
// Number of residuals: 6
// Residual (0): control
// Residual (1): COM_xy - average(feet position)_xy
// Residual (2): torso_xy - COM_xy
// Residual (3): head_z - feet^{(i)}_position_z - height_goal
// Residual (4): velocity COM_xy
// Residual (5): joint velocity
// Number of parameters: 1
// Parameter (0): height_goal
// ----------------------------------------------------------------
static void Residual(const double* parameters, const mjModel* model,
const mjData* data, double* residual);

};

} // namespace humanoid
} // namespace mjpc

#endif // MJPC_TASKS_HUMANOID_STAND_TASK_H_
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<mujoco model="Humanoid">
<include file="../common.xml"/>
<include file="humanoid.xml" />
<include file="../../common.xml"/>
<include file="../humanoid.xml" />
<size memory="400K"/>

<custom>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tasks/humanoid/humanoid.h"
#include "tasks/humanoid/walk/task.h"
#include "mujoco/mjmodel.h"

#include <iostream>

Expand All @@ -21,82 +22,6 @@

namespace mjpc {

// ------------------ Residuals for humanoid stand task ------------
// Number of residuals: 6
// Residual (0): Desired height
// Residual (1): Balance: COM_xy - average(feet position)_xy
// Residual (2): Com Vel: should be 0 and equal feet average vel
// Residual (3): Control: minimise control
// Residual (4): Joint vel: minimise joint velocity
// Number of parameters: 1
// Parameter (0): height_goal
// ----------------------------------------------------------------
void Humanoid::ResidualStand(const double* parameters, const mjModel* model,
const mjData* data, double* residual) {
int counter = 0;

// ----- Height: head feet vertical error ----- //

// feet sensor positions
double* f1_position = mjpc::SensorByName(model, data, "sp0");
double* f2_position = mjpc::SensorByName(model, data, "sp1");
double* f3_position = mjpc::SensorByName(model, data, "sp2");
double* f4_position = mjpc::SensorByName(model, data, "sp3");
double* head_position = mjpc::SensorByName(model, data, "head_position");
double head_feet_error =
head_position[2] - 0.25 * (f1_position[2] + f2_position[2] +
f3_position[2] + f4_position[2]);
residual[counter++] = head_feet_error - parameters[0];

// ----- Balance: CoM-feet xy error ----- //

// capture point
double* com_position = mjpc::SensorByName(model, data, "torso_subtreecom");
double* com_velocity = mjpc::SensorByName(model, data, "torso_subtreelinvel");
double kFallTime = 0.2;
double capture_point[3] = {com_position[0], com_position[1], com_position[2]};
mju_addToScl3(capture_point, com_velocity, kFallTime);

// average feet xy position
double fxy_avg[2] = {0.0};
mju_addTo(fxy_avg, f1_position, 2);
mju_addTo(fxy_avg, f2_position, 2);
mju_addTo(fxy_avg, f3_position, 2);
mju_addTo(fxy_avg, f4_position, 2);
mju_scl(fxy_avg, fxy_avg, 0.25, 2);

mju_subFrom(fxy_avg, capture_point, 2);
double com_feet_distance = mju_norm(fxy_avg, 2);
residual[counter++] = com_feet_distance;

// ----- COM xy velocity should be 0 ----- //
mju_copy(&residual[counter], com_velocity, 2);
counter += 2;

// ----- joint velocity ----- //
mju_copy(residual + counter, data->qvel + 6, model->nv - 6);
counter += model->nv - 6;

// ----- action ----- //
mju_copy(&residual[counter], data->ctrl, model->nu);
counter += model->nu;

// sensor dim sanity check
// TODO: use this pattern everywhere and make this a utility function
int user_sensor_dim = 0;
for (int i = 0; i < model->nsensor; i++) {
if (model->sensor_type[i] == mjSENS_USER) {
user_sensor_dim += model->sensor_dim[i];
}
}
if (user_sensor_dim != counter) {
mju_error_i(
"mismatch between total user-sensor dimension "
"and actual length of residual %d",
counter);
}
}

// ------------------ Residuals for humanoid walk task ------------
// Number of residuals:
// Residual (0): torso height
Expand All @@ -111,8 +36,8 @@ void Humanoid::ResidualStand(const double* parameters, const mjModel* model,
// Parameter (0): torso height goal
// Parameter (1): speed goal
// ----------------------------------------------------------------
void Humanoid::ResidualWalk(const double* parameters, const mjModel* model,
const mjData* data, double* residual) {
void humanoid::Walk::Residual(const double* parameters, const mjModel* model,
const mjData* data, double* residual) {
int counter = 0;

// ----- torso height ----- //
Expand Down
30 changes: 11 additions & 19 deletions mjpc/tasks/humanoid/humanoid.h → mjpc/tasks/humanoid/walk/task.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef MJPC_TASKS_HUMANOID_HUMANOID_H_
#define MJPC_TASKS_HUMANOID_HUMANOID_H_
#ifndef MJPC_TASKS_HUMANOID_WALK_TASK_H_
#define MJPC_TASKS_HUMANOID_WALK_TASK_H_

#include <mujoco/mujoco.h>

namespace mjpc {
struct Humanoid {
// ------------------ Residuals for humanoid stand task ------------
// Number of residuals: 6
// Residual (0): control
// Residual (1): COM_xy - average(feet position)_xy
// Residual (2): torso_xy - COM_xy
// Residual (3): head_z - feet^{(i)}_position_z - height_goal
// Residual (4): velocity COM_xy
// Residual (5): joint velocity
// Number of parameters: 1
// Parameter (0): height_goal
// ----------------------------------------------------------------
static void ResidualStand(const double* parameters, const mjModel* model,
const mjData* data, double* residual);
namespace humanoid {

struct Walk {

// ------------------ Residuals for humanoid walk task ------------
// Number of residuals:
Expand All @@ -47,9 +36,12 @@ struct Humanoid {
// Parameter (0): torso height goal
// Parameter (1): speed goal
// ----------------------------------------------------------------
static void ResidualWalk(const double* parameters, const mjModel* model,
const mjData* data, double* residual);
static void Residual(const double* parameters, const mjModel* model,
const mjData* data, double* residual);

};

} // namespace humanoid
} // namespace mjpc

#endif // MJPC_TASKS_HUMANOID_HUMANOID_H_
#endif // MJPC_TASKS_HUMANOID_WALK_TASK_H_
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<mujoco model="Humanoid Locomotion">
<include file="../common.xml"/>
<include file="humanoid.xml" />
<include file="../../common.xml"/>
<include file="../humanoid.xml" />
<size memory="400K"/>
<custom>
<numeric name="agent_planner" data="2" />
Expand Down
11 changes: 6 additions & 5 deletions mjpc/tasks/tasks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
#include "tasks/acrobot/acrobot.h"
#include "tasks/cartpole/cartpole.h"
#include "tasks/hand/hand.h"
#include "tasks/humanoid/humanoid.h"
#include "tasks/humanoid/stand/task.h"
#include "tasks/humanoid/walk/task.h"
#include "tasks/panda/panda.h"
// DEEPMIND INTERNAL IMPORT
#include "tasks/particle/particle.h"
Expand All @@ -35,13 +36,13 @@ namespace {
const TaskDefinition<const char*> kTasksArray[]{
{
.name = "Humanoid Stand",
.xml_path = "humanoid/task_stand.xml",
.residual = &Humanoid::ResidualStand,
.xml_path = "humanoid/stand/task.xml",
.residual = &humanoid::Stand::Residual,
},
{
.name = "Humanoid Walk",
.xml_path = "humanoid/task_walk.xml",
.residual = &Humanoid::ResidualWalk,
.xml_path = "humanoid/walk/task.xml",
.residual = &humanoid::Walk::Residual,
},
{
.name = "Swimmer",
Expand Down

0 comments on commit 67af331

Please sign in to comment.