Skip to content

Conversation

@juanjqo
Copy link
Member

@juanjqo juanjqo commented Dec 3, 2022

@dqrobotics/developers

Hi @bvadorno,

this PR modifies the classes DQ_SerialManipulator and DQ_SerialManipulatorDH. The following changes are proposed:

  • DQ_SerialManipulator is an abstract class now.
  • The methods raw_fkm(), raw_pose_jacobian() and raw_pose_jacobian_derivative() are defined as abstract methods in DQ_SerialManipulator and they are defined as concrete ones in DQ_SerialManipulatorDH.
  • The methods fkm(), pose_jacobian() and pose_jacobian_derivative() are defined only in DQ_SerialManipulator.

Update

  • Added the class DQ_SerialManipulatorMDH.

Requirements:

  • This PR does not implement the class DQ_SerialManipulatorMDH() and therefore it is required this modification in matlab-examples.

UML diagram:
Blue background with bold text represents modifications or new things.

drawing

Final design (proposed by @mmmarinho)

drawing

Tasks:

  • Add the contributing file.
  • DQ_SerialManipulator is now an abstrac class.
  • Update DQ_SerialManipulatorDH.
  • Update the matlab-examples to ensure compatibility. (here)
  • Include a UML diagram to show the proposed changes.
  • Add the class DQ_SerialManipulatorMDH.

The main goal is to update/sincronize the current version of dqrobotics-matlab with respecto to the C++ version. A lot of things are not sincronized between them yet, but this is the first step.

Best regards,

Juancho

@juanjqo juanjqo changed the title Contributing file Added the contributing file Dec 3, 2022
@juanjqo juanjqo marked this pull request as draft December 3, 2022 08:11
@juanjqo juanjqo changed the title Added the contributing file Conversion of DQ_SerialManipulator to an abstract class Dec 3, 2022
…an abstract method and defined its concrete version.
[DQ_SerialManipulator.m] the Fixed error message of the constructor.
[DQ_SerialManipulator.m] Added comments in some lines.
[DQ_SerialManipulatorDH.m] Protected the methods get_w and dh2dq, as in C++.
[DQ_SerialManipulatorDH.m] Added minimal changes in the dh2dq method.
[DQ_SerialManipulator.m] Updated the year of the copyright
[DQ_SerialManipulatorDH.m] Updated the copyright.
@juanjqo
Copy link
Member Author

juanjqo commented Dec 12, 2022

@dqrobotics/developers

Hi @mmmarinho and @bvadorno,

Assuming I'm not missing anything, this is the UML design proposed by Murilo.

drawing

Best regards,

Juancho

@juanjqo
Copy link
Member Author

juanjqo commented Dec 12, 2022

Hi @bvadorno and @mmmarinho

Following our previous discussion, I have a proposal to modify the constructor of the subclasses. Instead of using a cell, we could have two arguments: a 4xn DH matrix and the type of joints. For instance:

dh_matrix = [theta; d; a; alpha];
types = repmat(DQ_JointType.REVOLUTE, 1,5);  % No casting to double 
robot = DQ_SerialManipulatorDH(dh_matrix, types); 

The key justification is that while a cell might be simple to create in Matlab or (pure) Python, it might be challenging to do so in C++ without using a struct, and, looks like that somethings as structs or raw pointers (raw pointers are being replaced by smart pointers) are not being used in the current implementation of the library in C++, at least for public functions or methods. (@mmmarinho please correct me if I'm wrong).

To ensure compatibility with previous versions, the constructor could be (this is a very raw beta implementation)

function obj = DQ_SerialManipulatorDH(A, types)
        obj.n_links = size(A,2);
        str_new = ['DQ_SerialManipulatorDH(A, types), where ' ...
                   'A = [theta1 ... thetan; ' ...
                   ' d1  ...   dn; ' ...
                   ' a1  ...   an; ' ...
                   ' alpha1 ... alphan;] ' ...
                   '                     ' ...
                   'types = [DQ_JointType.REVOLUTE ... DQ_JointType.PRISMATIC]'];
        
        switch nargin
            case 0
                error(['Input: matrix whose columns contain the DH parameters' ...
                   ' and type of joints. Example: ' str_new])
            case 1
                 warning(['DQ_SerialManipulatorDH(A) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead. Example: ' str_new]);  
                 if(size(A,1) ~= 5)
                   error('Input: Invalid DH matrix. It must have 5 rows.')
                 end
                 obj.theta = A(1,:);
                 obj.d     = A(2,:);
                 obj.a     = A(3,:);
                 obj.alpha = A(4,:);
                 obj.type  = A(5,:);

            case 2
                if isa( types, 'char') % ex: types = 'standard'
                    warning(['DQ_SerialManipulatorDH(A, convention) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead. Example: ' str_new]);   
                    if(size(A,1) ~= 5)
                       error('Input: Invalid DH matrix. It must have 5 rows.')
                    end
                    obj.theta = A(1,:);
                    obj.d     = A(2,:);
                    obj.a     = A(3,:);
                    obj.alpha = A(4,:);
                    obj.type  = A(5,:);
                elseif strcmp(class(convention), 'DQ_JointType')
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.theta = A(1,:);
                    obj.d     = A(2,:);
                    obj.a     = A(3,:);
                    obj.alpha = A(4,:);
                    obj.type  = types;
                elseif isa(obj.type, 'double') 
                    warning(['bla bla bla. Use DQ_JoinType instead.'])
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.theta = A(1,:);
                    obj.d     = A(2,:);
                    obj.a     = A(3,:);
                    obj.alpha = A(4,:);
                    obj.type  = types;
                    
                end
        end
    end
end

Cases:

  1. DQ_SerialManipulatorDH(A, 'standard'), where A is a 5xn matrix. This throws a warning of deprecation
types = double(repmat(DQ_JointType.REVOLUTE, 1,5));  
dh_matrix = [theta; d; a; alpha, types];
robot = DQ_SerialManipulatorDH(dh_matrix, 'standard'); 
  1. DQ_SerialManipulatorDH(A), where A is a 5xn matrix. This throws a warning of deprecation
types = double(repmat(DQ_JointType.REVOLUTE, 1,5));  
dh_matrix = [theta; d; a; alpha, types];
robot = DQ_SerialManipulatorDH(dh_matrix); 
  1. DQ_SerialManipulatorDH(A, types), where A is a 4xn matrix, and types is built using integers. This throws a warning because the user is not using the class DQ_JointTypes.
dh_matrix = [theta; d; a; alpha];
types = [1 ... 1];
robot = DQ_SerialManipulatorDH(dh_matrix, types); 
  1. DQ_SerialManipulatorDH(A, types), where A is a 4xn, and types is built using the class DQ_JointType.
dh_matrix = [theta; d; a; alpha];
types = repmat(DQ_JointType.REVOLUTE, 1,5);  % No casting to double 
robot = DQ_SerialManipulatorDH(dh_matrix, types); 

I think this could be easily implemented in C++/Python. For instance, we could have something like

DQ_SerialManipulatorDH(const MatrixXd& dh_matrix, const std::vector<DQ_JointTypes>& types);

This proposal make sense or could be useful? what do you think?

Best regards,

Juancho

@bvadorno
Copy link
Member

@juanjqo,
The calculations for get_w() are correct. However, this class is essentially the same as the DQ_SerialManipulatorDH except for the methods dh2dq() and get_w(). A better design would be to have DQ_SerialManipulatorMDH inheriting from DQ_SerialManipulatorDH, and then overloading the methods dh2dq() and get_w().
The implementation will become much cleaner, the distinction between the two classes much more evident, and any future maintenance will be much simpler.

@bvadorno @juanjqo

Sorry to intrude, but can we take this one step further?

The original work in @bvadorno's thesis describes, among other things, general fkm and Jacobian derivations for any serial-link manipulator regardless of parametrization. Hence, I'd like to suggest that we reflect that on the code by doing the following:

1. We move the current implementation of


* `raw_fkm()`

* `raw_pose_jacobian()`
  and possibly others to `DQ_SerialManipulator`.


2. In `DQ_SerialManipulator`, we can have two protected abstract methods, such as
   `get_w()` (Same as before because the naming is generic)
   `get_link2dq()` (A more general name instead of `dh2dq`), naming pending. (@bvadorno @juanjqo please help me with a better name here.)

3. `DQ_SerialManipulatorDH`, `DQ_SerialManipulatorMDH`, `DQ_SerialManipulatorDenso`, and possibly other sub-classes inherit only from `DQ_SerialManipulator` and, by consequence, only need to implement `get_w()` and `get_link_dq()`.

This way, all sub-classes will be much easier to implement and maintain. In addition, the hierarchy chain will be also cleaner. This is basically @bvadorno's suggestion one step up in the hierarchy.

@juanjqo could you please make a quick UML to help me describe this concept? Please only make any possible changes to the code related to my suggestion after we all agree on this point. Thanks in advance!

Hi @mmmarinho,

It's a sensible strategy. Let's proceed with it.

Best wishes,
Bruno

@bvadorno
Copy link
Member

Hi @bvadorno and @mmmarinho

Following our previous discussion, I have a proposal to modify the constructor of the subclasses. Instead of using a cell, we could have two arguments: a 4xn DH matrix and the type of joints. For instance:

dh_matrix = [theta; d; a; alpha];
types = repmat(DQ_JointType.REVOLUTE, 1,5);  % No casting to double 
robot = DQ_SerialManipulatorDH(dh_matrix, types); 

The key justification is that while a cell might be simple to create in Matlab or (pure) Python, it might be challenging to do so in C++ without using a struct, and, looks like that somethings as structs or raw pointers (raw pointers are being replaced by smart pointers) are not being used in the current implementation of the library in C++, at least for public functions or methods. (@mmmarinho please correct me if I'm wrong).

To ensure compatibility with previous versions, the constructor could be (this is a very raw beta implementation)

function obj = DQ_SerialManipulatorDH(A, types)
        obj.n_links = size(A,2);
        str_new = ['DQ_SerialManipulatorDH(A, types), where ' ...
                   'A = [theta1 ... thetan; ' ...
                   ' d1  ...   dn; ' ...
                   ' a1  ...   an; ' ...
                   ' alpha1 ... alphan;] ' ...
                   '                     ' ...
                   'types = [DQ_JointType.REVOLUTE ... DQ_JointType.PRISMATIC]'];
        
        switch nargin
            case 0
                error(['Input: matrix whose columns contain the DH parameters' ...
                   ' and type of joints. Example: ' str_new])
            case 1
                 warning(['DQ_SerialManipulatorDH(A) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead. Example: ' str_new]);  
                 if(size(A,1) ~= 5)
                   error('Input: Invalid DH matrix. It must have 5 rows.')
                 end
                 obj.theta = A(1,:);
                 obj.d     = A(2,:);
                 obj.a     = A(3,:);
                 obj.alpha = A(4,:);
                 obj.type  = A(5,:);

            case 2
                if isa( types, 'char') % ex: types = 'standard'
                    warning(['DQ_SerialManipulatorDH(A, convention) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead. Example: ' str_new]);   
                    if(size(A,1) ~= 5)
                       error('Input: Invalid DH matrix. It must have 5 rows.')
                    end
                    obj.theta = A(1,:);
                    obj.d     = A(2,:);
                    obj.a     = A(3,:);
                    obj.alpha = A(4,:);
                    obj.type  = A(5,:);
                elseif strcmp(class(convention), 'DQ_JointType')
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.theta = A(1,:);
                    obj.d     = A(2,:);
                    obj.a     = A(3,:);
                    obj.alpha = A(4,:);
                    obj.type  = types;
                elseif isa(obj.type, 'double') 
                    warning(['bla bla bla. Use DQ_JoinType instead.'])
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.theta = A(1,:);
                    obj.d     = A(2,:);
                    obj.a     = A(3,:);
                    obj.alpha = A(4,:);
                    obj.type  = types;
                    
                end
        end
    end
end

Cases:

1. DQ_SerialManipulatorDH(A, 'standard'), where A is a 5xn matrix.  This throws a warning of deprecation
types = double(repmat(DQ_JointType.REVOLUTE, 1,5));  
dh_matrix = [theta; d; a; alpha, types];
robot = DQ_SerialManipulatorDH(dh_matrix, 'standard'); 
2. DQ_SerialManipulatorDH(A), where A is a 5xn matrix. This throws a warning of deprecation
types = double(repmat(DQ_JointType.REVOLUTE, 1,5));  
dh_matrix = [theta; d; a; alpha, types];
robot = DQ_SerialManipulatorDH(dh_matrix); 
3. DQ_SerialManipulatorDH(A, types), where A is a 4xn matrix, and types is built using integers. This throws a warning because the user is not using the class DQ_JointTypes.
dh_matrix = [theta; d; a; alpha];
types = [1 ... 1];
robot = DQ_SerialManipulatorDH(dh_matrix, types); 
4. DQ_SerialManipulatorDH(A, types), where A is a 4xn, and types is built using the class DQ_JointType.
dh_matrix = [theta; d; a; alpha];
types = repmat(DQ_JointType.REVOLUTE, 1,5);  % No casting to double 
robot = DQ_SerialManipulatorDH(dh_matrix, types); 

I think this could be easily implemented in C++/Python. For instance, we could have something like

DQ_SerialManipulatorDH(const MatrixXd& dh_matrix, const std::vector<DQ_JointTypes>& types);

This proposal make sense or could be useful? what do you think?

Best regards,

Juancho

Hi @juancho,

Let's defer this because we need to focus on @mmmarinho's suggestion.

Your solution works, but we need to see if it's necessary, given your motivations, because cells in MATLAB are just a mechanism to store data. Therefore, it suffices to use a container in C++, which is pretty standard, to provide the same functionality as cells. For example, see how to use lists.

@mmmarinho
Copy link
Member

@juanjqo

No comment on the applicability of the code for now, but a little bit of advice in making it less verbose, if applicable.

function obj = DQ_SerialManipulatorDH(A, types)
        obj.n_links = size(A,2);

        % Maybe explain what this switch aims to achieve and some information about which is legacy
        switch nargin
            case 0 % No empty constructor
                error(['Input: matrix whose columns contain the DH parameters' ...
                   ' and type of joints.'])
            case 1 % One argument initialization is deprecated from 23.04
                 warning(['DQ_SerialManipulatorDH(A) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead.']);  
                 if(size(A,1) ~= 5)
                   error('Input: Invalid DH matrix. It must have 5 rows.')
                 end
                 obj.type  = A(5,:);
            case 2 % String convention is deprecated since (?) 
                if isa( types, 'char') % ex: types = 'standard'
                    warning(['DQ_SerialManipulatorDH(A, convention) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead. Example: ' str_new]);   
                    if(size(A,1) ~= 5)
                       error('Input: Invalid DH matrix. It must have 5 rows.')
                    end
                    obj.type  = A(5,:);
                elseif strcmp(class(types), 'DQ_JointType')
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.type  = types;
                elseif isa(types, 'double') 
                    warning(['TODO warning. Use DQ_JoinType instead.'])
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.type  = types;
                end
        end
        obj.theta = A(1,:);
        obj.d     = A(2,:);
        obj.a     = A(3,:);
        obj.alpha = A(4,:);
    end
end

@juanjqo
Copy link
Member Author

juanjqo commented Dec 12, 2022

Hi @bvadorno, thank you for your feedback. I implemented the new design proposed by @mmmarinho.

@juanjqo
Copy link
Member Author

juanjqo commented Dec 12, 2022

@juanjqo

No comment on the applicability of the code for now, but a little bit of advice in making it less verbose, if applicable.

function obj = DQ_SerialManipulatorDH(A, types)
        obj.n_links = size(A,2);

        % Maybe explain what this switch aims to achieve and some information about which is legacy
        switch nargin
            case 0 % No empty constructor
                error(['Input: matrix whose columns contain the DH parameters' ...
                   ' and type of joints.'])
            case 1 % One argument initialization is deprecated from 23.04
                 warning(['DQ_SerialManipulatorDH(A) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead.']);  
                 if(size(A,1) ~= 5)
                   error('Input: Invalid DH matrix. It must have 5 rows.')
                 end
                 obj.type  = A(5,:);
            case 2 % String convention is deprecated since (?) 
                if isa( types, 'char') % ex: types = 'standard'
                    warning(['DQ_SerialManipulatorDH(A, convention) is deprecated.' ...
                    ' Please use DQ_SerialManipulatorDH(A, types) instead. Example: ' str_new]);   
                    if(size(A,1) ~= 5)
                       error('Input: Invalid DH matrix. It must have 5 rows.')
                    end
                    obj.type  = A(5,:);
                elseif strcmp(class(types), 'DQ_JointType')
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.type  = types;
                elseif isa(types, 'double') 
                    warning(['TODO warning. Use DQ_JoinType instead.'])
                    if(size(A,1) ~= 4)
                      error('Input: Invalid DH matrix. It must have 4 rows.')
                    end
                    obj.type  = types;
                end
        end
        obj.theta = A(1,:);
        obj.d     = A(2,:);
        obj.a     = A(3,:);
        obj.alpha = A(4,:);
    end
end

Hi @mmmarinho, thank you for your feedback. Your suggestion is really welcome. The code is less verbose!

@juanjqo
Copy link
Member Author

juanjqo commented Dec 12, 2022

@bvadorno I realized that I forgot to update the header of DQ_SerialManipulator, specifically the part describing raw_fkm, raw_pose_jacobian, and raw_pose_jacobian_derivative as abstract methods.
Can I update it?

@bvadorno
Copy link
Member

@bvadorno I realized that I forgot to update the header of DQ_SerialManipulator, specifically the part describing raw_fkm, raw_pose_jacobian, and raw_pose_jacobian_derivative as abstract methods. Can I update it?

Hi @juanjqo,

Yes, you can. I won't be able to work on this review in the next few hours.

Best wishes,
Bruno

@juanjqo
Copy link
Member Author

juanjqo commented Dec 12, 2022

@bvadorno I realized that I forgot to update the header of DQ_SerialManipulator, specifically the part describing raw_fkm, raw_pose_jacobian, and raw_pose_jacobian_derivative as abstract methods. Can I update it?

Hi @juanjqo,

Yes, you can. I won't be able to work on this review in the next few hours.

Best wishes, Bruno

@bvadorno thanks. I implemented the modifications. The PR is ready to your review.

@bvadorno bvadorno merged commit 3570914 into dqrobotics:master Dec 15, 2022
bvadorno pushed a commit that referenced this pull request Jan 5, 2023
[DQ_Kinematics.m] Added the dim_configuration_space protected property.

[DQ_SerialManipulatorDH] Added the properties theta,a, d, alpha and updated the constructor of the class.
[DQ_SerialManipulatorDH.m] Updated the documentation.

[DQ_SerialManipulator.m] Defined the class as an abstract class and updated the constructor.
[DQ_SerialManipulator.m] Defined abstract methods. Removed raw_fkm.

[DQ_SerialManipulatorDH.m] Removed fkm, which is now in DQ_SerialManipulator.

[DQ_SerialManipulator.m] Removed raw_pose_jacobian_derivative.
[DQ_SerialManipulator.m] Removed raw_pose_jacobian_derivative.

[DQ_SerialManipulatorDH.m] Added the pose_jacobian_derivative.

[DQ_Kinematics.m] Removed changes in DQ_Kinematics

[DQ_SerialManipulator.m] Removed dim_configuration_space to keep using the n_links property.

[DQ_SerialManipulatorDH.m] Removed dim_configuration_space to keep using the n_links property.

[ComauSmartSixRobot.m] Updated the robot definition.

[DQ_SerialManipulator.m] Defined the raw_pose_jacobian_derivative as an abstract method and defined its concrete version.

[DQ_SerialManipulatorDH.m] Modified the name of the method to raw_pose_jacobian_derivative.

[DQ_SerialManipulatorMDH.m] Added a concrete class to model robots using the modified DH convention.

[CONTRIBUTING.md] Updated the file.
Updated the file with last Bruno's recommendations.

[DQ_Kinematics.h] Fixed missing semi-colon.

[DQ_SerialManipulator.m] the Fixed error message of the constructor.
[DQ_SerialManipulator.m] Added comments in some lines.

[DQ_SerialManipulatorDH.m] Protected the methods get_w and dh2dq, as in C++.
[DQ_SerialManipulatorDH.m] Added minimal changes in the dh2dq method.

[DQ_SerialManipulator.m] Removed the convention property and some comments.
[DQ_SerialManipulator.m] Updated the year of the copyright

[DQ_SerialManipulatorDH.m] Updated the copyright.

[DQ_SerialManipulatorMDH] Removed the class. I will add it in a future PR.

[DQ_SerialManipulator.m] Updated the documentation.

Update CONTRIBUTING.md

- Fixed grammar problems across the file.
- Added more information about longer commits.

[CONTRIBUTING.md] Fixed typos pointed out by Bruno in the contributing diagram
[CONTRIBUTING.md] Fixed typos pointed out by Bruno in the contributing diagram

[DQ_Kinematics.m] Updated the copyright and the Bruno's email.

[DQ_SerialManipulator.m] Removed TODO comments and updated the Bruno's email.
[DQ_SerialManipulator.m] Fixed comment according to Bruno's suggestion
[DQ_SerialManipulator.m] Fixed comment according to Bruno's suggestion.

[DQ_SerialManipulatorDH.m] Fixed error message according to Bruno's suggestion.
[DQ_SerialManipulatorDH.m] Added modifications according to Bruno's suggestion

[DQ_SerialManipulator.m] Added the dh2dq as an abstract method.

[DQ_SerialManipulatorDH.m] Updated the documentation of dh2dq

[JointType.m] Created a enumeration class containing type of joints.

[DQ_JointType] Implemented the Bruno's suggestions.

[DQ_JointType.m] Updated the contributors section according to Murilo's suggestion

[DQ_SerialManipulatorDH.m] Updated the header as discussed in #75

[DQ_SerialManipulator.m] Removed the argument of the constructor, as suggested by Bruno.

[DQ_SerialManipulatorDH.m] Updated the constructor of the class taking into account the modifications in the superclass.
[DQ_SerialManipulatorDH.m] Added the date of some commits.
[DQ_SerialManipulatorDH.m] Modified the class to use DQ_JointType

[ComauSmartSixRobot.m] Updated the class to use DQ_JointType
[ComauSmartSixRobot.m] Updated the website, Bruno's email and the copyright.
[ComauSmartSixRobot.m] Fixed the robot definition using the MDH class for serial manipulators.

[DQ_SerialManiplator.m] Updated the comments of pose_jacobian and pose_jacobian_derivative according to Bruno's suggestion.
[DQ_SerialManipulator.m] Updated the condition of pose_jacobian_derivative. If ith==n_links the effector is not taken into account anymore
[DQ_SerialManipulator.m] Modified the if condition in pose_jacobian()

Now, when ith==n_links the effector is not taken into account.

Revert "[DQ_SerialManipulator.m] Modified the if condition in pose_jacobian()"
This reverts commit 4ee9ebd.

[DQ_SerialManipulator.m] Removed the abstract method dq2dh().

[CONTRIBUTING.md] Fixed type of font and the color of two words.

[DQ_SerialManipulator.m] Removed some lines in the header as requested by Bruno
[DQ_SerialManipulator.m] Updated the pose_jacobian_derivative method to match pose_jacobian, as discussed in #75

[DQ_SerialManipulatorDH.m] Fixed the number of the PR to which I contributed.

[DQ_SerialManipulatorMDH.m] Added the class to model robots using the MDH parameters.
[DQ_SerialManipulatorMDH.m] Updated the header.
[DQ_SerialManipulatorMDH.m] Updated the header according to Bruno's suggestion.
[DQ_SerialManipulatorMDH.m] Improved the design of the class as requested by Bruno.

[DQ_SerialManipulator.m] Added get_w and get_link2dq as protected abstract methods.
[DQ_SerialManipulator.m] The raw methods are concrete methods instead of abstract ones.

[DQ_SerialManipulatorDH.m] Removed the concrete methods raw_fkm, raw_pose_jacobian, and raw_pose_jacobian_derivative
[DQ_SerialManipulatorDH.m] Renamed the method dh2dq.

[DQ_SerialManipulatorMDH.m] Updated the class according to the new design proposed by Murilo.

[DQ_SerialManipulator.m] Updated the header.

[DQ_SerialManipulatorDH.m] Updated the header.

[DQ_SerialManipulatorMDH.m] Updated the header.

[DQ_SerialManipulator.m] Modified the documentation of raw_fkm as suggested by Bruno.

 Author:    juancho <juanjqogm@gmail.com>
 Date:      Sat Dec 3 16:51:55 2022 +0900
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants