先锋机器人学习笔记_1-8 Config Client相关的类与例程

1. class ArClienBase

  1.  You need to connect a client to a server using blockingConnect() with the address for the server.  
  2. Then you should add handlers to the client to receive information from the server (with addHandler(), request(), and requestOnce()).  
  3. Then call run() or runAsync() (or loopOnce() if you really know what you're doing). You can also add a callback that will get called every cycle of the client. 

  • User and password information may be required by the server. For details on that see ArServerBase.  
  • The most important thing is the modification to blockingConnect(), it can now take a user and password argument and upon failure you'll want to check wasRejected() to determine whether the client couldn't find the server or if the user and password were rejected. 
  • Another relevant function is setServerKey() to set the key (string of text) we need to connect to the server.
  • This class should be thread safe... The only thing you cannot do is call 'addHandler' or 'remHandler' from within a handler for that specific piece of data.

2. class ArClientHandlerConfig

    Client handler for receiving and updating ArConfig data via ArNetworking.
    ArClientHandlerConfig processes the network packets that describe a robot's ArConfig.  It also provides a means to save the modified configuration data to the robot server.  This class is designed to work inconjunction with the ArServerHandlerConfig.  See the server handler documentation for a complete description of the networking interface.

    This class should be thread safe, with the exception of unThreadSafeGetConfig. (If you want to use this method, surround it with calls to lock() and unlock().) Note that you can't add callbacks or remove callbacks from within a callback function.

3. class ArConfig : public ArHasFileName

    Stores configuration information which may be read to and from files or other sources
    The configuration is a set of parameters (or config arguments), organized into sections.  Parameters contain a key or name (a short string), a value (which may be one of several types), a priority (important, normal, or trivial to most users), a longer description, and a display hint which suggests what kind of UI control might be most appropriate for the parameter.
    After adding a parameter to the configuration, its value may be changed. when the configuration is loaded or reloaded from a file. Various program modules may register callbacks to be notified when a shared global configuration (such as the static ArConfig object kept by the Aria class) is loaded or otherwise changed. Classes dealing with more specialized kinds of config files inherit from this one.
    Important methods in this class are: addParam(), addProcessFileCB(), remProcessFileCB(), parseFile(), writeFile().Usually, configuration data are read from and written to a file using parseFile() and writeFile(), or are set by a remote client via ArNetworking.  It is also possible to import configuration settings from an ArArgumentParser (which, for example, may contain a program's command line arguments) using useArgumentParser().

例程1:configClient.cpp

#include "Aria.h"
#include "ArNetworking.h"

ArClientBase *client; //define a class type pointer
ArClientHandlerConfig *configHandler;
bool done = false;

void gotConfig(void)
{
	ArConfig *newConfig;//Stores configuration information
	                    //which may be read to and from files or other sources
	done = true;
	configHandler->getConfig()->writeFile("configClient.txt");
	newConfig = new ArConfig(*(configHandler->getConfig()));
	newConfig->writeFile("configClientNew.txt");
}

int main(int argc, char **argv)
{
	Aria::init();
	ArGlobalFunctor gotConfigCB(&gotConfig);
	std::string hostname;

	client = new ArClientBase;// initialize a pointer
	configHandler = new ArClientHandlerConfig(client);

	configHandler->addGotConfigCB(&gotConfigCB);

	ArArgumentParser parser(&argc, argv);
	 
	ArClientSimpleConnector clientConnector(&parser);

	parser.loadDefaultArguments();

	/* Check for -help, and unhandled arguments: */
	if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
	{
		Aria::logOptions();
		exit(0);
	}
	/* Connect our client object to the remote server: */
	if (!clientConnector.connectClient(client))
	{
		exit(1);
	}

	client->setRobotName(client->getHost()); // include server hostname in log messages

	configHandler->requestConfigFromServer();
	client->runAsync();//Runs the client in its own thread

	while (!done)
		ArUtil::sleep(100);//Sleep for the given number of milliseconds

	if (configHandler->canRequestDefaults()) 
	{
		configHandler->requestDefaultConfigFromServer();
		while (!configHandler->haveGottenDefaults())
			ArUtil::sleep(100);
		printf("%d\n", configHandler->haveGottenDefaults());
		configHandler->getDefaultConfig()->writeFile("configClientDefaults.txt");
		printf("wrote defaults\n");
	}
	//在此处进行输出语句操作 运行client时并不会输出,这说明client提示语句的输出是另一种机制

	Aria::exit(0);
}


例程2:configClientToServer.cpp

注意运行后两个程序输出的不同之处(如第二个无法使用-help命令),找到对应的命令行,通过添加修改相关命令,加深对此程序的理解。

#include "Aria.h"
#include "ArNetworking.h"

/*
Pass this a file to send to the server (should be made by configClient then modified).

Takes a file to send, and can take the host to send to too

*/

ArClientBase *client;
ArClientHandlerConfig *configHandler;

char *file;

void saveConfigSucceeded(void)
{
	printf("HERE: Save config succeeded\n");
}

void saveConfigFailed(const char *str)
{
	printf("HERE: Save config failed: %s\n", str);
}

void gotConfig(void)
{
	char errorBuffer[1024];
	ArConfig *newConfig;
	if (!configHandler->getConfig()->parseFile(file, false, false, errorBuffer,
		sizeof(errorBuffer)))
		printf("Error loading file: %s\n", errorBuffer);

	configHandler->saveConfigToServer();
	client->loopOnce();
	ArUtil::sleep(1000);
	client->loopOnce();
	ArUtil::sleep(1000);
	client->disconnect();
	Aria::shutdown();
	exit(0);
}

int main(int argc, char **argv)
{
	Aria::init();
	//ArLog::init(ArLog::StdOut, ArLog::Verbose);
	/*
	This is a class for global functions. This ties a C style function
   pointer into the functor class hierarchy as a convience. Code that
   has a reference to this class and treat it as an ArFunctor can use
   it like any other functor.
   */
	ArGlobalFunctor gotConfigCB(&gotConfig);
	ArGlobalFunctor saveConfigSucceededCB(&saveConfigSucceeded);
	ArGlobalFunctor1<const char *> saveConfigFailedCB(&saveConfigFailed);
	std::string hostname;

	client = new ArClientBase;
	configHandler = new ArClientHandlerConfig(client, true);

	configHandler->addGotConfigCB(&gotConfigCB);
	configHandler->addSaveConfigSucceededCB(&saveConfigSucceededCB);
	configHandler->addSaveConfigFailedCB(&saveConfigFailedCB);

	if (argc == 1)
	{
		printf("Usage: %s <file> <host>\n", argv[0]);
		exit(1);
	}
	file = argv[1];
	if (argc == 2)
		hostname = "localhost";
	else
		hostname = argv[2];


	if (!client->blockingConnect(hostname.c_str(), 7272))
	{
		printf("Could not connect  server, exiting\n");
		exit(1);
	}
	//client->requestOnce("setConfig");
	configHandler->requestConfigFromServer();
	//client->requestOnce("setConfig");
	client->run();
	return 0;
}


例程3:ClientCommandLister.cpp

#include "Aria.h"
#include "ArNetworking.h"

int main(int argc, char **argv)
{
	Aria::init();
	ArLog::init(ArLog::StdOut, ArLog::Normal);
	ArClientBase client;

	ArArgumentParser parser(&argc, argv);
	/*
	simpleconnector中的函数执行后大都返回bool值顺便用来判断是否连接成功
	*/
	ArClientSimpleConnector clientConnector(&parser);//通过parser中的myHost参数传递ip值用于判断

	parser.loadDefaultArguments();
	//parseArgs()负责检测输入的-host等参数,检测到返回true
	if (!clientConnector.parseArgs() || !parser.checkHelpAndWarnUnparsed())
	{
		clientConnector.logOptions();
		exit(0);
	}

	if (!clientConnector.connectClient(&client))
	{
		if (client.wasRejected())
			printf("Server '%s' rejected connection, exiting\n", client.getHost());
		else
			printf("Could not connect to server '%s', exiting\n", client.getHost());
		exit(1);
	}

	client.setRobotName(client.getHost());  // include server hostname in log messages
	client.runAsync();
	ArUtil::sleep(500);
	client.logDataList();// Print out data with descriptions
	Aria::shutdown(); 
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值