this is a nontrivial issue. As in general nodes arent by design allowed to do this. Alltough there is a nodes in maya that do break this rule but they are rather specialized ones. but directly form the manual "A node must not know anything outside of its attributes and plugs" wich inidrectly states you may not querry them at other times as time is a node outside yours. (there is way tough more on this later)
Well as with the expression you dont actualy need to use gatAttr at all if you can contend with a caching solution. Also the velocity has allmost no meaning if your not stepping the animation at frame by frame basis, wich means cached soultiions are not realy all that optimal.
And it doe snot sho correctly in the graph editor.
Se if you cache the position of this frame and in next frame us e new value - cached value you get MUCH faster preformance, and the expression is totaly possible to copy without a problem (if you enable the duplicate input graph option). The beauty of expression nodel les in NOT using mel inside them, since mel does not know the connections its static and stupid.
here let me show you how to do such a expression, its not optimal but works in numer of situations such as when needing to roll wheels in final rendered animations! tough not whan scrubbing around.
sphere -p 0 0 0 -ax 0 1 0 -ssw 0 -esw 360 -r 1 -d 3 -ut 0 -tol 0.01 -s 8 -nsp 4 -ch 1;
addAttr -ln velocityX -at double |nurbsSphere1;
setAttr -e -keyable true |nurbsSphere1.velocityX;
addAttr -ln velocityCacheX -at double |nurbsSphere1;
addAttr -ln timeCache -at double |nurbsSphere1;
$expr="nurbsSphere1.velocityX=(nurbsSphere1.translateX-nurbsSphere1.velocityCacheX)/(time-nurbsSphere1.timeCache);rn";
$expr+="nurbsSphere1.velocityCacheX=nurbsSphere1.translateX;";
$expr+="rnnurbsSphere1.timeCache=time;";
expression -s $expr -o nurbsSphere1 -ae 1 -uc all -n "nurbsSphere1Velocity";
//steps out well but does not bake all that well with bakeResults but does with bakeSimulation!
im only doing this on one channel but nothing says you cant do this for more then one. (im lazy), but theres still a problem it only works in a timely fashion so if you jump around in the anim it will NOT work.
The same applies as a plugin too.
Now for the tough part future/past lookup, well its certainly possible BUT its allways expensive at the same magnitude as getAttr is because it does refresh (since the dg needs to refresh more then one time per frame), because it might happen that the data isnt computed yet (but unlike getattr its possible to handle cached values!). Secondly its a against the design of the dg so you would constantly be working against it. Se dg nodes are meant to not know their parents.
There is way to do this STRICTLY within the design parameter tough, and its to make a node thet actualy handles looping and use the loop node to feed data to your curves time. and loop 1 extra time to obtain it. Note such a loop node can do all manner of other cool stuff too! So its actualy worthwhile for other resons ebyond this. Se iits not agianst to modify the flow! its stille xpensive tough compared to caching.
Other solutions. If you just wish to see the vellocity curve! the i suggest doing something like the resultCurve node, as it doe smaple the entire time for you to see! You could try to overload it!
Edity improoved the legibility of the expression slightly