# Two Methods for Obtaining TCP Force

**URL:** <https://forum.universal-robots.com/t/two-methods-for-obtaining-tcp-force/42011>\
**Category:** URScript\
**Created:** [December 22, 2025, 6:42am UTC](https://forum.universal-robots.com/t/two-methods-for-obtaining-tcp-force/42011 "2025-12-22T06:42:40Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![DoraBa](https://avatars.discourse-cdn.com/v4/letter/d/cab0a1/32.png) [@DoraBa](https://forum.universal-robots.com/u/DoraBa)\
**Post date:** [December 22, 2025, 6:42am UTC](https://forum.universal-robots.com/t/two-methods-for-obtaining-tcp-force/42011/1 "2025-12-22T06:42:40Z")

</div>

Hi, community

I’m a beginner in UR development. I found two methods for obtaining TCP force within the community. However, the values obtained are inconsistent.

Is my understanding incorrect? Please advise.

demo1: get\_wrench\_at\_tcp()

```auto
def get_wrench_at_tool_flange():
	ft= get_tcp_force() #Tcp force returns the force and torques at the tool flange with base orientation
	t_flange_in_base = pose_trans(get_target_tcp_pose(), pose_inv(get_tcp_offset()))
	flange_rot= pose_inv(p[0, 0, 0,t_flange_in_base[3],t_flange_in_base,[4],t_flange_in_base[5]])
	f= pose_trans(flange_rot,p[ft[0],ft[1],ft[2], 0, 0, 0])
	t= pose_trans(flange_rot,p[ft[3],ft[4],ft[5], 0, 0, 0])
	return [f[0],f[1],f[2],t[0],t[1],t[2]]
end
	
def get_wrench_at_tcp():
	return wrench_trans(get_tcp_offset(),get_wrench_at_tool_flange())
end

```

demo2: get\_tcp\_force\_tool()

```auto
def get_tcp_force_tool():
	force_torque = get_tcp_force()
	force_B = p[force_torque[0], force_torque[1], force_torque[2], 0, 0, 0 ]
	torque_B = p[force_torque[3], force_torque[4], force_torque[5], 0, 0, 0 ]
	tcp = get_actual_tcp_pose()
	rotation_BT = p[0, 0, 0, tcp[3], tcp[4], tcp[5] ]
	force_T = pose_trans( pose_inv(rotation_BT), force_B )
	torque_T = pose_trans( pose_inv(rotation_BT), torque_B )
	force_torque_T = p[force_T[0], force_T[1], force_T[2], torque_T[0], torque_T[1], torque_T[2] ]
	return force_torque_T
end

```

thanks

---

<div class="post-metadata">

**Author:** ![sko](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.universal-robots.com/sko/32/573_2.png) [@sko](https://forum.universal-robots.com/u/sko)\
**Post date:** [December 22, 2025, 8:48am UTC](https://forum.universal-robots.com/t/two-methods-for-obtaining-tcp-force/42011/2 "2025-12-22T08:48:19Z")

</div>

Hello @DoraBa

The first method you have listed is the one also mentioned inside our [UR Script manual](https://s3-eu-west-1.amazonaws.com/ur-support-site/241375/script_directory_Poly5.pdf) on how to use the _get\_tcp\_force()_ - function.

At first sight the second function does not take the TCP offset into account.

---

<div class="post-metadata">

**Author:** ![DoraBa](https://avatars.discourse-cdn.com/v4/letter/d/cab0a1/32.png) [@DoraBa](https://forum.universal-robots.com/u/DoraBa)\
**Post date:** [December 24, 2025, 6:21am UTC](https://forum.universal-robots.com/t/two-methods-for-obtaining-tcp-force/42011/3 "2025-12-24T06:21:23Z")

</div>

Thanks for you kind reply.

Indeed, the first function (demo1) comes from UR Script Manual, the second function (demo2) comes from [universal-robots.com](https://www.universal-robots.com/articles/ur/programming/get-force-and-torque-values-in-tool-coordinate-system/).

> At first sight the second function does not take the TCP offset into account.

As you said, I ran two tests:

```auto
 # Test A: with default tcp offset p[0,0,0,0,0,0]
	  
      # the first function 
      local wrench_at_tool_flange = get_wrench_at_tool_flange()
      local wrench_at_tcp = wrench_trans(get_tcp_offset(),wrench_at_tool_flange)

      textmsg(""tcp_offset = "", get_tcp_offset())
      textmsg(""wrench_at_tool_flange = "", wrench_at_tool_flange)
      textmsg(""wrench_at_tcp = "", wrench_at_tcp)

      # the second function :get_tcp_force_tool
      local wrench_at_tcp_tool = get_tcp_force_tool()
      textmsg(""wrench_at_tcp_tool = "", wrench_at_tcp_tool)

      # the print
      # tcp_offset = p[0,0,0,0,0,0]
      # wrench_at_tool_flange = [0.197695,4.27879,2.91762,0.222555,0.0324379,0.41454]
      # wrench_at_tcp = [0.197695,4.27879,2.91762,0.222555,0.0324379,0.41454]
      # wrench_at_tcp_tool = p[0.197553,4.27837,2.91824,0.222525,0.032375,0.414562]

 # Test B: with my tcp offset p[0.13576,0.13576,0.12651,0.0145742,-0.0437474,2.31727]
	  
      # the first function 
      local wrench_at_tool_flange = get_flange_wrench()
      local wrench_at_tcp = wrench_trans(get_tcp_offset(),wrench_at_tool_flange)

      textmsg(""tcp_offset = "", get_tcp_offset())
      textmsg(""wrench_at_tool_flange = "", wrench_at_tool_flange)
      textmsg(""wrench_at_tcp = "", wrench_at_tcp)

      # the second function :get_tcp_force_tool
      local wrench_at_tcp_tool = get_tcp_force_tool()
      textmsg(""wrench_at_tcp_tool = "", wrench_at_tcp_tool)

      # the print
      # tcp_offset = 0.13576,0.13576,0.12651,0.0145742,-0.0437474,2.31727
      # wrench_at_tool_flange = [3.64337,-2.21221,2.03934,0.917855,-0.115615,-0.855018]
      # wrench_at_tcp = [-0.858366,4.09975,2.18682,-0.757643,0.37723,-0.155802]
      # wrench_at_tcp_tool = p[-4.04778,-1.22544,2.10728,-0.729278,-0.572403,-0.85287]

```

Test A proves what you said (ignore the error).

How to interpret “wrench\_at\_tcp “ and “wrench\_at\_tcp\_tool “ in Test B ?

thanks!
