Is there anyway to do proper action masking while using Ray and an Open Spiel environment? - reinforcement-learning

Whenever I run an Open Spiel environment with Ray, I always get tons of errors about the moves not being legal. I was wondering if there was anyway to apply action masking with an Open Spiel environment.
I ran the example included with ray: https://github.com/ray-project/ray/blob/master/rllib/examples/self_play_with_open_spiel.py
I kept getting this error:
(RolloutWorker pid=27106) OpenSpiel exception: /project/open_spiel/games/connect_four.cc:94 CellAt(kRows - 1, move) == CellState::kEmpty (RolloutWorker pid=27106) CellAt(kRows - 1, move) = X, CellState::kEmpty = Empty

The ActionMasking example does just that. You can use ActionMaskModel to avoid illegal actions. Be aware that such a model always needs access to the actual illegal actions. RLlib itself has no knowledge of the specifics of Open Spiel environments. So in order to successfully mask them, you'll have to wrap the environment.
This example should include all you need.
There is also a user implementation out there.

Related

How can I fix all my area2D functions in Godot to not run on startup?

Ok, I've been using Godot for a while now, and haven't really had any issues. But, after I added an area2D to detect the player and teleport them as shown below that I run into issues. Every time I start the game, the console shows that both of the functions have already been run, even though the starting location is nowhere near the area2Ds. In addition, because they run in enter -> exit order, it spawns me at the exit of the tunnel, instead of the start of the map.
func _on_Tunnel_body_entered(_body):
print("entered_tunnel")
global_position.x = 952.5
global_position.y = 487
func _on_TunnelBack_body_entered(_body):
print("exited_tunnel")
global_position.x = 920
global_position.y = 635
Any help would be appreciated!
Are you, by chance, instancing the player character, adding it to the scene, and then setting its position (in that order)?
That is a common reason for this problem. What happens is that it collides with the areas once you add it to the scene but before you set its position.
To solve it set the global position before adding it to the scene.
You could temporarily disable the behavior by any of these means:
Temporarily changing the layers and mask to avoid the collision (you can do it with set_collision_layer_bit and set_collision_mask_bit).
Temporarily disabling collision shapes (by setting disabled to true. However, use set_deferred to avoid disabling it while Godot is still doing physics computations)
Temporarily adding collision exceptions (by calling add_collision_exception_with and remove_collision_exception_with).
Having a flag that you can check in the function that takes the signal to decide if it should take effect or not.
Connecting the signals from code once, so they are not connected beforehand.

App Widget getting hijacked by Google Sound Search?

So I'm seeing some bizarre behavior in an appwidget that I wrote.
The widget itself is quite simple - it reads a few values from persistent storage and then displays them as text. Nothing fancy in the layout - just a FrameLayout root element with some Linear Layout and TextView children.
The widget has a simple configuration activity associated with it.
The bizarre behavior is that the widget will initially show "Problem Loading Widget" after the user closes the configuration activity, and then after a few seconds it shows a "Google Sound Search" button (and clicking on the button actually does launch Google Sound Search). Then, after a few more seconds, it finally shows the expected display.
I am away from my code right now, so I'll have to wait until tonight to post code snippets. However, in the meantime, can anyone provide some insight into how such a thing could happen? Has anyone else ever experienced this? How could another widget "hijack" mine?
Thanks,
-Ron
Here are some screenshots:
There are a couple of issues with your widget and there are answers to all of them (although you didn't post any code so some of my statements are based on assumptions):
"Problem loading widget": this is the default view Android uses before the widget is initialized and the layout updated. Simply add the following line to your widget xml configuration (to show a loading message instead of the problem message):
android:initialLayout="#layout/my_cool_widget_loading_message"
If the widget shows the wrong layout then you probably have an issue in the widget's onReceive method. onReceive is called for all the widgets no matter whether the broadcast is for that specific widget. Android's AppWidgetProvider filters the broadcasts by appwidget Id and dispatches to the other methods (like onUpdate).
See also: https://developer.android.com/reference/android/appwidget/AppWidgetProvider.html#onReceive(android.content.Context, android.content.Intent).
If you override onReceive (which I assume you do), you need to call through to super.onReceive(Context, Intent) to make sure your other methods don't get calls meant for other widgets.
Now for the configuration of the widget. If you follow the Google documentation then it will all work nicely. The only improvement I'd do is what my other answer that you reference suggests (https://stackoverflow.com/a/14991479/534471). This will NOT send out two broadcasts. The setResult()/finish() part does only terminate the config Activity and let Android know whether to actually add the widget or not (depending on whether the result is RESULT_CANCELED or RESULT_OK.
From your own answer I can see why your code wouldn't work. The code is:
Intent intent = new Intent();
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, intent);
sendBroadcast(intent);
finish();
First of all there's no need to add the appWidgetId twice, use the AppWidgetManager.EXTRA_APPWIDGET_IDS version and you're good. Second you're using the same Intent to return as a result for the Activity. AFAIK it's not documented what happens when you do set an action on that Intent but my experience with Android widgets is that you need to stick exactly to the documentation or you'll end up having strange issues (like the ones you encounter). So please use two different Intents.
Activity result:
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
Broadcast:
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidget.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
sendBroadcast(intent);
ok, so I figured it out. Posting here in case anyone else runs into this. I think that the Android Developer docs are a little misleading here.
The problem was that in my configuration Activity, I had this code at the end:
Intent intent = new Intent();
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {mAppWidgetId});
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, intent);
sendBroadcast(intent);
finish();
Providing an intent with the extra EXTRA_APPWIDGET_ID is recommended by the documentation provided by google.
However, that same document says that you have to update the widget's view by creating a RemoteView and calling AppWidgetManager.updateAppWidget() like so:
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.example_appwidget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
I didn't like the idea of placing the presentation logic in both the configuration activity and the widget class, so I instead decided to broadcast an intent at the end of the configuration activity to tell the widget to redraw itself. That's why I have setResult() AND sendBroadcast() at the end of the activity. The documentation further states that the onUpdate() callback will not be called when using a configuration activity. So this seemed neccessary. I added the ACTION_APPWIDGET_UPDATE and the EXTRA_APPWIDGET_IDS to the intent so that it would trigger the onUpdate() method. This practice was recommended by this SO answer (albeit without being included in the activity result intent - but I tried separating the two and it had no effect).
Now I'm not certain exactly how the "Google Sound Search" widget got in there, nor do I fully understand the mechanics of how the intents interacted to produce the observed results. However, as soon as I replaced my code above with the code stated in the docs, the widget was updated properly.
Intent resultIntent = new Intent();
resultIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultIntent);
finish();
This seems to contradict the documentation's statement that the configuration activity must update the widget's view. Simply providing the configuration activity result as below triggers the onUpdate() method in the widget, thus allowing the widget to redraw itself. I confirmed the behavior on an emulator running API 23 and also on a Samsung device running Samsung's android flavor.

Start pairing with the code (Zwave)

I am developping a PoC Zwave using the project "Zwave Adapter Headless Host" and the program provided here
But trying this program, I have one problem and one question:
-When I remove my Zwave dongle, there is no change in the properties I see. Is it a normal behaviour?
-In my program, I would like to start pairing my dongle to another device by the code. Is it a possible thing?
Thank you
To answer your 2nd question :
Executing the function addNode(uint32 const _homeId, bool _doSecurity) make the Z-Wave controller to enter inclusion mode. Once you execute this function, you need to activate inclusion mode (physically) with your module (zwave light/sensor/...).
In other word, you can enter your z-Wave controller into inclusion mode using code and function, however, you need to physically press button on your other z-wave module to make them enter inclusion mode.
Bonus : To remove a module from your z-wave network, use the following function : removeNode(uint32 const _homeId)

How do BundleActivator, ManagedService, and my application interact on start/stop?

I had a non-OSGi application. To convert it to OSGi, I first bundled it up and gave it a simple BundleActivator. The activator's start() started up a thread of what used to be the main() of my app (and is now a Runnable), and remembered that thread. The activator's stop() interrupted that thread, and waited for it to end (via join()), then returned. This all seemed to be working fine.
As a next step in the OSGiification process, I am now trying to use OSGi configuration management instead of the Properties-based configuration that the application used to use. So I am adding in a ManagedService in addition to the Activator.
But it's no longer clear to me how I am supposed to start and stop my application; examples that I've seen are only serving to confuse me. Specifically, here:
http://felix.apache.org/site/apache-felix-config-admin.html
They no longer seem to do any real starting of the application in BundleActivator.start(). Instead, they just register a ManagedService to receive configuration. So I'm guessing maybe I start up the app's main thread when I receive configuration, in the ManagedService? They don't show it - the ManagedService's updated() just has vague comments saying to "apply configuration from config admin" when it is passed a non-null Dictionary.
So then I look here:
http://blog.osgi.org/2010/06/how-to-use-config-admin.html
In there, it seems like maybe they're doing what I guessed. They seem to have moved the actual app from BundleActivator to ManagedService, and are dealing with starting it when updated() receives non-null configuration, stopping it first if it's already started.
But now what about when the BundleActivator's stop() gets called?
Back on the first example page that I mentioned above, they unregister the ManagedService. On the second example page, they don't show what they do.
So I'm guessing maybe unregistering the ManagedService will cause null configuration to be sent to ManagedService.updated(), at which point I can interrupte the app thread, wait for it to end, and then return?
I suspect that I'm thoroughly incorrect, but I don't know what the "real" way to do this is. Thanks in advance for any help.
BundleActivator (BA) and ManagedService (MS) are callbacks to your bundle. BundleActivator is for the active state of your bundle. BA.start is when you bundle is being started and BA.stop is when it is being stopped. MS is called to provide your bundle a configuration, if there is one, or notify you there is no configuration.
So in BA.start, you register your MS service and return. When MS is called (on some other thread), you will either receive your configuration or be told there is no configuration and you can act accordingly (start app, etc.)
Your MS can also be called at anytime to advice of the modification or deletion of your configuration and you should act accordingly (i.e. adjust your app behavior).
When you are called at BA.stop, you need to stop your app. You can unregister the MS or let the framework do it for you as part of normal bundle stop processing.

sfErrorNotifierPlugin: The "default" context does not exist

I have installed the sfErrorNotifierPlugin. When both options reportErrors/reportPHPErrors reportPHPWarnings/reportWarnings are set to false, everything is ok. But I want to catch PHP exceptions and warnings to receive E-mails, but then all my tasks fail, including clear-cache. After few hours of tests I'm 100% sure that the problem is with set_exception_handler/set_error_handler.
There's a similar question:
sfErrorNotifierPlugin on symfony task but the author there is having problems with a custom task. In my case, even built-in tasks fail.
I haven't used sfErrorNotifierPlugin, but I have run into 'The “default” context does not exist.' messages before. It happens when a call is made to sfContext::getInstance() and the context simply doesn't exist. I've had this happen a lot from within custom tasks. One solution is to add sfContext::createInstance() before the call to sfContext::getInstance(). This will ensure that a context exists.
There's an interesting blog post on 'Why sfContext::getInstance() is bad' that goes into more detail - http://webmozarts.com/2009/07/01/why-sfcontextgetinstance-is-bad/
Well, the problem could not be solved this way, unfortunately. Using sfErrorNotifierPlugin, I have enabled reporting PHP warning/errors (apart from symfony exceptions) and this resulted in huge problems, e.g. built-in tasks such as clear-cache failed.
The solution I chose was to load the plugin only in non-task mode (project configuration class):
public function setup()
{
$this->enableAllPluginsExcept('sfPropelPlugin');
if ('cli' == php_sapi_name()) $this->disablePlugins('sfErrorNotifierPlugin');
}
WHen a task is executed, everything works normally. When an app is fired from the browser, emails are sent when exception/warning occurs (maybe someone will find it useful).
Arms has explained the problem correctly. But usually context does not exist when executing backend/maintenance tasks on the console. And it is easier if you handle the condition yourself.
Check, if you really need the context?
If you do, what exactly do you need it for?
Sometimes you only want a user to populate a created_by field. You can work around by hard-coding a user ID.
If you want to do something more integrated, create a page (which will have a context) and trigger the task from there.
you can test the existance of the instance before doing something inside a class. Like:
if(sfContext::hasInstance())
$this->microsite_id = sfContext::getInstance()->getUser()->getAttribute('active_microsite');
I've been experiencing the same problem using the plugin sfErrorNotifier.
In my specific case, I noticed a warning was raised:
Warning: ob_start(): function '' not found or invalid function name in /var/www/ncsoft_qa/lib/vendor/symfony/lib/config/sfApplicationConfiguration.class.php on line 155
Notice: ob_start(): failed to create buffer in /var/www/ncsoft_qa/lib/vendor/symfony/lib/config/sfApplicationConfiguration.class.php on line 155
So, checking the file: sfApplicationConfiguration.class.php class, line 155,
I've replaced the ' ' for a null, then the warnings disappears, and also the error!
ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : ''); bad
ob_start(sfConfig::get('sf_compressed') ? 'ob_gzhandler' : null); good