General_Robotics - RicoJia/notes GitHub Wiki
========================================================================
========================================================================
-
Roll-Pitch-Yaw are euler angles (Tait-Bryan). 2 orders:
- XYZ (x pointing forward, mobile vehicle)
- ZYX (z pointing forward, gripper)
-
Angular Velocity
R_dot = w x R
- The write them in a group:
- The write them in a group:
-
Another way to prove
R_dot = w x R
due to rotation is from rodrigue's formula,R = e^(w theta)
. Notice the use of skew-matrix -
Additive rule of angular velocity: when two frames are rotating at the same time, the angular velocity at each moment is the sum
-
DH parameters: rotation around x (
alpha
), distance along x (ai
), distance along z (di
), rotation around z (theta
)-
E.g, PUMA 560
-
DH formula: rotate z -> translate along z -> translate along x -> rotate x
-
Finally, it's
-
========================================================================
========================================================================
-
Behavior Tree
-
Intro
- executable nodes are: conditional node (1 tick), and executable node
- leaf nodes = executable nodes
- Tree starts from left to right. If root returns failure, then it's a failure
- 4 types of control nodes:
- sequence (all nodes must return true)
- fallback (one node returns true)
- Parallel (nodes will execute in parallel, not necessarily true parallelism)
- Decorator (modifies result of child), can invert, force a result, or repeat
- Only one child!
- Infrastructure
- Blackboard:
- Blackboard:
- executable nodes are: conditional node (1 tick), and executable node
-
Pros and Cons:
- reactivity: check if battery is okay at every single step. Easier to do it wtih state machines, than with BT
- So finite state machine with bt in it.
-
The combo: py_trees, py_trees_ros, rqt_py_trees
- py_trees_ros publishes all nodes in tick()
-
pytree ros
- Installation:
py_trees
need ot bepip install .
- Installation:
-
Code review (read the behavior tree example first)
-
5 elements: Selectors, Sequences, Parallels (these are composites), Decorator, and Behavior
-
Behavior
- behavior.attach_blackboard_client: create blackboard client, store it, and return it
- Setup_with_descendents: call setup() on descendents too
- Alternatively: py_trees.trees.BehaviourTree.setup()
- tick():
- call initialise() if not running
- call update()
- update status
- yield itself. So you must use for ...
- tick_once():
- for _ in self.tick()
- iterate(): yield the leaf child nodes first, then finally itself.
- stop():
calls terminate(). terminate(new_status)
- terminate() is called when a behavior ends
- had_parent_with_name(): searches through all parents
- Behaviors:
ConditionalBlackboardSet: generic condicitonal that writes values to blackboard on success/failure of the outcome. - In init: - get blackboard keys, success_write (function(blackboard)), default None, and failure_write - get ```condition(blackboard)``` - In update: - Check condition(blackboard). If success, then try checking success_write if defined. Else, try failure_write
-
composites: Selector(Fallback), Sequences, Parallels
- Selector: keeps going until one succeeds
- Sequence: keeps going until one fails
- memory: if previous tick is RUNNING, resume from there.
- Parallel:
- in one tick, all behaviors are ticked (though sequentially, on a single thread)
- Note that if one child fails, SuccessOnOne doesn't work (it only works with child that that's invalid/success)
-
render dot tree:/home/rjia/third_party_installs/py_trees/py_trees/demos/context_switching.py
-
decorators:
decorator class: - Init 1. check if child are Behaviour 2. has children (only one child?). decorated is its first child - tick: 1. initialise itself 2. call decorated.tick() (all its children too) 3. self.update() Condition(Decorator): - self.update(): 1. check if decorated is in a desire state (default is SUCCESS). - If so, return SUCCESS - Else: return FAILURE SUCCESS_IS_X: - self.update(): returns X when state becomes SUCCESS FAILURE_IS_X: - self.update(): returns X when state becomes FAILURE Inverter: - self.update(): returns not(state) Oneshot: 1. self.tick(): ticks through all children. When final_state is set, call self.update(), and calls self.stop() 2. self.update(): keep running and return decorated status until final_state is set. - self.terminate(): called when decorated status is not RUNNING. - Then check if final_state is set, and check if it's policy value. Set final_state Timeout: - self.update(): when time is up, return failure StatusToBlackboard: - init: creates a blackboard, gets a variable, rip the variable's first part before '.', - update: set blackboard variable to value: child.status (success/failure) EternalGuard?
-
Blackboard: fake "Singleton" by using class variables and static methods
1. client = Behaviour.attach_blackboard_client: create Client object: -> Blackboard.clients[Client.unique_identifier ] = Client.name 2. client.register_key("number_of_noodles", Access.write): Blackboard.metadata[remapped_key].write.write.add() # write is actually a Set object. this param is added to this set 3. self.state.number_of_noodles = 32 # now you can write to this param, Note, you are calling this __getattr__ func, so the attr will be fetched from here
-
tree:
1. behaviour_tree = py_trees.trees.BehaviourTree( root=root): just setting vars 2. behaviour_tree.setup(timeout=15) 3. behaviour_tree.tick_tock( period_ms=500, number_of_iterations=py_trees.trees.CONTINUOUS_TICK_TOCK, pre_tick_handler=None, post_tick_handler=print_tree ) tick_tock is to call self.tick(pre_tick_handler, post_tick_handler), until interruption -> tick: 1. call all pre-handlers (can be a list) - calls all visitor.initialise() 2. Call all ticks: (let all visitors to visit?) - call all ticked node.visit(visitor) 3. call iterate on all tree nodes - calls all iterated nodes.visit() 4. Calls all visitor.finalise() 5. call post_tick_handler
-
Additionals
- Conditional
conditional_behavior = Conditional( condition=check_blackboard_predicate, blackboard_keys={'board_waypoint'}
)
class Conditional(py_trees.behaviour.Behaviour): def __init__(self, name: str, condition, blackboard_keys: Union[List[str], Set[str]]): super(Conditional, self).__init__(name) self.blackboard = py_trees.blackboard.Client(name=name) for key in blackboard_keys: print(f"registering {key} for read access") self.blackboard.register_key(key, py_trees.common.Access.READ) self.condition = condition def update(self): return self.condition(self.blackboard) ```
- Visitors:
1. class SnapshotVisitor() - initialize visited, previously visited () - And a bunch of other variables 2. def post_tick_handler(snapshot_visitor, behaviour_tree): print( tree_str = py_trees.display.unicode_tree( behaviour_tree.root, visited=snapshot_visitor.visited, previously_visited=snapshot_visitor.visited ) ) - This displays a tree. 3. behaviour_tree.add_post_tick_handler( functools.partial(post_tick_handler, snapshot_visitor)) - This binds snapshot_visitor to post_tick_handler - adds the print as post_tick_handler 4. behaviour_tree.visitors.append(snapshot_visitor) 5. behaviour_tree.tick_tock()
- Conditional
-
========================================================================
========================================================================
- all motors work by magnets being attracted to & propelled from each other.
-
- velocity is defined: 60 deg/time. Usually 0.11-0.21/60deg
- Voltage: 4.8v, 6v. Higher the voltage, the better torque
- Current, usually not provided, but usually no load: <400mA, with load > 1A. Of course, motor near the ee has lower current. 6v, 5A power source is good.
- If on battery, need LDO (Linear regulator); 同时可能要稳压
- gear box is to reduce speed, and increase torque.
- 行星减速箱, planetary gears: transform very large torque in compact form.
- at the ee, use 谐波减速器, harmonic gear drive
- harmonic drive: misaligned stator and output rings' teeth will become a wedge. Inserting the flex's tooth into them will cause the the two rings aligned.
- 行星减速箱, planetary gears: transform very large torque in compact form.
-
Disadvantages:
- Closed loop control is pretty coarse: encoder needs to be more precise;
- deadzone (or deadband) is certain input, but zero output
- closure can be aluminum, better cooling
- metal gear is harder
- Closed loop control is pretty coarse: encoder needs to be more precise;
-
Nice article for troubleshooting see article
-
When one teeth is energized (usually as north), the rotor will come
-
Can do half stepping by energizing two neighboring teeth.
-
In a full on motor, 1.8 deg is quite common. With Half stepping, it can be 0.9 deg
-
Advantages:
- Open loop control, ok precision, good torque, so cheap
- Accuracy: errors don't add up
- cheap
- Torque is good for slow speed
- has "detent torque", will hold things in place
- Only the shaft bearing will wear out
-
Disadvantages:
- torque will plummet as speed goes up
- need to overcome detent torque, which draws a lot of current
- Can be noisy.
- Cannot accelerate very rapidly
-
Zero-gravity?
- In low gravity, Korioli force and M are small. Only consider Gravity & friction terms
- H(G) is a matrix of trigonometric functions of joint angles.
- There's a solution to H. But we need to estimate
Pi_G
. So we let the joint travel at very low speed, forward and backward, measure the torques. Then we can get an estimate ofPi_G
as the psudo-inverse as shown below
========================================================================
========================================================================
- torque sensor: there are two types: using "serial elastic actuator" (联动轴) and emasure angular differences, or measure strain with resistive strain gauge
- LIDAR technology
- Tech
- HDDM: high definition distance measurement; 1.5km retro-reflective tape
- Laser (Light Amplification by Stimulated Emission of Radiation) can operate in IR range.
- Sick: tim571, 0.05m - 25m, Hokuyo: 10m
- diffuse reflectors, like matte surface, or reflective tape, scatter light in many directions
- specular reflectors, like a mirror, reflect infrared in different angles. So you may not get a signal at all.
- glasses, light rays can be refracted and bend light travel paths
- Tech
- Ethernet cable is better than USB:
- more physically robust
- More robust in electrically noisy env
- faster speed: Ethercat can do real time. USB3.1 10Gbps, 3.2 20Gbps; ethernet: 10, 25, 40, 100 Gbps
- Power over Ethernet
========================================================================
========================================================================
-
You need a "slicer" to convert stl to steps. https://www.learnrobotics.org/blog/convert-stl-g-code-3d-printing/
-
Things to check for 3D printing:
- Y-axis bolts. (bottom)
- Bed should be loose.
- Bed motion should be smooth
- Check rollers below the bed. Rollers should be loose
- Lower the nozzle to the lowest. There should be a gap between the nozzle and the bed.
-
Work flow:
- Connect to power.
- Preheat PLA
prepare -> autohome
- move-> Z to zero
- Disable stepper motor
-
move -> manually change z offset to fit a piece of paper underneath
- Springs should turn to the right to lower the bed
- Auto leveling
- It goes to 4x4 positions to find the level spot
- Connect to power.
-
Nozzle cleaning:
- The 90 deg method
- heat up your nozzle to 200.
- go to
control
, change nozzle temp to 90 - when it hits 90, pull the filament out.
- The 90 deg method
-
Misc:
- Tnut
========================================================================
========================================================================
-
docking & undocking: kobuki has some interesting stuff there. http://wiki.ros.org/kobuki/Tutorials/Automatic%20Docking
-
Simulators:
- Gazebo: Physics Engine, ODE, bullet, simbody, DART -> OGRE(object-oriented graphics rendering engine)
- Webots come as a close second
-
robot code:
- Know what can fail: Manip, perception ..., and add error handling
- Important rule: LOG EVERYTHING: the world is more hairy than you think. Reproducing the issue
- Have different types of errors, not just a simple return True
- Decorator: on high level of the stack, we need to wait for hardware to respond, etc., time spent gets lost in noise
- If it's training, save the intermediate results in a rolling buffer (if something breaks)
-
Snapshot-logger Kafka: Say we have
/point_cloud
on the robot.- serialize the message using protobuf.
- ros bridge: -> kafka topics
- On the server, need java to run kafka, and the zoo keeper (sync)
- create kafka topic using a kafka script
- What does a kafka log look like? Stored as ordered, immutable partitions, which then are ordered, immutable segments in files: each segment has
.index
and.log
Each.log
has recordstimestamp, key-value, metadata
- store events as logs temporarily with a retention policy. Otherwise, you have to have a huge monolith database.
- timescale db to permanently store; else, Amazon S3.
- Can read with an
index
- What does a kafka log look like? Stored as ordered, immutable partitions, which then are ordered, immutable segments in files: each segment has
- Kafka consumer subscribes to the topic.
- What you get from kafka:
- retention
- Fault tolerance
- Partition: a topic can be broken down to different partitions
- from a list of brokers, the zoo keeper elects the leader broker, the broker that handles the current partition
- So consumers' reading can be parallelized