def __str__(self):
        """
        Pretty prints the ETS Model of the robot. Will output angles in
        degrees

        :return: Pretty print of the robot model
        :rtype: str

        Constant links are shown in blue.
        End-effector links are prefixed with an @
        """
        table = ANSITable(Column("id", headalign="^"),
                          Column("link", headalign="^"),
                          Column("parent", headalign="^"),
                          Column("joint", headalign="^"),
                          Column("ETS", headalign="^", colalign=">"),
                          border="thin")
        for k, link in enumerate(self):
            color = "" if link.isjoint else "<<blue>>"
            ee = "@" if link in self.ee_links else ""
            ets = link.ets()
            table.row(k, color + ee + link.name,
                      link.parent.name if link.parent is not None else "-",
                      link._joint_name if link.parent is not None else "",
                      ets.__str__(f"q{link._jindex}"))

        s = str(table)
        s += self.configurations_str()

        return s
    def configurations_str(self):
        deg = 180 / np.pi

        # TODO: factor this out of DHRobot
        def angle(theta, fmt=None):

            if fmt is not None:
                return fmt.format(theta * deg) + "\u00b0"
            else:
                return str(theta * deg) + "\u00b0"

        config = self.config()
        # show named configurations
        if len(self._configdict) > 0:
            table = ANSITable(Column("name", colalign=">"),
                              *[
                                  Column(f"q{j:d}",
                                         colalign="<",
                                         headalign="<") for j in range(self.n)
                              ],
                              border="thin")

            for name, q in self._configdict.items():
                qlist = []
                for i, c in enumerate(config):
                    if c == 'P':
                        qlist.append(f"{q[i]: .3g}")
                    else:
                        qlist.append(angle(q[i], "{: .3g}"))
                table.row(name, *qlist)

            return "\n" + str(table)
        else:
            return ""
Beispiel #3
0
 def __repr__(self):
     table = ANSITable(Column("id"),
                       Column("centroid"),
                       Column("strength", fmt="{:.3g}"),
                       Column("scale", fmt="{:.3g}"),
                       border="thin")
     for i, f in enumerate(self):
         table.row(i, f"{f.u:.1f}, {f.v:.1f}", f.strength, f.scale)
     return str(table)
    def __repr__(self):
        # s = "" for i, blob in enumerate(self): s += f"{i}:
        # area={blob.area:.1f} @ ({blob.uc:.1f}, {blob.vc:.1f}),
        # touch={blob.touch}, orient={blob.orientation * 180 / np.pi:.1f}°,
        # aspect={blob.aspect:.2f}, circularity={blob.circularity:.2f},
        # parent={blob._parent}\n"

        # return s

        table = ANSITable(Column("id"),
                          Column("parent"),
                          Column("centroid"),
                          Column("area", fmt="{:.3g}"),
                          Column("touch"),
                          Column("perim", fmt="{:.1f}"),
                          Column("circularity", fmt="{:.3f}"),
                          Column("orient", fmt="{:.1f}°"),
                          Column("aspect", fmt="{:.3g}"),
                          border="thin")
        for i, b in enumerate(self):
            table.row(i, b.parent, f"{b.u:.1f}, {b.v:.1f}", b.area, b.touch,
                      b.perimeter, b.circularity, b.orientation * 180 / np.pi,
                      b.aspect)

        return str(table)
    def make_table(border):
        table = ANSITable(Column("class", headalign="^", colalign="<"),
                          Column("name", headalign="^", colalign="<"),
                          Column("manufacturer", headalign="^", colalign="<"),
                          Column("type", headalign="^", colalign="<"),
                          Column("DoF", colalign="<"),
                          Column("dims", colalign="<"),
                          Column("structure", colalign="<"),
                          Column("dynamics", colalign="<"),
                          Column("geometry", colalign="<"),
                          Column("keywords", headalign="^", colalign="<"),
                          border=border)

        if mtype is not None:
            categories = [mtype]
        else:
            categories = ['DH', 'URDF', 'ETS']
        for category in categories:
            group = m.__dict__[category]
            for cls in group.__dict__.values():
                if isinstance(cls, type) and issubclass(cls, Robot):
                    # we found a BaseRobot subclass, instantiate it
                    try:
                        robot = cls()
                    except:
                        print(f"failed to load {cls}")
                    try:
                        structure = robot.structure
                    except Exception:  # pragma nocover
                        structure = ""

                    # apply filters
                    if keywords is not None:
                        if len(set(keywords) & set(robot.keywords)) == 0:
                            continue
                    if dof is not None and robot.n != dof:
                        continue  # pragma nocover

                    dims = 0

                    if isinstance(robot, ERobot2):
                        dims = 2
                    else:
                        dims = 3
                    # add the row
                    table.row(cls.__name__, robot.name, robot.manufacturer,
                              category, robot.n, f"{dims}d", structure,
                              'Y' if robot._hasdynamics else '',
                              'Y' if robot._hasgeometry else '',
                              ', '.join(robot.keywords))

        table.print()
    def dyntable(self):
        """
        Pretty print the dynamic parameters (Robot superclass)

        The dynamic parameters are printed in a table, with one row per link.

        Example:

        .. runblock:: pycon

            >>> import roboticstoolbox as rtb
            >>> robot = rtb.models.DH.Puma560()
            >>> robot.links[2].dyntable()

            >>> import roboticstoolbox as rtb
            >>> robot = rtb.models.DH.Puma560()
            >>> robot.dyntable()
        """
        table = ANSITable(Column("j", colalign=">", headalign="^"),
                          Column("m", colalign="<", headalign="^"),
                          Column("r", colalign="<", headalign="^"),
                          Column("I", colalign="<", headalign="^"),
                          Column("Jm", colalign="<", headalign="^"),
                          Column("B", colalign="<", headalign="^"),
                          Column("Tc", colalign="<", headalign="^"),
                          Column("G", colalign="<", headalign="^"),
                          border="thin")

        for j, link in enumerate(self):
            table.row(link.name, *link._dyn2list())
        return str(table)
Beispiel #7
0
    def test_table_5(self):
        ans = r"""      col1  column 2 has a big header    column 3  
 aaaaaaaaa                        2.2      3.0000  
bbbbbbbbb…                       -5.5      6.0000  
   ccccccc                        8.8     -9.0000  
"""

        table = ANSITable(Column("col1", width=10),
                          Column("column 2 has a big header", "{:.3g}"),
                          Column("column 3", "{:-10.4f}"),
                          color=False)
        table.row("aaaaaaaaa", 2.2, 3)
        table.row("bbbbbbbbbbbbb", -5.5, 6)
        table.row("ccccccc", 8.8, -9)

        self.assertEqual(str(table), ans)
Beispiel #8
0
    def test_table_3(self):
        ans = r"""         col1  column 2 has a big header  column 3  
    aaaaaaaaa                        2.2         3  
bbbbbbbbbbbbb                       -5.5         6  
      ccccccc                        8.8        -9  
"""

        table = ANSITable(Column("col1"),
                          Column("column 2 has a big header"),
                          Column("column 3"),
                          color=False)
        table.row("aaaaaaaaa", 2.2, 3)
        table.row("bbbbbbbbbbbbb", -5.5, 6)
        table.row("ccccccc", 8.8, -9)

        self.assertEqual(str(table), ans)
Beispiel #9
0
    def report(self):
        """
        Print a tabular report about the block diagram

        """
        
        # print all the blocks
        print('\nBlocks::\n')
        table = ANSITable(
                Column("id"),
                Column("name"),
                Column("nin"),
                Column("nout"),
                Column("nstate"),
                border="thin"
            )
        for b in self.blocklist:
            table.row( b.id, str(b), b.nin, b.nout, b.nstates)
        table.print()
        
        # print all the wires
        print('\nWires::\n')
        table = ANSITable(
                Column("id"),
                Column("from", headalign="^"),
                Column("to", headalign="^"),
                Column("description", headalign="^", colalign="<"),
                Column("type", headalign="^", colalign="<"),
                border="thin"
            )
        for w in self.wirelist:
            start = "{:d}[{:d}]".format(w.start.block.id, w.start.port)
            end = "{:d}[{:d}]".format(w.end.block.id, w.end.port)
            
            value = w.end.block.inputs[w.end.port]
            typ = type(value).__name__
            if isinstance(value, np.ndarray):
                typ += ' {:s}'.format(str(value.shape))
            table.row( w.id, start, end, w.fullname, typ)
        table.print()

        print('\nState variables: {:d}'.format(self.nstates))
        
        if not self.compiled:
            print('** System has not been compiled, or had a compile time error')
Beispiel #10
0
def list(keywords=None, dof=None):
    """
    Display all robot models in summary form

    :param keywords: keywords to filter on, defaults to None
    :type keywords: tuple of str, optional
    :param dof: number of DoF to filter on, defaults to None
    :type dof: int, optional
    
    - ``list()`` displays a list of all models provided by the Toolbox.  It
      lists the name, manufacturer, model type, number of DoF, and keywords.

    - ``list(keywords=KW)`` as above, but only displays models that have a
      keyword in the tuple ``KW``.

    - ``list(dof=N)`` as above, but only display models that have ``N``
      degrees of freedom.

    The filters can be combined
    
    - ``list(keywords=KW, dof=N)`` are those models that have a keyword in
      ``KW`` and have ``N`` degrees of freedom.
    """

    import roboticstoolbox.models as m
    # module = importlib.import_module('.' + os.path.splitext(file)[0], package='bdsim.blocks')

    table = ANSITable(Column("class", headalign="^", colalign="<"),
                      Column("model", headalign="^", colalign="<"),
                      Column("manufacturer", headalign="^", colalign="<"),
                      Column("model type", headalign="^", colalign="<"),
                      Column("DoF", colalign="<"),
                      Column("config", colalign="<"),
                      Column("keywords", headalign="^", colalign="<"),
                      border="thin")
    for category in ['DH', 'URDF', 'ETS']:
        group = m.__dict__[category]
        for cls in group.__dict__.values():
            if isinstance(cls, type) and issubclass(cls, Robot):
                # we found a Robot subclass, instantiate it
                robot = cls()
                try:
                    config = robot.config()
                except:
                    config = ""

                # apply filters
                if keywords is not None:
                    if len(set(keywords) & set(robot.keywords)) == 0:
                        continue
                if dof is not None and robot.n != dof:
                    continue

                # add the row
                table.row(cls.__name__, robot.name, robot.manufacturer,
                          category, robot.n, config, ', '.join(robot.keywords))
    table.print()
Beispiel #11
0
    def test_table_ascii(self):
        ans = r"""+--------------+---------------------------+----------+
|         col1 | column 2 has a big header | column 3 |
+--------------+---------------------------+----------+
|    aaaaaaaaa |                       2.2 |        3 |
|bbbbbbbbbbbbb |                      -5.5 |        6 |
|      ccccccc |                       8.8 |       -9 |
+--------------+---------------------------+----------+
"""

        table = ANSITable(Column("col1"),
                          Column("column 2 has a big header"),
                          Column("column 3"),
                          border="ascii",
                          color=False)
        table.row("aaaaaaaaa", 2.2, 3)
        table.row("bbbbbbbbbbbbb", -5.5, 6)
        table.row("ccccccc", 8.8, -9)

        self.assertEqual(str(table), ans)
Beispiel #12
0
    def test_table_border_3(self):

        ans = r"""┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃col1          ┃ column 2 has a big header ┃ column 3 ┃
┣━━━━━━━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━╋━━━━━━━━━━┫
┃    aaaaaaaaa ┃            2.2            ┃ 3        ┃
┃bbbbbbbbbbbbb ┃           -5.5            ┃ 6        ┃
┃      ccccccc ┃            8.8            ┃ -9       ┃
┗━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━┛
"""
        table = ANSITable(Column("col1", headalign="<"),
                          Column("column 2 has a big header", colalign="^"),
                          Column("column 3", colalign="<"),
                          border="thick",
                          color=False)
        table.row("aaaaaaaaa", 2.2, 3)
        table.row("bbbbbbbbbbbbb", -5.5, 6)
        table.row("ccccccc", 8.8, -9)

        self.assertEqual(str(table), ans)
Beispiel #13
0
    def _dyn2list(self, fmt="{: .3g}"):
        """
        Inertial properties of link as a string

        :param fmt: conversion format for each number
        :type fmt: str
        :return: The string representation of the link dynamics
        :rtype: string

        ``link.)_dyn2list()`` returns a list of pretty-printed inertial
        properties of the link The properties included are mass, centre of
        mass, inertia, friction, gear ratio and motor properties.

        :seealso: :func:`~dyn`
        """
        ANSITable(
            Column("Parameter", headalign="^"),
            Column("Value", headalign="^", colalign="<"),
            border="thin")

        def format(l, fmt, val):  # noqa
            if isinstance(val, np.ndarray):
                s = ', '.join([fmt.format(v) for v in val])
            else:
                s = fmt.format(val)
            l.append(s)

        dyn = []
        format(dyn, fmt, self.m)
        format(dyn, fmt, self.r)
        I = self.I.flatten()  # noqa
        format(dyn, fmt, np.r_[[I[k] for k in [0, 4, 8, 1, 2, 5]]])
        format(dyn, fmt, self.Jm)
        format(dyn, fmt, self.B)
        format(dyn, fmt, self.Tc)
        format(dyn, fmt, self.G)

        return dyn
Beispiel #14
0
    def make_table(border):
        table = ANSITable(Column("class", headalign="^", colalign="<"),
                          Column("model", headalign="^", colalign="<"),
                          Column("manufacturer", headalign="^", colalign="<"),
                          Column("model type", headalign="^", colalign="<"),
                          Column("DoF", colalign="<"),
                          Column("config", colalign="<"),
                          Column("keywords", headalign="^", colalign="<"),
                          border=border)

        if mtype is not None:
            categories = [mtype]
        else:
            categories = ['DH', 'URDF', 'ETS']
        for category in categories:
            group = m.__dict__[category]
            for cls in group.__dict__.values():
                if isinstance(cls, type) and issubclass(cls, Robot):
                    # we found a Robot subclass, instantiate it
                    robot = cls()
                    try:
                        config = robot.config()
                    except Exception:  # pragma nocover
                        config = ""

                    # apply filters
                    if keywords is not None:
                        if len(set(keywords) & set(robot.keywords)) == 0:
                            continue
                    if dof is not None and robot.n != dof:
                        continue  # pragma nocover

                    # add the row
                    table.row(cls.__name__, robot.name, robot.manufacturer,
                              category, robot.n, config,
                              ', '.join(robot.keywords))

        print(str(table))
Beispiel #15
0
    print(robot.n, robot.M)
    print(robot.elinks)
    print(robot.q_idx)
    for link in robot:
        print(link.name, link)
        print(link.ets, link.v, link.isjoint)
        print(link.parent, link.child)
        print(link.Ts)
        print(link.geometry, link.collision)

        print()

    from ansitable import ANSITable, Column

    table = ANSITable(
        Column("link"),
        Column("parent"),
        Column("ETS", headalign="^", colalign="<"),
        border="thin")
    for link in robot:
        if link.isjoint:
            color = ""
        else:
            color = "<<blue>>"
        table.row(
            color + link.name,
            link.parent.name if link.parent is not None else "-",
            link.ets * link.v if link.v is not None else link.ets)
    table.print()
if hasattr(robot, "ikine_a"):
    a =  (robot.ikine_a, # analytic solution
        "ikine_a",
        "sol = robot.ikine_a(T)"
    )
    ikfuncs.insert(0, a)    

# setup to run timeit
setup = '''
from __main__ import robot, T, q0
'''
N = 10

# setup results table
table = ANSITable(
    Column("Operation", headalign="^", colalign='<'),
    Column("Time (ms)", headalign="^", fmt="{:.2g}"),
    Column("Error", headalign="^", fmt="{:.3g}"),
    border="thick")

# test the IK methods
for ik in ikfuncs:
    print('Testing:', ik[1])
    
    # test the method, don't pass q0 to the analytic function
    if ik[1] == "ikine_a":
        sol = ik[0](T)
    else:
        sol = ik[0](T, q0=q0)

    # print error message if there is one
Beispiel #17
0
]
if hasattr(robot, "ikine_a"):
    a = (
        robot.ikine_a,  # analytic solution
        "ikine_a",
        "sol = robot.ikine_a}(T)")
    ikfuncs.insert(0, a)

# setup to run timeit
setup = '''
from __main__ import robot, T, q0
'''
N = 10

# setup results table
table = ANSITable(Column("Operation", headalign="^"),
                  Column("Time (μs)", headalign="^", fmt="{:.2f}"),
                  Column("Error", headalign="^", fmt="{:.3g}"),
                  border="thick")

# test the IK methods
for ik in ikfuncs:
    print('Testing:', ik[1])

    # test the method, don't pass q0 to the analytic function
    if ik[1] == "ikine_a":
        sol = ik[0](T)
    else:
        sol = ik[0](T, q0=q0)

    # print error message if there is one
Beispiel #18
0
    'SLSQP',
    'trust-constr',
    'dogleg',
    'trust-ncg',
    'trust-exact',
    'trust-krylov',
]

# setup to run timeit
setup = '''
from __main__ import robot, T, q0
'''
N = 10

# setup results table
table = ANSITable(Column("Solver", headalign="^", colalign='<'),
                  Column("Time (ms)",
                         headalign="^",
                         fmt="{:.2g}",
                         colalign='>'),
                  Column("Error", headalign="^", fmt="{:.3g}", colalign='>'),
                  border="thick")

# test the IK methods
for solver in solvers:
    print('Testing:', solver)

    # test the method, don't pass q0 to the analytic function
    try:
        sol = robot.ikine_min(T, q0=q0, qlim=True, method=solver)
    except Exception as e: