epfl-lasa / iiwa_ros

ROS Meta-package for controlling KUKA IIWA
GNU General Public License v3.0
136 stars 42 forks source link

Robot does not hold current position when iiwa_driver is launched #84

Closed victoralad closed 2 years ago

victoralad commented 2 years ago

According to the instructions on this repository, to launch the robot, the application is selected on the smartpad and the command roslaunch iiwa_driver iiwa_bringup.launch is run in the terminal. However, when I do that, and select Torque (the other options are wrench and position) on the smart pad, the robot suddenly starts moving very fast to a configuration I have no idea what it is. I expected the robot to stay in its current pose. Am I missing something or is there a solution to this?

costashatz commented 2 years ago

Which controller are you using? The default one or the CustomEffortController?

victoralad commented 2 years ago

Yes, I used the default one. Are you suggesting I use CustomControllers instead? Based on how the default controller behaves in simulation, I suspect there is no gravity compensation being done by the TorqueController. However, the motion I observed on the hardware appears to be an active torque commanded, and not just the lack of gravity compensation.

victoralad commented 2 years ago

I went ahead to try the CustomControllers on the hardware, but I got the same behavior as I did when I used TorqueController. The robot suddenly starts moving to an unknown configuration.

costashatz commented 2 years ago

This is weird. The TorqueController should do nothing (just gravity compensation). Are you sure that you are following the bringup instructions here correctly?

The only other thing that comes to my mind is the following: Do you have some tool attached to the end-effector? Which Java file have you loaded (look here)? FRIOverlay or FRIOverlayGripper? If you have weight attached to the end-effector without launching the gripper file or you have not configured your gripper correctly (you need to identify the mass properties) then you might get weird behaviors.

victoralad commented 2 years ago

Hmm, I may have used FRIOverlay. Indeed, I have a Robotiq gripper at my end effector. I may need to switch to FRIOverlayGripper. I will try it out and let you know how it goes. Thanks

matthias-mayr commented 2 years ago

As you probably found out, the line in FRIOverlayGripper

_toolAttached = getApplicationData().createFromTemplate("MyVirtualGripper");

needs to have the name of the tool that is known to the KUKA Java stack. But then - besides some slight miscalibration it works for us.

victoralad commented 2 years ago

Indeed, using FRIOverlayGripper, when I have a gripper attached, works after proper calibration. When I use TorqueController, the robot holds its position. However, when I use CustomControllers, the robot still tries to go to an unknown location. I went back into the code custom_effort_controller.cpp to review what might be going on. However, I could not tell for sure if the control is a full task space control (position + orientation) or if it is just orientation control. I know the default is a task-space control, but the iiwa_control.yaml file currently sets the type to just orientation (see CustomControllers type).

In summary, what exactly is the CustomControllers doing?

Lastly, it appears there is no consideration of Coriolis forces. Was this done on purpose?

Thanks

costashatz commented 2 years ago

Indeed, using FRIOverlayGripper, when I have a gripper attached, works after proper calibration. When I use TorqueController, the robot holds its position

This is nice!

In summary, what exactly is the CustomControllers doing?

This part needs a big documentation that we never found time to write. It is not just Orientation. The yaml defines a structure of the defined controllers. In the default configuration (as seen in the yaml), we have 3 controllers: LinearDS, PassiveDS and PD. In the structure, we define that the signal goes first into LinearDS and then in PassiveDS which are combined into a new controller and (this is assumed by the absence of any other structure) this new controller is added with the PD one. LinearDS and PassiveDS operate in the Position part and PD in the Orientation part, thus we have two independent controllers. Overall the default configuration of the yaml, is a basic controller for both translation and orientation that reaches points commanded via the iiwa_control/CustomEffortController/command topic (first 3 values are angle-axis representation of orientation, last 3 values target positions). You should be able to see the initial command the robot attempts to go by examining the output of this line (again first 3 values are angle-axis representation of orientation, last 3 values target positions).

It could be that the driver is launched too soon and the initial command is junk. What is the output of the above?

Lastly, it appears there is no consideration of Coriolis forces. Was this done on purpose?

Yes because iiwa adds this (and gravity forces) automatically and there is no way to remove it. So we do not add anything for this.

victoralad commented 2 years ago

@costashatz I tested the CustomControllers again, and it works! The problem I had before was that I had modified the custom_effort_controller.cpp file to account for my namespace modification. This resulted in the weird behavior I saw. Once I fixed that, everything appears to be working perfectly for just a single robot.

I am now working on addressing the issues with namespace as recommended by you and Matthias in the other post (namespace). It appears that wrapping namespace for simulation seems to be slightly different from wrapping namespace for the hardware. On the hardware, it is as simple as creating two yaml files for the controller and passing the appropriate yaml file for each robot. Whereas in simulation, I also have to worry about spawning both robots, so I must pay attention to how I setup the robot_description parameter. I was hoping I could load just one robot_description to the parameter server, and spawn two separate robots using the same robot_description, but it appears that is not possible.

costashatz commented 2 years ago

@costashatz I tested the CustomControllers again, and it works! The problem I had before was that I had modified the custom_effort_controller.cpp file to account for my namespace modification. This resulted in the weird behavior I saw. Once I fixed that, everything appears to be working perfectly for just a single robot.

Happy that this is working..

I am now working on addressing the issues with namespace as recommended by you and Matthias in the other post (namespace). It appears that wrapping namespace for simulation seems to be slightly different from wrapping namespace for the hardware. On the hardware, it is as simple as creating two yaml files for the controller and passing the appropriate yaml file for each robot. Whereas in simulation, I also have to worry about spawning both robots, so I must pay attention to how I setup the robot_description parameter. I was hoping I could load just one robot_description to the parameter server, and spawn two separate robots using the same robot_description, but it appears that is not possible.

Let's move this discussion in #85 . See @matthias-mayr's reply. Closing this.

victoralad commented 2 years ago

Hello Konstantinos, I would like to cite iiwa_ros, please do you have a bibtex reference for your software? Regards

Victor Aladele

PhD student

Robotics and Machine Learning

Electrical and Computer Engineering Department

Georgia Institute of Technology

The true sign of intelligence is not knowledge but imagination.

Albert Einsteinhttp://www.brainyquote.com/quotes/authors/a/albert_einstein.html


From: Konstantinos Chatzilygeroudis @.> Sent: Monday, May 9, 2022 4:11 AM To: epfl-lasa/iiwa_ros @.> Cc: Aladele, Victor Oluwatobi @.>; Author @.> Subject: Re: [epfl-lasa/iiwa_ros] Robot does not hold current position when iiwa_driver is launched (Issue #84)

@costashatzhttps://github.com/costashatz I tested the CustomControllers again, and it works! The problem I had before was that I had modified the custom_effort_controller.cpp file to account for my namespace modification. This resulted in the weird behavior I saw. Once I fixed that, everything appears to be working perfectly for just a single robot.

Happy that this is working..

I am now working on addressing the issues with namespace as recommended by you and Matthias in the other post (namespacehttps://github.com/epfl-lasa/iiwa_ros/issues/85). It appears that wrapping namespace for simulation seems to be slightly different from wrapping namespace for the hardware. On the hardware, it is as simple as creating two yaml files for the controller and passing the appropriate yaml file for each robot. Whereas in simulation, I also have to worry about spawning both robots, so I must pay attention to how I setup the robot_description parameter. I was hoping I could load just one robot_description to the parameter server, and spawn two separate robots using the same robot_description, but it appears that is not possible.

Let's move this discussion in #85https://github.com/epfl-lasa/iiwa_ros/issues/85 . See @matthias-mayrhttps://github.com/matthias-mayr's reply. Closing this.

— Reply to this email directly, view it on GitHubhttps://github.com/epfl-lasa/iiwa_ros/issues/84#issuecomment-1120783488, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AIME5TC2IBROF4THLJTW7A3VJDCE3ANCNFSM5U5MSRUA. You are receiving this because you authored the thread.Message ID: @.***>

costashatz commented 2 years ago

Hello Konstantinos, I would like to cite iiwa_ros, please do you have a bibtex reference for your software? Regards

Check here. This should suffice for now. Aiming for a proper citation soon :)

victoralad commented 2 years ago

Great! Thank you! Regards

Victor Aladele

PhD student

Robotics and Machine Learning

Electrical and Computer Engineering Department

Georgia Institute of Technology

The true sign of intelligence is not knowledge but imagination.

Albert Einsteinhttp://www.brainyquote.com/quotes/authors/a/albert_einstein.html


From: Konstantinos Chatzilygeroudis @.> Sent: Tuesday, June 28, 2022 10:34 AM To: epfl-lasa/iiwa_ros @.> Cc: Aladele, Victor Oluwatobi @.>; Author @.> Subject: Re: [epfl-lasa/iiwa_ros] Robot does not hold current position when iiwa_driver is launched (Issue #84)

Hello Konstantinos, I would like to cite iiwa_ros, please do you have a bibtex reference for your software? Regards

Check herehttps://github.com/epfl-lasa/iiwa_ros#citing-iiwa_ros. This should suffice for now. Aiming for a proper citation soon :)

— Reply to this email directly, view it on GitHubhttps://github.com/epfl-lasa/iiwa_ros/issues/84#issuecomment-1168807321, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AIME5TDG6NRICW7UT54HKIDVRMEPJANCNFSM5U5MSRUA. You are receiving this because you authored the thread.Message ID: @.***>

XinyuanZhao commented 1 year ago

According to the instructions on this repository, to launch the robot, the application is selected on the smartpad and the command roslaunch iiwa_driver iiwa_bringup.launch is run in the terminal. However, when I do that, and select Torque (the other options are wrench and position) on the smart pad, the robot suddenly starts moving very fast to a configuration I have no idea what it is. I expected the robot to stay in its current pose. Am I missing something or is there a solution to this?

Hello. I met the same problem as described here when I managed to communicate with the robot and run roslaunch iiwa_driver iiwa_bringup.launch. The robot didn't hold its current position but tried to move to another configuration.The following are what I found and checked.

Do you have any ideas why it is the case? By the way, how does the controller decide the reference joint positions when I launch the TorqueController? 1675216049935

costashatz commented 1 year ago
  • When I set the stiffness to be 50 or 100, the robot moved fast. When I set the stiffness to be 0 (so there should be only the automatic gravity compensation), the robot moved gently but it still tried to reach another configuration.

This seems to me like a bad calibration of the robot. Try to calibrate the robot using your smartpad.

how does the controller decide the reference joint positions when I launch the TorqueController?

The TorqueController does not have reference joint positions. It waits for torque commands looking at the topic /iiwa/TorqueController/command (assuming you have all defaults namespaces etc).

Do you have any ideas why it is the case?

This is most probably due to wrong configuration. Are you using FRIOverlay or FRIOveralyGripper?

XinyuanZhao commented 1 year ago

Thank you for the timely response!

Are you using FRIOverlay or FRIOveralyGripper?

We are using FRIOverlay since there is no tool attached to the EE.

This seems to me like a bad calibration of the robot. Try to calibrate the robot using your smartpad.

We did calibration on SmartPad in the morning, after which the performance might be a little bit better (but still the robot cannot hold its configuration at any initial pose). What we found is that the default gravity compensation performs differently at different robot's configuration: Under some joint configuration the robot can really stay still for minutes but under another configuration some joints (in our case joint 5 is the one demonstrating the most weird behavior) tend to rotate until reaching the limits. It is worth mentioning that the robot keeps still when launching the torque controller in all the cases.

So basically we suppose that the default URDF used by KUKA to realize the gravity compensation is not perfect -- the modeling mismatch may cause larger effect on the compensation under some joint configuration than under others. But anyway we are able to achieve simple joint-wise torque control using IIWA_ROS. Please let me know if you think up possible solutions or detect any incorrect operation in our test.

costashatz commented 1 year ago

It is worth mentioning that the robot keeps still when launching the torque controller in all the cases.

Wait. What do you mean here? I thought you were saying that it wasn't working with the torque controller.

So basically we suppose that the default URDF used by KUKA to realize the gravity compensation is not perfect -- the modeling mismatch may cause larger effect on the compensation under some joint configuration than under others.

Yes, the gravity compensation is not perfect. It doesn't account for velocities for example. It's pure gravity compensation. Also KUKA is not using a URDF and their model is pretty good. It's just that you cannot compensate for everything.

But anyway we are able to achieve simple joint-wise torque control using IIWA_ROS.

Your signal should be much stronger than the gravity compensation in any case.

XinyuanZhao commented 1 year ago

Wait. What do you mean here? I thought you were saying that it wasn't working with the torque controller.

Sorry for the misleading expressions. I wanted to say that the joint velocities are zero when launching the torque controller so that the gravity compensation was not affected by initial movement of the robot.

It doesn't account for velocities for example. It's pure gravity compensation.

Thank you for the reminder. Previously I suppose KUKA also took Coriolis and centrifugal into account.

It's just that you cannot compensate for everything.

It is the case. I cannot adjust the performance of gravity compensation by modifying the URDF accordingly.

matthias-mayr commented 1 year ago

I met some guys from Stanford who visited about 50 points in the workspace and recorded the external torques reported by KUKA. Since there shouldn't be any if the robot is undisturbed, this tells you how much it is off. Then they mapped this to a virtual mass at the end-effector that they compensated themselves for. In the context of this driver, one would write a script that reads the robot state and send torques to the TorqueController.

Before doing that, they saw the same behavior that you are experiencing. They also had a quite good connection to KUKA people, so I am sure they talked to them about this and apparently this is still the solution of the Stanford lab.

XinyuanZhao commented 1 year ago

Thank you for sharing this story! It made me believe that we are not alone encountering this weird behavior and also shed light on how it can be solved.

matthias-mayr commented 1 year ago

We typically run a Cartesian impedance controller with iiwa_ros. Then it is not that apparent, except if we completely disable the stiffness.

XinyuanZhao commented 1 year ago

We typically run a Cartesian impedance controller with iiwa_ros. Then it is not that apparent, except if we completely disable the stiffness.

Thank you again for sharing this toolbox, which seems to be a well-designed impedance controllers for manipulator's control. We will follow it later if we find it useful for our study.

Just think of another question using iiwa_ros: what are the stiffness gains (e.g. 0, 50, 100, etc.) shown on SmartPad when I just run roslaunch iiwa_driver iiwa_bringup.launch? Are they joint-wise stiffness? Am I able to tune these values in my controller via rostopic or rosservice?

matthias-mayr commented 1 year ago

Are they joint-wise stiffness?

Yes, you are configuring KUKA's joint impedance controller

Am I able to tune these values in my controller via rostopic or rosservice?

Not really. Once the FRI connection is built up, only joint position references and joint effort references are sent from the ROS side.

There is the code around grl that allowed to configure things on the robot side with a different channel. I spent some time with it in 2020, but did not make it work before I opted for another solution. It seems like the repository got abandoned when the PhD student left.

XinyuanZhao commented 1 year ago

Yes, you are configuring KUKA's joint impedance controller

Thanks! But what is the reference joint position for KUKA's joint impedance controller? Am I able to check and modify this value? Are there also default damping gains for that joint impedance controller?

And further, if I implement another controller and publish torque signal, I wonder if the robot will receive a compound torque command of default gravity compensation + default joint impedance control + user's control?

matthias-mayr commented 1 year ago

Thanks! But what is the reference joint position for KUKA's joint impedance controller? Am I able to check and modify this value? When it's initialized it's the current position & later on whatever ROS sends. You can switch to the PositionJointInterface in iiwa_ros for that & then use whatever controller.

Are there also default damping gains for that joint impedance controller?

I assume so. That is on the KUKA side. You should have received some documentation for their Java API

I wonder if the robot will receive a compound torque command of default gravity compensation + default joint impedance control + user's control?

FRI allows users to overlay KUKA's control with custom references. And this is what is sent from the ROS side with iiwa_ros. KUKA's control is gravity compensation + the control signal of the controller that is started on the Java side. (which is the Joint impedance for you right now)

This means that if some stiffness for that joint impedance controller is defined, then it would output a torque signal as well. When we do torque control like in the Cartesian impedance controller repo we typically do not want that the KUKA controller to interfere, so we set the stiffness to 0.

The gravity compensation would always be applied and the it's gravity compensation + user torques

XinyuanZhao commented 1 year ago

You can switch to the PositionJointInterface in iiwa_ros for that & then use whatever controller.

Glad to know that I may have control over the reference joint position for KUKA's joint impedance controller. May you please explain this operation in a bit more detail? Some questions are listed below for example

When we do torque control like in the Cartesian impedance controller repo we typically do not want that the KUKA controller to interfere, so we set the stiffness to 0.

It is very likely that we will also set the stiffness to 0 so as to avoid interference between KUKA's controller and our custom controller. I want to play with KUKA's stiffness gains and its reference joint position mainly because the robot didn't behave as we expected when I gave non-zero stiffness: the robot moved rapidly to an unknown configuration and incur safety shutdown (while with 0 stiffness the robot seems to be a bit normal). So there should be something wrong such as incorrect configuration from us or mechanical failure of one joint, etc. Hope I can figure them out before they ruin the results in the future.