问:
Control signal of an LQR Controller
I'm working on building an LQR for a system which consists of a ball in a vertical tube, a fan is situated at the bottom of the tube and a distance sensor is at the top, a raspberry Pi is used to send a PWM signal to the fan which can be supplied with 0-5 Volts. The idea is that the user can set the desired height of the ball and the fan will lift it up the the desired height. I have two equations which I combined to get the ball dynamics in terms of voltage supplied, my maths can be seen below:

I have the simulation working in MATLAB but I've gotten stuck in a rut with grasping what the "U" control signal actually refers to in the physical system, I want to believe that the "U" term in the state space model is the voltage supplied to the fan but I've received other opinions that this isn't the case and that the "U" signal being produced by the LQR calculations is somewhat arbitrary and is to be converted for interpretation  by the Pi with a multiplier of "5/255" (which is referring to the resolution that the Pi can receive the signal in). The main reason for this question is I have to ensure that the 0-5 Volts saturation limit is adhered to by the LQR and am unsure as to how to achieve this. So in this case, is the "U" term in the state space model exactly equal to the required supply voltage, or is there something more to consider? Any thoughts are welcome.

Thanks in advance.

答:
I've gotten stuck in a rut with grasping what the "U" control signal actually refers to in the physical system

But you've written what it is already!

$$
\dot{x} = Ax + Bu
$$

It's whatever the input to your system is. Maybe it's speed, or thrust, or acceleration. It's the thing that is exciting your system.

I'm looking at your equations and I don't think they're correct - you have your input there mapping to $\dot{x_3}$. You are writing that $x_3$ is acceleration, so your input is affecting... Jerk? Is that correct? Typically I would expect to see an x1/x2 that are position and speed, and then the inputs map to the derivative of x2, which is acceleration.

It is very likely that your control output goes to some other system, like a throttle pedal, or a speed regulator, etc. It's up to you to map the signals appropriately and, importantly, the dynamics of the downstream system need to either be negligible or included in the plant model.

Title: Control signal of an LQR Controller


问:
ABB RAPID - calculating seam length
I have an Arc welding RAPID program with many seams. One of them looks like this:

```<code>ArcLStart W007_On, vtoArc, sm01, s_12, fine, R1_tWeld\WObj:=R1_wFix;
ArcL W007_1, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcC W007_2, W007_3, Vweld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcL W007_4, vWeld, sm01, s_8, z10, R1_tWeld\WObj:=R1_wFix;
ArcL W007_5, vWeld, sm01, s_8, z5, R1_tWeld\WObj:=R1_wFix;
ArcLEnd W007_Off, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
</code>```

What I want to do is measure/calculate the seam length programatically. Calculation can take place during normal program execution or in specialised routine (doesn't matter). How can I do that in RAPID?

答:
Thanks everyone for useful suggestions!

I ended up using module with ArcX instruction aliases. It calculates seam length during program execution. Following is a simplified example of implementation:

```<code>MODULE ArcEx(NOSTEPIN)
   CONST robtarget ArcEx_pNonePoint := [[0,0,0],[0,0,0,0],[0,0,0,0],[9E9,9E9,9E9,9E9,9E9,9E9]];
   TASK VAR robtarget ArcEx_pRefPoint := ArcEx_pNonePoint; ! Variable for storing previous point
   TASK VAR num ArcEx_nWeldDistance := 0; ! Calculated weld distance

   PROC ArcLStartEx(robtarget ToPoint) ! Arguments ommited for readibility (same as original ArcLStart)
      ArcEx_nWeldDistance := 0;
      ArcEx_pRefPoint := ToPoint;

      ArcLStart ToPoint, \ID?ID, Speed, Seam, \AdvData?AdvData, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \SeamName?SeamName, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
   ENDPROC

   PROC ArcLEx() ! Arguments ommited for readibility (same as original ArcL)
      ArcEx_nWeldDistance := ArcEx_nWeldDistance + Distance(ArcEx_pRefPoint.trans, ToPoint.trans);
      ArcEx_pRefPoint := ToPoint;

      ArcL ToPoint, \ID?ID, Speed, Seam, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \Time?Time, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
   ENDPROC

   PROC ArcLEndEx() ! Arguments ommited for readibility (same as original ArcLEnd)
      ArcEx_nWeldDistance := ArcEx_nWeldDistance + Distance(ArcEx_pRefPoint.trans, ToPoint.trans);
      ArcEx_pRefPoint := ArcEx_pNonePoint;

      TPWrite "Seam length: "\num:=ArcEx_nWeldDistance

      ArcLEnd ToPoint, \ID?ID, Speed, Seam, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \Time?Time, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
   ENDPROC
ENDMODULE
</code>```

Example usage:

```<code>ArcLStartEx W007_On, vtoArc, sm01, s_12, fine, R1_tWeld\WObj:=R1_wFix\SeamName:="W007";
ArcLEx W007_1, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcCEx W007_2, W007_3, Vweld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcLEx W007_4, vWeld, sm01, s_8, z10, R1_tWeld\WObj:=R1_wFix;
ArcLEx W007_5, vWeld, sm01, s_8, z5, R1_tWeld\WObj:=R1_wFix;
ArcLEndEx W007_Off, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
</code>```

This obviously needs a lot of work for handling circular movements, zones etc. That's why I'm not marking this question answered yet.

ContentLicense: CC BY-SA 4.0

Title: ABB RAPID - calculating seam length

Body:
Thanks everyone for useful suggestions!

I ended up using module with ArcX instruction aliases. It calculates seam length during program execution. Following is a simplified example of implementation:

MODULE ArcEx(NOSTEPIN)
   CONST robtarget ArcEx_pNonePoint := [[0,0,0],[0,0,0,0],[0,0,0,0],[9E9,9E9,9E9,9E9,9E9,9E9]];
   TASK VAR robtarget ArcEx_pRefPoint := ArcEx_pNonePoint; ! Variable for storing previous point
   TASK VAR num ArcEx_nWeldDistance := 0; ! Calculated weld distance

   PROC ArcLStartEx(robtarget ToPoint) ! Arguments ommited for readibility (same as original ArcLStart)
      ArcEx_nWeldDistance := 0;
      ArcEx_pRefPoint := ToPoint;

      ArcLStart ToPoint, \ID?ID, Speed, Seam, \AdvData?AdvData, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \SeamName?SeamName, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
   ENDPROC

   PROC ArcLEx() ! Arguments ommited for readibility (same as original ArcL)
      ArcEx_nWeldDistance := ArcEx_nWeldDistance + Distance(ArcEx_pRefPoint.trans, ToPoint.trans);
      ArcEx_pRefPoint := ToPoint;

      ArcL ToPoint, \ID?ID, Speed, Seam, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \Time?Time, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
   ENDPROC

   PROC ArcLEndEx() ! Arguments ommited for readibility (same as original ArcLEnd)
      ArcEx_nWeldDistance := ArcEx_nWeldDistance + Distance(ArcEx_pRefPoint.trans, ToPoint.trans);
      ArcEx_pRefPoint := ArcEx_pNonePoint;

      TPWrite "Seam length: "\num:=ArcEx_nWeldDistance

      ArcLEnd ToPoint, \ID?ID, Speed, Seam, Weld, \Weave?Weave, Zone, Tool, \WObj?WObj, \Corr?Corr, \Track?Track, \Time?Time, \T1?T1, \T2?T2, \T3?T3, \T4?T4, \T5?T5, \T6?T6, \T7?T7, \TLoad?TLoad;
   ENDPROC
ENDMODULE

Example usage:

ArcLStartEx W007_On, vtoArc, sm01, s_12, fine, R1_tWeld\WObj:=R1_wFix\SeamName:="W007";
ArcLEx W007_1, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcCEx W007_2, W007_3, Vweld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;
ArcLEx W007_4, vWeld, sm01, s_8, z10, R1_tWeld\WObj:=R1_wFix;
ArcLEx W007_5, vWeld, sm01, s_8, z5, R1_tWeld\WObj:=R1_wFix;
ArcLEndEx W007_Off, vWeld, sm01, s_8, z1, R1_tWeld\WObj:=R1_wFix;

This obviously needs a lot of work for handling circular movements, zones etc. That's why I'm not marking this question answered yet.


问:
Quadrotor dynamics: How is torque created
I'm a software engineer and I've recently engaged into Robotics field. I've started by a course on Coursera which talks about Aerial robotics and thus quad-rotors. I'm trying to understand how quad-rotors dynamic works and i'm struggling understanding some key points.

I'm going to explain and make some assumptions based on what i've understood by studying till now, and will ask a specific question at the end, please correct me if i'm wrong.

A quad-rotor is a robot of 6 degrees of freedom, which involved translations in the 3 different axis (X, Y, Z) and rotating over the same axis, which defines the 3 famous movements: Roll, Pitch and Yaw.

The quad-rotor has 4 motors rotating with specific angular velocities, and the previously discussed motions are achieved by regulating these angular velocities. More specifically, when rotating, the motor blades create two type of forces, commonly known as Thrust and Torque. The Thrust permit the robot to maintain a specific altitude, however the Torque is used to allow the robot to rotate.

My question is: how are these forces generated ? what's the physical explanation behind it ?

My assumptions are as follow:

1- The Thrust is generated because of the existence of a flowing air which flows from the bottom to the top passing through the motor's blade due to the high velocity of this latter

2- The b is generated due to the existing of Thrust and depends on the blade's length. What i basically understood is that, when an object is rotating over an axe of rotation, a moment is generated (also denoted Torque when the involved quantity is a force), which is no more than the cross-product of both the force and the length between a considered point of that object and the axis of rotation. (Here i'm assuming this force is the Thrust, but my mind is doubting on my assumption, correct me if i'm wrong)

To illustrate my assumptions, here's a picture depicting what i said:

From this picture you can see the flowing air, creating the Thurst, and the Torque represented on the blade's tip, created by the previous Thrust and depends on the blade's length (or radius). More specifically:

$$
\overrightarrow{Torque} = \overrightarrow{Thrust} * \overrightarrow{Blade's length}
$$

The above operation is the Vector Cross-Product

One more question, is about the Torque's direction, i've been reading across multiple sources that it should be in the inverse direction of the angular velocity, but i don't exactly know why.

Thanks and sorry for the long post.

答:
Each motor generates torque to spin it's fan.   As the fan turns, the quadrotor will experience the same torque on the frame, only in the opposite direction.

This is similar to a helicopter - the tail rotor is needed to counteract the torque from the main engine.    If the tail rotor fails, the helicopter will start to rotate in the opposite direction from it's airfoil.

This is why drones always have an even number of fans - half of them spin counterclockwise and half spin clockwise to keep the torque balanced.

The fans convert most of the torque into thrust by pushing air down.  The relationship between torque and thrust isn't going to be a simple linear relationship as you suggest.    Fan/propeller performance is usually modelled empirically.


问:
How to implement the Wavefront algorithm?
I am thinking of creating a robot that can navigate using a map. It is controlled from a PC. An 8-bit controller performs low level tasks and the PC is doing the image processing. I plan to implement it in a single room where the robot is placed and the robot and environment are tracked by a camera from a height or from the ceiling of the room. First, the robot needs to be mapped, like this http://www.societyofrobots.com/programming_wavefront.shtml

To do:

Track the robot from some height using a camera Following the
Wavefront algorithm to locate the robot and obstacles.

Procedure:(just my idea)

The camera will give an image of the robot surrounded by obstacles in random places.
using some OpenCV technique draws some grind over the image.

Locating the grid which contains robot (by having some colored symbol over the robot) and locating the grids containing the obstacle.

Now, the grids with an obstacle are thought of as wall and the remaining is the free space for the robot to navigate.

The robot is going to get the goal place which should be reached is given from the pc(maybe like point the place to reach in the image by mouse click).

Unknowns :

Mapping the room and locating the robot

How to do that? The robot should know where it is in the map or the image. We cannot believe only the camera is enough to locate the robot. So I thought of adding triangulation mapping like placing two IRs in the room and a receiver in the robot.

The doubt I have in this is how an IR receiver can know from which direction it is receiving the IR signal (from left or right ). I think it knows only that it receives IR, not the direction. Then how is the triangulation going to happen if I don't know the angle and direction?

coming to the image processing, how can I implement the Wavefront
algorithm (that captures the live video and draw grids over it to
find the robot and the obstacles)?

I have HC-05 Bluetooth module, Arduino, Bluetooth dongle, chassis with dc motors and driver, and a dc supply.

答:
First run the Canny edge detector on the captured image. Next dilate the edges by 1 or 2 pixels in the image. Then search the colour image for what ever colour you are looking for. generally pure R,G,or B are good as they aren't very natural. This allows you to localize in the image. Now run the wave front algorithm in the Canny image. It's not very hard to implement its just breadth first search where neighbours are pixels and pixels with value 255 (white) aren't added to the search queue as they are walls. You may want to convert the canny image from 8bit to 16bit so that you can move more than 255 pixels.

The only problem is that is assumes the ground plane has no edges (i.e. not tile or hardwood floor) and it can't deal with obstacles like tables that one can navigate under.

In order to remedy this you would have to find the ground plane somehow. This could be done with a stereo camera or a Kinect.

ContentLicense: CC BY-SA 3.0


答:
You're right that each spinning prop creates both a force and a torque.

The force is created opposite the direction of the flowing air; each action has an equal and opposite reaction. The same way you can push away from a wall by pushing onto it, the propeller pushes "away" from the air (up) by pushing the air down.

That same force also exerts a torque on the body of the quadrotor, since typically the line of action does not go through the center of mass. This is separate from the torque generated by the propeller itself. The torque about the body center of mass generated by the force is used to tilt the quadrotor and initiate motion in the horizontal plane. When the quadrotor is hovering, each of the four rotors is carefully balancing the torques they generate.

The torque generated by the propeller itself is, as @billmcc mentioned, produced in opposite direction to the torque exerted by the motor on the prop (the same equal and opposite reaction principle as with the force). This torque is around the axis of the motor shaft, and tends to spin the body of the quadrotor around its z-axis. When the rotor is spinning at a constant angular velocity, this torque is needed to fight the drag the propeller experiences as it moves through the air, as well as friction from the motor itself. If there were no air and no friction, a prop spinning at constant angular velocity would not generate any torque on the body.

So the torque generated by the propeller is not quite coming from the force generated by the propeller, but incidentally, many quadrotor controllers model this relationship linearly: Torque = C * Thrust. This tends to hold roughly after empirical analysis. By your "r x F" reasoning and diagram, the torque would be generated coming out of the screen, and since the prop is rotating, the torque on one side is equally cancelled by an opposite torque on the other side.

There is a second type of torque generated around the z-axis when the rotor speed is changing due to the conservation of angular momentum. This torque is proportional to the rate of change of the angular velocity of the rotor, but is typically ignored in quadrotor controllers since it's quite small for small propellers relative to the other torque (the torque due to propeller drag).

Hope this helps and let me know if you have questions!

Title: Quadrotor dynamics: How is torque created

Body:
I'm a software engineer and I've recently engaged into Robotics field. I've started by a course on Coursera which talks about Aerial robotics and thus quad-rotors. I'm trying to understand how quad-rotors dynamic works and i'm struggling understanding some key points.

I'm going to explain and make some assumptions based on what i've understood by studying till now, and will ask a specific question at the end, please correct me if i'm wrong.

A quad-rotor is a robot of 6 degrees of freedom, which involved translations in the 3 different axis (X, Y, Z) and rotating over the same axis, which defines the 3 famous movements: Roll, Pitch and Yaw.

The quad-rotor has 4 motors rotating with specific angular velocities, and the previously discussed motions are achieved by regulating these angular velocities. More specifically, when rotating, the motor blades create two type of forces, commonly known as Thrust and Torque. The Thrust permit the robot to maintain a specific altitude, however the Torque is used to allow the robot to rotate.

My question is: how are these forces generated ? what's the physical explanation behind it ?

My assumptions are as follow:

1- The Thrust is generated because of the existence of a flowing air which flows from the bottom to the top passing through the motor's blade due to the high velocity of this latter

2- The b is generated due to the existing of Thrust and depends on the blade's length. What i basically understood is that, when an object is rotating over an axe of rotation, a moment is generated (also denoted Torque when the involved quantity is a force), which is no more than the cross-product of both the force and the length between a considered point of that object and the axis of rotation. (Here i'm assuming this force is the Thrust, but my mind is doubting on my assumption, correct me if i'm wrong)

To illustrate my assumptions, here's a picture depicting what i said:

From this picture you can see the flowing air, creating the Thurst, and the Torque represented on the blade's tip, created by the previous Thrust and depends on the blade's length (or radius). More specifically:

$$
\overrightarrow{Torque} = \overrightarrow{Thrust} * \overrightarrow{Blade's length}
$$

The above operation is the Vector Cross-Product

One more question, is about the Torque's direction, i've been reading across multiple sources that it should be in the inverse direction of the angular velocity, but i don't exactly know why.

Thanks and sorry for the long post.


问:
How to estimate gradient of Jerk
A trajectory is described by a position vector, i.e., traj = $[q_0, q_1,...,q_n]$. The objective is to minimize the jerk of the trajectory.

I am referring to this code to understand how the gradient of jerk is defined. It's clear how Jerk is defined, but I am not clear how the gradient of jerk is defined. Any help to understand this much appreciated.

$jerk_i = q_{i+3}-3q_{i+2}+3q_{i+1}-x_i, \forall jerk_i, i=1,...,n-3$

In that implementation, $\bigtriangledown jerk_i $ is defined as follows:

$\bigtriangledown jerk_i \; \mathrel{+}= -2 \cdot jerk_i , \quad  \bigtriangledown jerk_{i+1} \; \mathrel{+}= 6 \cdot jerk_i, \quad   \bigtriangledown jerk_{i+2} \; \mathrel{-}= 6 \cdot jerk_i, \quad  \bigtriangledown jerk_{i+2} \; \mathrel{+}= 2 \cdot jerk_i$

Not clear why they have defined gradient this way?

答:
The code is computing the gradient of the cost, which is jerk squared, not the gradient of the jerk. The comment there is misleading! As written, it seems the code is implementing the chain rule of
$$
c = j^\top j
$$
$$
\frac{\partial c}{\partial q} = 2j\frac{\partial j}{\partial q}
$$

$2j$ is set to temp_j and you can see how the partial of jerk w.r.t q is computed given the expression for jerk. The constants 1, -3, 3, and -1 can be read off.

Title: How to estimate gradient of Jerk


问:
How to subscribe message coming from a package of ROS into Python code of another package?
I am using darknet_ros_3d package and getting the published 3D coordinates. Now I need to subscribe these coordinates into a Python file (main.py) of another package named kth-ros-pkg/yumi_demos. The code of main.py is given as below:

```<code>import sys
import copy
import rospy
import moveit_commander
import yumi_moveit_utils as yumi
import moveit_msgs.msg
import geometry_msgs.msg
from std_srvs.srv import Empty

def close_grippers(arm):
    """Closes the grippers.
    Closes the grippers with an effort of 15 and then relaxes the effort to 0.
    :param arm: The side to be closed (moveit_utils LEFT or RIGHT)
    :type arm: int
    :returns: Nothing
    :rtype: None
    """
    yumi.gripper_effort(arm, 15.0)
    yumi.gripper_effort(arm, 0.0)

def open_grippers(arm):
    """Opens the grippers.
    Opens the grippers with an effort of -15 and then relaxes the effort to 0.
    :param arm: The side to be opened (moveit_utils LEFT or RIGHT)
    :type arm: int
    :returns: Nothing
    :rtype: None
    """
    yumi.gripper_effort(arm, -15.0)
    yumi.gripper_effort(arm, 0.0)

def move_and_grasp(arm, pose_ee, grip_effort):
    try:
        yumi.traverse_path([pose_ee], arm, 10)
    except Exception:
        if (arm == yumi.LEFT):
            yumi.plan_and_move(yumi.group_l, yumi.create_pose_euler(pose_ee[0], pose_ee[1], pose_ee[2], pose_ee[3], pose_ee[4], pose_ee[5]))
        elif (arm == yumi.RIGHT):
            yumi.plan_and_move(yumi.group_r, yumi.create_pose_euler(pose_ee[0], pose_ee[1], pose_ee[2], pose_ee[3], pose_ee[4], pose_ee[5]))

    if (grip_effort <= 20 and grip_effort >= -20):
        yumi.gripper_effort(arm, grip_effort)
    else:
        print("The gripper effort values should be in the range [-20, 20]")

def run():
    """Starts the node
    Runs to start the node and initialize everthing. Runs forever via Spin()
    :returns: Nothing
    :rtype: None
    """

    rospy.init_node('yumi_moveit_demo')

    #Start by connecting to ROS and MoveIt!
    yumi.init_Moveit()

    # Print current joint angles
    yumi.print_current_joint_states(yumi.RIGHT)
    yumi.print_current_joint_states(yumi.LEFT)

    # Reset YuMi joints to "home" position
    yumi.reset_pose()

    # Drive YuMi end effectors to a desired position (pose_ee), and perform a grasping task with a given effort (grip_effort)
    # Gripper effort: opening if negative, closing if positive, static if zero
    pose_ee = [0.3, 0.15, 0.2, 0.0, 3.14, 3.14]
    grip_effort = -10.0
    move_and_grasp(yumi.LEFT, pose_ee, grip_effort)

    pose_ee = [0.3, -0.15, 0.2, 0.0, 3.14, 3.14]
    grip_effort = -10.0
    move_and_grasp(yumi.RIGHT, pose_ee, grip_effort)

    rospy.spin()

if __name__ == '__main__':
    try:
        run()

        print "####################################     Program finished     ####################################"
    except rospy.ROSInterruptException:
        pass
</code>```

And I am getting coordinates from the darknet package in the following format:

```<code>header:
  stamp:
    sec: 1593723845
    nanosec: 430724839
  frame_id: camera_link
bounding_boxes:
- object_name: person
  probability: 0.7609682679176331
  xmin: 0.4506256580352783
  ymin: -0.3164764642715454
  xmax: 0.7936256527900696
  ymax: 0.11368180811405182
  zmin: -0.25958430767059326
  zmax: 0.10506562888622284
</code>```

答:
Subscribing to messages from a different package is no different than from the same package, just make sure to get the topic name right in case of namespaces.

The rospy Subscriber tutorial shows how to create a subscriber for a topic:

```<code>rospy.Subscriber(<topic_name>, <msg_type>, <callback_function>)
</code>```

A quick search shows the topic of interest for you might be /darknet_ros_3d/bounding_boxes? If that's so, import the corresponding message type from gb_visual_detection_3d_msgs:

```<code>from gb_visual_detection_3d_msgs.msg import BoundingBoxes3d
</code>```

Body:
Subscribing to messages from a different package is no different than from the same package, just make sure to get the topic name right in case of namespaces.

The rospy Subscriber tutorial shows how to create a subscriber for a topic:

rospy.Subscriber(<topic_name>, <msg_type>, <callback_function>)

A quick search shows the topic of interest for you might be /darknet_ros_3d/bounding_boxes? If that's so, import the corresponding message type from gb_visual_detection_3d_msgs:

from gb_visual_detection_3d_msgs.msg import BoundingBoxes3d


问:
How can I save messages publishing from a ROS package into a variable?
I am using darknet_ros_3d package and writing a subscriber. So far, I have followed the code given as under:

```<code>import rospy
from sensor_msgs.msg import Image
from darknet_ros_msgs.msg import BoundingBoxes
from std_msgs.msg import Header
from std_msgs.msg import String

def callback(data):
    for box in data.bounding_boxes:
        rospy.loginfo(
            "Xmin: {}, Xmax: {} Ymin: {}, Ymax: {}".format(
                box.xmin, box.xmax, box.ymin, box.ymax
            )
        )

def main():
    while not rospy.is_shutdown():
        rospy.init_node('listener', anonymous=True)
        rospy.Subscriber('/darknet_ros/bounding_boxes', BoundingBoxes , callback)
        rospy.spin()

if __name__ == '__main__':
    try :
        main()
    except rospy.ROSInterruptException:
        pass
</code>```

How can I save the values coming from Xmin: {}, Ymin: {}, etc. into the variables for the later usage?

答:
You will need to use classes and save the data into class variables. Try this:

```<code>import rospy
from sensor_msgs.msg import Image
from darknet_ros_msgs.msg import BoundingBoxes
from std_msgs.msg import Header
from std_msgs.msg import String

class darknet_ros_3d:

  def __init__(self):
    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber('/darknet_ros/bounding_boxes', BoundingBoxes , self.callback)

  def callback(self, data):
    for box in data.bounding_boxes:
      rospy.loginfo(
        "Xmin: {}, Xmax: {} Ymin: {}, Ymax: {}".format(
        box.xmin, box.xmax, box.ymin, box.ymax)
        )
    # save data into variables
    self.Xmin = box.xmin
    self.Xmax = box.xmax
    self.Ymin = box.ymin
    self.Ymax = box.ymax

if __name__ == '__main__':
  darknet_ros_3d()
  try:
    rospy.spin()
  except KeyboardInterrupt:
    print("Shutting down")

</code>```

You can now use these variables by calling self.(variable) in other parts of your code as long as it is referenced within the class

Body:
You will need to use classes and save the data into class variables. Try this:

import rospy
from sensor_msgs.msg import Image
from darknet_ros_msgs.msg import BoundingBoxes
from std_msgs.msg import Header
from std_msgs.msg import String

class darknet_ros_3d:

  def __init__(self):
    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber('/darknet_ros/bounding_boxes', BoundingBoxes , self.callback)

  def callback(self, data):
    for box in data.bounding_boxes:
      rospy.loginfo(
        "Xmin: {}, Xmax: {} Ymin: {}, Ymax: {}".format(
        box.xmin, box.xmax, box.ymin, box.ymax)
        )
    # save data into variables
    self.Xmin = box.xmin
    self.Xmax = box.xmax
    self.Ymin = box.ymin
    self.Ymax = box.ymax

if __name__ == '__main__':
  darknet_ros_3d()
  try:
    rospy.spin()
  except KeyboardInterrupt:
    print("Shutting down")

You can now use these variables by calling self.(variable) in other parts of your code as long as it is referenced within the class


问:
Starting out advice on making robots and tinkering with microcontrollers
I'd like to start making robots and tinkering with microcontrollers. Where do I start, and what do I need?

I'd like to make my own robots. I'm comfortable with programming (assembly and C) so I've got that part covered, but my electronics/circuits knowledge is a little weak. I have no idea what material to start with and which tools I need, nor how to put stuff together.

For the microcontroller, I'm thinking about going with the Pololu Orangutan LV-168 or the Arduino Duemilanove, although I'm leaning more towards the Orangutan because of the built-in LCD and pushbuttons (which I would expect to use, especially for debugging and user interaction). Am I on the right track? It seems to me like the number of I/O ports is small, but is that the case in practice?

答:
I'd recommend getting your hands on a 3pi and an Arduino. They both use the same chip, and are a great place to start.

Get yourself some tools.

A soldering iron with a sharp point.

A multimeter.

Some breadboards and some wire.

Actually, just look here:
Ladyada's Equipment List


问:
How to handle curved paths in maze
-I have an RPi on Ubuntu with ROS (Kinetic). The task is to solve a maze. I have implemented a left-hand algorithm to navigate through the maze.

-The robot is equipped with 3 ultrasonic HC-SR04 sensors.

How do I detect and navigate through a curved path using these sensors?

答: Use a distance threshold between the wall and robot and make the robot turn every time the output of sensor is less than the threshold. I guess you are using a differential drive robot. And if you are not mapping, there is no use of other 2 sensors. You just need to create a publisher for the sensor data and subscribe it to calculate the threshold and send the appropriate velocity for the bot.</p>

Title: How to handle curved paths in maze


问:
AttributeError: darknet_ros_3d instance has no attribute 'Xmin'
After publishing the messages from another package, I am using darknet_ros_3d package and writing a subscriber. For saving the messages into variables for the later use, I am following the answer mentioned in: https://robotics.stackexchange.com/a/21798/27972.

The code is given as follows:

```<code>import rospy
from sensor_msgs.msg import Image
from darknet_ros_msgs.msg import BoundingBoxes3d
from std_msgs.msg import Header
from std_msgs.msg import String

class darknet_ros_3d:

  def callback(self, msg):
    for box in msg.bounding_boxes:
      rospy.loginfo(
        "Xmin: {}, Xmax: {} Ymin: {}, Ymax: {}, Zmin: {}, Zmax: {}".format(
        box.xmin, box.xmax, box.ymin, box.ymax)
        )
    # save data into variables
    self.Xmin = box.xmin
    self.Xmax = box.xmax
    self.Ymin = box.ymin
    self.Ymax = box.ymax
    self.Zmin = box.zmin
    self.Zmax = box.zmax

  def __init__(self):
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber('/darknet_ros_3d/bounding_boxes', BoundingBoxes3d, self.callback)
    pose = [self.Xmin, self.Ymin, self.Zmin, self.Xmax, self.Ymax, self.Zmax]

if __name__ == '__main__':
  darknet_ros_3d()
  try:
    rospy.spin()
  except KeyboardInterrupt:
    print("Shutting down")
</code>```

I am getting the following error for the line

```<code>pose = [self.Xmin, self.Ymin, self.Zmin, self.Xmax, self.Ymax, self.Zmax]:
</code>```
```<code>AttributeError: darknet_ros_3d instance has no attribute 'Xmin'
</code>```

答:
You have added an extra line to the __init__ function given in the referenced answer, and that code tries to use values which haven't been set yet.

To fix the error just remove the pose = [self.Xmin, ... , self.Zmax] line.


问:
Standard equation for steering differential drive robot
I am writing a code in Arduino IDE for NodeMCU Board to control a differential drive 2 wheeled robot.

I am able to steer only one direction for some reason and the steering response time is a little awkward.

Is there perhaps a better strategy for the code that I am using?`

I am using an app called Blynk that has a virtual joystick that controls that feeds the data through Virtual Pins. V1 param 0 and 1 are x and y. x would be left to right on the joystick and y would be forward and back.

Information about the App is available here: http://www.blynk.cc/. I have it working for the most part, but there is some latency since it is through a cloud service.

The main problem I am stuck on is steering while driving forward and backward.

```<code>    //#define BLYNK_DEBUG
//#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

int motorA ;
int motorB ;
int X=0;
int Y=0;
int Steer=0;
int maximo=0;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "b41ff7f1659b4badb694be4c59601c2c";

void setup()
{
  // Set console baud rate
  Serial.begin(9600);

 Blynk.begin(auth,"100Grand","Mob4life");

 pinMode(motorA, OUTPUT);
 pinMode(motorB, OUTPUT);
 pinMode(0,OUTPUT);
 pinMode(2,OUTPUT);
 pinMode(4,OUTPUT);
 pinMode(5,OUTPUT);

}

 BLYNK_WRITE(V1)
{
  int X1 = param[0].asInt();
  X=X1;
  int Y1 = param[1].asInt();
 Y=Y1;

}

 BLYNK_WRITE(V0)//      slider  de 100 a 255!!!!
{
 int vel = param.asInt();
 maximo=vel;
}

void loop()
{

  if(X == 128  &&  Y == 128)  //  Stop
  {
   motorA = 0;
   motorB = 0;
   analogWrite(5, motorA);
   analogWrite(4, motorA);
   analogWrite(0, motorB);
   analogWrite(2, motorB);
   }

   if(Y > 130 && X > 127 && X < 129)   //Forward
  {
    motorA = Y;
    motorB = Y;

    motorA = map(motorA, 450,maximo,130, 255);
    analogWrite(5, motorA);
    digitalWrite(0,LOW);
    motorB = map(motorA, 450,maximo,130, 255);
    analogWrite(4, motorB);
    digitalWrite(2,HIGH);
  }

  else if(Y < 126 && X > 127 && X < 129)   //Reverse
  {
    motorA = Y;
    motorB = Y;

    motorA = map(motorA, 450,maximo,126, 0);
    analogWrite(5, motorA);
    digitalWrite(0,HIGH);
    motorB = map(motorA, 450,maximo,126, 0);//something is wrong with HIGH signal
    analogWrite(4, motorB);
    digitalWrite(2,LOW);
  }

   if(Y > 130 && X < 126)   //Steer Left
  {
    motorA = Y;
    motorB = Y;
    Steer = map(X, 450,maximo, 126,0);
     Steer = X / maximo;

    motorA = map(motorA, 450,maximo,130, 255);
    analogWrite(5, motorA * (1 + Steer));
    digitalWrite(0,LOW);
   motorB = map(motorA, 450,maximo,130, 255);
    analogWrite(4, motorB * (1 - Steer));
    digitalWrite(2,HIGH);
  }

   if(Y > 130 && X > 130)   //Steer Right
  {
    motorA = Y;
    motorB = Y;
    Steer = map(X, 450,maximo, 126,0);
    Steer = X / maximo;

    motorA = map(motorA, 450,maximo,130, 255);
    analogWrite(5, motorA * (1 - Steer));
    digitalWrite(0,LOW);
    motorB = map(motorA, 450,maximo,130, 255);
    analogWrite(4, motorB * (1 + Steer));
    digitalWrite(2,HIGH);
  }

  Blynk.run();
}
</code>```

Any help would be appreciated. Thanks!`

答:
I used ESP8266 with BL HC-10 and L293D motor controller to operate RC car with the differential steering. I used a factor, "f" to adjust (tune) the steering
The code is as follows</p>
```<code>#include <SoftwareSerial.h>
#include <ArduinoBlue.h>

int prevThrottle = 49;
int prevSteering = 49;
int throttle, steering;

SoftwareSerial bluetooth(13, 15);
ArduinoBlue phone(bluetooth);

void setup()
{
  pinMode(16, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(0, OUTPUT);

  Serial.begin(9600);

  bluetooth.begin(9600);

  delay(100);

  Serial.println("setup complete");

}
void loop()
{
  throttle = phone.getThrottle();
  steering = phone.getSteering();

  if (prevThrottle != throttle || prevSteering != steering) {
    Serial.print("Throttle: "); Serial.print(throttle); Serial.print("\tSteering: "); Serial.println(steering);
    prevThrottle = throttle;
    prevSteering = steering;
    int f = 25;     // factor for steering response

    if (throttle > 49 && steering > 49) {

      digitalWrite(16, HIGH);   // L side wheels
      digitalWrite(4, LOW);
      analogWrite(5, (throttle - 50) * 20);

      digitalWrite(14, HIGH);   // R side wheels
      digitalWrite(12, LOW);
      analogWrite(0, ((throttle - 50) * 20  - (steering - 50)*f));
    }

    if (throttle > 49 && steering < 50) {

      digitalWrite(16, HIGH);
      digitalWrite(4, LOW);
      analogWrite(5, (throttle - 50) * 20 - (49 - steering)* f) ;

      digitalWrite(14, HIGH);
      digitalWrite(12, LOW);
      analogWrite(0, ((throttle - 50) * 20));
    }

    if (throttle < 50 && steering > 49) {

      digitalWrite(16, LOW);
      digitalWrite(4, HIGH);
      analogWrite(5, ((49 - throttle) * 20));

      digitalWrite(14, LOW);
      digitalWrite(12, HIGH);
      analogWrite(0, (49 - throttle) * 20 - (steering - 50)* f);
    }

    if (throttle < 50 && steering < 50) {

      digitalWrite(16, LOW);
      digitalWrite(4, HIGH);
      analogWrite(5, (49 - throttle) * 20 - (49 - steering)* f);

      digitalWrite(14, LOW);
      digitalWrite(12, HIGH);
      analogWrite(0, (49 - throttle) * 20);
    }

  }

}
</code>```

Body:
I used ESP8266 with BL HC-10 and L293D motor controller to operate RC car with the differential steering. I used a factor, "f" to adjust (tune) the steering
The code is as follows

#include <SoftwareSerial.h>
#include <ArduinoBlue.h>

int prevThrottle = 49;
int prevSteering = 49;
int throttle, steering;

SoftwareSerial bluetooth(13, 15);
ArduinoBlue phone(bluetooth);

void setup()
{
  pinMode(16, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(0, OUTPUT);

  Serial.begin(9600);

  bluetooth.begin(9600);

  delay(100);

  Serial.println("setup complete");

}
void loop()
{
  throttle = phone.getThrottle();
  steering = phone.getSteering();

  if (prevThrottle != throttle || prevSteering != steering) {
    Serial.print("Throttle: "); Serial.print(throttle); Serial.print("\tSteering: "); Serial.println(steering);
    prevThrottle = throttle;
    prevSteering = steering;
    int f = 25;     // factor for steering response

    if (throttle > 49 && steering > 49) {

      digitalWrite(16, HIGH);   // L side wheels
      digitalWrite(4, LOW);
      analogWrite(5, (throttle - 50) * 20);

      digitalWrite(14, HIGH);   // R side wheels
      digitalWrite(12, LOW);
      analogWrite(0, ((throttle - 50) * 20  - (steering - 50)*f));
    }

    if (throttle > 49 && steering < 50) {

      digitalWrite(16, HIGH);
      digitalWrite(4, LOW);
      analogWrite(5, (throttle - 50) * 20 - (49 - steering)* f) ;

      digitalWrite(14, HIGH);
      digitalWrite(12, LOW);
      analogWrite(0, ((throttle - 50) * 20));
    }

    if (throttle < 50 && steering > 49) {

      digitalWrite(16, LOW);
      digitalWrite(4, HIGH);
      analogWrite(5, ((49 - throttle) * 20));

      digitalWrite(14, LOW);
      digitalWrite(12, HIGH);
      analogWrite(0, (49 - throttle) * 20 - (steering - 50)* f);
    }

    if (throttle < 50 && steering < 50) {

      digitalWrite(16, LOW);
      digitalWrite(4, HIGH);
      analogWrite(5, (49 - throttle) * 20 - (49 - steering)* f);

      digitalWrite(14, LOW);
      digitalWrite(12, HIGH);
      analogWrite(0, (49 - throttle) * 20);
    }

  }

}


问:
SEIF slam: Effect on information matrix when there is no landmarks
I studied about Sparse Extended Information Filter slam. I want to clarify some points regarding this topic. As per the sparse extended information(SEIIF) slam when the robot sees some landmarks it can update the information matrix according to it's position and landmarks number. Lets the robot at $x_t$ position and sees landmarks $m_1$ and $m_2$. So according to the algorithm it update rows and columns of $x_t$,$m_1$,$m_2$. Then it move and at $x_{t+1}$ position it sees landmark $m_3$ ,then it update rows and columns of $x_{t+1}$,$m_3$ and also there is a weak link between $m_1$ , $m_2$, $m_3$. At the $x_{t+1}$ position it discard previous position and the rows and columns corresponding to $x_t$.

Now my doubts is that what happened with the information matrix when the robot moving around to arena without observing any landmarks.Say, $x_1$ is the robot initial position then it go to the next position say, $x_2$ then as per the algorithm $x_1$ position will be discard. So if the robot only moving around without observing landmarks means only the 1st cell of information matrix say(0,0) is overwrite all the time. Then what is its effect on $\mu$?

The key formula on which the algorithm based is $\mu=\Omega^{-1}Xi$ where $\Omega$ represent information matrix and Xi represent information vector.

The algorithm taken from Probabilistic Robotics Chapter 12 page 315[pdf] and page 304[hard copy].

答: If I get this correctly, you should think that the filter is divided into prediction step "motion update" and correction step "measurement update". if the bot has not observed any landmark then there is no measurement to process in the measurement update. therefore, the robot is entirely relying on the dead reckoning algorithm for position and the SEIF is just updating pose. However, since the SEIF SLAM algorithm information matrix express the landmarks relation in links that are stronger if they are near, after many timestamps and long range movement the next landmark observed will present a weak link to the previous landmarks. hence, this link is subject to sparsification.


问:
DH Parameter for OpenManipulator X from Robotis
I try to solve forward kinematics problem for OpenManipulator X from Robotis by using standard DH convention. The figure and dimension of the robot like this pic

I try to find DH parameter and got result like this

To match frame assignment requirement, I move frame 2 to the left 0.024m. But when I verify the forward kinematics result, the position of end effector is wrong when I move joint 3. For example if I move joint 3 to 90 degree, the position of end effector should be X = 0.024m, Y = 0, and Z = 0.455M. But I got from the software X = 0, Y = 0, and Z = 0.455. It is because of I move the centre of frame 3 to the left. But if I dont move it, the DH frame assignment rule doesn't match.

How to figure out this problem?

Here is my code to find forward kinematics

def std_DH(theta, alpha, a, d):
    DH = np.array([[np.cos(theta),  -np.sin(theta)*np.cos(alpha),   np.sin(theta)*np.sin(alpha),    a*np.cos(theta)],
                   [np.sin(theta),  np.cos(theta)*np.cos(alpha),    -np.cos(theta)*np.sin(alpha),   a*np.sin(theta)],
                   [0,              np.sin(alpha),                  np.cos(alpha),                  d],
                   [0,              0,                              0,                              1]])
    return DH
```

<pre class="lang-py prettyprint-override"><code>def forward_kinematics(q1, q2, q3, q4):
    _0T1 = std_DH(q1, np.pi/2, 0, 0.077)
    _1T2 = std_DH(q2+np.pi/2, 0, 0.128, 0)
    _2T3 = std_DH(q3-np.pi/2, 0, 0.124, 0)
    _3T4 = std_DH(q4, 0, 0.126, 0)
    _0T4 = _0T1.dot(_1T2).dot(_2T3).dot(_3T4)
    return _0T4
</code>```

Is there any method to find forward kinematics without using DH convention?

答: Not sure if it still helps, but for both traditional and modified D-H convention, you need your Z-axis to be at the direction of the joint axis. Your frame 2 did not comply to this requirement. This probably explains the missing link parameter 0.024m.</p>


问:
Installing ROS in a conda environment
I'm planning to setup ROS and it's dependencies in a conda environment (similar to virtualenv). I've read a few posts where they state it's not going to be simple. Did any of you guys do it ? If you did, can you please share the steps ? Thanks in advance!</p>

答:
I found this answer from a Google search, just for your information in 2021 installing ROS in conda should be much straightforward, see the following links:

https://medium.com/robostack/cross-platform-conda-packages-for-ros-fa1974fd1de3

https://github.com/RoboStack/ros-noetic

Title: Installing ROS in a conda environment


问:
Inverse kinematics in KDL without rotation
I am trying to use KDL to do inverse kinematics. However I am not interested in the orientation of the end effector, but only in the location. Is there a way to specify this in KDL? The function CartToJnt only seems to accept a Frame with a rotation matrix. Is there maybe a different way to do this in KDL?

答: The KDL Ik solver KDL::ChainIkSolverPos_LMA can be construct with a weight matrix. You should be able to solve using only the end effector's target position by setting rotation components weights to 0.


问:
What is the easiest way to install ROS on OSX Mountain Lion?
The latest OSX documentation I found on the website is from 2011, and the latest build is from over a year ago. I'm a complete n00b to all things ROS and wanted to start playing with it. What is the easiest way?

Edit: this version of the installation instructions is more recent (April 2013), but it says that

OSX is not officially supported by ROS and the installation might fail for several reasons. This page does not (yet) contain instructions for most higher level ROS packages, only for the base system. This includes the middleware and command line tools but not much more.

"Does not contain instructions" also means it doesn't work? What do OSX users who work on ROS usually do? Run it on an Ubuntu VM? Install it just fine on their own on OSX, even though there aren't detailed instructions on the website?

答: There is now an easy way of installing ROS on OSX using conda: conda install ros-noetic-desktop -c robostack. More info on https://medium.com/robostack/cross-platform-conda-packages-for-ros-fa1974fd1de3 and https://github.com/RoboStack/ros-noetic


问:
Lawn mower robot (type of cutter)
If not all, but major types of lawn mower robots are rotary mowers.
I presume1 that reel mower is more efficient, and is said to leave a better lawn health and cut. So, why industry go to the other option?

1 - I'm assuming the efficiency, as electrical rotary mowers have at least 900W universal-motors or induction motors, and a manual reel mower is capable nearly the same cutting speed.

答:
Rotary mowers are mechanically simpler, so cheaper to make. The rotary mower is more tolerant of getting dull, and if you run over something like small trees or rocks, the blades take less damage, and the motor is harder to jam and stall.
The blades are also easier to sharpen.
For this simplicity, you get a poorer cut, and more grass damage.
I do agree, though, that the reel mower would be more efficient. You'd probably need more sensors though, to watch for jamming.</p>

Title: Lawn mower robot (type of cutter)


问:
Impedance Control vs Position Control
I have been reading up on impedance control, and several sources have stated that it is much safer than position control. However, frustratingly, none of these sources have explained why this is. So... why is impedance control safer than position control?

I have tried to think about this myself, based on my understanding of the difference in the control loop of the two methods. I know that impedance control models the system as a mass-spring-damper. So here, the larger the position error, the larger the force, due to the spring. However, I also know that in regular position control, the larger the position error, the larger the force (proportional control). So I don't really see what the main difference is, and why impedance control would be any safer.

For example, in this video describing impedance control, there is the following quote (at 00:52):
"While the end-effector follows the reference position, a person can still deflect it away. An ordinary position-controlled system would not allow for such smooth deflection". But in both methods, the force would increase linearly as the person deflects the end-effector away, so I don't understand why the behaviour would be "smoother" in impedance control.

答:
You can view impedance control as having more control over the force resulting at the end effector, than in position control. In position control, the goal is to get to the reference position no matter what, even if it needs the maximum force of the motor.

In impedance control, you control the ratio between force and velocity. Even if the robot deviates from its target position, the controller will not engage the full motor force to get back on track.

Title: Impedance Control vs Position Control


答:
In classical position control, the feedback controller only cares about the position error and is tuned to minimize it. This is done by using very high gains, i.e. if there is even a small position error, the controller counteracts by applying very high torques to the joints. It does not matter if there is a person or a concrete wall in its path; just minimize the error with whatever force is necessary.

Impedance control is designed to adapt to the characteristics of the environment and thus limit contact forces. This achieved through (virtual) mass, damping and stiffness matrices that are not isotropic, i.e. different directions see different reaction forces. If you expect a stiff environment in one direction, you command the robot to react softly / compliantly in that direction. In directions you expect to move freely along, you command the robot to be stiff in order to achieve low position error.
To go with the example from the lecture slides:
Imagine standing in front of a wall blindfolded (slide 10 in reference [1]). You know that a flat wall is in front of you, but not where exactly. So in order to get into contact, you cautiously / softly move your arm forwards until you make contact.
Perpendicular to the wall you can move rigidly without excessive force (neglecting friction).

This system can be extended by using various state-dependent matrices depending on where in your task space you are and how certain you are that there might be contacts.

Also, to quote the main points from the introduction of [1]:

Impedance Control

imposes a desired dynamic behavior to the interaction between robot end-effector and environment

the desired performance is specified through a generalized dynamic impedance, namely a complete set of mass-spring-damper equations (typically chosen as linear and decoupled, but also nonlinear)

a model describing how reaction forces are generated in association with environment deformation is not explicitly required

suited for tasks in which contact forces should be “kept small”, while their accurate regulation is not mandatory

since a control loop based on force error is missing, contact forces are only indirectly assigned by controlling position

the choice of a specific stiffness in the impedance model along a Cartesian direction results in a trade-off between contact forces and position accuracy in that direction

Reference:

[1] De Luca, Robotics 2, Lecture 15: Impedance Control Slides Mirror

Title: Impedance Control vs Position Control

Body:
I have been reading up on impedance control, and several sources have stated that it is much safer than position control. However, frustratingly, none of these sources have explained why this is. So... why is impedance control safer than position control?

I have tried to think about this myself, based on my understanding of the difference in the control loop of the two methods. I know that impedance control models the system as a mass-spring-damper. So here, the larger the position error, the larger the force, due to the spring. However, I also know that in regular position control, the larger the position error, the larger the force (proportional control). So I don't really see what the main difference is, and why impedance control would be any safer.

For example, in this video describing impedance control, there is the following quote (at 00:52):
"While the end-effector follows the reference position, a person can still deflect it away. An ordinary position-controlled system would not allow for such smooth deflection". But in both methods, the force would increase linearly as the person deflects the end-effector away, so I don't understand why the behaviour would be "smoother" in impedance control.


问:
Define end-effector quaternion orientation from unit vector
I want to define ee-poses from a point cloud in a way that the pose for each point is pointed to by a unit vector from origin. Rotation about the vector pointing towards the point can be whatever as the tool is round.

I guess this would be mathematically equal to using the normal of a surface and not care about rotation about the normal?

E.g.

$p(x, y, z) => q(w,x, y, z)$

$p(1, 0, 0) => q(1, 0, 0, 0) => \text{No rotation}$

$p(0, 1,0) => q(\frac{1}{\sqrt{2}}, 0, 0, \frac{1}{\sqrt{2}})  => \text{equal to 90deg rotation about Z}$

$p(0, 0, 1) => q(\frac{1}{\sqrt{2}}, 0, -\frac{1}{\sqrt{2}}, 0)  => \text{equal to -90deg rotation about Y}$

How can i solve this?

答:
From your examples it seems that you are looking for a rotation that rotates the vector $(1,0,0)$ to some given unit vector $(x,y,z)$. This indeed doesn't define a unique rotation. However, the rotation with the smallest angle of rotation can in most cases be defined uniquely. If desired one could always apply an additional rotation with as rotation axis the $(x,y,z)$ vector. This shortest rotation can be found using the dot and cross products, which gives

\begin{align}
\cos \theta =& (1,0,0) \cdot (x,y,z) = x, \\
n \sin\theta =& (1,0,0) \times (x,y,z) = (0,-z,y),
\end{align}

with $\theta$ the (smallest) angle of rotation and the $n$ the unit axis of rotation.

A unit quaternion, used to describe such rotation can be defined with $\theta$ and $n$ using

$$
q = \left(\cos\theta/2,n\sin\theta/2\right).
$$

In order to evaluate the sine and cosine of half the angle one could first calculate $\theta$ for example using the atan2 function. However, one could also use the following mathematical identities

\begin{align}
\cos \theta/2 =& \sqrt{(1+\cos\theta)/2}, \\
\sin\theta/2 =& \frac{\sin\theta}{\sqrt{2\,(1+\cos\theta)}}.
\end{align}

Substituting this together with the dot and cross products in the unit quaternion expression yields

$$
q = \left(\sqrt{\frac{1+x}2},0,\frac{-z}{\sqrt{2\,(1+x)}},\frac{y}{\sqrt{2\,(1+x)}}\right).
$$

The identities used do have some sign discrepancies, but when multiplying a unit quaternion by minus one yields another unit quaternion which represents the same rotation. The only thing you need to watch out for is when $x$ is equal (or sufficiently close) to minus one. In that case you could pick any axis perpendicular to the x-axis and rotate around that with 180°.


问:
Automated Manual Testing / Robot-computer interaction
What is the technical term for a computer mechanically interfaces another computer? For example a robot mechanically interacting (vs API) with a PC or smartphone as a human would to automatically gather data and making input decisions based on feedback from the device

At a software level, it can be like Selenium Webdriver simulating clicks on a web page.

Possible use cases are

Quick and dirty way to interface with a proprietary mobile app system to achieve automation interoperability without reverse engineering APIs

Software Testing Cases

I wish to do more research into this. Is there an off the shelf prototype that is available for purchase? Or some schematic that would allow you to device your own, complete with open source APIs? One that fits many device types and brands?

答:
Is there an off the shelf prototype that is available for purchase?

Generally, of the shelf robots, there are plenty, specifically for UI testing there are none

Or some schematic that would allow you to device your own, complete with open source APIs?

Generally schematics/APIs for robots, there are plenty. Specifically for UI testing there are none


问:
What RF transceivers modules are used on AUVs for communication with ground station?
I am working on a project where we want a RF transceiver on the AUV for communicating with the ground station when its on the water surface.

I am looking for RF modules that can work in proximity to water body and can provide transmission range of 5 km with throughput of 10 Mbps.

Can you please suggest me some OEMs that make long range RF transceivers. Also, how do other AUVs use RF with antenna being just some centimetres above from water surface?

I talked with one RF OEM, he mentioned that due to fresnel zone clearance issue we cannot have RF communication for than 200 m for antenna being 25 cm above water. He said that for 5 km range the the fresnel zone radius is 10 m so antenna on AUV should be 10 m above water surface which is not feasible in our application.

So how do other AUVs have RF communication for long range?

答:
I will mention that fresnel zone issues are no joke.  When the zone is violated either by the ground plane, or other objects, the transmission will be severely attenuated.

Note however that the shape of the fresnel zone depends on:

the frequency used, (higher frequency is a smaller zone)

the locations of the antennas, (higher antennas move the zone away from the ground and other objects).

So using low-frequency transmissions to a low base-station antenna may not work, but high-frequency transmissions to a very high base-station antenna might be ok.

Existence proof: the Seaglider AUV.  This underwater glider had an antenna that was over a meter long.  The antenna communicated via satellite link.  (i.e. nearly straight up).


问:
Determining (Heading) Yaw to rotate the Turtle Robot to desired point (X,Y) so it moves towards it
I have a turtle bot and I want to modify its heading so it moves to certain point (x,y) in the world.

Now I reckon that yaw is angle from robots reference, how do I determine the yaw as the point (x,y) is from global (world's reference)?

答:
This is basic geometry/trigonometry. Here is an image of your situation (the plane being your turtle bot, and the red circle being your target ($x$,$y$).

You want your turtle bot to first turn to face the target and then head towards it. So first you need to compute your desired heading ($\theta_t$)

This is basic trigonometry:
$$ tan(\theta_t) = \frac{y_t-y}{x_t - x} \Rightarrow \theta_t = atan(\frac{y_t-y}{x_t - x})$$

So you need to turn your robot of $\theta - \theta_t$ to face your target first.


问:
Inertial frame VS Body-fixed frame momentum correction factor
I've recently enrolled in a Coursera aerial robotics course and i'm trying to understand how the rate of change of the angular momentum is computed from the inertia frame to the body-fixed frame.

According to the course:

From this picture, we can see that the rate of change of the angular momentum in the inertial frame (denoted with the super-script A) of the center of mass (denoted with the sub-script C) is equal to the net moment generated by a quad-rotor.

By computing this quantity in the body-fixed frame, this is translated to the rate of change of the angular momentum in the body-fixed frame (denoted with super-script B) plus a correction factor.

This correction factor is equal to the cross product of the angular velocity of the body B (denoted with the super-script B) in the inertial frame (denoted with the super-script A) with the angular momentum itself.

The professor talks about this correction factor as a well-known correction factor used in mechanics / kinematics and this i can't find anywhere in the net and doesn't seem to be very obvious to me.

Can you explain me the origin of that correction factor or maybe give me a resource i can document myself on ?

Thanks in advance.

答:
The cross-product correction factor shows up any time we take the time derivative of a vector described in a moving frame.

When I teach this topic in my classes, I generally introduce it when talking about taking time derivatives of position vectors, because it's easier to visualize in that situation:

Start by considering the positions of two points $A$ and $B$, denoted by vectors $\vec{r}_{A}$ and $\vec{r}_{B}$. We can then take the relative position of $B$ with respect to $A$ as a vector $\vec{r}_{B/A} = \vec{r}_{B}-\vec{r}_{A}$ such that $\vec{r}_{B} = \vec{r}_{A} + \vec{r}_{B/A}$.

Now let's say that the vector $\vec{r}_{B/A}$ is fundamentally defined in a frame whose orientation is encoded by a rotation matrix $R_{AB}$, such that $\vec{r}_{B/A}=R_{AB}\ \vec{r}_{B/A}'$ (where $'$ indicates a vector defined in the rotated frame).

If we take the time derivative of the position of $B$, we then get
\begin{equation}
\frac{d}{dt} \vec{r}_{B} = \frac{d}{dt} \vec{r}_{A} + \left(\frac{d}{dt} R_{AB}\right)\ \vec{r}_{B/A}' + R_{AB} \left(\frac{d}{dt} \vec{r}_{B/A}'\right).
\end{equation}

The time derivative of a rotation matrix is the product of its rotational velocity with itself, $\frac{d}{dt} R_{AB} = \vec{\Omega}_{AB} \times R_{AB}$, such that the total time derivative can be regrouped as
$$
\frac{d}{dt} \vec{r}_{B} = \frac{d}{dt} \vec{r}_{A} + \vec{\Omega}_{AB} \times \left(\vphantom{\frac{d}{dt}}R_{AB}\ \vec{r}_{B/A}'\right) + R_{AB} \left(\frac{d}{dt} \vec{r}_{B/A}'\right).
$$
If you think of $A$ and $B$ as being points on a piece of paper, the first term in the expansion says how the paper is moving at point $A$, which transfers to how it is moving at point $B$. The second term describes how rotation of the paper makes point $B$ orbit around $A$, and the third term describes how point $B$ moves on the paper relative to point $A$.

For your angular momentum problem, you can think of the angular momentum as a "free vector", i.e., saying that we only want the $\vec{r}_{B/A}$ component and not the $\vec{r}_{A}$ component. When we take the time derivative, we then get the latter two terms from the full equation, and thus the "time derivative as seen in the frame" plus the "frame-rotation cross product" terms.

In the standard expression from within the body frame, we then multiply all the terms by ${R}^{-1}_{AB}$. By a bit of algebra that I won't go into right now, it works out that
$$
{R}^{-1}_{AB}\left[\vec{\Omega}_{AB} \times \left(\vphantom{\frac{d}{dt}}R_{AB}\ \vec{r}_{B/A}'\right)\right] = \vec{\Omega}_{AB}' \times  \vec{r}_{B/A}'
$$
so that
$$
{R}^{-1}_{AB} \left(\frac{d}{dt} \vec{r}_{B}\right) = {R}^{-1}_{AB}\left(\frac{d}{dt} \vec{r}_{A}\right) + \vec{\Omega}_{AB}' \times  \vec{r}_{B/A}' +\frac{d}{dt} \vec{r}_{B/A}',
$$
in which the last two terms are the standard expression for the derivative of a free vector expressed in a rotating set of coordinates.


问:
HC-SR04 sensor - beginners gpiozero coding problems
New here and to robotics and have encountered my first 2 problems. Following instructions in a book, I have fitted 1 HR-SR04 ultra sound detector but could not get the code given to work, seems to get stuck in the first while loop, so never getting a return time :

```<code>import gpiozero
import time

TRIG = 23
ECHO = 24

trigger = gpiozero.OutputDevice(TRIG)
echo = gpiozero.DigitalInputDevice(ECHO)

robot = gpiozero.Robot(left=(17,18), right=(27,22))

def get_distance(trigger, echo):
    trigger.on()
    time.sleep(0.00001)
    trigger.off()

    while echo.is_active == False:
        pulse_start = time.time()

    while echo.is_active == True:
        pulse_end = time.time()

    pulse_duration = pulse_end - pulse_start

    distance = 34300 * (pulse_duration/2)

    round_distance = round(distance,1)

    return(round_distance)

while True:
    dist = get_distance(trigger,echo)
    if dist <= 15:
        robot.right(0.3)
        time.sleep(0.25)
    else:
        robot.forward(0.3)
        time.sleep(0.1)
</code>```

I then found some sample code using RPi.GPIO - which worked,returning values down to 3-4cm, so I know the sensor is ok.
I also found the GPIOzero docs and tried the following code:

```<code>from gpiozero import DistanceSensor
from time import sleep

sensor = DistanceSensor(echo=18, trigger=17)
while True:
    print('Distance: ', sensor.distance * 100)
    sleep(1)
</code>```

This code worked in that it would detect an obstacle, but wouldn't return a value less than 10cm.

So my 2 questions (after 2 days of trying to figure this out myself!):

Why does the first code not work? I have seen almost exactly the same code repeated elsewhere as how to use the sensor but I just cannot get it to work for me.

Why does the second code, using gpiozero not return a value less than 10cm?

I know this is probably very basic stuff, but would greatly appreciate some advice/explanations/pointers.

答: Your code looks fine but maybe the problem is about your circuit. I dont know if you did but you should connect a voltage divider to HC SR04's Echo pin. The reason for this is that the sensor works at 5V but your Raspberry is working at 3.3V. You can use 2K and 1K resistor with 2K is the one connected to GND.


问:
What should I use for speech recognition?
I was wondering, my team and me are working on a robot communication-oriented and we wanted to add speech recognition on it.

What technology should I use ?

答:
You must go through softwares like matlab(licensed). Open source versions are also available like QtOctave and FreeMat.

You must have a sound knowledge about Digital Signal Procesing , different type of Filters etc..


问:
Is this encoder error expected?
I'm working with the iRobot Create 2. When I read the encoder count and sum it for total, I'm able to do so without apparent error. I've used this to 'successfully' estimate position combining with heading from a gyro. However, when I try to estimate velocity from the encoder count, the signal seems pretty noisy.

I'll get maybe 10-15 values that are expected, and then a random outlier or two. For example: If I set the wheels to 100 mm/s and calculate the change of time between cycles (which also appears to agree with the sample time i've set of 0.017s), maybe 10-14 values will be within +-10 of 100mm/s, but then I'll get a one or two values that differ by +-50-100 mm/s.

Is this normal and I'll need to filter for a better estimation, or could there be a possible timing issue? The only thing that really impacts the program speed is the checksum used to initially discard corrupted packets.

答:
This might be "normal", depending on how the signal is acquired. Whenever a signal is derived, timing of the signal acquisition is crucial.

Counting ticks is not time sensitive, as it does not matter if one tick is acquires a few microseconds later or earlier, what matter is, that it is acquired.

For deriving a velocity from the ticks of an encoder, we need to know exactly when the tick happened. Given a constant velocity of 100 mm/s, we can assume a wheel circumference of 100mm, meaning 1 rotation per second. If an encoder has 1024 ticks per rotation, translates to approximately 1 tick every millisecond.

So if we do the calculation backwards, 1024 translates to 100mm/s, to make the calculations easier let us assume 1 tick translates to 0.1mm movement.

1 tick every 1 millisecond translating to 0.1 mm movement every millisecond.

In order to calculate the velocity for every tick, means that we need to measure the time between ticks, which translates to registering the exact time of the tick event or stating a timer and stopping a timer at tick events. The precision of the time measurement can be influenced by:

The timer precision. If the timer has a millisecond precision, that, in an extreme worst case could mean that we have 0 registered milliseconds between two ticks resulting in an unfeasible velocity. A 0.1 millisecond precision of the timer would mean a 10% precision of the velocity for the example above

The event detection. Before we get to start top timers or register time, we need to actually detect the event. If the encoder can trigger hardware interrupts, that translates to starting the interrupt routine at clock frequency (e.g. 8Mhz for a microcontroller). If we are regularly polling the state of the encoder, the polling rate has a major influence on the precision. If we are polling with 0.1 milliseconds the extreme worst case is that we register the tick event 0.1 ms late, but we register the next tick exactly at the right moment. So 0.1 ms polling would lead to a 10% precision on the velocity for the example above.

Title: Is this encoder error expected?


问:
Looking for a wheel
If this is not the right community please point me in the right direction.

I am looking for a speed measuring wheel similar to the one in the picture..

What is it called?

I have googled for a description and used an image search for google but can't find a wheel that's the same.

It is for a Square Meter measuring table in our factory. Everywhere we ask they want to supply us with an encoder that is directly connected to the wheel. This means the encoder is spinning the whole time. We don't want this setup.
What were looking for is a wheel that can be used by the pickup sensor that is connected to the bracket, and the wheel must have its own bearing.
I have added descriptions on the image.

答:
The device you're looking for is called a Hall-effect sensor. There's a decent video on how they work here, and they're commonly used as crankshaft and camshaft position sensors in vehicles.

A typical Hall-effect sensor will only send a pulse when the magnetic/ferrous object passes by the sensor, so you've got no way to determine direction. If you want to determine direction, too, then you should look for a Hall-effect quadrature encoder.

Title: Looking for a wheel


问:
Doubt regarding a slam parameter in research paper
I was reading about the SLAM problem in a research paper, Multi-robot Simultaneous Localization and Mapping using Particle Filters by Andrew Howard.

What does '$m$' mean here?

The SLAM problem for a single robot is treated as follows.

Let $x_{1:t}$ denote a sequence of robot poses at times 1, 2, ...t,
let $z_{1:t}$ denote a corresponding sequence of observations, and let
$u_{0:t−1}$ denote the sequence of actions executed by the robot.

Our (intermediate) aim is to compute the posterior probability
$p(x_{1:t}, m | z_{1:t}, u_{0:t−1}, x_0)$ over the robot trajectory
$x_{1:t}$ and map $m$, given some initial pose $x_0$. We write this as
the product of two factors:

$p(x_{1:t}, m | z_{1:t}, u_{0:t−1}, x_0) = p(m | x_{1:t}, z_{1:t},
> u_{0:t−1}, x_0)p(x_{1:t} | z_{1:t}, u_{0:t−1}, x_0)$.

答: It represents the map. It is mentioned above the product.</p>


问:
Make servo's shaft longer
I’ve got a few servo motors MG995, MG996R, etc.

For my make I need a servo to have a longer shaft – 6cm or so.

I cannot find a way to achieve it.
There is lots of Shaft Coupler for steppers and DC motors in the shop. But they don’t suite a servo motor shaft which is short.

Does anybody know how to solve this problem?

答:
This is something I used in a Lego assembly some time back. It's using an FS90 servo which is considerably smaller than the one you list, but You can get the picture. This version of gluing things on, allows some amount of disassembly and reuse. Other glue jobs are not equally as graceful.

To get the servo horn screw in, I had to knock off the corners of the shaft hole in the Lego piece that is glued to the horn. Then the next piece gives good engagement to the shaft.

Title: Make servo's shaft longer


答:
I don't think there is any "must" for you task. In turn, it depends on what your robot platform is. In the context of embedded systems, MATLAB could be cumbersome.

I don't know what your robot system is like, but maybe this article based on ROS and Sphinx is a good starting point?

Also, for the purpose of understanding speech recognition technologies, the HTK toolkit and the HTK book are a good reference.

For a general idea of the state-of-art research on speech recognition, you can also visit http://www-i6.informatik.rwth-aachen.de/rwth-asr/

Title: What should I use for speech recognition?

Body:
I was wondering, my team and me are working on a robot communication-oriented and we wanted to add speech recognition on it.

What technology should I use ?


问:
Learning ROS for Absolute Beginners in Robotics
I am a student studying in 11th grade.

I have some knowledge about python (more than what an ordinary student in 12th grade will have). I also have some knowledge of C# as I have been creating games with unity using C#.

But, I have no knowledge of C++ and I am planning to start learning ROS. I do not have any knowledge about where to start. Just have read a bunch of articles online which made me very confused for where to begin.

Should I start learning ROS with python only or should I first learn C++ as it is more efficient? As a school student, I literally have no money so I cannot buy paid content. It will be very grateful if you will suggest me some free content online to begin my Journey with ROS. Is there any good book that I can start reading? ...

答:
Welcome to the ROS world :).
Definitely, stick with python in learning ROS. You'll learn C++ with time and adapt your ROS knowledge to it.

You'll find a lot of very good tutorials online, starting with the ROS ownd tutorials.

You should learn the basics: topics, services, actions.

As I often like to teach it, ROS is 3 things:

a middleware that allows multiple process to communicate together via topics, services, actions

a set of visual tools for debugging (RViz, RQT ...)

a community of developers that propose a thousands of open source packages that already implement a lot of robot functions.

For references, you'll find many free books online. A quick google search gaves me the following results:

https://vladestivill-castro.net/teaching/robotics.d/READINGS/Learning%20ROS%20for%20Robotics%20Programming%20%5beBook%5d.pdf

https://www.cse.sc.edu/~jokane/agitr/agitr-letter.pdf

But my all time favorite is the Programming Robotics with ROS by Morgan Quigley.. If you had to read one book, that would be my go to book.


答: I'd use a bolt or something. I had this issue with the MG995. A 3mm bolt will fit snug into the hole, maybe use some nuts to add spacing?

Title: Make servo's shaft longer

Body:
I’ve got a few servo motors MG995, MG996R, etc.

For my make I need a servo to have a longer shaft – 6cm or so.

I cannot find a way to achieve it.
There is lots of Shaft Coupler for steppers and DC motors in the shop. But they don’t suite a servo motor shaft which is short.

Does anybody know how to solve this problem?


答: In addition to what Yahya said, An arduino does a way better job of controlling sensors than an RPi does. I would personally use an arduino to get the sensor values and send that to the RPi for processing.</p>

Title: HC-SR04 sensor - beginners gpiozero coding problems

Body:
New here and to robotics and have encountered my first 2 problems. Following instructions in a book, I have fitted 1 HR-SR04 ultra sound detector but could not get the code given to work, seems to get stuck in the first while loop, so never getting a return time :

```<code>import gpiozero
import time

TRIG = 23
ECHO = 24

trigger = gpiozero.OutputDevice(TRIG)
echo = gpiozero.DigitalInputDevice(ECHO)

robot = gpiozero.Robot(left=(17,18), right=(27,22))

def get_distance(trigger, echo):
    trigger.on()
    time.sleep(0.00001)
    trigger.off()

    while echo.is_active == False:
        pulse_start = time.time()

    while echo.is_active == True:
        pulse_end = time.time()

    pulse_duration = pulse_end - pulse_start

    distance = 34300 * (pulse_duration/2)

    round_distance = round(distance,1)

    return(round_distance)

while True:
    dist = get_distance(trigger,echo)
    if dist <= 15:
        robot.right(0.3)
        time.sleep(0.25)
    else:
        robot.forward(0.3)
        time.sleep(0.1)
</code>```

I then found some sample code using RPi.GPIO - which worked,returning values down to 3-4cm, so I know the sensor is ok.
I also found the GPIOzero docs and tried the following code:

```<code>from gpiozero import DistanceSensor
from time import sleep

sensor = DistanceSensor(echo=18, trigger=17)
while True:
    print('Distance: ', sensor.distance * 100)
    sleep(1)
</code>```

This code worked in that it would detect an obstacle, but wouldn't return a value less than 10cm.

So my 2 questions (after 2 days of trying to figure this out myself!):

Why does the first code not work? I have seen almost exactly the same code repeated elsewhere as how to use the sensor but I just cannot get it to work for me.

Why does the second code, using gpiozero not return a value less than 10cm?

I know this is probably very basic stuff, but would greatly appreciate some advice/explanations/pointers.


问:
PID controller for motor speed control and distance control
I am building a robot rover comprised of dual DC motors each with hall sensors to obtain rotaional speed. I currently have a PID controller for each DC motor that is able to control the speed of the rover.. ie. I can provide a setpoint and the rover will move forward at a steady speed.

The next step is that I want to tel the Robot to move forward a certain distance. I'm thinking the approach here is to use a outer PID loop running at a much lower rate, taking a cumulative measuerment from the hall sensor to determin the distance traveled from the start point. The output would feed the inner PID loop for the motors.

Is this the right approach ?

My concern is that i've used the input from the hall sensors in two place, is one of these redundant for example ?

答:
The approach is the right beginning. The term for it is dead reckoning. It has some problems regarding its precision. Next steps in increasing precision would be sensor adding optical flow or other sources for distance travelled some using sensor fusion technique.

You do not have a redundancy problem. If you use the same sensor signal and transform it into something else it will not be redundant. You would need to have redundancy later, to increase precision. E.g. you get another signal measuring position, now you have redundancy, and it is good to have redundancy in this case, because you can (probably) increase precision.


问:
How to calibrate an industrial Robot?
I am testing an industrial robot (ABB IRB 1410) using three simple Micron Dial gauges to get x,y,z values at particular point by varying Speed, Load and distance from home position.
My questions are,
Whether these three parameters influencing the repeatability or only the accuracy?
Using dial gauges, without any relation to the Base frame, is it possible to measure accuracy?
Is any other cost effective method to measure the repeatability and accuracy like above method?</p>

答:
Without relation to the base frame, or to some physical point, absolute accuracy cannot be measured.
You can measure repeatability via a dial gauge and any fixed point, but absolute accuracy will require careful measurements from wherever on the robot that 0,0,0 is referenced from.
Repeatability requires only one point of reference, although you will get a better idea of over all performance if you use several points. But accuracy has to be a measurement between TWO points.
One being a reference point - such as the base frame, and the other can be arbitrary.
If you have a long accurate ruler,or rod of known length, this could be clamped into any arbitrary position, and the arm  made to run from one end to the other, and then measure the offset from that. That would give you some idea of how accurate it is across the section of its reach, which would be probably pretty close to its absolute accuracy.
Errors would be introduced by the rulers inaccuracys in length, and bend.</p>

Title: How to calibrate an industrial Robot?


问:
Force-torque sensor reading when a robot is stationary
Let's say I have a robot arm with a force-torque sensor on the wrist, between the final motor and the gripper. If the arm and wrist are stationary, then what would the reading on the sensor be?

I know this might sound like a silly question, but I don't understand which of the following would be true:

The reading would be g (gravity), since the only force acting on the sensor is gravity.

The reading would be g + w, where w is the weight of the gripper, because both gravity and the gripper's weight are acting on the sensor.

The reading would be 0, because whilst g + w are acting down on the sensor, since the arm is stationary, there must be an equal an opposite upward force applied by the robot, which exactly cancels out the downwards force.

Which of these is correct? And consequently, why are the other two not correct?

Thanks!

答:
The answer is $\vec{G}$! and also any $\vec{\tau}$ torque caused by it, if the axis connecting the geometrical center of the sensor (assuming it measures torques relative to its geometrical center) to the centre of gravity of the gripper.

$\vec{G} = m * \vec{g}$

where $m$ is the mass of the gripper, $g$ is the gravitational ACCELERATION, not force and G is the gravitational pull (force) on the gripper.


问:
Is it possible to setup a wireless network without internet for the robot and PC?
The system includes three devices: PC, robot's computer, and wireless device.

In order to improve the signal quality of the wireless in the whole robot's environment. I'd like to put a big wireless device in the middle corridor where it is not Ethernet (no internet) and only feed by power, then use its signal to connects it with the robot's computer. The robot's computer has a small wireless device that will connect with a big wireless device. Both wireless devices have no internet, only electric power, and signal.

Can I transmit data from the robot to my PC and vice versa over Wi-Fi's signal ?

Can I access the robot's computer using Wi-Fi's signal to launch the robot ?

If yes, please your suggestions, and what are its disadvantages?

Any suggestions would be greatly appreciated.

Note: the system is working fine now using the internet in the big wireless device and connect it with the robot's computer and PC, only some problem when the robot is very far from a big wireless device because of dropping the signal quality to 5% here

答:
The easiest way is to set up a new router that is not connected to the internet. This gives you an isolated network that only local devices can see and connect with. You can even hide the SSID so it can be even more private. This requires the expense of purchasing a new router but has the advantage that you can use a router with multiple high gain antennas and your range for the robot is limited by the range to the fixed router, not to the computer which may be on the other end of the routers range. This effectively gives you twice the range to the computer from the robot with the right setup. If the robot always operates in the same area, this is most ideal.

Another option is to use the WIFI controller on the robot as an access point (most WIFI controllers can do this) and connect your computer to that SSID each time you want to communicate with the robot. This SSID may also be hidden if you like that option. The down side of this is that you'll have to use a high gain antenna (not likely supplied) on the robot in order to get a decent range to the computer. This will not have the same range as with the router, even using high gain antennas. The plus side is that you can follow the robot with the computer and you essentially have an unlimited area of operation as long as you can be close to the robot.


问:
Do hobby servos respond to step inputs with a step in torque?
I'm designing a piston that I need to expand a few cm in <100ms to load energy into a spring-mass system with around a pound of force (as shown below). Based on power specs alone, high-end hobby servos are light, strong and cheap enough for my needs: they simulate well when I'm able to push max voltage into them right away (i.e. operating them on the max torque-speed curve).

What I'm concerned about is the torque behavior in real-world servos. I'm interested in digital high-torque, high-frequency servos, typically used for steering in RC vehicles, that are either coreless or brushless. As a representative example, consider something like the Savox SV1272 or SB2274 (resp.), with refresh rates of 333Hz.

Is anyone aware if servos like this hold back on their power output with some kind of integrating control/loop delay in response to a step function? The tight timing of the stroke is what really concerns me: even if they wait for ~50ms I could lose most of the energy.

Looking around for clues, I've seen this comment here that links to this linearized position model of a Futaba servo as an example. This model is a PID controller in position rather than torque, so I imagine this is the response you get from operating below the torque-speed ceiling, while I really want to know the delta → torque behavior along that ceiling.

答:
Generally, for small movements (or steps), most servos are torque limited to prevent overshoot and oscillations. If you change the input pulse timing by 20uS, the motor will not reach full torque before it starts braking the motor to stop. The motor torque is also throttled at the end of the desired motion to prevent overshoot of the target position. Even when moving about 10 degrees (100uS change in pulse width) the motor will not reach full torque before it starts to get throttled to stop. At movements of about 15 degrees the motor will reach maximum speed in about 20-40 mS (depends on load), but then is throttled to stop within 10-20 mS. Greater movements sustain maximum speed for longer, of course.

So, If 50 mS is problematic in your system, you will likely have problems with the servo response.

One additional note is that servos can behave poorly with elastic loads.

As far as the specific servos that you reference, I don't have experience with those. The second one claims 12 bit resolution, I'm guessing this is the encoder resolution that is probably a magnetic sensor rather than a potentiometer like the old-school servos. If these servos are very high accuracy, this definitely requires some advanced motor current control schemes that will limit torque for low angle moves and at the end of the movement as the angle approaches the set point.

Some scope traces measuring motor current @300mA/V Ch1 and motor voltage (across motor terminals) Ch2. Servo is JX 5521 digital with a constant elastic load. Notice that the rise time on motor current stays the same no matter the step size of the setpoint. Also, you can see by the commutation glitch frequency that the speed is still increasing even after the current reaches its maximum. Time constant on this servo is about 28 mS for max current and >70 mS for max speed.

Image 1 - 100 uS step from 1500 uS to 1600 uS.

Image 2 - 200 uS step from 1400 uS to 1600 uS.

Image 3 - 400 uS step from 1300 uS to 1700 uS.


答:
m is an abstract representation of the map. In practice, m typically is some form of parametric model, whose parameters need to be estimated. Some very typical models:

A set of point locations of objects in space. m becomes a vector of (x,y,[z]) coordinates (each for one object).

A grid of cells which can have distinct states, in the simplest form just free/occupied. m becomes a vector of cell states (which each refer to a certain part of 2d/3d space).

The formula given above is a very abstract problem formulation. For actual solutions allowing calculation, it is required to choose a concrete state representation (where SLAM state = combination of environment state + robot location), as well as certain models describing the robot's(/environment's) behavior and the sensor used to observe.

Title: Doubt regarding a slam parameter in research paper

Body:
I was reading about the SLAM problem in a research paper, Multi-robot Simultaneous Localization and Mapping using Particle Filters by Andrew Howard.

What does '$m$' mean here?

The SLAM problem for a single robot is treated as follows.

Let $x_{1:t}$ denote a sequence of robot poses at times 1, 2, ...t,
let $z_{1:t}$ denote a corresponding sequence of observations, and let
$u_{0:t−1}$ denote the sequence of actions executed by the robot.

Our (intermediate) aim is to compute the posterior probability
$p(x_{1:t}, m | z_{1:t}, u_{0:t−1}, x_0)$ over the robot trajectory
$x_{1:t}$ and map $m$, given some initial pose $x_0$. We write this as
the product of two factors:

$p(x_{1:t}, m | z_{1:t}, u_{0:t−1}, x_0) = p(m | x_{1:t}, z_{1:t},
> u_{0:t−1}, x_0)p(x_{1:t} | z_{1:t}, u_{0:t−1}, x_0)$.


问:
Inertial frame's angular velocity expression
I'm following a robotics course on coursera which talks about aerial robotics and more specifically quadrotors.

I'm trying to understand the logic behind the relationship between the angular velocity expressed in the Inertial frame and the rates of change of the euler angles expressed in the body-fixed frame which are collected using an IMU sensor.

Basically in the course, the answer is given as shown below, but unfortunatly, nothing is explained.

I decided to look arround in the internet in order to understand the origin behind this inbetween matrix which converts one angular velocity to another and came up with very convenients explanations in these articles:

Wilselby Article
Chrobotics Article

After understanding the idea behind this transformation matrix, which is the fact that each angular need to be reversed to a specific intermediate reference frame, which also depends on which convention we consider (Z-Y-X convention, Z-X-Y convention, ...) which is makes sense since changing the convention would mean that a specific euler angle would have a different reference frame to be reversed to afterwards.

In my course, the convention used is the Z-X-Y convention. I decided then to prove and compute the provided matrix in the course's picture with the help of Matlab. Below is the matrix i got from my Matlab program:

```<code>angularRotation =

[  cos(theta), 0, cos(phi)*sin(theta)]
[           0, 1,           -sin(phi)]
[ -sin(theta), 0, cos(phi)*cos(theta)]
</code>```

You can see that the result is exactly the same as shown in the picture, except some components are in a incorrect sign.

Below is my Matlab program:

```<code>syms psi theta phi real

yaw = [cos(psi), -sin(psi), 0; sin(psi), cos(psi), 0; 0, 0, 1]
pitch = [1 0 0; 0 cos(phi) -sin(phi); 0 sin(phi) cos(phi)]
roll = [cos(theta) 0 sin(theta); 0 1 0; -sin(theta) 0 cos(theta)]

angularRotation_1 = roll * pitch * [0 0 1]' * [0 0 1]
angularRotation_2 = roll * [1 0 0]' * [1 0 0]
angularRotation_3 = [0 1 0]' * [0 1 0]

angularRotation = angularRotation_1 + angularRotation_2 + angularRotation_3
</code>```

In any case the full Matlab log is needed, here it is:

```<code>yaw =

[ cos(psi), -sin(psi), 0]
[ sin(psi),  cos(psi), 0]
[        0,         0, 1]

pitch =

[ 1,        0,         0]
[ 0, cos(phi), -sin(phi)]
[ 0, sin(phi),  cos(phi)]

roll =

[  cos(theta), 0, sin(theta)]
[           0, 1,          0]
[ -sin(theta), 0, cos(theta)]

angularRotation_1 =

[ 0, 0, cos(phi)*sin(theta)]
[ 0, 0,           -sin(phi)]
[ 0, 0, cos(phi)*cos(theta)]

angularRotation_2 =

[  cos(theta), 0, 0]
[           0, 0, 0]
[ -sin(theta), 0, 0]

angularRotation_3 =

 0     0     0
 0     1     0
 0     0     0

angularRotation =

[  cos(theta), 0, cos(phi)*sin(theta)]
[           0, 1,           -sin(phi)]
[ -sin(theta), 0, cos(phi)*cos(theta)]
</code>```

Thanks in advance.

答: My initial response would be that your angular variables are being measured in the opposite direction from the matrix in the slide you shared. In other words, theta should actually be negative theta, phi should actually be negative phi, and psi should be negative psi. If you perform this conversion, then you have the same matrix as the slide.</p>


问:
Velocity-Control of a manipulator without a dynamic model
I have a five DoF robot. Each axis is connected to a cylinder. You can send PWM values to each cylinder and you are able to read out the position values of each cylinder which makes it possible to design a closed-loop inverse kinematic controller. Given a desired goal position for the manipulator, assume you have estimated the desired velocity change of each joint (for example using move_group library in ROS).

Although we can control the velocity of the robot's joints by manipulating the PWM values, we cannot perfectly recreate these velocity values since we don't have the dynamic model of the robot. Thus, our best bet is to go for the position control of the robot.

Is my theory so far correct? Or is there a way to implement a velocity controller without a dynamic model?

答:
Your intuition is partially correct in the sense that you ought to go with position control implemented via velocity commands resorting to a kinematic (not dynamic) model of the manipulator.

This can be explained by inspecting one of the easiest policy used for inverse kinematics,

$$
\dot{\mathbf{q}} = \mathbf{J}^{-1} \cdot \left( \mathbf{x}_d - \mathbf{x}(\mathbf{q}) \right),
$$

that establishes a closed-loop between the actual error in the Cartesian space and the velocity commands to be sent to the joint motors $\dot{\mathbf{q}}$, being $\mathbf{J}^{-1}$ the inverse of the Jacobian matrix.

Essentially, you cannot send velocity commands without applying instant corrections through the readouts of the end-effector position $\mathbf{x}(\mathbf{q})$, otherwise the small discrepancies of how the commands will get integrated into joint positions (because motors are not perfect integrators) will let you end up far from the target $\mathbf{x}_d$.

The point here is that you only need a kinematic model – in this case the Jacobian – and not a complete dynamic model of the joints comprising for example the masses distribution. The lack of such a latter knowledge can be in fact compensated by the high-level kinematic closed loop.

Nevertheless, if you somehow deal with the dynamics of the system, then you'll certainly obtain better performance.


问:
How to design a behavior tree with ROS1 framework
I am confused about how high level my behavior tree has to be. For example, if I want to create an autonomous robot that goes from point A to point, what would be a reasonable behavior tree?

For now, I think one of the first actions should be something like, loading parameter / configure nodes but I don't know if that's way lower level than the behavior tree is supposed to take care of.

答:
A behaviour tree in robotics is in most cases used instead of an application program. It already assumes a running robot and a set of behaviours which are available at programming time.

I am not sure if ROS supports an application program based programming model, like industrial robots. If yes, the behaviour tree would represent the application program and would not include any steps, which are infrastructure relevant (like node config). But this is only through analogy with the current behaviour tree use-cases, not a technical limitation.

Other use-cases can be found for behaviour trees, so there is no rule on how granular a behaviour tree "has to be" or what it "has to do". For sure it could include configuration steps also, it might also make sense, the only limitation is that the entity interpreting/executing the behaviour tree instance has to support the defined behaviour. This is the only technical limitation.


问:
How to find mathematical model of a wheeled robot (to compute robot's trajectory at given time steps) including its kinematic
I would like to learn, how to find proper kinematic model of robot in mathematical form.

For example:

I would like to create a model of a car, from which I could compute its position and rotation at given time steps.

Assume Ackerman steering system and knowns l, w (see picture)

Inputs are:

constant speed of wheels's rolling

variable velocity of wheels's steering

I found similar problem here path-of-a-simple-turning-car. I think principal is the same, but my question is what are the steps to find proper model. I understand the equations in the link, but I would not be able to make them on my own and slight change in geometry of robot  would confuse me.

答: This lecture from Georgia Tech's Control of Mobile Robot's Coursera class derives the bicycle model; https://youtu.be/cQWhYCrK06M</p>


答:
Given that you are using 2 dc motors, I'm guessing you are using a differential drive configuration.  Your intuition about the algorithm is good.  The encoders on the motors along with some physical/mechanical measurements (wheel radius/circumference and wheel base) are used as input to a kinematic model, in this case the unicycle model. Using this, you can maintain a running estimate of the robot's position and orientation.  Using that, you can find the delta from a desired goal point (as a delta angle).  You can then use this delta as input to a P-regulator whose set point is the angle to the goal and whose output is wheel velocities.  I've implemented that algorithm this project; see the gotoPoint() method in the go-to-goal behavior.  The documentation on the firmware internals contains a link to a presentation that describes the unicycle model and dead reckoning algorithm with illustrations.

Note that dead reckoning with only wheel encoders is useful for short distances, but other sensors will be necessary for accurate pose estimates for anything more.

Title: PID controller for motor speed control and distance control

Body:
I am building a robot rover comprised of dual DC motors each with hall sensors to obtain rotaional speed. I currently have a PID controller for each DC motor that is able to control the speed of the rover.. ie. I can provide a setpoint and the rover will move forward at a steady speed.

The next step is that I want to tel the Robot to move forward a certain distance. I'm thinking the approach here is to use a outer PID loop running at a much lower rate, taking a cumulative measuerment from the hall sensor to determin the distance traveled from the start point. The output would feed the inner PID loop for the motors.

Is this the right approach ?

My concern is that i've used the input from the hall sensors in two place, is one of these redundant for example ?


答:
You may find the Natural Language Tool Kit useful.

http://nltk.org/