I need help validating my forward kinematic using Simulink and the Robotic Systems Toolbox for a surgical robot.

15 ビュー (過去 30 日間)
Hi all,
I am a student and I am working on a surgical eye robot which utilises a remote centre of motion mechanism (RCM). I have found the forward kinematics for it using the DH method and another method. I have also found the Jacobian velocity matrix for it. However, my Jacobian seems a bit off and I am looking to validate it and the forward kinematic using RST. I have exported the CAD model as XML and created an slx file for it. The robot composes of multiple joints. However, in reality, only 4 joints are actuation joints, the rest are closed loop joints that reduce the robots DOF to 1 or 2 DOF (pitch and translation).
I have set up the robots and actuated it fine using a constant block connected a degree to radians block which is then connected to the robot, which is connected to a MATLAB function script which is then connected to a display to show me the homogenous matrix.
I am now at the stage where I am looking to connect a GetTransform block in order to retrieve the forward kinematic. Below is the way I am connecting the blocks. My apologies since I am using a different computer and can't screenshot my layout.
3 Sine blocks and a constant block connected to the robots (I have made the robots connection and blocks a subsystem). From the robot subsystem, it's connected to a mux that takes 4 inputs. The mux is connected to the GetTransform block. The GetTransform block is connected to a Coordinate Transformation Conversion block which is then connected to a scope.
All of my setup seems fine. However, I am getting an error that says the input is a vector of 4 whereas the outputs requires 11. I know this is due to the joints block where I have set up 4 of them to sense the postion and computed the torque automatically and I have 11 joints in total. When I add an additional Simulink to PS and PS to simulink to another joint, I get an error like this: "The input is a vector of 5 whereas the outputs requires 11". As mentioned, only 4 of the joints are actuating joints and joints that I need to find the forward kinematic for. How can I fix this issue without adding more joints to sense the position?
My second question is rather simple. I am using 3R1P configuration. I know I can get a constant block connected to a degrees to radians block to control the revolute arm of the robot. What is a similar setup I can use to move the prismatic joints?
Thank you so much for the help in advance!

採用された回答

Umar
Umar 2024 年 9 月 9 日

Hi @Cuong Huynh Nguyen

You mentioned, “3 Sine blocks and a constant block connected to the robots (I have made the robots connection and blocks a subsystem). From the robot subsystem, it's connected to a mux that takes 4 inputs. The mux is connected to the GetTransform block. The GetTransform block is connected to a Coordinate Transformation Conversion block which is then connected to a scope. All of my setup seems fine. However, I am getting an error that says the input is a vector of 4 whereas the outputs requires 11. I know this is due to the joints block where I have set up 4 of them to sense the postion and computed the torque automatically and I have 11 joints in total. When I add an additional Simulink to PS and PS to simulink to another joint, I get an error like this: "The input is a vector of 5 whereas the outputs requires 11". As mentioned, only 4 of the joints are actuating joints and joints that I need to find the forward kinematic for. How can I fix this issue without adding more joints to sense the position?”

Please see my response by addressing your first query.

The error message indicates that the GetTransform block expects an input vector of size 11, which corresponds to the total number of joints in your robot model. However, your current setup only provides a vector of size 4, which is likely derived from the four actuating joints. Since you have 11 joints in total, it is essential to make sure that the input to the GetTransform block includes all necessary joint states. The four actuating joints are not sufficient to represent the entire robot's configuration. The remaining joints must be accounted for, even if they are not actively controlled. So, to resolve the mismatch, you can modify the Mux input to include additional elements that represent the remaining joints. Here are a few strategies:

Option A: Zero Padding

If the non-actuating joints do not contribute to the transformation, you can pad the input vector with zeros. This way, you maintain the required size of 11 without adding additional sensing or control mechanisms.

% Assuming 'actuatingJoints' is a vector of size 4
actuatingJoints = [joint1_position; joint2_position; joint3_position;   
joint4_position];
% Create a zero vector for the remaining joints
remainingJoints = zeros(7, 1); % 11 total - 4 actuating = 7 non-actuating
% Combine both vectors
inputVector = [actuatingJoints; remainingJoints]; % This will be of size 11

Option B: State Estimation

If the non-actuating joints have states that can be estimated or are known, you can create a mechanism to compute or retrieve their positions. This could involve using a Constant block or a MATLAB Function block to output the known positions of these joints.

function output = getJointStates()
  % Example of known positions for non-actuating joints
  joint5_position = 0.5; % Example value
  joint6_position = 0.3; % Example value
  % Add more as needed
  output = [joint5_position; joint6_position; ...]; % Continue for all non-  
  actuating joints
end

Once you have constructed the input vector of size 11, connect it to the GetTransform block. For more information on this block, please refer to

https://www.mathworks.com/help/robotics/ref/transformtree.gettransform.html?s_tid=doc_ta

Make sure that the Mux block is configured to accept the new input vector correctly. After making these adjustments, run your Simulink model again. Monitor the output in the Scope to ensure that the transformations are computed correctly and that the error regarding vector size is resolved. This will make sure that the input vector to the GetTransform block matches the expected size of 11, you can effectively resolve the error you are encountering. Whether through zero padding or state estimation, it is crucial to account for all joints in your robot model. This approach not only fixes the immediate issue but also enhances the robustness of your simulation by ensuring that all joint states are appropriately represented.

To address your second query regarding, “My second question is rather simple. I am using 3R1P configuration. I know I can get a constant block connected to a degrees to radians block to control the revolute arm of the robot. What is a similar setup I can use to move the prismatic joints?”

To control a prismatic joint in MATLAB, you can use a combination of blocks in Simulink or write a script in MATLAB. Since you are using Simulink, I will focus on it by providing step by step instructions. In Simulink, create a model that includes the following components:

Position Target: Use the State Targets parameters in the Prismatic Joint block to specify the desired position of the prismatic joint. The position can be controlled using a constant input or a time-varying signal, much like you would for angular positions in revolute joints.

Actuation Input: You can provide the actuation force through the input port f for controlling the joint. If you want to specify the position and velocity directly, enable the corresponding input ports in the block parameters.

By utilizing constant values, gain adjustments, and saturation limits, you can make sure that the prismatic joint operates within its physical constraints.

I would also recommend example documentation “Control PR2 Arm Movements Using ROS Actions and Inverse Kinematics” by clicking the link below

https://www.mathworks.com/help/robotics/ug/control-pr2-arm-movements-using-actions-and-ik.html

Here is an example code snippet for ROS if you feel like experimenting with it.

The code snippet below is a basic example to illustrate sending commands to a prismatic joint:

% Create action client for the prismatic joint
prismaticActionClient = rosactionclient('/prismatic_joint_controller/. 
joint_trajectory_action');
waitForServer(prismaticActionClient);
% Set up the goal message
goalMessage = rosmessage('trajectory_msgs/JointTrajectoryGoal');
goalMessage.Trajectory.JointNames = {'prismatic_joint_name'}; % Specify 
your joint name here
% Define trajectory points
point1 = rosmessage('trajectory_msgs/JointTrajectoryPoint');
point1.Positions = [0]; % Initial position
point1.Velocities = [0]; % Initial velocity
point1.TimeFromStart = rosduration(1.0); % Time from start
point2 = rosmessage('trajectory_msgs/JointTrajectoryPoint');
point2.Positions = [1]; % Desired position
point2.Velocities = [0]; % Desired velocity
point2.TimeFromStart = rosduration(2.0); % Time from start
% Assign points to goal message
goalMessage.Trajectory.Points = [point1, point2];
% Send goal to prismatic joint
sendGoalAndWait(prismaticActionClient, goalMessage);

Additional Suggestions

Calibration:

Make that the prismatic joints are calibrated correctly within your simulation environment to avoid unexpected behavior during motion execution.

Limits and Constraints:

Always define the limits for the prismatic joints to prevent any out-of-bound movements, which could lead to simulation errors or physical damages in real robots.

Testing and Validation:

Before deploying commands to the physical robot, run simulations to validate the behavior of the prismatic joints in various scenarios, ensuring smooth transitions and adherence to trajectory commands.

Hope following these suggestions helps resolve your problem. Please let me know if you have any further questions.

  7 件のコメント
Umar
Umar 2024 年 9 月 18 日

Hi @Cuong Huynh Nguyen,

It appears you are making significant progress in your robotics project, but the issues you're encountering with the Matrix Multiply block stem from the mismatch in dimensions between the inputs. After reviewing your robotics Simulink diagrams and the following documentations listed below

<https://www.mathworks.com/help/simulink/slref/mux.html?searchHighlight=mux%252520block&s_tid=srchtitle_support_results_1_mux%25252520block%20 https://www.mathworks.com/help/simulink/slref/mux.html?searchHighlight=mux%2520block&s_tid=srchtitle_support_results_1_mux%252520block >

https://www.mathworks.com/help/simulink/slref/buscreator.html

https://www.mathworks.com/help/simulink/slref/product.html?searchHighlight=matrix%20multiply%20block&s_tid=srchtitle_support_results_1_matrix%2520multiply%2520block

Let me break down the situation and address your concerns systematically.

Understanding the Matrix Multiply Block

The Matrix Multiply block performs matrix multiplication based on the defined dimensions of its inputs. For your case:

Input A (from the MUX): You have a 4x1 vector (1D array with 4 elements). Input B (from the Jacobian): You have a 6x4 matrix.

For matrix multiplication to be valid, the number of columns in Input A must match the number of rows in Input B. Since Input A is 4x1, it cannot multiply with Input B directly because the required configuration for multiplication is that Input A should ideally be 4xn where n can be any integer.

So, based on the errors you encountered, I would suggest the following suggestions.

Dimension Adjustment: Since you're extracting joint velocities and want to use them effectively, ensure that Input A is reshaped correctly. Instead of using a MUX to create a 1D output, consider creating a 4x1 or 4xN output directly so that it aligns with your intended operations.

Using Identity Matrices: Your approach to using an identity matrix as a transformation for joint velocities could work if set up correctly. However, ensure that this transformation results in a compatible size. For example, if you want to transform your 4-element velocity vector into a 4xN format for multiplication, consider explicitly defining this transformation rather than relying solely on an identity matrix.

Validate Slicing Logic: Double-check your slicing logic in extractJacobian function. Make sure that it indeed returns a 6x4 matrix. If your original Jacobian is indeed 6x11, your slicing command should only extract the columns corresponding to the joints of interest.

   reducedJacobian = Jacobian(:, [1, 2, 3, 4]); % Ensure these    indices match your desired joints

Matrix Multiply Configuration: Make sure that you configure the Matrix Multiply block properly: Set Number of Inputs to 2 and set Multiplication to Matrix(*).

Testing Outputs: Before connecting everything together, test each output separately:

  • Connect constant blocks with known dimensions to see if they yield expected results.
  • If you get errors when connecting outputs from different subsystems, investigate each subsystem's output dimension closely.

In my opinion, errors often propagate through interconnected systems due to mismatched expectations in dimensions. Pay careful attention to how each block's output is defined and used downstream.

Since you are interested in avoiding hardcoding values for velocity outputs, consider utilizing Simulink's capabilities for dynamic signal routing or use Bus Creator blocks for more flexible connections instead of MUX blocks.

If issues persist, consider isolating sections of your model to identify specific points of failure more easily. Feel free to reach out again for further clarification or assistance!

Cuong
Cuong 2024 年 9 月 21 日
Thank you for your help so far!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeCode Generation についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by