Description
Characters can reach, touch. grab or point at objects in their environment.The reaching algorithm is example-based, so the reaching motion will be of similar quality to the original motion. In addition, SmartBody implements a grabbing control when characters are instructed to pick up or drop objects. The grabbing controller will modify the configuration of the hand so that it matches the shape of the target object.
Shown here is an example of interactive reaching. The blue spheres denote example reaches from a standing position, while the green dots indicate interpolated examples between reaches. The reaching algorithm finds the nearest green example, then uses inverse kinematics (IK) to move the arm to the exact desired location.
In the above two examples, the character reaches for an object then grasps it. Notice that the hand grasp is different for the cube-shaped object (left) than for the capsule-shaped object (right).
Requirements
For reaching, the characters need a set of reaching motion examples.
For grasping, two hand poses are needed: a rest hand pose, and a closed hand pose.
For pointing, a single hand pose that represents the pointing hand pose.
Please see the section on Configuring Reaching and Grasping For Characters for more details.
In the absence of a set of example reaching motions, SmartBody will use inverse kinematics to reach, grasp and touch.
Usage
<sbm:reach sbm:action="touch" target="ball"/> <sbm:reach sbm:action="pick-up" target="ball"/> <sbm:reach sbm:action="put-down" target="ball"/> <sbm:reach sbm:action="point-at" target="ball"/>
Parameters
Parameter | Description | Example |
---|---|---|
target | the reach target. Can either be a character/pawn name, or a character:joint | <sbm:reach |
sbm:action | pick-up, put-down, touch, point-at
| <sbm:reach sbm:action="touch" target="ball"/> |
sbm:handle | the name of the reaching instance which can be reused later | <sbm:reach |
sbm:foot-ik | whether or not to restrict potential foot sliding by enabling inverse kinematics on the feet. Default is false. | <sbm:reach |
sbm:reach-finish | whether to complete the reaching action by returning to the rest pose | <sbm:reach |
sbm:reach-velocity | the end-effector velocity when interpolating between reach poses. Default is 60 | <sbm:reach |
sbm:reach-duration | the time to allow the hand to rest on the target object before automatically returning the hand to the rest position. If this value is < 0, the duration is infinite. | <sbm:reach |
start | time when the reach motion will start. | <sbm:reach |
Reach Events
The event "reachNotifier" is sent out during a reach behavior. This was created to facilitate the customizing of high-level behaviors with reach/grasp being one of the building blocks.
The user can easily define the following event handler in Python script, which will be triggered during different stages of the reach action.
class ReachingHandler(SBEventHandler): def executeAction(self, ev): params = ev.getParameters() # handle the event here ... reachingHdl = ReachingHandler() evtMgr = scene.getEventManager() evtMgr.addEventHandler("reachNotifier", reachingHdl)
The "params" is simply a string in the form of "bml char CHRNAME KEYWORD" or "bml char CHRNAME KEYWORD: VALUE".
CHRNAME is the name of the character;
KEYWORD is one of the following: "pawn-attached", "pawn-released", "reach-returned", "reach-complete", "reach-stateCurrent", "reach-stateNew". See table below.
KEYWORD | Note |
---|---|
pawn-attached, pawn-released | detect if pawn is attached or detached from character's hand |
reach-returned, reach-complete | detect if reach has finished. note that if reach-return=false, it still sends out reach-complete when character holds at reach stroke. |
reach-stateCurrent, reach-stateNew | current/new reach state (currently it sends out either Return or Idle) for ex: use "reach-stateNew: Idle" to detect when reach has finished. |
VALUE is either "Return" or "Idle".
Together with event handlers for locomotion and facing adjustment, characters can be programmed to perform interesting tasks. Please see the example scripts "hot-potato.py" and "hot-potato-multiagent-demo.py" for details.
Examples
1. Passing an object from one character (giver) to another (taker).
See "hot-potato.py" and the control diagram below for details.
To run this example, follow these steps:
# 1. load the script
scene.run("hot-potato.py")
# 2. set up names for agents and object
giver = 'doctor' taker = 'brad' obj = 'box'
# 3. make sure object is somewhere can be picked up
dummyPos = offerHandPos(giver, taker) target = scene.getPawn(obj) target.setPosition(dummyPos)
# 4. this triggers the object passing, from giver to taker
giverHandToTaker(giver, taker, obj)
# 5. swap the giver and taker, and run it again:
swap() giverHandToTaker(giver, taker, obj)
# 5. taker release the object:
reset()
# 6. if agent(s) got stuck in the middle of the state, use this to reset:
masterReset()
# 7. you can directly specify giver, taker, obj as follows:
giverHandToTaker('elder', 'utah', 'box') giverHandToTaker('brad', 'doctor', 'box')
2. "Hot Potato" demo with miltiple agents:
The above two pictures are snapshots taken from the demo. left picture shows the initial setup with 30 agents standing in a circle. As one agent passes the object to the next agent, they form an interesting pattern shown in the right picture.
To run this demo, simply start SmartBody with "hot-potato-multiagent-demo.py". Change "totalChr" inside the script for total head count of the agents in the demo.
Attachments:









