Both sides previous revisionPrevious revisionNext revision | Previous revision |
turtlebot:adventures:sensing101_hints [2015/10/06 17:33] – pvela | turtlebot:adventures:sensing101_hints [2024/08/20 21:38] (current) – external edit 127.0.0.1 |
---|
==== Bumper Events ==== | ==== Bumper Events ==== |
| |
The button callback code should be pretty self-explanatory. The main thing is to create your own subscriber, then to use ''rostopic echo'' and ''rostopic type'' to understand the structure of the bumper events enough to create a properly modified version of the button callback function (the direct link to some github code also provides this information and defines some constants that might be of interest). This code should then be re-used and modified for the next learning task. | The button callback code should be pretty self-explanatory. The main thing is to create your own subscriber, then to use ''rostopic echo'' and ''rostopic type'' to understand the structure of the bumper events enough to create a properly modified version of the button callback function (the direct link to the Turtlebot [[https://github.com/yujinrobot/kobuki_msgs/tree/indigo/msg|github code]] also provides this information and defines some constants that might be of interest). This code should then be re-used and modified for the next learning task. |
| |
==== Bumper Events for Safe Forward Motion ==== | ==== Bumper Events for Safe Forward Motion ==== |
| |
Drawing a state diagram for the finite state machine should clarify what is involved. Try to get it working for a single sensor (say the bump sensor), then work it out for two sensors (bump and wheel drop). If you do so, then you should see that the main logic is predicated on a boolean value that checks the hit and drop statuses (you can even go crazy and add in the cliff sensor status). | Drawing a state diagram for the finite state machine should clarify what is involved. Try to get it working for a single sensor (say the bump sensor), then work it out for two sensors (bump and wheel drop). If you do so, then you should see that the main logic is predicated on a boolean value that checks the hit and drop statuses (you can even go crazy and add in the cliff sensor status). |
| |
| ==== Gyro-Based Forward Motion ==== |
| |
| The adventure here is to try to keep the orientation of the robot constant. It is not quite the same as going straight since that means following a very specific line. Nevertheless, if the orientation is able to stay constant, the if the desired line is not followed then a parallel line will be followed that is very close to the original desired line. For us that will be close enough (when eyeballing it). |
| |
| The main trick here is the implementation since the error feedback has already been [[Turtlebot:Adventures:Sensing101_ThetaError|described]]. If a subscriber with callback is defined for the Odometry topic, then one has access to the current pose. The pose data has an orientation quaternion that should be converted to a complex number within the callback. In fact, all of the error feedback math should be implemented within the callback. Even building up the twist command and its publication to the Navigation message subscriber. The python code in the construction should then just call the ROS spin command to relinquish control and let the callbacks do their magic. The spin command is basically a "wait until it is time to exit" command. |
| |
| Some turtlebots are actually quite decent at driving straight, while some will veer quite quickly. If you have a turtlebot that's good at driving straight and you want to see the controller in action, you'll have to give it a little nudge when it is running to perturb it away from its forward motion. It should turn back properly. |
| |
| ==== Gyro-Based Turning ==== |
| |
| The solution is quite similar to the drive straight one above, but the twist should not include forward motion. That means the linear parts won't be set, only the angular parts. Also, rather than set the desired orientation to be at 0 degrees (which is the same as $1+j0$), you should set it to turn 90 degrees (which is $0 + j$). If you want to turn to some other angle, then set $z_{des} = e^{j \theta_{des}}$ and you'll be good to go. |
| |
==== Gyro-Based Square Drawing ==== | ==== Gyro-Based Square Drawing ==== |
| |
There are two ways to solve this: (1) write your own orientation estimator to integrate the gyro information, or (2) access the orientation estimate of the system and use it. In both cases, what happens next is that some kind of feedback control is needed to regulate the orientation to the desired value (90 degrees offset from the initial value). Once close enough, then the turn maneuver should be considered executed. | This one combines the above two and uses a finite state machine to alternate between them. The finite state machine should have four states it seems. One state is for forward driving and uses the ''gostraight'' feedback control algorithm above modified to [[Turtlebot:Adventures:Sensing101_ForwardError|regulate the forward velocity]]. Another is for pure turning and uses the ''turninplace'' feedback control algorithm. What about the other two? |
| |
If using the built-in ROS topic for the orientation part of the robot's pose, then you'll have to work it out in quaternion form (or really in complex form since the other two quaternion values remain at zero). Given the current robot orientation as a complex number, it is possible to get the desired final orientation through multiplication by the proper complex number. It is best to get a paper and pencil and draw out the math. | Well, I think they should be to transition from forward driving state to the turning (and vice-versa). that means the system would really be state 1, prepare for straight driving and identify goal; state 2, perform straight driving to a specified goal; state 3, prepare for turning by identifying goal; state 4, perform turning to a specified orientation. When state 4 terminates, then it goes back to state 1. A combination of a while loop with a finite state machine (operating at a certain rate) and a series of odometry subscribers with different callbacks should be employed. |
| |
Now, what about the feedback control part given that everything is in complex form? Remember that these numbers live on the unit circle, so they are like vectors. The vector difference inner producted by the normal (in right hand rule sense) to the orientation vector give the error. If it is positive, then the robot must turn left. If ti is negative, right. The closer to zero it is, the closer to the desired orientation. This becomes the feedback term. The only problem is that a complete 180 degree turn is not possible with feedback since the inner product is zero. For 180 degree turns, some special logic is needed. Usually one just commands it to turn in an arbitrary direction. The next time step, the standard feedback control should work. | Prior to the drive straight, one needs to grab the current robot position, figure out the relative forward location that it needs to go to, then define all the proper variables for use in the callback. Once defined, the system can transition to the drive straight. Here, there needs to be a feedback controller to do that. In addition to ensuring straight progress via turn feedback control, the forward velocity should also have some feedback based on how close it is to the goal. Once it is "close enough" to the goal then it should transition to the next state (which should be turn in place preparation). |
==== Gyro-Based Forward Motion ==== | |
| Likewise, prior to the turn in place, one needs to grab the current robot pose, figure out the relative orientation that it needs to go to in absolute odometry terms, then define the proper variables for use in the callback. Here, nothing special beyond what was already done in the ''turninplace'' adventure is needed except to recognize when to terminate this finite state and move to the next one. |
| |
| If you do the above, the Turtlebot may drive in a square forever unless you keep track of the amount of times you've driven forward and turned. If you do so, then you can figure out an additional terminating condition that could be triggered to end the square maneuver. This would be extra, but good to figure out. |
| |
| When you want to grab the current state (pose) of the Turtlebot but don't want to have to create a subscriber, then it is possible to simply request the information using ''wait_for_message'': |
| <code> |
| msg = rospy.wait_for_message("my_topic", MyType) |
| </code> |
| The ''msg'' variable (or whatever you call it) will have the data associated to the topic. Mind you it may wait a bit for the latest data to be made available (depending on the message and its publication frequency). |
| |
This task is quite similar to the previous task, but the objective is to remain straight. That means whatever the initial orientation is, that is now the target orientation. The feedback controller should use the inner product between the target orientation and the current orientation to arrive at the feedback law. | Also, when you want to stop subscribing to something, there is a function called ''unregister'' that will do the trick. You need to have the subscriber object available to you though. The way to do that is to save the subscriber when you start it. As an example, for ''kobuki_button'' code one would do: |
| <code> |
| subButtons = rospy.Subscriber("/mobile_base/events/button",ButtonEvent,self.ButtonEventCallback) |
| |
The turtlebot is actually quite decent at driving straight. If you want to see the controller in action, you'll have to give it a little nudge when it is running to perturb it away from its forward motion. It should turn back properly. | ... some code here ... |
| |
| subButtons.unregister() |
| </code> |
| Once the topic has been unregistered, the callback will no longer be called. More generaly the subscriber will have been killed. To start appears to require re-instantiating a new subscriber and overwriting the subButtons object with the newly created one. |
| |
--------- | --------- |