Metadata-Version: 2.5
Name: PolyElmap
Version: 1.0.2
Summary: A Python package for polyline elastic maps.
Project-URL: Homepage, https://github.com/brenhertel/PolyElmap
Project-URL: Issues, https://github.com/brenhertel/PolyElmap/issues
Author-email: Brendan Hertel <brenhertel@gmail.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.9
Requires-Dist: numpy>=1.14.0
Requires-Dist: scipy>=0.19.0
Description-Content-Type: text/markdown

# PolyElmap

# Generate Polyline Elastic Maps

This package implements Elastic Maps [1], specifically a polyline version of Elastic Maps. These maps can be used for many purposes, with the intention of this package to specialize use for generating robot trajectories [2].

# Installation
Install with pip

```
python -m pip install PolyElmap
```
or clone and install from source.
```
git clone https://github.com/brenhertel/PolyElmap
python -m pip install ./PolyElmap
```

# Example usage
This shows you how to compute the various similarity measures
```python
import numpy as np
from PolyElmap import elmap
import matplotlib.pyplot as plt

# demonstration setup
num_points = 1000
t = np.linspace(0, 10, num_points).reshape((num_points, 1))
x_demo = np.sin(t) + 0.01 * t**2 - 0.05 * (t-5)**2
y_demo = np.cos(t) - 0.01 * t - 0.03 * t**2
traj = np.hstack((x_demo, y_demo))

# default params, no constraints
repro1 = elmap([traj], inds=[], consts=[], params={})

# default params, start/end constraints
repro2 = elmap([traj], inds=[0, -1], consts=[np.array([x_demo[0]+0.5, y_demo[0]-0.2]).flatten(), np.array([x_demo[-1], y_demo[-1]]).flatten()], params={})

# custom params, start/end constraints
new_params = {
    'downsampling' : 'distance',
    'weighting' : 'curvature',
    'stretch' : 0.000001,
    'bend' : 0.00001,
    'n' : 200,
    'iters' : 100,
    'use_sparse' : True,
    'pre_transform' : True
}
repro3 = elmap([traj], inds=[0, -1], consts=[np.array([x_demo[0]+0.5, y_demo[0]-0.2]).flatten(), np.array([x_demo[-1], y_demo[-1]]).flatten()], params=new_params)
    
# plotting
plt.rcParams['figure.figsize'] = (6.5, 6.5)
fig, axs = plt.subplots(2, 2)
axs[0][0].set_title('Demonstration')
axs[1][0].set_title('All defaults')
axs[0][1].set_title('Init/Final Consts')
axs[1][1].set_title('Consts and Params')
axs[0][0].plot(traj[:, 0], traj[:, 1], 'k', lw=3)
axs[1][0].plot(traj[:, 0], traj[:, 1], 'k', lw=3)
axs[0][1].plot(traj[:, 0], traj[:, 1], 'k', lw=3)
axs[1][1].plot(traj[:, 0], traj[:, 1], 'k', lw=3)

axs[1][0].plot(repro1[:, 0], repro1[:, 1], 'r', lw=3)

axs[0][1].plot(repro2[:, 0], repro2[:, 1], 'g', lw=3)
axs[0][1].plot(x_demo[0], y_demo[0], 'k.', ms=10)
axs[0][1].plot(x_demo[-1], y_demo[-1], 'k.', ms=10)
axs[0][1].plot(x_demo[0]+0.5, y_demo[0]-0.2, 'rx', ms=10, mew=2)
axs[0][1].plot(x_demo[-1], y_demo[-1], 'rx', ms=10, mew=2)

axs[1][1].plot(repro3[:, 0], repro3[:, 1], 'm', lw=3)
axs[1][1].plot(x_demo[0], y_demo[0], 'k.', ms=10)
axs[1][1].plot(x_demo[-1], y_demo[-1], 'k.', ms=10)
axs[1][1].plot(x_demo[0]+0.5, y_demo[0]-0.2, 'rx', ms=10, mew=2)
axs[1][1].plot(x_demo[-1], y_demo[-1], 'rx', ms=10, mew=2)

plt.show()
```

# Elmap I/O
```
inputs
  demos: list of demonstrations, which are n x d numpy arrays
  inds (optional): list of indices (ints) of selected constraints (note: indices are for the final elmap reproduction)
  consts (optional): location of constraints, should be a list of d-dimensional numpy arrays
  params (optional): optional additional parameters
    'downsampling' : 'naive' (default), 'distance', or 'douglaspeucker',
    'weighting' : 'uniform' (default), 'curvature', or 'jerk'
    'stretch' : float for stretching parameter lambda (default=0.01)
    'bend' : float for bending parameter mu (default=0.01)
    'n' : int for number of nodes in resulting elastic map (default=100)
    'iters' : int for number of iterations to run Expectation-Maximization optimization (default=50)
    'use_sparse' : boolean for whether or not to use numpy arrays or sparse scipy arrays (can be faster with a large number of points) (note: changing this parameter can lead to different results even keeping all other conditions the same) (default=False) 
    'pre_transform' : boolean for whether to use LTE [3] to transform demonstrations to match constraints before running elastic maps (can be useful if constraints are well outside demonstration space) (default=False)
output
  traj: resulting elastic map trajectory
```

# References
[1] Gorban, Alexander N., and Andrei Y. Zinovyev. "Principal graphs and manifolds." In Handbook of research on machine learning applications and trends: algorithms, methods, and techniques, pp. 28-59. IGI Global Scientific Publishing, 2010.

[2] Hertel, Brendan, Matthew Pelland, and S. Reza Ahmadzadeh. "Robot learning from demonstration using elastic maps." In 2022 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), pp. 7407-7413. IEEE, 2022.

[3] Nierhoff, Thomas, Sandra Hirche, and Yoshihiko Nakamura. "Spatial adaption of robot trajectories based on laplacian trajectory editing." Autonomous Robots 40, no. 1 (2016): 159-173.

# Please Cite
If you've found this information or library helpful please cite the following paper.

Hertel, Brendan, Matthew Pelland, and S. Reza Ahmadzadeh. "Robot learning from demonstration using elastic maps." In 2022 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), pp. 7407-7413. IEEE, 2022.

```
@inproceedings{hertel2022elmap,
  title={Robot learning from demonstration using elastic maps},
  author={Hertel, Brendan and Pelland, Matthew and Ahmadzadeh, S Reza},
  booktitle={2022 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
  pages={7407--7413},
  year={2022},
  organization={IEEE}
}
```

# Contact
If you have any questions, please contact Brendan Hertel (brenhertel@gmail.com).