Maya Plugin attribute validation - plugins

I am trying to validate my custom MPxEmitterNode attributes.
I have force_min and force_max attributes that are double3 typed in maya parlance, basically two objects containing double[3] data.
I want to ensure the force_min is less than force_max for each of its 3 components. I'd like to do this by just swapping the min and max around if someone enters a value on the attribute in the attribute editor, or calls mels setAttr for those attributes, which then fails the "min < max" check.
I have tried setting up ATTRIBUTE_AFFECTS relationships between force_min, force_max and their individual component x,y,z objects. That seems to cause a cyclic issue leading to Maya crashing. I have also tried editing the custom compute function for the derived MPxEmitterNode, so it sets the force_min and force_max values to swap. The force_* attributes are seemingly never computed in this case.
Any help would be much appreciated.

Generally the 'Maya' way to do this would be to let the output look wrong if the min and max are set incorrectly. You don't know who is going to set those attributes -- it could be as connection or a script, and it could even get reset in between frames of an animation -- and so it's better to let the dag evaluation flow through even if the result is nonsense. It's like setting a radius of zero on a sphere node --it's 'correct' even thought it's wrong.
You can however swap the values inside your compute() method to get the same effect as swapping the values without resetting the plug values themselves. Setting an input plug from inside compute is a bad idea, because it introduces a loop into the flow of the dag evaluation. Dag nodes must be acyclical (that's the "a" in dag: Directed Acyclic Graph)

Related

Writing custom QGIS function in Python - is there a difference between "feature" and "$currentfeature"

I wrote the following custom qgsfunction:
#qgsfunction(args='auto', group='Custom', referenced_columns=[])
def f1(currentfeature, feature, parent):
return "%s\n%s" % (repr(currentfeature),repr(feature))
In the config for the label I enter the following expression:
f1($currentfeature)
And here is the result:
I always believed that the $currentfeature would hold the same value as the implicitly passed argument feature, but they appear to be separate objects.
Can someone please either
confirm that they should be the same value, or
explain the difference between the two
(I also experience other odd things when executing my own custom functions, and I suspect something is not behaving as it should. Sometimes the addresss of the object changes when I zoom in or out, the address seems to cycle between af few values, and simply takes the next value in the cycle when I do any kind of zoom action. And the reason why I got to experiment with this in the first place is because I did not get the expected/correct attribute values back)

Dynamically adjusting arrival rate in source

the basic idea behind the modeling issue is a breakdown of a production machine.
I would like to model this by setting the arrival rate (simply arrivals per second) to zero (Source.rate = 0). After the machine is repaired, the arrival rate is set to its actual value again (e.g., Source.rate = 5). While the first command does the job, the second does not seem to have any effect, i.e. new agents are not created.
The segment of the model is rather simple: Source --> Select Output (decision about breakdown) --> true: go on in production; false: delay (repair machine) --> go on in production.
Source.rate = 0 is called at the out port (false) of "breakdown" and Source.rate = 5 at the out port of "repair".
https://i.stack.imgur.com/hqGoI.png
Of cause, this issue might be modeled differently (e.g., using hold with disabled "forced pushing"), however, it is not clear for me why my approach does not work.
Thanks in advance!
Instead of using source.rate=5; use source.set_rate(5);
To expand on Felipe's answer with an explanation:
Instead of using source.rate=5; use source.set_rate(5);
rate is effectively a Parameter (in the AnyLogic sense) of the Source block. (All AnyLogic's Process Modeling blocks are actually themselves Agents developed by AnyLogic, and thus with Parameters, Variables, etc.)
You can set an AnyLogic Parameter directly (via just assigning a value as you did), but they also all have a set_<parameter name> method (function) which should really always be used instead because this triggers any internal on-change logic for this Parameter. It is only this triggered logic (internal to the Source block) which causes the Source to 're-evaluate' the rate properly.
(You can use on-change logic for Parameters in your own models, and need to do so when altering a parameter requires some 'adjustments' to the rest of the model; i.e., in situations where the change doesn't 'just work' due to other bits of the model reading the new value after the change point.)
I don't know why your model doesn't work (maybe more details of your model is needed), but a simple solution which I tested and worked, is as below:
You can set the source's "Type of arrival" to "calls of inject() function", add an event to your model and set its "Trigger type" to "Rate" and set its rate value to 5. Then in action code of the event use below code:
if(yourCondition)
{
source.inject(1);
}
I hope it helps you.

A Grid of Clones

My goal is to build a 5x5 grid of images. In the following code, row, col and rowcol were created as variables local to the sprite, and newcol, newrow and cats are global. (By the way, is it possible to tell which variables are local and which are global? It's easy to forget or make mistakes.)
The result is a 5x1 grid only, as seen here.
I am unclear as to the order of execution of these statements. Does when I start as a clone get called before or after add_cat gets called the second time? My tentative conclusion is that it gets called afterwards, yet the clone's global variables seem to contain their values from beforehand instead.
When I attempted to debug it with ask and say and wait commands, the results varied wildly. Adding such pauses in some places fixed the problem completely, resulting in a 5x5 grid. In other places, they caused a 1x5 grid.
The main question is: How to fix this so that it produces a 5x5 grid?
Explanation
Unfortunately, the execution order in Scratch is a little bizarre. Whenever you edit a script (by adding or removing blocks, editing inputs, or dragging the entire script to a new location in the editor), it gets placed at the bottom of the list (so it runs last).
A good way to test this out is to create a blank project with the following scripts:
When you click the green flag, the sprite will either say "script one" or "script two", depending on which runs first. Try clicking and dragging one of the when green flag clicked blocks. The next time you click the green flag, the sprite will say whichever message corresponds to the script you just dragged.
This crazy order can make execution incredibly unpredictable, especially when using clones.
The solution
The only real solution is to write code that has a definite execution order built-in (rather than relying on the whims of the editor). For simpler scripts, this generally means utilizing the broadcast and wait block to run particular events in the necessary order.
For your specific project, I see two main solutions:
Procedural Solution
This is the most straightforward script, and it's probably what I would choose to go with:
(row and col are both sprite-only variables)
Because clones inherit all sprite-only variable values when they are created, each clone will be guaranteed to have the correct row and col when it is created.
Recursive Solution
This solution is a bit harder to understand than the first, so I would probably avoid it unless you're just looking for the novelty:

Make signal names coming from library links unique?

OK, I've been struggling with this for a while. What is the best way to accomplish the following:
where Reaction Wheel 1-4 are links to the same block in a library. When the Speed Counter, Speed Direction and Current signals are added to the final bus output as shown, MATLAB (rightfully) complains:
Warning: Signals 9, 10, 11, 12 entering Bus Creator
'myAwesomeModel' have duplicated names 'Current'. These are being made unique
by appending "(signal #)" to the signals within the resulting bus. Please
update the labels of the signals such that they are all unique.
Until now I've been using a "solution" like this:
that is, place a size-1-mux/gain-of-1/other-dummy block in the middle, so the signals can be renamed into something unique. However, I really like to believe that The MathWorks has thought of a better way to do this...
What is the "proper" way to construct bus signals like this? It feels rather like I'm being pushed to adopt a particular design/architecture, but what that is precisely, eludes me for the moment...
It was quite a challenge for me but looks like I kinda sorted it out. Matlab R2007a here. I'll do the example with an already done subsystem, with its inputs, outputs, ...
1- In Block Properties, add a tag to the block. This will be done to identify the block and its "siblings" among the system. MY_SUBSYSTEM for this example.
2- Block Properties again. Add the following snippet in CopyFcn callback:
%Find total amount of copies of the block in system
len = length(find_system(gcs,'Tag','MY_SUBSYSTEM'));
%Get handle of the block copied/added and name the desired signal accordingly
v = get_param(gcb,'PortHandles');
set(v.Outport(_INDEX_OF_PORT_TO_BE_RENAMED_),'SignalNameFromLabel',['BASENAME_HERE' num2str(len)]);
3- In _INDEX_OF_PORT_TO_BE_RENAMED_ you should put the port signal index (starting from 1) that you want to have renamed for each copy of the block. For a single output block this should be 1. BASENAME_HERE should be the port basename, in this case "Current" for you.
4- Add the block to the desired library, and delete the instance you used to create this example. From there on, as you add from the library or copy an existing block, the outport should name Current1, Current2, Current3, and so on. Notice that you could apply any convention or formatting.
Hope this helps. It worked for me, don't hesitate to ask/criticize!
Note: Obviously, as the model grows, this method may be computer-demanding as find_system will have to loop through the entire model, however looks like a good workaround for me in small-medium sized systems.
Connect a Bus Selector to each Data Output. Select the signals you want and set "Output as bus". Then connect all Bus Selectors to a Bus Creator.
simulink model

Implementing snapshot in FRP

I'm implementing an FRP framework in Scala and I seem to have run into a problem. Motivated by some thinking, this question I decided to restrict the public interface of my framework so Behaviours could only be evaluated in the 'present' i.e.:
behaviour.at(now)
This also falls in line with Conal's assumption in the Fran paper that Behaviours are only ever evaluated/sampled at increasing times. It does restrict transformations on Behaviours but otherwise we find ourselves in huge problems with Behaviours that represent some input:
val slider = Stepper(0, sliderChangeEvent)
With this Behaviour, evaluating future values would be incorrect and evaluating past values would require an unbounded amount of memory (all occurrences used in the 'slider' event would have to be stored).
I am having trouble with the specification for the 'snapshot' operation on Behaviours given this restriction. My problem is best explained with an example (using the slider mentioned above):
val event = mouseB // an event that occurs when the mouse is pressed
val sampler = slider.snapshot(event)
val stepper = Stepper(0, sampler)
My problem here is that if the 'mouseB' Event has occurred when this code is executed then the current value of 'stepper' will be the last 'sample' of 'slider' (the value at the time the last occurrence occurred). If the time of the last occurrence is in the past then we will consequently end up evaluating 'slider' using a past time which breaks the rule set above (and your original assumption). I can see a couple of ways to solve this:
We 'record' the past (keep hold of all past occurrences in an Event) allowing evaluation of Behaviours with past times (using an unbounded amount of memory)
We modify 'snapshot' to take a time argument ("sample after this time") and enforce that that time >= now
In a more wacky move, we could restrict creation of FRP objects to the initial setup of a program somehow and only start processing events/input after this setup is complete
I could also simply not implement 'sample' or remove 'stepper'/'switcher' (but I don't really want to do either of these things). Has anyone any thoughts on this? Have I misunderstood anything here?
Oh I see what you mean now.
Your "you can only sample at 'now'" restriction isn't tight enough, I think. It needs to be a bit stronger to avoid looking into the past. Since you are using an environmental conception of now, I would define the behavior construction functions in terms of it (so long as now cannot advance by the mere execution of definitions, which, per my last answer, would get messy). For example:
Stepper(i,e) is a behavior with the value i in the interval [now,e1] (where e1 is the
time of first occurrence of e after now), and the value of the most recent occurrence of e afterward.
With this semantics, your prediction about the value of stepper that got you into this conundrum is dismantled, and the stepper will now have the value 0. I don't know whether this semantics is desirable to you, but it seems natural enough to me.
From what I can tell, you are worried about a race condition: what happens if an event occurs while the code is executing.
Purely functional code does not like to have to know that it gets executed. Functional techniques are at their finest in the pure setting, such that it does not matter in what order code is executed. A way out of this dilemma is to pretend that every change happened in one sensitive (internal, probably) piece of imperative code; pretend that any functional declarations in the FRP framework happen in 0 time so it is impossible for something to change during their declaration.
Nobody should ever sleep, or really do anything time sensitive, in a section of code that is declaring behaviors and things. Essentially, code that works with FRP objects ought to be pure, then you don't have any problems.
This does not necessarily preclude running it on multiple threads, but to support that you might need to reorganize your internal representations. Welcome to the world of FRP library implementation -- I suspect your internal representation will fluctuate many times during this process. :-)
I'm confused about your confusion. The way I see is that Stepper will "set" the behavior to a new value whenever the event occurs. So, what happens is the following:
The instant in which the event mouseB occurs, the value of the slider behavior will be read (snapshot). This value will be "set" into the behavior stepper.
So, it is true that the Stepper will "remember" values from the past; the point is that it only remembers the latest value from the past, not everything.
Semantically, it is best to model Stepper as a function like luqui proposes.