How to use BufferSensorComponent

Hi, please help me with this, I am unable to do anything with this. I have a game where there are multiple targets that are sometimes visible and sometimes not. I want to collect the following observations about each of them that are visible:

  1. The inverse transform position of the target from the ml agent.
  2. The distance between the target and the agent.

I would like to use the buffersensorcomponent for this, but I am not sure how I can use it. I looked through the Sorter example in the example project in mlagents, however I am unable to fully understand it. It has a list of floats that gets added as an observation list in the CollectObservations function. I, on the other hand have a list of observations that have different data types. Please help me. Thank you very much.

Edit:
I have somehow added this piece of code for the buffer sensor, not sure if it is correct.

if (!noTarget)
        {
            foreach (var target in targets)
            {
                float[] targetObs = new float[4];
                targetObs[0] = transform.InverseTransformPoint(target.transform.position).x;
                targetObs[1] = transform.InverseTransformPoint(target.transform.position).y;
                targetObs[2] = transform.InverseTransformPoint(target.transform.position).z;
                targetObs[3] = Vector3.Distance(this.transform.position, target.transform.position);

                m_SensorComponent.AppendObservation(targetObs);
            }
        }

Please let me know if this makes sense.

Also my Unity Editor shows the following warnings under behavior parameters:

The model does not contain an Observation Placeholder Input for sensor component 1 (Stacking Sensor)
An Observation of the model does not match. Received TensorProxy of shape [?x2x4] but was expecting [?x18x1] for the BufferSensor sensor.

Hey!
A few weeks ago I was struggling with the buffer sensor myself.
The code you posted is correct.
The warning basically says that you append more/different observations to the sensor than you defined in the component. You can change the values in the inspector view of the component.
Judging by the warning you get I think that you defined the “ObservableSize” to be of size 1 but in your case it should be 4, since each observable consists of 4 floats.
This is why it says “Received TensorProxy of shape [?x2x4] but was expecting [?x18x1] for the BufferSensor sensor.”
The question mark stand for how often the sensor should be stacked, the second number is the number of observables and the third is the size of an observable.
Note that you can make fewer observations than the maximum number you defined in the component since the buffersensor will pad the rest with 0s. The size of an observable has to match though

Thank you so much for your reply.
I still have a question though :confused: . In the Sorter example I noticed that the behavior parameters in the inspector had an observation size that was equal to the number of floats collected in CollectObservations using the AddSensor method. It does not list the size of the buffer sensor. I did the same but I still get those warnings. Should I be adding the number of observations in the buffer sensor to the other observations in the behavior parameter?

Hi I figured it out, I had a model that was loaded to the model field of the behavior parameters component :sweat_smile:. I was not using the model, only training but the warning was triggered since the observation space did not match with the one in the loaded model. I entered None in that field, the warning is gone now. Thank you so much

Glad I could help

Hi, I have a follow up question on this, hope you can help me.

Can I have 2 buffer sensor components for the same agent? For example, I am now maintaining a list of all the targets I can ‘see’ and making observations on them , similarly I would like to maintain a list of the targets that are ‘seeing’ me. Should I create 2 buffer sensors for this or can I append this observation to the existing one.

However it should be noted that the 2 lists of targets will be mutually exclusive, the targets that I can see will be on the first list, while some of the targets that are seeing me will be on the second (if the target and I are seeing each other, the target will still appear only on the first list).

Thanks in advance :slight_smile:

Yes, you can multiple buffer sensors. Just make sure that the names differ!

Thanks a bunch. So, I am using something like float[ ] targetObs for the first one and float[ ] threatObs for the second. However both these observations will be appended to the same BufferSensorComponent (m_SensorComponent) in the script and there is only one BufferSensor attached in the inspector with new maximum size and number of observables. Is this is ok?

Thanks in advance :smile:

You can add multiple buffer sensor components. User one for each “type” of observations. So one for targetObs and one for threatObs

Hi, I wanted to post an update on this. I created two sensor components (first one - observation size: 7, max no. of observables: 2, second one - observation size: 3, max no. of observables: 2) like you said and attached 2 buffer sensor scripts with the corresponding sensor names. However I got an error saying the sensor received only 3 observations where it was expecting 7. So, I moved the second sensor component to above the first one in the inspector. Don’t know why that would fix it, but I didn’t get that error anymore. Hope I am going the right way :slight_smile:

This doesn’t work. Even though I have given the same name to buffer sensor in the inspector as the variable name for the buffer sensor component in the script - m_Sensor1, m_Sensor2, unity does not differentiate between the two based on this. The number of observables differ - 1 has 7 and 2 has 3, so unity throws an error depending on which sensor collects observation first, saying that observation size does not match.

UnityAgentsException: The BufferSensor was expecting an observation of size 3 but received 7 observations instead.

Please help! How exactly should I be using multiple buffer sensors?

Did you drag and drop the sensor references via the inspector?

No, how do I do that? I have attached a screenshot of how my buffer sensor looks in the inspector, do let me know if there is anything wrong. Thank you

in the script where you use the sensor you make the follwing properties:

[SerializeField] private BufferSensorComponent m_SensorComponent1;
[SerializeField] private BufferSensorComponent m_SensorComponent2;

then you will see two fields in the inspector on that script. you can now drag and drop the respective buffer components into those two fields.

Thank you soooooo much :smile:, I can finally see light at the end of the tunnel. One mistake I made was I had forgotten to take out the GetComponent lines from the script. For those who may have made some oopsies like me, GetComponent<> returns the first object/component of that type, so both my BufferSensorComponent’s were getting loaded with the same BufferSensor. Once I took those lines out, the training is going on smoothly :slight_smile:

Just one question about the buffer concept - does it fill the empty data with 0 (zeros) or with some empty data indication? i am asking because in my data a position of 0,0 is valid position - so i am trying to understand the meaning of what the buffer is doing.
for filling with 0 values i dont need any buffer sensor - i can just send 0 myself for all the params that i currently am not showing.
does the buffers sensor do more then just sending 0?