问:
Displaying a png-file on a display - stays black
In Webots with a Python controller: I have a PNG-File (640x480) which displays a Matrix-Numpy-Array-figure which is getting produced by my code. I would like to display it on an Display overlay. But display.imageLoad(filename.png) produces no visable image on the Display. It seems to load it, because if i remove the ".png" than it produces an error. What can I change to see it?

Hier is my world file:
https://github.com/MaximilianKlein92/Webots-Breitenberg/commit/25f6645ee3c4184fe4b46559735472f17f07ec24

Here my Controller:
https://github.com/MaximilianKlein92/Webots-Breitenberg/commit/59ceafb0833c29ffbb7e7b7562b0fba4dae587be

And here a short Video:
https://webots.cloud/AcRB4U4?upload=webots

答:
The Display.imageLoad simply reads the image from file and store it internally in Webots. To actually show the image in the Display, you have to call Display.imagePaste that will copy the image data into the Display board.

I saw in your code that you tried to call Display.imagePaste but the arguments are wrong:

the first expected argument is the image reference returned by Display.imageLoad (and not the image file name)

the second (x) and third (y) arguments specify the top left position of the copied image in the Display board:
so if you set x=imageWidth, y=imageHeight, the figure won't be visible in the Display board

So the correct code will be something like:

```<code>figure_ref = display.imageLoad(filename+".jpeg")
display.imagePaste(figure_ref, 0, 0, False)
</code>```

For reference, here is the link to the complete Display API documentation.

Just note that you should also change the line 305 where the figure is saved and specify the extension by adding +'.jpeg':

```<code>plt.savefig(filename + '.jpeg',format="jpeg")
</code>```

Disclaimer: I am a Webots developer working at Cyberbotics.

Body:
The Display.imageLoad simply reads the image from file and store it internally in Webots. To actually show the image in the Display, you have to call Display.imagePaste that will copy the image data into the Display board.

I saw in your code that you tried to call Display.imagePaste but the arguments are wrong:

the first expected argument is the image reference returned by Display.imageLoad (and not the image file name)

the second (x) and third (y) arguments specify the top left position of the copied image in the Display board:
so if you set x=imageWidth, y=imageHeight, the figure won't be visible in the Display board

So the correct code will be something like:

figure_ref = display.imageLoad(filename+".jpeg")
display.imagePaste(figure_ref, 0, 0, False)

For reference, here is the link to the complete Display API documentation.

Just note that you should also change the line 305 where the figure is saved and specify the extension by adding +'.jpeg':

plt.savefig(filename + '.jpeg',format="jpeg")

Disclaimer: I am a Webots developer working at Cyberbotics.


问:
How to use Supervisor along with regular libraries
In my Webots simulation, I am trying to use a supervisor in order to get parameters from other nodes to then have a motor respond by increasing or decreasing its torque, to which I have written the code below:

#include <webots/Supervisor.hpp>
#include <webots/Field.hpp>
#include <webots/Motor.hpp>
#include <webots/Robot.hpp>

#define TIME_STEP 32

using namespace webots;

int main() {
  Supervisor *supervisor = new Supervisor();
  Motor *wheel[1];
  Robot *robot = new Robot();

    // do this once only
  Node *mass = supervisor->getFromDef("Mass");
  Node *motor = supervisor->getFromDef("Motor1");

  if (mass == NULL) {
    std::cerr << "No DEF MY_ROBOT node found in the current world file" << std::endl;
    exit(1);
  }
  Field *trans_field = mass->getField("translation");
  Field *mass_field = mass->getField("mass");
  wheel[1] = robot->getMotor("Motor1");
  wheel[1]->setVelocity(1);

  while (supervisor->step(TIME_STEP) != -1) {
    // this is done repeatedly
    const double *values = trans_field->getSFVec3f();
    double mass = mass_field->getSFFloat();

    double radius = values[1];
    double newtons = mass*9.8;
    double torque = newtons *radius;
    wheel[1]->setTorque(torque);
    wheel[1]->setPosition(1.57);
  }

  delete supervisor;
  return 0;
}
```
<p>However, when I run it I end up getting an error like this:</p>
```Only one instance of the Robot class should be created
WARNING: 'Supervisor' controller exited with status: -1.
```

Can someone please explain what is going on?

答:
As it is explained by the error message you can only have one instance of the Robot class for each controller program.

In your code you are instantiating two instances of Robot class because the Supervisor class inherits from Robot.

In your case, if you need the Supervisor functionalities you should create directly an instance of the Supervisor class and remove the Robot instance.

The resulting code will simply be like the following and you can call both Robot and Supervisor API function from the Supervisor instance:

```<code>...
int main() {
  Supervisor *robot = new Supervisor();
  Motor *wheel[1];
  // Robot *robot = new Robot(); // this can be removed
  ..
  // do this once only
  Node *mass = robot->getFromDef("Mass");
  Node *motor = robot->getFromDef("Motor1");
  ...
  wheel[1] = robot->getMotor("Motor1");
  ..
}
</code>```

Disclaimer: I am a Webots developer working at Cyberbotics.

ContentLicense: CC BY-SA 4.0

Body:
As it is explained by the error message you can only have one instance of the Robot class for each controller program.

In your code you are instantiating two instances of Robot class because the Supervisor class inherits from Robot.

In your case, if you need the Supervisor functionalities you should create directly an instance of the Supervisor class and remove the Robot instance.

The resulting code will simply be like the following and you can call both Robot and Supervisor API function from the Supervisor instance:

...
int main() {
  Supervisor *robot = new Supervisor();
  Motor *wheel[1];
  // Robot *robot = new Robot(); // this can be removed
  ..
  // do this once only
  Node *mass = robot->getFromDef("Mass");
  Node *motor = robot->getFromDef("Motor1");
  ...
  wheel[1] = robot->getMotor("Motor1");
  ..
}

Disclaimer: I am a Webots developer working at Cyberbotics.


问:
Is it worth designing your own components to mount a ball screw?
As explained here I would like to build a MakerArm / Dobot M1 like robotic ARM (SCARA) that can lift few kgs (< 10kg for sure) using a ball screw for the translation on the Z axis.

Right now I consider/think that mounting methods for ball screws have been "standardized" (by CNC industry?) and that any situation (including mine) should match one of those 4 available "patterns" using the standard (and widespread) end support parts (BK, BF, FK series) that includes the bearing.

Am I right or should I consider designing my own ball screw support parts (why?) ?

PS : I am asking this as a separate question as suggested in a previous one that was asking too many different things.

答:
The general answer I would give anyone, working on any project, who asked this question:

Should I buy commercially available, off-the-shelf (COTS) parts, or make my own?

would be to always buy off-the-shelf parts unless you have a really, really good reason to make your own. Here's why:

Making whatever other parts (ballscrews, in your case) isn't the purpose of your project. All the other points here are just reinforcing the fact that making your own parts is going to turn into a distraction.

You don't have volume discounts. Most of the cost for getting parts made is the conversion from CAD to gcode or other machine programming, making jigs, setting machine stops, etc. These costs are fixed and you pay them regardless of the part quantity you order, so someone that orders 1,000 parts gets to amortize the machining setup cost across a larger number of items, resulting in a lower per-part cost. The cost to you to get 3 items made is sometimes nearly the same as the cost to you to get 10 parts made.

You're probably not a geometric dimensioning and tolerancing expert. Are your clearances specified correctly such that you get smooth motion without slop/backlash? Is there clearance for a lubricant? Are your hole positions and screw clearances specified correctly such that the resulting assembly will bolt together? Are they specified correctly such that it bolts to your project?

You're probably not a machine design expert. Are your leadscrew angles correct for your desired torque, force, and speed requirements? Are you taking material friction into account? Are you taking into account radial loading or bending? Are you taking viscous friction due to the lubricant into account? Are your material selections going to cause galvanic corrosion? Is the leadscrew minor diameter appropriate for your axial and bending forces? Are the fillets in your leadscrew threads sufficient to avoid stress concentration?

You're probably not a drafting expert. Did you forget to indicate the setscrew hole should be tapped? Did you forget to include a grease fitting? Did you change the motor last minute and forget to update the bolt pattern for the mating flange? Are your units correct?

If you mess up anything in points 3, 4, or 5, you wind up with a fancy paperweight. Because of point 2, you paid a lot for it. Because of point 1, the rest of your project is stalled until you get these issues resolved.

So you wind up fixing the problem you did notice, re-order the part(s), wait for fabrication and shipping, just to potentially discover either (1) issues you didn't notice that were already present in the first batch, or (2) issues that you introduced when resolving the issue(s) with the first batch.

I've done this. A lot. It will be a lot easier for you to identify the specs you need, then find the commercially-available part that just exceeds the performance specs you need. This may wind up adding weight, so then you need a bigger motor, which then means you need a different ballscrew, or whatever, but in this case you're not having to worry about part fabrication, durability, testing, etc. You just buy the parts and put them together. If there's a problem with the part quality, you send it back to the vendor and use a replacement.

So again, to summarize - if it's not the focus of your project, don't do it. If you want to learn to make a ballscrew, then you should put everything else aside and accept the fact that making a ballscrew is your new project. If you can't afford (time or money) to make that commitment then outsource it. Let the ballscrew manufacturers worry about design, production, and quality, and you focus on whatever novel thing you're trying to do with them.

This goes for professional companies, too - Ford doesn't make airbags, even though airbags are in all their vehicles, they buy them from an airbag supplier. A carpenter doesn't make their own lumber, they buy it from a lumber supplier. A chef doesn't make their own flour, etc. The only exceptions you'll find to any line of thinking like this will be cases where the person/company believes the specifications they want aren't commercially available, but that's the mindset you (and professional companies) need to take with decisions like this - buy the commercially available stuff until you can prove that whatever item isn't commercially available. Only then should you take on trying to do it yourself.


问:
What is minimum torque required for CNC stepper motors and spindle for aluminium milling?
I am planning to buy CNC mechanical skeleton without motors, spindle and controller. I will be using the CNC mainly for aluminium milling. Are there any specifications for minimum torque requirement for stepper motors and spindle to perform aluminium milling ?</p>

答: There are many calculators online for determining this sort of thing, and there are many factors involved.  Here is one such calculator.</p>

ContentLicense: CC BY-SA 3.0


问:
Holonomic Constraints
I'm currently reading the book "Principles of Robot Motion" by Choset and came across the following statement in Chapter 3 on Configuration Spaces, in a section where they discuss the dimensions of a configuration space (Section 3.3, pg 48, for anyone who has the book):

Each linearly independent holonomic constraint on a system reduces the dimension of the system's configuration space by one.

I'm having a little trouble understanding what makes a constraint linearly independent. Independent with reference to what?

Thanks for the help!

答:
Holonomic constraints are a difficult topic to grasp at the beginning. A nice answer I found is given here: https://physics.stackexchange.com/questions/409951/what-are-holonomic-and-non-holonomic-constraints . From the linked answer one can see that a holonomic constraint reduces a system's degrees of freedom by one.

Now imagine that you have a system and you can formulate different holonomic constraints the form of equations (see linked answer). Note that there can be different ways to formulate those constraints, e.g. different variables depending on how you define it. However, those equations will still describe the same constraint. Sometimes this is not as obvious as it seems and one has to do the math. By looking at the math we can see if two holonomic constraint equations are describing the same thing by checking if the constraint equations are linearly independent or not. If they are, we can say that they describe the same constraint, just in different ways. And since they describe just the same constraint they will not reduce the systems degrees of freedom by one individually, but together. In contrary if they are linearly independent, they are indeed describing two different constraints and therefore will reduce the systems degrees of freedom individually by one. Note that I explained it in terms of degrees of freedom of the system, but this is equivalent for the dimension of the configuration space.

Title: Holonomic Constraints


问:
How to get all ROS log messages from rostest?
I am trying to debug a problem with a rostest that it is probably failing due to multithreading, as the result of the test is always different.

That aside, my problem is that I cannot get to see the complete ROS logs. More specifically, I can see the logs but for only the first test case. The remaining tests don't show any logs.

Here is an example of what I get from the console. It shows ros logs up to the result of the first test MoveItCppTest.SimpleSimulatenousExecutionTest, which also always succeeds. For the remaining tests, I just get the logs of the result but nothing else.

This is the test file and I am executing it like this:

rostest moveit_ros_planning test_simultaneous_execution_manager.test --text

...
[DEBUG] [1674281108.466333224]: Event EXECUTION_COMPLETED
[DEBUG] [1674281108.724856326]: Event's group name: panda_2
[DEBUG] [1674281108.724891348]: 0 remaining active controllers for group name: panda_2
[DEBUG] [1674281108.724905334]: Clearing context with group name: panda_2
[DEBUG] [1674281108.724931419]: No active trajectories remaining
[ INFO] [1674281108.725006225]: Deleting PlanningComponent 'panda_2'
[ INFO] [1674281108.725067552]: Deleting PlanningComponent 'panda_1'
[ INFO] [1674281108.725092946]: Deleting MoveItCpp
[ WARN] [1674281108.746951670]: Stop!. stop_execution_: 0 run_event_manager_: 0
[ INFO] [1674281109.234819475]: Stopped publishing maintained planning scene.
[ INFO] [1674281109.236025658]: Stopping world geometry monitor
[ INFO] [1674281109.236683101]: Stopping planning scene monitor
[ WARN] [1674281109.329307461]: SEVERE WARNING!!!
Attempting to unload /root/ros_ws/devel/lib/libmoveit_kdl_kinematics_plugin.so
while objects created by this library still exist in the heap!
You should delete your objects before destroying the ClassLoader. The library will NOT be unloaded.
[       OK ] MoveItCppTest.SimpleSimulatenousExecutionTest (5903 ms)
[ RUN      ] MoveItCppTest.WaitForSingleTrajectory
/root/ros_ws/src/moveit/moveit_ros/planning/trajectory_execution_manager/test/test_simultaneous_execution_manager.cpp:115: Failure
Value of: moveit_cpp_ptr->getTrajectoryExecutionManager()->push(panda_1_robot_trajectory_msg)
  Actual: false
Expected: true
[  FAILED  ] MoveItCppTest.WaitForSingleTrajectory (1447 ms)
[ RUN      ] MoveItCppTest.RejectTrajectoryInCollision
[       OK ] MoveItCppTest.RejectTrajectoryInCollision (1489 ms)
[ RUN      ] MoveItCppTest.RejectInvalidTrajectory
[       OK ] MoveItCppTest.RejectInvalidTrajectory (1812 ms)
[ RUN      ] MoveItCppTest.CancelTrajectory
[       OK ] MoveItCppTest.CancelTrajectory (1314 ms)
[----------] 5 tests from MoveItCppTest (11965 ms total)

[----------] Global test environment tear-down
[==========] 5 tests from 1 test suite ran. (11965 ms total)
[  PASSED  ] 4 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] MoveItCppTest.WaitForSingleTrajectory

 1 FAILED TEST
```

Is there any way to enable logging for all tests?

答: I also have issues with that, normally what I would do is search in ~/.ros/logs for the latest logs or add some ROS_WARN, as that would be shown in the terminal as well


问:
Looking for details regarding ROS1 dispatching of subscription callbacks
I've run into some issues and confusion on serious subtleties with rospy, subscription callbacks, the use of rate.sleep(), spin(), rospy.sleep(). Does anyone know of a writeup that explains exactly how the dispatching of callbacks works in rospy. I gather that rospy is multi threaded, and that there are threads to handle callbacks, and some other little facts that I try to put together into a cogent picture. I don't really want to start reading the ROS code but maybe that's what it will take. Here are some questions that are related:

if a subscription callback includes sleep or other IO, can you create a race condition?

if a callback us an instance method and uses instance variables, or if it's just a function and uses python globals, is that going to cause problems?

What problems can occur if a callback (say odom) publishes cmd_vel directly during the callback?

I've dug around answers.ros, google, some books. But I can't find a clear explanation of how callback dispatching works with rospy and with threads.

答:
There is a good discussion about rospy callback handling on this page.

The bottom line from that discussion is that your subscribe callback needs to be thread-safe. When there is more than one publisher to the topic, rospy may invoke the callback simultaneously from multiple threads.

While it is permitted to call rospy.sleep() inside a subscribe callback, I consider it a poor design decision, because blocking the callback execution often leads to poor performance. A better design pattern is to use a rospy.Rate or a rospy.Timer outside of the subscribe callback.


问:
Just run program on NXT, not download?
Is there any way I can simply run a program on the NXT, but not download it?
  I have all my programs already downloaded, and I am connecting with a USB cable to a MacBook Pro using the NXT-G interface.  Is there any way I can just run programs existing on the NXT from the computer, and not download them?  It's really increasing my robot's run time.

  I am competing in Robocross in Science Olympiad, and my event is at noon.

Thank you.

答:
There have been some projects that allow you to run NXT programs on a computer, like this one:
http://ocaml-mindstorm.forge.ocamlcore.org/

However, this is done by downloading and running a different program on the NXT, which acts as a communications bridge -- passing control to and from the main computer.  There are probably other libraries that use this model of operation, so you might not need to learn OCaml specifically to try this.

Downloading programs onto the NXT is the only way that they can be run; there is no concept of a filesystem or external memory device on a microcontroller that you could use as an alternate source of the program instructions.

Title: Just run program on NXT, not download?


问:
Impedance control algorithm in The Modern Robotics: Mechanisms, Planning, and Control
I am studying The Modern Robotics: Mechanisms, Planning, and Control (by Kevin Lynch, Frank Park and Evan Suma). I am trying to implement Chapter 11.7.1 Impedance-Control Algorithm of the book with ROS simulation, but I am confused and I am asking for help.

he impedance control algorithm in the book has a dynamics formula for task space, but I am confused as to whether the theta used here is the desired theta or the current theta. In addition, jacobian and twist are also used to create Lambda and Eta, and I am not sure whether they are also desired jacobian, desired twist, current jacobian, or desired twist. Could you please help?

答:
All of the $\theta$'s listed represent current joint angles, because we are considering what the robot's dynamics look like at this moment in time - i.e. at the given configuration. Since this is an end-effector force control law, I would imagine the only "desired" values could be those of $x$, $\dot{x}$, and $\ddot{x}$ in the $f_{\text{ext}}$ term.

As for $\tilde{\Lambda}$ and $\tilde{\eta}$ - because these are the approximated equations of motion for your robot arm in the task space, they use the actual twist $\mathcal{V}$ and actual Jacobian $\mathbf{J}$. As a general rule of thumb, if you are using a model to "compensate" for your system dynamics, you will be using the true system state. Otherwise, you would be tracking, minimizing, etc. some sort of error associated with a desired value.


问:
how to solve the emitter can't send the 'list' or 'set' in webots?these data is important to me
hey，everyone！when I want to use the emitter to send some 'list' or 'set' type data,I got errors.it told me these types data are unsupported to send for emitter.but these data is important for my code.I must use all robots's data to updata my nerual network,I use emitters to send their data,but i meet the question,how to solve it?</p>

答:
You have to serialize your data in order to be able to send it with the Emitter (or in general to transmit data between two processes), i.e. your object needs to be translated to a flat string or byte stream.

You can write your own code to convert your list to string in the Emitter controller and then recover the list in the Receiver controller.
Otherwise you can find many libraries or modules that provides this functionality.

For example for Python there is the json module that can be used for serialization. Here is an example:

Emitter code:

from controller import Robot, Emitter
import json
...
emitter_robot = Robot()
emitter_device = emitter_robot.getDevice('emitter')
timestep = emitter_robot.getBasicTimeStep()
...
while self.step(timeStep) != -1:
    my_list = {'first': 1, 'second': 2}
    emitter_device.send(json.dumps(my_list))
```
<p>Receiver code:</p>
<pre class="lang-py prettyprint-override"><code>from controller import Robot, Receiver
import json
...
receiver_robot = Robot()
timestep = emitter_robot.getBasicTimeStep()
receiver_device = receiver_robot.getDevice('receiver')
receiver_device.enable(timeStep)
...
while receiver_robot.step(timeStep) != -1:
    while receiver_device.getQueueLength() > 0:
        data = receiver_device.getString()
        my_list = json.loads(data)
        receiver_device.nextPacket()
</code>```

Disclaimer: I am a Webots developer working at Cyberbotics.

Body:
You have to serialize your data in order to be able to send it with the Emitter (or in general to transmit data between two processes), i.e. your object needs to be translated to a flat string or byte stream.

You can write your own code to convert your list to string in the Emitter controller and then recover the list in the Receiver controller.
Otherwise you can find many libraries or modules that provides this functionality.

For example for Python there is the json module that can be used for serialization. Here is an example:

Emitter code:

from controller import Robot, Emitter
import json
...
emitter_robot = Robot()
emitter_device = emitter_robot.getDevice('emitter')
timestep = emitter_robot.getBasicTimeStep()
...
while self.step(timeStep) != -1:
    my_list = {'first': 1, 'second': 2}
    emitter_device.send(json.dumps(my_list))

Receiver code:

from controller import Robot, Receiver
import json
...
receiver_robot = Robot()
timestep = emitter_robot.getBasicTimeStep()
receiver_device = receiver_robot.getDevice('receiver')
receiver_device.enable(timeStep)
...
while receiver_robot.step(timeStep) != -1:
    while receiver_device.getQueueLength() > 0:
        data = receiver_device.getString()
        my_list = json.loads(data)
        receiver_device.nextPacket()

Disclaimer: I am a Webots developer working at Cyberbotics.


问:
What robotic simulators simulate the reflectivity of objects?
I want to simulate the reflectivity of objects in a simulation because I want to use a 2D laser scanner to detect certain objects that have higher reflectivity than other objects in a particular scene. I was wondering which robotics simulators have built-in support in object reflectivity. I know that Gazebo default behavior doesn't simulate reflectivity in objects. There is a property called <laser_retro> that you can add to the collision property. The problem with that is that the reflection is not realistic and it always returns the intensity value that you set in that property. That is, the intensity value is constant. Sure, I can create a gazebo plugin to simulate that with a particular object using real data but I'm looking for a built-in solution in the simulator.

Is there any with that feature? maybe Unity Robotics, CoppeliaSim or Nvidia Isaac Sim? or any other?

答:
This is exactly my domain - I've been doing realtime lidar simulations for industrial and automotive autonomy for 5 years now.

One of my biggest pet peeves is the assumption lots of people make that you can somehow determine infrared reflectivity based on visible color. The outputs of a regular camera and a thermal imaging camera aren't the same, because infrared is a completely different spectrum than visible light.

Just like this image doesn't give you any information about what visible spectrum is generating the return (yellow, blue, red, etc.), the combined intensity here doesn't give you any information about what the surface is like in the infrared range.

All this is to say that any engine, Unreal, Unity, etc. that generates returns based on visible colors are going to be wrong. I have not yet seen an engine that generates correct lidar reflectivities.

The solution seems to be to write your own encoding mechanism. This is typically done by creating and assigning an additional texture to your model. When you do the raycasting for your lidar simulation then you should get a UV coordinate for the hit, and then you can go to your lidar texture and use the UV position to get the surface reflectivity at that point.

Regarding specific engines, I've used both Unity and Unreal, and while Unreal's graphics are without a doubt better than Unity's, the issue you'll find is that your renderings are only as good as the source material will let them be. If you don't have high-quality meshes, textures, materials, lighting, lighting probes, etc., then forget it, you'll never get to the AAA video quality that Unreal uses in their marketing material.

For me, I prefer Unity because C# is the best language (fight me), and because Unreal doesn't use the standard template library - they roll their own types which are incompatible with stuff like OpenCV, which makes integration outside of the Unreal engine (like ROS) really tedious. If you can find an Unreal plugin or something that someone already wrote (and you're okay being bound to their license terms!) then great, but if you're writing stuff on your own then I think it's a lot easier to develop in Unity.

Wandering off-topic here a bit, but to your question specifically:

What robotic simulators simulate the reflectivity of objects?

None of them do it correctly, but most of them will let you write your own solution. The best choice for platform is almost always the one you're most comfortable working with, so pick a programming language and go from there.


问:
Drive to point PID doesn’t work properly
This is my first post here. I am trying to get a robot I’m working on to drive to a point via a PID controller. My code works fine if the point is in front of the robot, but completely falls apart if the point is behind or to the side of the robot. I have Odometry running in the background, and I am able to access updated position information easily.

Here’s the code I’m using now to determine the error which I feed to the PID:

current = odom->getPos();

// calculate our error
// our distance error is the distance to the target
double distError = util::distance(current, target);
double angError = (util::getAngDiff(current, target) - current.theta);

if (angError > 180)
{
    angError -= 360;
}

else if (angError < -180)
{
    angError += 360;
}
```
<p>And my getAngDiff:</p>
<pre class="lang-cpp prettyprint-override"><code>double util::getAngDiff(Point a, Point b)
{
    // current = a, target = b

    double tAngle = atan2(b.y - a.y, b.x - a.x);
    lib727::util::deg2rad(a.theta);

    // robot angle is in radians, target angle is in radians
    double aDiff = tAngle - a.theta;

    // convert difference to degrees
    lib727::util::rad2deg(aDiff);

    // round to 100th place
    return round(aDiff * 100) / 100;
}
</code>```

It’s worth noting that my current angle (current.theta) is in degrees and is in the range [0-360), and I use the Euclidean distance formula to calculate distance error. From there, I simply add/subtract my angular error from my distance error and multiply the final error per side by kP. Is there anything obvious wrong with my math? Here’s a video (in a simulator) of what happens when I tell the robot to go to the point {0, 3}:

https://imgur.com/a/I1TGuDy

It should turn 90 degrees and then drive straight, but it obviously doesn’t. Thanks for any help!

答:
I don't understand

```<code>lib727::util::deg2rad(a.theta);
</code>```

You're not assigning the output anywhere, so are you expecting that this is going to modify a.theta? If so, you're not modifying it back! This would seem to me then that you're constantly applying a degrees-to-radians conversion over top of the existing angle, which I believe should quickly drive it to zero, because the conversion of degrees to radians is approximately divide-by-sixty. First call it'd convert 120 to about 2, then the second call it'd convert a.theta from 2 to about 0.03, then on the third call it's basically zero.

I think it'd be easier to keep everything in degrees instead:

```<code>double tAngle = lib727::util::rad2deg(atan2(b.y - a.y, b.x - a.x));
double aDiff = tAngle - a.theta;
</code>```

It's not clear what kind of robot you've got, or what you're doing with the PID control, but if you don't tune your angular controller to be significantly more aggressive than your linear controller then you'll probably wind up with some form of a limit cycle where your robot is just driving circles around the target position.

If you're trying to do this with an Ackermann-steered vehicle (as opposed to a differentially-steered vehicle) then you're probably not going to succeed with brute PID control alone; you'd need to do some trajectory planning and PID to that trajectory.

Body:
I don't understand

lib727::util::deg2rad(a.theta);

You're not assigning the output anywhere, so are you expecting that this is going to modify a.theta? If so, you're not modifying it back! This would seem to me then that you're constantly applying a degrees-to-radians conversion over top of the existing angle, which I believe should quickly drive it to zero, because the conversion of degrees to radians is approximately divide-by-sixty. First call it'd convert 120 to about 2, then the second call it'd convert a.theta from 2 to about 0.03, then on the third call it's basically zero.

I think it'd be easier to keep everything in degrees instead:

double tAngle = lib727::util::rad2deg(atan2(b.y - a.y, b.x - a.x));
double aDiff = tAngle - a.theta;

It's not clear what kind of robot you've got, or what you're doing with the PID control, but if you don't tune your angular controller to be significantly more aggressive than your linear controller then you'll probably wind up with some form of a limit cycle where your robot is just driving circles around the target position.

If you're trying to do this with an Ackermann-steered vehicle (as opposed to a differentially-steered vehicle) then you're probably not going to succeed with brute PID control alone; you'd need to do some trajectory planning and PID to that trajectory.


问:
Launching an EC2 instance via AWS Systems Manager fail w/"Invalid IAM Instance Profile ARN (Service: AmazonEC2; Status Code: 400"
This is "AWS + Robomaker" question, not robotics. https://meta.stackexchange.com/a/141944/166296 suggests superuser.com for AWS + personal usage like mine, but I still think robotics site is more appropriate as the tutorial that my question is based on is taken from robomaker. I'm happy to move the question if there's better places.

What am I missing to get the tutorial working?

Issue

In a tutorial Build and Simulate Robotics Applications in AWS Cloud9 amazon.com, published 2022/08/19), I get stuck at the step 16.

Building the Amazon EC2 Instance"

Once you have configured the automation, select Execute at the bottom right of the screen to begin the automation.

Error reads (creds are swapped):

```<code>Value (arn:aws:ec2:us-east-1:292993933939:instance/i-0a0f99abeea700e54) for parameter iamInstanceProfile.arn is invalid. Invalid IAM Instance Profile ARN (Service: AmazonEC2; Status Code: 400; Error Code: InvalidParameterValue; Request ID: 9e4cdad7-9a7a-40a3-9864-3301a998319e; Proxy: null)
</code>```

Things I tried but didn't seem to help

Assuming the error message is saying that the ARN is incorrect, I've tried various ARN, none of which even returned a different error message.

arn:aws:ec2:us-east-1:292993933939:instance/i-0a0f99abeea700e54

arn:aws:ec2:us-east-1:292993933939:instance/robomaker_test1  (EC2 instance' name)

arn:aws:ec2:us-east-1:292993933939:instance/*  (referring https://stackoverflow.com/a/59371263/577001)

arn:aws:ec2:us-east-1:292993933939:instance/0a0f99abeea700e54

Maybe related finding in the tutorial

Prerequisites

To find your custom public SSH key, navigate to the AWS Cloud9 console (https://us-east-1.console.aws.amazon.com/cloud9/home?region=us-east-1#).

I think this is the point where the instructed step and what I see on the same link starts looking different.

I do NOT see step "18. Select Create and run in remote server (SSH connection) underneath Environment type." and step 19 on my AWS gui.

And I see some other required fields that I have no idea what I should put in (see screenshot below). Completely out of idea, I tried to refer to the public host name of an EC2 instance I'm running but no good.

答:
Resolved myself.

Hunch was in the screenshot in the tutorial where ARN contains "instance-profile" header. So tried to find on my end the one that has the same header.
 (Image from cloudfront.net)

Indeed, the "ec2-instance-builder" Role made in an earlier section does seem to have that header. With that ARN the blocked section on Systems Manager passed.

Also, unsure if this is related or not though, in the OP I said I saw different menus on Cloud9. I chose the following.

Prerequisites

Add a name, the example in the blog uses “test”, and select Next to proceed.

Select Create and run in remote server (SSH connection) underneath Environment type.

I don't see that option off the top, but just did:

New EC2 instance

t2.micro

Ubuntu 18.04 server

Network setting: SSH


问:
JSP container for embedded systems
There is this project I am working on which is using a BeagleBone and we need a JSP container to run on it. I was thinking of Tomcat but wanted to know if Tomcat is suitable for embedded systems.

Is it too resource-heavy? If yes, are there other lighter JSP containers? I know only of Tomcat and Jetty.

答:
Could you perhaps elaborate on your performance requirements?

I'm quite confident you will be able to get Tomcat running, here's a video of someone getting Tomcat 5.5 running on a beagleboard c4 (note the video is dated Feb 2011). Also remember that you can run a normal Ubuntu distro on the beaglebone, so installing Tomcat should be as easy as simply going 'sudo apt-get install tomcat7'.

The big issue is performance. If you're planning to use the beaglebone as a server handling thousands of requests a second you're probably going to have a problem.

The following table indicates the performance difference between embedded application processors and a desktop PC (the benchmark calculates pi to 500 digits, see Johannes Ernst's blog for more info).

The above benchmark obviously does not characterize other performance areas important in running a server (e.g. disk or network I/O), but let's assume you're looking at roughly a tenfold increase in processing time.

For instance, if a single Tomcat transaction usually took 10 ms to complete, it could now take 100 ms. If you're only using the beaglebone to serve a small number of consumers (infrequently), and responsiveness isn't as critical, it should work fine.

OwnerDisplayName: pratnala

Title: JSP container for embedded systems


问:
The Benefit of Hand-Eye calibration with 2D camera
I have a general question about the benefit of Hand-Eye calibration.
I know that the Hand-Eye calibration can be done with many softawres by solving the AX=XB or AX=ZB equation. But my question is, how can I use this calibration information afterwards.

Say, I have an eye-to-hand calibration configuration where a 2D camera is stationary and a gripper is mounted on the robot arm. After doing the calibration I would have the trasformation from 2D Camera to the robot base. Now I would like to detect some object using the 2D Camera and send its position to the robot to grip it. But since I don't have the depth information for this object I wouldn't be able to calculate the 3d Position of the object in the robot base, even though I have the calibration information.

So for me it seems that using a single 2D camera isn't helpful to work with a robot arm. One should use a 3D camera to be able to extract useful information and then send them to the robot. Or am I missing something?

答: There are cases where the object's dimension or shape is known. Especially 2D camera and manipulator combination is widely used in manufacturing automation where you have the 3D cad model of the object at a high chance. If you can register the 3D cad information to its projection in the image you can calculate the distance + orientation of the object from your camera. This registration process is often called template matching.</p>


问:
What does software-based parameterization in ISO 13849-1 mean?
I have no CS background except some coding experience. I am studying the standard ISO 13849-1 and find section 4.6.4 concerning "software-based parameterization" is not clear to me. I have tried to google it but can't find much information about it. Below is the first three paragraphs of section 4.6.4 (SRP/CS in below means safety-related parts of control systems):

Software-based parameterization of safety-related parameters shall be considered as a safety-related aspect of SRP/CS design to be described in the software safety requirements specification.
Parameterization shall be carried out using a dedicated software tool provided by the supplier of the SRP/CS. This tool shall have its own identification (name, version, etc.) and shall prevent unauthorized modification, for example, by use of a password.

The integrity of all data used for parameterization shall be maintained. This shall be achieved by applying measures to

— control the range of valid inputs,

— control data corruption before transmission,

— control the effects of errors from the parameter transmission process,

— control the effects of incomplete parameter transmission, and

— control the effects of faults and failures of hardware and software of the tool used for parameterization.

The parameterization tool shall fulfil all requirements for SRP/CS according to this part of ISO 13849. Alternatively, a special procedure shall be used for setting the safety-related parameters. This procedure shall include confirmation of input parameters to the SRP/CS by either

— retransmission of the modified parameters to the parameterization tool, or

— other suitable means of confirming the integrity of the parameters,

as well as subsequent confirmation, e.g. by a suitably skilled person and by means of an automatic check by a parameterization tool.

NOTE 1 This is of particular importance where parameterization is carried out using a device not specifically intended for the purpose (e.g. personal computer or equivalent).

Here are my questions:

Does "parameterization" here means modifying features of a software to match particular customer needs?

Are there differences between "parameterization" and "software-based parameterization"?

According to the provisions quoted above (e.g. "Parameterization shall be carried out using a dedicated software tool provided by the supplier of the safety-related parts of control systems."), I guess that parameterization is performed by an external software (e.g. software A and the parameterization software B of A). Is my understanding correct? If my understanding is correct, could anyone provide some explanations of how it works?

I would appreciate any help with this situation!

答:
ISO 13849 is a standard for safety systems. It defined among other thing safety performance levels that define the amount of risk mitigation. This standard is referenced by ISO 10218 which is the industrial robotics safety standard.

Often part of the safety related controls is a safety rated PLC. The PLC will be running a program. To make the system flexible that program is often controlled by setting parameters. This usually done by setting those parameters using a program running on a PC. For example the PLC has a dual channel safety rated input. When that set of inputs turns off do I want to do an E-Stop and shutdown all equipment in the cell, do I want to do a SS1 protective stop and shut off power to arm, but keep the rest of equipment in cell running, or do I want to a SS2 safe operating stop that halts the arm and prevents it from moving while remaining powered up? The action that the safety PLC does can be controlled by a setting or parameter.

The standard says what ever software sets this parameter needs to verify that the setting is correct. There are several ways to do this and often they are used in combination.

For example when I am uploading safety settings to a Staubli CS9 controller, one step is to press a button on the controller so the software on my PC can verify that it is connected to right controller. The software generates a validation document that includes CRC values or checksums. On the controller I check that checksum matches the one on the validation document.

The controller will also show me the version number of the safety software running on the safety PLC and that software also has a checksum. On start up the safety PLC connects to the controller computer and verifies that it the correct safety PLC program for that robot type


答: If you use PNP (Perspective N Point), you could estimate the distance in Z if dimensions of the objects are known.</p>

Title: The Benefit of Hand-Eye calibration with 2D camera

Body:
I have a general question about the benefit of Hand-Eye calibration.
I know that the Hand-Eye calibration can be done with many softawres by solving the AX=XB or AX=ZB equation. But my question is, how can I use this calibration information afterwards.

Say, I have an eye-to-hand calibration configuration where a 2D camera is stationary and a gripper is mounted on the robot arm. After doing the calibration I would have the trasformation from 2D Camera to the robot base. Now I would like to detect some object using the 2D Camera and send its position to the robot to grip it. But since I don't have the depth information for this object I wouldn't be able to calculate the 3d Position of the object in the robot base, even though I have the calibration information.

So for me it seems that using a single 2D camera isn't helpful to work with a robot arm. One should use a 3D camera to be able to extract useful information and then send them to the robot. Or am I missing something?


问:
Low Amp FPV Quadcopter Motors
Why do FPV Quadcopter Motors (usually the more expensive ones) draw lower amps than regular motors?

And why are they more squat(disk shaped) as opposed to normal motors which are about the same diameter and height?

答:
While doing FPV using multirotor, endurance is essential as you want to stay in air for maximum time in limited battery capacity. This requires minimizing current consumption while designing a multirotor. Multirotors use flight control system which works best with relatively lower rpm motors as response is faster with low rpm motor. This demands usage of bigger diameter propeller for desired thrust which expects high torque motor to drive it. Now we expect higher torque at lower current consumption for our purpose.

In case of brushless DC motor, torque depends on number of poles and current consumption depends on coil. Now in order to increase torque one has to increase number of poles and consequently diameter of motor is increased. In order to decrease coil, we have to decease length of stator. These requirement of large radius and small stator length results in disc like shape for a high torque and low current consuming motor.

Title: Low Amp FPV Quadcopter Motors


问:
How do we derive the loop closure equations?
Looking to derive these equations. I don't intuitively understand what it means to take a cos of two independent angles added together. Nor do I understand why all of these are equal to 0. It is hard to visualize when all the angles seem independent.

答:
I think perhaps you can proceed as follows:

First consider the each segment as a vector, $\bar{r}_1$, $\bar{r}_2$, etc.

The vectors each add as you place the tip of each to the tail of the following: $\bar{r}$ = $\bar{r}_1$ + $\bar{r}_2$ + $\bar{r}_3$ + $\bar{r}_4$

But you know that when you do this you just end up back at the origin - i.e.

$$\bar{r} = \bar{r}_1 + \bar{r}_2 + \bar{r}_3 + \bar{r}_4 = 0$$

This means that the $x$ and $y$ components must each add up to zero as well, since $\bar{r}$ = $\hat{x}x$ + $\hat{y}y$ $= 0$:

$$x = x_1 + x_2 + x_3 + x_4 = 0$$

$$y = y_1 + y_2 + y_3 + y_4 = 0$$

This is where the first two equations come from, with, e.g.:

$$x_1 = L_1\cos\theta_1$$
$$x_2 = L_2\cos(\theta_1+\theta_2)$$
$$\ldots$$

The last equation simply expresses the fact that you will end up back at the beginning as you rotate through each angle:

$$\theta_1 + \theta_2 + \theta_3 + \theta_4 = 2\pi$$

If some of the derivations are still a mystery, I recommend this paper from the MIT AI Lab.  It is quite old but very clear.


问:
How do you rotate positions from ENU-frame to body frame?
If positions are in the local frame of ENU (or ECEF - either works), how do you rotate that to the body frame of the device?

Logically, I thought that I could use the pitch, roll, and yaw angles of the body frame to form a rotation matrix to apply to ENU positions. However, when I apply the rotation matrix, the positions seems to grow cumulatively as shown in the figure. The across track variations grow over time with each sinusoid wave

I would like to be able to rotate the positions rather than the velocities in this instance because the positions are obtained from a mechanization process and filtered.

答:
I thought that I could use the pitch, roll, and yaw angles of the body frame

Whether this is true or not depends on the relationship between the Sensor and Body frames. You need to determine Tb2s (the full pose of the Sensor frame relative to the Body frame.) Then the calculation to transform a Ps (position in Sensor frame) to a Pb (position in the Body frame) is:

Pb = inverse(Tb2s) * Ps

In the case where the Sensor is attached to the Body, it is not necessary to know what the roll-pitch-yaw of the Body frame is. However, if the Sensor is not attached to the Body (maybe it's mounted on a wall), then you'll need to first calculate Tb2s through a frame common to both e.g. Body -> Map -> Sensor.


问:
[Raspberry Pi]: ROS 2 Humble on Ubuntu 22.04 Server: v4l2_camera reports "Failed stream start: Invalid argument (22)"
I have ROS2 Humble installed on Ubuntu 22.04 Server (64-bit) on a Raspberry Pi4.

When I run the v4l2_camera node it finds my Pi Camera (v1.3) but then complains:

Failed stream start: Invalid argument (22)

```<code>$ ros2 run v4l2_camera v4l2_camera_node -ros-args --params-file /home/ubuntu/ros2ws/v4l2_camera_params.yaml
[INFO] [1667398998.222438071] [v4l2_camera]: Driver: unicam
[INFO] [1667398998.223092209] [v4l2_camera]: Version: 331580
[INFO] [1667398998.223198373] [v4l2_camera]: Device: unicam
[INFO] [1667398998.223268817] [v4l2_camera]: Location: platform:fe801000.csi
[INFO] [1667398998.223331871] [v4l2_camera]: Capabilities:
[INFO] [1667398998.223396278] [v4l2_camera]:   Read/write: YES
[INFO] [1667398998.223460721] [v4l2_camera]:   Streaming: YES
[INFO] [1667398998.223542720] [v4l2_camera]: Current pixel format: pgAA @ 2592x1944
[INFO] [1667398998.223637940] [v4l2_camera]: Available pixel formats:
[INFO] [1667398998.223709587] [v4l2_camera]: Available controls:
[INFO] [1667398998.225908478] [v4l2_camera]: Requesting format: 2592x1944 YUYV
[INFO] [1667398998.226086845] [v4l2_camera]: Success
[INFO] [1667398998.226256139] [v4l2_camera]: Requesting format: 640x480 YUYV
[INFO] [1667398998.226385618] [v4l2_camera]: Success
[INFO] [1667398998.226483839] [v4l2_camera]: Starting camera
[ERROR] [1667398998.245779840] [v4l2_camera]: Failed stream start: Invalid argument (22)
</code>```

This is my params file:

```<code>/**:
  ros__parameters:
    video_device: /dev/video0
    pixel_format: YUYV
    output_encoding: rgb8
    image_size: [640, 480]
    time_per_frame: [1, 30]
    camera_frame_id: camera_optical_frame
</code>```

I noticed that the startup does not list any "Available pixel formats" but do not know if that could be contributing.

How do I find out what is the "Invalid argument (22)" in the error message?

答:
This is a known issue, which is discussed here:
https://gitlab.com/boldhearts/ros2_v4l2_camera/-/issues/45

The underlying cause is that Raspberry Pi has moved to the new 'unicam' driver. Seemingly as part of their effort to move to libcamera to power their camera stack. Although this new driver is a V4L2 driver as well, unfortunately it proofs tricky to get YUV or RGB frames out of it.

Based on this comment in the v4l2_camera issue, you can comment out camera_auto_detect=1 in /boot/firmware/config.txt to have the old driver loaded instead. The v4l2_camera package then works as normal with that. This may affect other, libcamera based, utilities if you want to use any.


问:
Using vision for Monte-Carlo localization
From each step of my vision code I am able to get around 400 coordinates of where the robot thinks the walls are

I want to integrate this into Monte-Carlo observation step.

I'm storing the map of the maze as a set of Line segments. What would be a nice way to implement the sensor update, i.e. given the position (x,y) of the robot what is the probability that it is found there given the above described coordinates of the walls.

The main idea I currently have:

Transform points in polar coordinates. Then for each point (from vision output) compute a ray with this angle and find the first intersection with the maze. Now we have the predicted distance and real distance and we can compute the probability that this measurement is right.

The main drawback is that this is slow. For each point from vision output I have to iterate over all line segments to find the one with the closest intersection. The line segments number is around 50. So it gets to O(400*50*Particle number).

答:
I have done this with a kinect and it wasn't slow.

So Give more details about:

Sensor output sample

the system you are running on

In monte carlo you have to traverse all the points one way or another to get a Posterior distribution from the Prior.

If the System has a GPU you can parallel process the whole array at once.

What you are saying is one of the Cons of Monte Carlo Localization it doesn't scale well for bigger problems specially for 3-dimensional spaces.

there are other continous models which scale better than it


问:
Set global_frame and robot_base_frame parameters for costmap_2d::Costmap2DROS object
I am trying to use a costmap_2d::Costmap2DROS object to read the occupacy grid being published on the /map topic. How do I modify the values of the global_frame and the robot_base_frame parameters for the costmap_2d::Costmap2DROS object? I tried to go through the documentation. But, I didn't really get it.

答:
A simple consumer of Costmap information is not expected to use this class. The expectation is that you subscribe to the costmap topic, and receive nav_msgs/OccupancyGrid messages. The data field of this message contains a 2D grid of cost for each cell. For this message, the 2D grid has been flattened to 1D, so you use the height and width metadata to recreate the 2D coordinates.

Typically the costmap_2d::Costmap2DROS class is used internally by move_base to buffer data, merge updates and do other maintenance stuff. Consumers of costmap data don't perform these operations. Inside move_base, the frame_ids are obtained from the ros parameter server - a simple consumer doesn't modify these values.


问:
Minimum distance that can be measured using Rplidar A1M8
can you please explain what is the minimum distance that can be measured using RPliadr A1M8</p>

答:
From Slamtech's specifications for RPLIDAR A1, you can see that the measuring range is 0.15 m to 12 m.

Normally, the minimum range is related to the light pulse length transmitted, and also the optics (separation and parallax between emitter and receiver).


问:
How to calculate Exponential coordinates of end_effector from Transformation matrix
I want to know Exponential coordinates of end effector $\text{S}\theta$(6-vector) from end effector transformation matrix. I calculated the transformation matrix of the end effector from the forward kinematics. And I took the logarithm of Transformation to get ${[S]\theta} ∈se(3)$.

The question is, is ${[S]\theta}$ the same as ${[S\theta]}$? If so, if I solve the skew-symmetric matrix representation of ${[S\theta]}$, is it an exponential coordinate? If not, how do we get the exponential coordinates?

答:
The question is, is $[S]θ$ the same as $[Sθ]$

Going by your notation of $[S]\theta\in se(3)$, yes. $se(3)$ is the Lie algebra of the group and $[S]$ forming the matrix form for the spatial vector $S$, yes, multiplication by scalar $\theta$ would still keep you within the Lie algebra because it is a vector space.

From a conceptual lens, while orientations themselves have multiple representations, the derivative of an orientation has one canonical form in this Lie algebra space, and what we're doing when we represent an orientation through this $se(3)$ vector, we're representing it like a normalised velocity from the identity oreintstion in that direction of the end orientation, integrated for $theta$ time (making $[S]\theta$), but equivalently it's the same as a non normalised velocity for unit time (or $[S\theta]$). Like how a displacement could be represented as a normalised velocity vector and a time taken, or as a non normalised velocity vector for 1 second.

If not, how do we get the exponential coordinates?

It's not clear to me what exponential coordinates mean in your context. $se(3)$ is the Lie algebra as I described. The concrete representations of the transforms (homogenous matrices, quaternions, etc.) would be group elements (part of $SE(3)$) and you would get them through the exponential map for the group: $\exp(\cdot) : se(3) \rightarrow SE(3)$


问:
How to Access Robot Fields Inside a Webots-ROS2 Plugin?
I'm running Webots R2023a where I have a robot node marked as Supervisor in Webots world (*.wbt file) to be controlled by an external node in ROS2 network. When writing a webots-ros2 plugin, I'm faced with an issue where I cannot access robot fields inside the plugin implementation file.

The init function of the plugin provides a WebotsNode object which inherits a ROS2 node:

```<code>init(webots_ros2_driver::WebotsNode *node, std::unordered_map<std::string, std::string> &parameters)
</code>```

However, I need a reference to the current robot as a webots::Supervisor object so I can retrieve nodes and fields of this robot (using the Supervisor API methods) to have full control over various aspects of the simulation.

Is it possible to get a handle to the robot?

答:
Since version 2023.0.0 of the webots_ros2 package, the Robot node (or Supervisor or Driver) cannot be accessed anymore. This is due to the fact that the webots_ros2_driver package (which defines the WebotsNode) doesn't use the C++ API of the libController anymore. Instead it now uses the C API.

Therefore, only the C API can now be used in plugins. You can take a look at the following tutorial: Creating a Custom C++ Plugin which uses the C API to access the robot devices and apply velocities to its motors.


问:
What mechanical parts can be attached to a 28BYJ-48 stepper motor?
Sorry I am asking a mechanical question here, but, after all, where else people have experience with using motors? If there is a better forum for this, please do guide me.

Everywhere I've seen online, the stepper motor 28BYJ-48 is used in tutorials, to rotate on its own, or, at most, to spin a clothes pin attached to it. I am trying to get Arduino to work for my 10 year old kid. He's got the motor rotating, now what? How does he attach anything to it?

Don't laugh, I made him a wheel out of a raw potato. He is happy with it now. Where can I find any guidance as to what to do next?

答:
As others have already stated, the shaft in a 28byj-48 is a "5mm diameter round shaft with 2 drive flats".

(Just for reference, the shaft diameter on a 28BYJ-48 is the same as on Nema 11, Nema 14 and Nema 17 stepper motors in case you ever want to upgrade your stepper motor!)

One option that has already been suggested is to use a "5mm mounting hub" (also known as a "set screw hub"). Pololu make an "all-metric" item (both the mounting holes and the grub screw/set screw are metric.) (Web Archive link) You can buy these from ebay - in the UK, a pack of 2 is approximately 8 GBP.

An alternative is to look for a "5mm  flange coupling". These are also available on ebay and start at approx 4 GBP. (I have just received mine and it's perfect for my project.)

OwnerDisplayName: Таня Т.


问:
Visualize state of gamepad/joystick in ros in rviz or in an Image?
A non-ros but python or C++ solution like https://github.com/KernelZechs/open-joystick-display (this video shows it off) is what I was originally looking for, and I'll possibly still that use if it immediately works- but it is no longer being maintained and given the language and build process I'm unlikely to be able to quickly make any needed alterations (or discern which is best of all the forks).

But the other route is to do something quickly in a ros node from scratch using the Joy message as an input topic, and publish a crude image or turn all of the Joy message into JointStates and combine with a simple gamepad urdf (and maybe find a free mesh file of an xbox controller to use with it later)- unless something like that already exists?

答:
I serched everywhere something like this too.

I know that it's not the exact thing you ask, but I would suggest using jstest-gtk as quick & dirty visual representation of your joystick input.

If you want a more ROS-oriented application, try to code a rqt plugin on the lines of rqt_virtual_joystick.

If this is not enough and want more control, I would start coding a graphical application reading directly the serial input of your device.


问:
Is configuration space same as joint space?
For robotic manipulator like the one on the picture:

are the configuration space and joint space equivalent? I am trying to understand difference between the two...

答: Configuration space refers to the set of all possible configurations of the end-effector, the tool frame in this case. Joint space is the set of joint parameters which describe the overall configuration of the robotic manipulator. Forward kinematics are used to map the Joint space to the Configuration space and Inverse kinematics do the opposite.


问:
ROS across computers connected with low-bandwidth bit steams
I am at the early stages in a design project which will involve a complex robotic system operating mostly autonomously (payload) with a very flaky downlink to a ground station.

ROS seems to be useful for the payload side of the project but I am uncertain if ROS is capable of setting up a configurable downlink for the ground station. The message bandwidth within the payload will far exceed the bandwidth capability of the downlink and thus we must be able to: decimate, down-sample, compress, and nitpick topics to broadcast across the radio-link. In addition, this must be configurable in real-time to accommodate the changing signal integrity. The ground station also needs to be able to send commanding to the payload with ideally some form of acknowledgment.

In the past this was achieved using fully custom serialization code which allowed the ground station to request certain fields at given (configurable) resolutions. Since the radio links are usually simple, we did not implement any form of acknowledgment (think UDP) and error correction was also left out due to complexity.

My question is: is there a way to configure ROS messages for decimation/down-sampling and compression? Can these messages be piped across a "custom" radio link (one way bit streams)?

My searches on the topic have not given me anything viable so far (maybe I am using the wrong search terms? I am fairly new to ROS...) so I am looking for anything from an answer to a direction to take my research.

答:
If you have an IP based link ROS can generally be configured to do what you want over that link. You can write nodes that will implement the logic you need to decimate, downsample, compress, or do whatever you want. And then only subscribe to those topics on the other end of the link. You should setup the networking so that only the relevant topics flow over that network interface.

If you can assume it's more like a serial link, another common way to go over lower bandwidth links is via Micro-ROS which is optimized for serial types of links.

However if your link gets down to the range of highly custom, broadcast only that's not a use case where ROS is designed to work and I don't think that you'll find anything general purpose for that case as it's very specific to your system doing customized partial serialization. If you're optimizing to that level general purpose frameworks likely aren't the right tool.


问:
Omnidirectional kinematic model in robot_localization's EKF
I am looking for a more detailed mathematical background of robot_localization's kinematic model used for nonlinear kalman filtering.

From the documentation, the robot state used is:

$$\mathcal{X} = [p^W, q^W, \dot{p}^L, \dot{q}^L, \ddot{p}^L]$$

Where $W$ is the world reference frame and $L$ the robot local reference frame.

Of course,

$p^\top = [x,y,z]$ is the 3d position.

$\dot{p}$, $\ddot{p}$ its first and second time derivative (vel, acc).

$q^\top = [\phi, \psi, \theta]$ are the usual roll, pitch and yaw euler angles.

$\dot{q}$ its time derivative.

By looking at the code for the position transition function, it seems it's implemented something of this fashion:

$$ p_{t+1}^W = p_t^W + \dot{p}_t^W\Delta t + \frac{1}{2} \ddot{p}_t^W \Delta t^2,  \qquad $$

In this equation, linear velocity $\dot{p}$ and acceleration $\ddot{p}$ vectors are rotated from the robot's state variables, i.e. via a rotation matrix from robot frame $L$ to world frame derived from the estimated orientation of the robot $\hat{q}$, .

$$ p_{t+1}^W = p_t^W + R_t^{WL}(\hat{q}) \dot{p}_t^L\Delta t + \frac{1}{2}R_t^{WL}(\hat{q}) \ddot{p}_t^L \Delta t^2$$

The other transition funtions for the other states are:
$$\dot{p}_{t+1} = \dot{p}_t + \ddot{p}_t\Delta t$$
$$\ddot{p}_{t+1} = \ddot{p}_t$$
$$\dot{q}_{t+1} = \dot{q}_t$$

However I am missing the reasoning behind euler angles $q$ evolution from angular rates $\omega$.

At first, I thought euler angles were simply integrated from a gyroscope's angular rates

$$ q_{t+1}^W = q_t^W + \omega_t^?\Delta t $$

But clearly it's not what's being used there.

I cant' explain these relations:

```<code>    transferFunction_(StateMemberRoll, StateMemberVroll) = delta;
transferFunction_(StateMemberRoll, StateMemberVpitch) = sr * tp * delta;
transferFunction_(StateMemberRoll, StateMemberVyaw) = cr * tp * delta;
transferFunction_(StateMemberPitch, StateMemberVpitch) = cr * delta;
transferFunction_(StateMemberPitch, StateMemberVyaw) = -sr * delta;
transferFunction_(StateMemberYaw, StateMemberVpitch) = sr * cpi * delta;
transferFunction_(StateMemberYaw, StateMemberVyaw) = cr * cpi * delta;
</code>```

Thanks for the help!

答:
I forgot that Euler angle rates $\dot{q}$ are of course NOT EQUAL to body angular rates $\omega$.
$$\dot{q} \neq \omega$$
Their relation, given RPY rotation convention, is

$$
\begin{bmatrix}
\dot{\phi}\\
\dot{\psi}\\
\dot{\theta}
\end{bmatrix} =
\overbrace{\begin{bmatrix}
1 & \sin(\phi) \tan(\psi) & \cos(\phi)\tan(\psi)\\
0 & \cos(\phi) & -\sin(\phi) \\
0 & \frac{\sin(\phi)}{\cos(\psi)} & \frac{\cos(\phi)}{\cos(\psi)}
\end{bmatrix}}^{T}
\begin{bmatrix}
\omega_x\\
\omega_y\\
\omega_z
\end{bmatrix}
$$

The derivation implemented in the code is correct.

Although numerically unstable for pitch $\psi = \pi/2$
, should be fine for UGVs..

Calling $T$ this matrix, we have

$$q_{t+1}^W = q_t^W + T\omega_t^L \Delta t$$

However, robot_localization does NOT sample $\omega$ with a gyroscope.


问:
How to add a new sensor to webots ros2 plugins?
I was wondering how can add a new node type to activate under the <device> tag in the URDF file.
Looking in the webots_ros2 repository, I found that is required to create a header and implementation file accordingly with the C++ plugin tutorial.

Can anybody give me some guidance to include this?
I'm interested in using the Emitter and Receiver nodes.

Thank in advance

答:
The first possibility is to add the new sensors (Emitter and Receiver) to the list of supported devices in the webots_ros2_driver package. This would require modifying or enhancing the source code of the package. This would allow you to use the sensors in your URDF files without the need for a custom plugin. Please feel free to open a PR with your contribution if you decide to use this solution. You could use other already implemented devices (webots_ros2_driver/src/plugins) as examples.

The second possibility is to create a custom plugin that uses the C controller API to access the devices, configure them and get their values. This would require writing a custom plugin that interfaces with the Webots simulation software. You would then need to add the plugin to the URDF file.

You can create your custom plugin in C++ or Python:

Creating a Custom C++ Plugin

Creating a Custom Python Plugin

If you use the plugin in C++, make sure you use the C controller API as the C++ controller API cannot be used anymore since version 2023.0.0 of the package.


问:
How do the PID parameters (Kp, Ki, and Kd) affect the heading of a differential driving robot when they are increased individually?

Question: A PID controller has three parameters Kp, Ki and Kd which could affect the output performance. A differential driving robot is controlled by a PID controller. The heading information is sensed by a compass sensor. The moving forward speed is kept constant. The PID controller is able to control the heading information to follow a given direction. Explain the outcome on the differential driving robot performance when the three parameters are increased individually.

This is a question that has come up in a past paper but most likely won't show up this year but it still worries me. It's the only question that has me thinking for quite some time.
I'd love an answer in simple terms. Most stuff i've read on the internet don't make much sense to me as it goes heavy into the detail and off topic for my case.

My take on this:

I know that the proportional term, Kp, is entirely based on the error and that, let's say, double the error would mean doubling Kp (applying proportional force). This therefore implies that increasing Kp is a result of the robot heading in the wrong direction so Kp is increased to ensure the robot goes on the right direction or at least tries to reduce the error as time passes so an increase in Kp would affect the robot in such a way to adjust the heading of the robot so it stays on the right path.

The derivative term, Kd, is based on the rate of change of the error so an increase in Kd implies that the rate of change of error has increased over time so double the error would result in double the force. An increase by double the change in the robot's heading would take place if the robot's heading is doubled in error from the previous feedback result. Kd causes the robot to react faster as the error increases.

An increase in the integral term, Ki, means that the error is increased over time. The integral accounts for the sum of error over time. Even a small increase in the error would increase the integral so the robot would have to head in the right direction for an equal amount of time for the integral to balance to zero.

I would appreciate a much better answer and it would be great to be confident for a similar upcoming question in the finals.

答:
(Kp, Ki, and Kd) are the three parameters or gains used in a PID controller. Each of these gains contributes to the overall control action and helps the controller achieve its desired setpoint or reference value.

1.Proportional gain (Kp): This is the gain that applies a control action proportional to the difference between the setpoint and the actual process variable. A higher Kp results in a stronger control action and faster response to changes in the process variable. However, too high of a Kp can cause the system to become unstable or lead to overshoot.

2.Integral gain (Ki): This is the gain that adds up the errors over time and helps eliminate steady-state errors. Ki acts as a correction factor to adjust the control signal based on the accumulated error. A higher Ki results in a stronger correction, but it can also cause the system to become sluggish or unstable.

3.Derivative gain (Kd): This is the gain that measures the rate of change of the error and applies a correction based on that rate. Kd acts as a damping factor to reduce overshoot and improve the response time. A higher Kd results in stronger damping, but it can also amplify noise in the system.

Together, these three gains work in concert to provide a control signal that can regulate the process variable and maintain it at the desired setpoint. Tuning the values of Kp, Ki, and Kd is an essential step in designing a PID controller that can achieve stable, accurate, and responsive control.


问:
Light weight one axis hinge name/recommendation
I'm attempting to build a crow that can stay upright even when its perch tilts.  For that I need to have some single axis hinges (not u-joints).  I'm using 3mm rod for my internal supports and am hoping to find some light weight hinges that are sized appropriately and can take a lot of duty cycles and still remain fairly friction free.

I've included an image of one I'm thinking of but I can't for the life of me find the name of it.  Does anyone knew the name so I can find one on amazon or McMaster Carr?  (I could make them myself, but time is short and I have plenty of others things to do first)

Is there a better choice?

答: Here is the kind of hinge you're looking for on McMaster, and it takes 8-32 threaded rod, but I'm not understanding how the upper platform doesn't just fall over in your drawing, so I can't comment on alternatives.</p>


问:
Differential Inverse Kinematic Controller ROS
Inverse differential Kinematic - Problem with Orientation

Hey guys,

currently I am working to control my UR-Robot. My goal is to control the robot with inverse differential kinematics :
1.)  vel_q = J^-1 * (x_goal - x_act)

I am able to get the actual position via Moveit Service GetPositionFK. I translate the quaternion to euler with tf_transformation.

Furthermore I subscribe and publish the jacobian matrix with movegroup_commander.

My problem is that the Robot is moving (gazebo) to the target position (x,y,z) but does not find the correct orientation. The result is that the robot goes literally crazy.

Can somebody tell me maybe what is my mistake or what can I improve? Is the method x_target - x_act = error wrong? Should I maybe use x_act - x_previous / t_act - t_previous to calculate the tcp velocity?

Thanks in advance!

答:
As discussed here, the orientation error is not simply one orientation minus another. It is best to convert your orientations into rotation matrices (which can be obtained from both Euler angles and quaternions), and use the following formula:

$$ \mathbf{e}_{o} = 0.5 \cdot  \sum^{3}_{i=1} \mathbf{r}_{a,i} \times \mathbf{r}_{d,i} $$

where $\mathbf{r}_{a,i}$ represents the $i^{\text{th}}$ column of the rotation matrix $\mathbf{R}_{a}$ representing the current (actual) orientation, $\mathbf{r}_{d,i}$ represents the $i^{\text{th}}$ column of the rotation matrix $\mathbf{R}_{d}$ representing the goal (desired) orientation, and $\times$ represents the cross product. So, the error vector is a 6 by 1 vector where the first three entries are the differences between the current and desired x, y, and z positions - and the last three entries are $\mathbf{e}_{o}$.


问:
Lookup would require extrapolation into the future on the same machine
I get this error when trying to view my RPLidar A2 scan in rviz2. It’s on a differential drive robot controlled using arduino using Articulated Robotics’ code that I quickly ported to Humble, alongside the controller manager code. I am running everything on a laptop, no separate machines, on ROS2 humble.
It’s connected to the base_link via the URDF but I tried a static transform publisher but the same thing occurred.

It shows perfectly fine when viewing the base_link frame, but with Odom the issue occurs.

Oddly enough when I use a YDLIDAR G4, it works intermittently but it loses transform often. When I use the rplidar it doesn’t work at all. This is my first time using ros2 so I am confused

```<code>[ERROR] [1668990540.121377402] [rviz2]: Lookup would require extrapolation into the future. Requested time 1668990540.179102 but the latest data is at time 1668990540.113331, when looking up transform from frame [laser_frame] to frame [odom]
</code>```

答:
I'm assuming that you're using this REPO for the ros2 humble rplidar.

I think the reason the scan is not showing up in rviz is because the timestamp in the header for the scan msg is different than the actual acquisition time of the first ray in the scan. Thus, using the same start_scan_time as the scan_msg.header.stamp will fix your problem

Here's what you need to add/change in the source code of this rplidar repo

file: rplidar_ros2/src/rplidar_node.cpp

Add start as a parameter to publish_scan method

Change header for the scan msg

```<code>line 142
void rplidar_node::publish_scan(
  const double scan_time, ResponseNodeArray nodes, size_t node_count)
{
....
line 149
scan_msg.header.stamp = this->now();

</code>```

Change it to this

```<code>line 142
void rplidar_node::publish_scan(
  const double scan_time, rclcpp::Time start, ResponseNodeArray nodes, size_t node_count)
{
.....

line 149
scan_msg.header.stamp = start;
</code>```

Change the locations publish_scan is called to include start_scan_time

```<code>line 368
publish_scan(scan_duration, start_scan_time, std::move(angle_compensate_nodes), angle_compensate_nodes_count);

line 386
publish_scan(scan_duration, start_scan_time, std::move(valid), end_node - start_node + 1);
    }

line 393
publish_scan(scan_duration, start_scan_time, std::move(nodes), count);
</code>```

file: rplidar_ros2/include/rplidar_node.hpp

Change the method declaration to include rclcpp::Time start

```<code>line 87
void publish_scan(const double scan_time, rclcpp::Time start, ResponseNodeArray nodes, size_t node_count);

</code>```

Hope this helps.

Body:
I'm assuming that you're using this REPO for the ros2 humble rplidar.

I think the reason the scan is not showing up in rviz is because the timestamp in the header for the scan msg is different than the actual acquisition time of the first ray in the scan. Thus, using the same start_scan_time as the scan_msg.header.stamp will fix your problem

Here's what you need to add/change in the source code of this rplidar repo

file: rplidar_ros2/src/rplidar_node.cpp

Add start as a parameter to publish_scan method

Change header for the scan msg

line 142
void rplidar_node::publish_scan(
  const double scan_time, ResponseNodeArray nodes, size_t node_count)
{
....
line 149
scan_msg.header.stamp = this->now();

Change it to this

line 142
void rplidar_node::publish_scan(
  const double scan_time, rclcpp::Time start, ResponseNodeArray nodes, size_t node_count)
{
.....

line 149
scan_msg.header.stamp = start;

Change the locations publish_scan is called to include start_scan_time

line 368
publish_scan(scan_duration, start_scan_time, std::move(angle_compensate_nodes), angle_compensate_nodes_count);

line 386
publish_scan(scan_duration, start_scan_time, std::move(valid), end_node - start_node + 1);
    }

line 393
publish_scan(scan_duration, start_scan_time, std::move(nodes), count);

file: rplidar_ros2/include/rplidar_node.hpp

Change the method declaration to include rclcpp::Time start

line 87
void publish_scan(const double scan_time, rclcpp::Time start, ResponseNodeArray nodes, size_t node_count);

Hope this helps.


问:
How to use hector slam autonomous navigation without odometry?
I have a robot that i want to make autonomous, i will try to get a rplidar A1 for making things easy on the mapping through the HECTOR SLAM package but i want to use autonomous navigation, i only have an mpu6050 and the Lidar sensor and no odometry, anyone has an example of this to me?</p>

答:
You can use Hector SLAM without Odometry and IMU data as well. The ONLY prerequisite is that you have a LIDAR that publishes data.

The Hector SLAM algorithm works by using Laser Scan matching, and then builds the world based on the points that it receives from the LIDAR. By matching the points from consecutive LIDAR frames, it is able to ascertain the transformation between the frames and therefore also calculate its own odometry (based on changes in it's POSE).

You can easily clone the repository, setup your robot with the correct frames and use information from the A1 RPLidar. There are quite a few tutorials on getting this working without a hassle that already exist on YouTube and other sources :)

Wish you the best of luck.


答:
In order to answer my own question Configuration space and Joint space must be defined.

Configuration space of a rigid body is a minimum set of parameters that can determine position of each point in that body or Configuration space is set of all possible configurations of that body.

Configuration space of the end-effector is set of all possible positions and orientations of the end-effector, while Configuration space of the robot is the set of all possible positions and orientations for each rigid link of the robot. Shape of the Configuration space depends on which rigid body it refers to.

Joint space is set of all joint parameters. In case of the robot in the picture those are its joint angles.

For the robotic manipulator in the picture it can be assumed that its configuration is completely determined by its joint parameters. It can be said that Configuration space and Joint space are equivalent for this robot (give or take few mathematical definitions of equivalent).

Title: Is configuration space same as joint space?

Body:
For robotic manipulator like the one on the picture:

are the configuration space and joint space equivalent? I am trying to understand difference between the two...


问:
Staubli TX2-140 URDF
Where coul I find the URDF for Staubli TX2-140? I want to insert it in ROS and Gazebo and also use Peter Corke python toolbox to model it? How can I implement it in the toolbox?

Thanks.

答: The only ROS support I am aware of was for the Staubli CS8C with a RX160 robot arm. The TX2-140 runs on a CS9 controller. I am not aware of any ROS support for the TX2-140 arm or the CS9 controller. Staubli has never officially support ROS or Gazebo.</p>

Title: Staubli TX2-140 URDF


问:
Will increasing voltage on brushless DC motor increase torque, if speed is kept constant?
I have a brushless DC motor that takes as input voltage 12-60V. If I want to drive the motor at a constant RPM, will increasing the voltage also increase the torque? For example, if I drive the motor at 60RPM with 24V and also 60RPM with 48V, would the motor at 48V have higher torque even though it's driving at the same speed?

Edit: If that's the case, is there a way (or equation) to approximate the voltage-torque relationship if RPM is kept constant? I would like to use a 24V source, but if there is a linear relationship (torque would double if voltage doubles), then maybe I can consider using a 48V source.

答:
It depends on various other factors as well. If the motor outputs 60RPM @24V under load, given the motor is rated for 12V - 60V and the load is kept the same, then by doubling the voltage from 24V to 48V you should definitely see an increase in torque output since it would leave the system with twice the amount of current available for the motor to consume. Now, the question  is "Is your motor rated for such a high current draw?"

The information provided in the question is not enough to draw any hard conclusions to guarantee this result. Because Speed, Voltage, and Torque are interdependent.

Eg:

Increase in Voltage, increases in the motor speed

Increase in Voltage, increases the ability to draw more current

Increase in Current, increases the torque output

Increase in Torque, decreases the Speed (as torque approached stall torque, speed is effectively zero)

You also have efficiency, and power which have non-linear relationships with respect to torque

From the graph, you can get an insight into the speed vs torque curve relationship with respect to load, current, and power. So if you get your motor's datasheet you should be able to understand your motor better by inferring the relationship curves.

Also, if you look into the DC motor speed control techniques, the voltage applied across the motor determines the speed for the most part. So if you increase the motor voltage then it will also increase the speed and if the motor is rated to draw twice the current then you would also see an increase in the output torque.

Hope this answer helps point you in the right direction.


问:
Powering 3 MG996R servos
I'm building a robotic arm with 3 MG996R servos using Arduino Uno R3 board. I'm using this 16 channel servo motor driver for the project. I'd like to use an AC-DC adapter to power the servos. Is that possible? If not what can I do?

PS: I'm a mechanical engineer who's got no idea about electronics (at least for now).

答:
Let's say you operate the servo at 5V nominal, then it can draw up to 3A and 3A being the stall current for a typical MG996R servo.

So you need at least 9A, to account for inrush current let's add 1.6x as a safety factor to the current requirement (which is 14.4A), and hence an AC to Dc power supply of 5V @15A (Approx) should be adequate enough to run 3x MG996R servos.

The power supply in the comments section is unreasonably overkill and expensive. I would suggest going with adapters like this which are cheap and easy to find on amazon.

Note: Also make sure to check the max. current per channel capability on your controller board to support at least 3A draw.

Hope this answer helps in answering your question.

Title: Powering 3 MG996R servos


问:
Want to make an URDF starting from a robot .STL
I want to make an URDF from a Staubli TX2-140. I have the .STL of the all arm. Does someone know how to separate it to get individual links .STL?

Thanks

答:
Just open it with any graphics tool (Blender gets the job done, but also FreeCad is an option), select each link's point cloud and save them as separate .stl files.

This is of course not perfect and very error prone! If you are building a urdf robot model I would suggest using an automated export tool on a .step/.cad file for the best results. There are plenty of options, for these tools, just search online.

In this way you have already the link groups assemblies and hopefully even materials to export mass values and inertia tensors.

A later step is to get the built .urdf and converting to .xacro for better extensibility with Gazebo and other ROS tools.


问:
Why does Webots 2022b not support VRLM97?
I am creating a complex robot and I do not know what is better:

Use Webots 2023a and use CADshape. The .DAE doesn't look great because it's a mesh.

Use Webots 2021b and import VRLM97. It looks much better.

Does this decision impact the performance of the simulation? I will use 8 robots at the same time.

I would appreciate any help.

答:
The VRML97 import feature was removed from Webots R2023a because it is replaced by the Mesh and CadShape nodes.

Referring to an external CAD file is way better than including it inside the world or proto file for several reasons:

It is easier to maintain the shapes: you can edit/regenerate the CAD file independently of your simulation worlds or proto files.

It makes the world and proto files lighter, more readable and easier to maintain.

If your DAE file doesn't look great because it is a mesh, I would recommend you to use the Mesh node instead of the CadShape node to import it. This way, you will be able to set a nice appearance for it in Webots. See for example metal or plastic appearances available in Webots.

You may also want to use the indexMaterial field of the Mesh node to be able to specify different materials for every part of your CAD model.

Webots version R2023a is the best choice in terms of performance and features compared to R2021b. So, I would definitely recommend using the newest version.

Disclaimer: I am a Webots developer working at Cyberbotics.


问:
Webots hinge joint, physics issue
I am in the process of carrying out my thesis, I am using Webots software to measure the displacement of linear actuators and then carry out PID control for a manipulator of an ROV which is based on an excavator design, I have reconstructed the arm using shapes and transforms, as imported CAD models caused errors.

Once the parts were reconstructed then I connected everything with hinge joints with appropriate anchor coordinates, then by applying physics with actual mass of each component acquired from data sheets I tested the functionality, every time I added and connected each part.

Upon adding the arm actuator, connecting it with appropriate anchor coordinates which I double checked, then applying physics the actuator started to act unnatural, instead of falling down with the arm, as there is no force applied to the actuators yet it moves in the other direction. I have also noticed that the other actuators and their hinges are not at the correct anchor points.

I have tried to fix it but nothing seems to work apart from changing the gravity at which point the hinge joints stay 'semi-fixed', once I move the actuators it seems like the joints are fixed on a string or a spring and the actuators lift above the boom part and then the boom follows.

This is my first time using a robotics simulation software so it might just be lack of experience and knowledge, or might it be some parameter and or the large weight?

I have recorded a quick video as well showing the issue.

答:
Your model needs some calibration because it uses heavy masses. By default Webots can handle lightweight models properly, but if you are using an heavyweight model, you should adapt some parameters in particular:

The WorldInfo.CFM value should be reduced and the WorldInfo.ERP should be adapted, see explanations here.

If you use ContactProperties, you should also adapt the softCFM/softERP there.

You may also need to adjust some parameters with joints, such as the spring and damper properties and the stopERP and stopCFM of the HingeJointParameters.

Disclaimer: I am a Webots developer working at Cyberbotics.

Title: Webots hinge joint, physics issue


问:
When express a first-order system as a block diagram with feedback?
I've seen in many places that a first-order system is depicted as a block diagram using an integrator. For example, this figure comes from https://www.tutorialspoint.com/control_systems/control_systems_response_first_order.htm

What is the rationale for using this depiction rather than just using the transfer function bock itself as in (https://electricalacademia.com/control-systems/block-diagrams-in-control-systems/):

答: Logically, there is no difference, of course. However, when it comes down to implementation, engineers tend to stick to basic building blocks, both in terms of SW libraries and HW components. Among all the basic building blocks, the integrator is the most important in the context of dynamical systems.</p>


问:
ROS buildfarm - Debian Buster Binary Job Failure (noetic)
I recently made a release of image_transport_plugins in ROS noetic, but the noetic debian binary builds have started failing afterwards.

Looking at the logs, the issue seems to be apt coming from an invocation of apt-get install ... catkin on the BuildFarm, but I can't quite figure out why catkin is getting installed rather than ros-noetic-catkin.

All logs have the following problem:

```<code>01:20:43 Invoking 'apt-get install -q -y -o Debug::pkgProblemResolver=yes apt-src catkin debhelper image-transport-tools libcv-bridge-dev libdynamic-reconfigure-config-init-mutex-dev libgmock-dev libgtest-dev libimage-transport-dev libogg-dev librosbag-dev libstd-msgs-dev libtheora-dev pluginlib-dev python3-cv-bridge python3-dynamic-reconfigure python3-rosbag python3-std-msgs ros-message-generation ros-std-msgs'
01:20:43 Reading package lists...
01:20:44 Building dependency tree...
01:20:44 Reading state information...
01:20:44 Starting pkgProblemResolver with broken count: 5
01:20:44 Starting 2 pkgProblemResolver with broken count: 5
...
</code>```

Does anyone know, or have come across similar issues?

Buildfarm failures Logs:

Nbin_dbv8_dBv8__theora_image_transport__debian_buster_arm64__binary
Nbin_dbv8_dBv8__compressed_image_transport__debian_buster_arm64__binary
Nbin_dbv8_dBv8__compressed_depth_image_transport__debian_buster_arm64__binary
Nbin_db_dB64__theora_image_transport__debian_buster_amd64__binary
Nbin_db_dB64__compressed_image_transport__debian_buster_amd64__binary
Nbin_db_dB64__compressed_depth_image_transport__debian_buster_amd64__binary

答:
Looking at the ros/rosdistro PR which included this release, the bloom version used was 0.10.7 which is quite old compared to the current 0.11.2 version from the time of the release PR.

I have not been able to determine what is causing this with older bloom versions on current distributions but using the current version of bloom to re-run bloom-release ...  resolves it.


问:
How to stop writing to a bag file when using the rosbag2_py API?
I'd like to modify this example of recording a bag file from a ROS node written in Python to be able to effectively start and stop recording using a service call. My thought is I could create self.writer = rosbag2_py.SequentialWriter() in my service callback, and add some logic in the callbacks for the topic subscriptions to ensure that it will only try to write the data if self.writer exists and is ready to be written to.

I think what I describe should work for starting recording, my question is how will I handle safely stopping the recording, such that I can subsequently start recording a new bag file again with a subsequent service call. Since there is an open function on SequentialWriter, I was expecting to see a close or flush function, but I don't see such functionality in the exposed Python API. My guess then is that maybe this isn't working like how I normally think of files being "open" in Python.

So, what I would like to know: what is the correct way to "stop" recording when using the Python API? Is it sufficient to simply call self.writer.open() with different StorageOptions that assign a new uri to save to? If I do that, am I somehow leaving "open" resources dangling?

UPDATE (1/2):
It seems there is in fact a close function on SequentialWriter, but only in the C++ API and it's not offered yet in the Python bindings. There is an issue on GitHub that gives some awareness to this.

UPDATE (2/2):
I wrote what I described in C++, and me calling the close function on SequentialWriter just caused my program to crash without any error. I ended up finding the package system_data_recorder that implements the functionality I needed of being able to programmatically start/stop bag recording. They use node lifecycles to manage start/pause/resume/stop recording and have the added benefit that they can copy incremental chunks of the bags to a copy location so that you can incrementally save your data to a backup. Very nice!

答: One possible approach (that was often done in ROS1 since there wasn't a stable rosbag API) would be to instead use Python subprocess to call the ros2 bag record command as you would from the command line - it is then very easy to send a ctrl-C to the subprocess.


问:
HC-05 not responding to AT Commands from Raspberry Pi Pico
I'm trying to write AT commands to HC-05 module using Raspberry Pi Pico and MicroPython, nothing complicated. But for some reason my module doesn't respond. It works well in data mode and I'm able to send/receive messages from my phone via BT connection.

I've tried doing the same thing but using Arduino and my HC-05 was working. The module is blinking with interval of 2Hz so it's clearly in command mode.

Changing Baud Rate doesn't change anything.

Connecting TX to TX and RX to RX causes the first message to be b'\x00', otherwise nothing is returned.

My Code:

from machine import Pin,UART #importing PIN and PWM
import utime #importing time

#Defining UART channel and Baud Rate
uart = UART(0, 38400)

while True:
    command = input("COMM>")

    uart.write(command)
    utime.sleep(1)  # to make sure that HC-05 has time to respond
    print("checking", uart.any())

    if uart.any(): #Checking if data available
        data=uart.read() #Getting data
        data=str(data) #Converting bytes to str type
        print(data)
```

Ultimately I want to use AT+INQ to retrieve data about RSSI of nearby devices.

答:
AT commands require '\r\n' for input. Try replacing uart.write(command + '\r\n')
In addition, for better viewing, converting bytes to str type:
data=str(data, 'UTF-8')


问:
ROS2 AMCL vs robot_localization
When using ROS2 with Nav2, what function does AMCL and robot_localization serve?

Do both of them estimate the robot position and publish the odom -> base_link transform? If yes, don't they conflict each other?

答:
robot_localization is somewhat poorly named - at this point it is mostly an Extended Kalman Filter (EKF), usually it is used to merge multiple sources of odometry information (most commonly, IMU and wheel odometry, although it also provides some tools for GPS). Thus, robot_localization is used to create the odom->base_link transform.

AMCL is actually localization software - it provides the map->odom transform using a particle filter to determine where the robot is in within a map (usually using a planar laser scanner and the odometry information).

Therefore, these two can actually work together - by combining multiple sources of odometry information you can minimize the odometry drift that occurs in your odom->base_link estimation. Then AMCL can be used to correct for that drift by keeping the robot properly localized within the map.

Title: ROS2 AMCL vs robot_localization


问:
Define system forward dynamics with sympy
I would like to model the dynamics of a robot via the usual discretized system of equations

$$
x_{k+1} = f(x_k, u_k) \qquad x\in\mathbb{R}^{n_x}, \quad f:\mathbb{R}^{n_x}\times\mathbb{R}^{n_u} \to \mathbb{R}^{n_x}
$$

via sympy python package, but in the documentation there are only examples of scalar functions $f:\mathbb{R}^{n_x}\times\mathbb{R}^{n_u} \to \mathbb{R}$.

Are there any shortcuts besides defining a sympy.Matrix of functions?

答:
It's not clear from the question why you can't represent the system of equations using scalar functions.

A system of equations is a set of scalar functions where the solution is the intersecting point(s) between the functions. Therefore, you can model and solve them using sympy.

possible approached can be found here and here. Maybe one of the links would help you with your task.


问:
RC Helicopter Connect with computer
I am planing to control my RC helicopter with my computer. I have experience of programming in .Net. Could we use .Net to control RC helicopter?
From where can I start this project?</p>

答:
Yes you can do it and there are a number of different ways
as far as the language you choose its your choice because you can manipulate serial ports with any language. Think of an RC Heli as another computer. What comes to mind is you just need a medium for communication. Choosing what medium of course depends on how much data you want to send and receive and what range you want.

Example:

Bluetooth: if you need only few meters range and small amount of data

RC Transmitter Another way is to connect the RC transmitter to your computer directly. See this blog Post

Wifi can also be used to communicate see this Post

If you need more help give more details what you intend to do.

Title: RC Helicopter Connect with computer