def __getitem__(self, i): """ Index or slice an ETS :param i: the index or slince :type i: int or slice :return: Elementary transform (sequence) :rtype: ETS Example: .. runblock:: pycon >>> from roboticstoolbox import ETS >>> e = ETS.rz() * ETS.tx(1) * ETS.rz() * ETS.tx(1) >>> e[0] >>> e[1] >>> e[1:3] """ item = ETS() data = self.data[i] # can be [2] or slice, eg. [3:5] # ensure that data is always a list if isinstance(data, list): item.data = data else: item.data = [data] return item
def pop(self, i=-1): """ Pop value :param i: item in the list to pop, default is last :type i: int :return: the popped value :rtype: instance of same type :raises IndexError: if there are no values to pop Removes a value from the value list and returns it. The original instance is modified. Example: .. runblock:: pycon >>> from roboticstoolbox import ETS >>> e = ETS.rz() * ETS.tx(1) * ETS.rz() * ETS.tx(1) >>> tail = e.pop() >>> tail >>> e """ item = ETS() item.data = [super().pop(i)] return item
def __mul__(self, rest): """ Overloaded ``*`` operator :return: [description] :rtype: [type] Example: .. runblock:: pycon >>> from roboticstoolbox import ETS >>> e1 = ETS.rz() >>> len(e1) >>> e2= ETS.tx(2) >>> len(e2) >>> e = e1 * e2 >>> len(e) .. note:: The ``*`` operator implies composition, but actually the result is a new ETS instance that contains the concatenation of the left and right operands in an internal list. In this example we see the length of the product is 2. """ prod = ETS() prod.data = self.data + rest.data return prod
def inv(self): r""" Inverse of ETS :return: [description] :rtype: ETS instance The inverse of a given ETS. It is computed as the inverse of the individual ETs in the reverse order. .. math:: (\mathbf{E}_0, \mathbf{E}_1 \cdots \mathbf{E}_{n-1} )^{-1} = (\mathbf{E}_{n-1}^{-1}, \mathbf{E}_{n-2}^{-1} \cdots \mathbf{E}_0^{-1}{n-1} ) Example: .. runblock:: pycon >>> from roboticstoolbox import ETS >>> e = ETS.rz(j=2) * ETS.tx(1) * ETS.rx(j=3,flip=True) * ETS.tx(1) >>> print(e) >>> print(e.inv()) >>> q = [1,2,3,4] >>> print(e.eval(q) * e.inv().eval(q)) .. note:: It is essential to use explicit joint indices to account for the reversed order of the transforms. """ # noqa inv = ETS() for ns in reversed(self.data): # get the namespace from the list # clone it, and invert the elements to create an inverse nsi = copy.copy(ns) if nsi.joint: nsi.flip ^= True # toggle flip status elif nsi.axis[0] == 'C': nsi.T = trinv(nsi.T) elif nsi.eta is not None: nsi.T = trinv(nsi.T) nsi.eta = -nsi.eta et = ETS() # create a new ETS instance et.data = [nsi] # set it's data from the dict inv *= et return inv
def inv(self): r""" Inverse of ETS :return: [description] :rtype: ETS instance The inverse of a given ETS. It is computed as the inverse of the individual ETs in the reverse order. .. math:: (\mathbf{E}_0, \mathbf{E}_1 \cdots \mathbf{E}_{n-1} )^{-1} = (\mathbf{E}_{n-1}^{-1}, \mathbf{E}_{n-2}^{-1} \cdots \mathbf{E}_0^{-1}{n-1} ) Example: .. runblock:: pycon >>> from roboticstoolbox import ETS >>> e = ETS.rz(j=2) * ETS.tx(1) * ETS.rx(j=3,flip=True) * ETS.tx(1) >>> print(e) >>> print(e.inv()) >>> q = [1,2,3,4] >>> print(e.eval(q) * e.inv().eval(q)) .. note:: It is essential to use explicit joint indices to account for the reversed order of the transforms. """ inv = ETS() for e in reversed(self.data): # get the named tuple from the list, and convert to a dict etdict = e._asdict() # update the dict to make this an inverse if etdict['joint']: etdict['flip'] ^= True # toggle flip status elif etdict['axis'][0] == 'C': etdict['T'] = trinv(etdict['T']) elif etdict['eta'] is not None: etdict['T'] = trinv(etdict['T']) etdict['eta'] = -etdict['eta'] et = ETS() # create a new ETS instance et.data = [self.ets_tuple(**etdict)] # set it's data from the dict inv *= et return inv
def __imul__(self, rest): prod = ETS() prod.data = self.data + rest.data return prod