Skip to content
This repository has been archived by the owner on Dec 14, 2022. It is now read-only.

Commit

Permalink
Python 3 compatibility and update headers to GPL
Browse files Browse the repository at this point in the history
  • Loading branch information
Stéphane Caron committed Oct 16, 2019
1 parent 0f4c022 commit 5848443
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 124 deletions.
31 changes: 15 additions & 16 deletions benchmark/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
# <https://github.com/stephane-caron/3d-balance>.
#
# 3d-balance is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 3d-balance is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with 3d-balance. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License along with
# 3d-balance. If not, see <http://www.gnu.org/licenses/>.

import os
import IPython
Expand All @@ -35,7 +34,7 @@
script_path = os.path.realpath(__file__)
sys.path = [os.path.dirname(script_path) + '/..'] + sys.path
from punkah import InvertedPendulum, Stabilizer2D, Stabilizer3D
except: # this is to avoid warning E402 from Pylint
except Exception: # this is to avoid warning E402 from Pylint
pass

TOTAL_LAUNCHES = 100
Expand Down Expand Up @@ -76,7 +75,7 @@ def reset_state(scenario):
sim = pymanoid.Simulation(dt=3e-2)
try: # use HRP4 if available
robot = pymanoid.robots.HRP4()
except: # otherwise use default model
except Exception: # otherwise use default model
robot = pymanoid.robots.JVRC1()
robot.set_transparency(0.5)
robot.suntan()
Expand Down Expand Up @@ -135,25 +134,25 @@ def reset_state(scenario):
error("Unfeasible state encountered during execution")
break
sim.step()
print "\n------------------------------------------\n"
print "Launch %d for %s" % (
nb_launches + 1, type(stabilizer).__name__)
print("\n------------------------------------------\n")
print("Launch %d for %s" % (
nb_launches + 1, type(stabilizer).__name__))
stabilizer.solver.print_debug_info()
nb_2d_samples = len(stabilizer_2d.solver.solve_times)
nb_3d_samples = len(stabilizer_3d.solver.solve_times)
nb_samples = min(nb_2d_samples, nb_3d_samples)
nb_launches += 1

print "Results"
print "-------"
print("Results")
print("-------")
for stabilizer in [stabilizer_2d, stabilizer_3d]:
msg = "Solve time: %.1f +/- %.1f ms over %d samples, %d launches" % (
1000 * average(stabilizer.solver.solve_times),
1000 * std(stabilizer.solver.solve_times),
len(stabilizer.solver.solve_times), nb_launches)
name = type(stabilizer).__name__
print "%s: %s" % (name, msg)
print ""
print("%s: %s" % (name, msg))
print("")

if IPython.get_ipython() is None:
IPython.embed()
13 changes: 6 additions & 7 deletions punkah/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
# <https://github.com/stephane-caron/3d-balance>.
#
# 3d-balance is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 3d-balance is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with 3d-balance. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License along with
# 3d-balance. If not, see <http://www.gnu.org/licenses/>.

from pendulum import InvertedPendulum
from stabilize2d import Stabilizer2D
Expand Down
31 changes: 16 additions & 15 deletions punkah/convex.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
# <https://github.com/stephane-caron/3d-balance>.
#
# 3d-balance is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 3d-balance is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with 3d-balance. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License along with
# 3d-balance. If not, see <http://www.gnu.org/licenses/>.

from bisect import bisect_right
from numpy import array, linspace, log, sqrt
Expand All @@ -40,9 +39,9 @@ class ConvexProblem(object):
"""

def __init__(self, lambda_min, lambda_max, nb_steps):
s_list = [i * 1. / nb_steps for i in xrange(nb_steps)] + [1.]
s_list = [i * 1. / nb_steps for i in range(nb_steps)] + [1.]
s_sq = [s ** 2 for s in s_list]
Delta = [s_sq[i + 1] - s_sq[i] for i in xrange(nb_steps)]
Delta = [s_sq[i + 1] - s_sq[i] for i in range(nb_steps)]
self.Delta = Delta
self.N = nb_steps
self.Phi = None
Expand Down Expand Up @@ -72,7 +71,7 @@ def get_omega_i(self):
def compute_lambda(self):
lambda_ = [
(self.Phi[i + 1] - self.Phi[i]) / self.Delta[i]
for i in xrange(self.N)]
for i in range(self.N)]
lambda_ = array(lambda_ + [lambda_[-1]])
self.lambda_ = lambda_

Expand All @@ -92,7 +91,8 @@ def lambda_from_s(self, s):
Note
----
This function is not called by the stabilizer, but useful for debugging.
This function is not called by the stabilizer, but useful for
debugging.
"""
i = bisect_right(self.s, s) - 1 if s > 0 else 0
assert self.s[i] <= s and (i == self.N or s < self.s[i + 1])
Expand All @@ -114,7 +114,8 @@ def omega_from_s(self, s):
Note
----
This function is not called by the stabilizer, but useful for debugging.
This function is not called by the stabilizer, but useful for
debugging.
"""
if s < 1e-3:
return sqrt(self.lambda_[0])
Expand All @@ -136,7 +137,7 @@ def compute_switch_times(self):
"""
switch_times = [0.]
switch_time = 0.
for i in xrange(self.N - 1, 0, -1):
for i in range(self.N - 1, 0, -1):
num = sqrt(self.Phi[i + 1]) + sqrt(self.lambda_[i]) * self.s[i + 1]
denom = sqrt(self.Phi[i]) + sqrt(self.lambda_[i]) * self.s[i]
duration = log(num / denom) / sqrt(self.lambda_[i])
Expand All @@ -150,7 +151,7 @@ def compute_full_trajectory(self):

def find_switch_time_before(self, t):
"""
Find a switch time :math:`t_i` such that :math:`t_i \leq t < t_{i+1}`.
Find a switch time :math:`t_i` such that :math:`t_i \\leq t < t_{i+1}`.
Parameters
----------
Expand Down Expand Up @@ -236,7 +237,7 @@ def plot_s(self):
from pylab import grid, legend, plot, step, xlabel, ylim

def subsample(s):
s2 = [(s[i] + s[i + 1]) / 2. for i in xrange(len(s) - 1)]
s2 = [(s[i] + s[i + 1]) / 2. for i in range(len(s) - 1)]
s2.extend(s)
s2.sort()
return s2
Expand Down
19 changes: 8 additions & 11 deletions punkah/pendulum.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
# <https://github.com/stephane-caron/3d-balance>.
#
# 3d-balance is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 3d-balance is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with 3d-balance. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License along with
# 3d-balance. If not, see <http://www.gnu.org/licenses/>.

import pymanoid

Expand Down Expand Up @@ -67,7 +66,8 @@ def target(self):

def copy(self):
return InvertedPendulum(
self.com.mass, self.com.p, self.com.pd, self.contact, self.z_target)
self.com.mass, self.com.p, self.com.pd, self.contact,
self.z_target)

def hide(self):
self.com.hide()
Expand Down Expand Up @@ -121,9 +121,6 @@ def draw(self, step=0.02):
self.handles['parabola'] = draw_trajectory(parabola, pointsize=0)

def integrate(self, duration):
if __debug__ and abs(dot(self.contact.n, self.cop)) > 1e-10:
self.cop = self.cop - dot(self.cop, self.contact.n) * self.contact.n
warn("CoP was offset from contact surface")
omega = sqrt(self.lambda_)
p0 = self.com.p
pd0 = self.com.pd
Expand Down
13 changes: 6 additions & 7 deletions punkah/stabilize.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
# <https://github.com/stephane-caron/3d-balance>.
#
# 3d-balance is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 3d-balance is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with 3d-balance. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License along with
# 3d-balance. If not, see <http://www.gnu.org/licenses/>.

from numpy import array, cross, dot, vstack

Expand Down
55 changes: 27 additions & 28 deletions punkah/stabilize2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@
# <https://github.com/stephane-caron/3d-balance>.
#
# 3d-balance is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option) any
# later version.
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 3d-balance is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with 3d-balance. If not, see <http://www.gnu.org/licenses/>.
# You should have received a copy of the GNU General Public License along with
# 3d-balance. If not, see <http://www.gnu.org/licenses/>.

from casadi import sqrt as casadi_sqrt
from numpy import array, sqrt
Expand Down Expand Up @@ -55,7 +54,7 @@ def compute_Phi(self):
lambda_cost = 0.
lambda_guess = self.omega_i ** 2
lambda_prev = self.omega_f ** 2
for i in xrange(self.N):
for i in range(self.N):
Phi_next = nlp.new_variable(
'Phi_%d' % (i + 1), # from Phi_1 to Phi_N
dim=1,
Expand Down Expand Up @@ -117,32 +116,32 @@ def succ(a, b):
return
out_bc_integral = sum(self.Delta[i] / (
sqrt(self.Phi[i + 1]) + sqrt(self.Phi[i]))
for i in xrange(self.N))
for i in range(self.N))
out_omega_i = sqrt(self.Phi[self.N])
out_omega_f = sqrt(self.Phi[1] / self.Delta[0])
succ_omega_i = succ(self.omega_i, out_omega_i)
succ_omega_f = succ(self.omega_f, out_omega_f)
succ_bc_integral = succ(self.bc_integral, out_bc_integral)
print "Init. state: %.1f%%" % succ_omega_i
print "Limit state: %.1f%%" % succ_omega_f
print "Boundedness: %.1f%%" % succ_bc_integral
print "Avg. solve time: %.1f +/- %.1f ms over %d samples" % (
print("Init. state: %.1f%%" % succ_omega_i)
print("Limit state: %.1f%%" % succ_omega_f)
print("Boundedness: %.1f%%" % succ_bc_integral)
print("Avg. solve time: %.1f +/- %.1f ms over %d samples" % (
1000 * average(self.solve_times), 1000 * std(self.solve_times),
len(self.solve_times))
len(self.solve_times)))

def print_instance(self):
print "(zd_bar + omega_i * z_bar) / g = %f;" % self.bc_integral
print "Delta = %s;" % str(list(self.Delta))
print "g = %f;" % -gravity[2]
print "lambda_max = %f;" % self.lambda_max
print "lambda_min = %f;" % self.lambda_min
print "omega_i = %f;" % self.omega_i
print "s = %s;" % str(list(self.s))
print "z_f = %f;" % (-gravity[2] / self.omega_f ** 2)
print("(zd_bar + omega_i * z_bar) / g = %f;" % self.bc_integral)
print("Delta = %s;" % str(list(self.Delta)))
print("g = %f;" % -gravity[2])
print("lambda_max = %f;" % self.lambda_max)
print("lambda_min = %f;" % self.lambda_min)
print("omega_i = %f;" % self.omega_i)
print("s = %s;" % str(list(self.s)))
print("z_f = %f;" % (-gravity[2] / self.omega_f ** 2))
if self.Phi is not None:
print ""
print "(solution)"
print "Phi = %s;" % str(list(self.Phi))
print("")
print("(solution)")
print("Phi = %s;" % str(list(self.Phi)))


class Stabilizer2D(Stabilizer):
Expand All @@ -164,8 +163,8 @@ def z_crit(self, state):
References
----------
.. [Koolen2016] "Balance control using center of mass height variation:
Limitations imposed by unilateral contact", T. Koolen, M. Posa and R.
Tedrake, IEEE-RAS International Conference on Humanoid Robots,
Limitations imposed by unilateral contact", T. Koolen, M. Posa and
R. Tedrake, IEEE-RAS International Conference on Humanoid Robots,
November 2016.
"""
z, zd = state.z, state.zd
Expand Down Expand Up @@ -216,7 +215,7 @@ def draw_solution(self):
virt_pendulum.hide()
points = []
max_time = solver.switch_times[-1] * 2
for i in xrange(solver.N):
for i in range(solver.N):
t_i = solver.switch_times[i]
t_next = solver.switch_times[i + 1] if i < N - 1 else max_time
virt_pendulum.set_lambda(solver.lambda_[N - i - 1])
Expand Down
Loading

0 comments on commit 5848443

Please sign in to comment.