I was trying to use the package pid (http://wiki.ros.org/pid) to control the stability of a drone (Parrot AR drone 2.0).
I created a launch that use one controller for each axis (x,y and z):
<node name="controller" pkg="pid" type="controller" ns="pid_x" output="screen" >
<param name="node_name" value="pid_x" />
<param name="Kp" value="-0.0887" />
<param name="Ki" value="0.0" /> <!-- Arranca en cero pero es 0.16597 -->
<param name="Kd" value="0.0" />
<param name="max_loop_frequency" value="105.0" />
<param name="min_loop_frequency" value="95.0" />
<remap from="setpoint" to="/setpoint_x" />
<remap from="state" to="/ardrone/odometry/pose/pose/position/x" />
<remap from="/pid_x/control_effort" to="/publicador_intermedio_x" />
</node>
<node name="controller" pkg="pid" type="controller" ns="pid_y" output="screen" >
<param name="node_name" value="pid_y" />
<param name="Kp" value="0.0763" />
<param name="Ki" value="0.0" /> <!-- Arranca en cero pero es 0.11037 -->
<param name="Kd" value="0.0" />
<param name="max_loop_frequency" value="105.0" />
<param name="min_loop_frequency" value="95.0" />
<remap from="setpoint" to="/pid_y/setpoint_y" />
<remap from="state" to="/pid_y/state" />
<remap from="/pid_y/control_effort" to="/publicador_intermedio_y" />
</node>
<node name="controller" pkg="pid" type="controller" ns="pid_z" output="screen" >
<param name="node_name" value="pid_z" />
<param name="Kp" value="0.9827" />
<param name="Ki" value="0.0" />
<param name="Kd" value="0.0" />
<param name="max_loop_frequency" value="105.0" />
<param name="min_loop_frequency" value="95.0" />
<remap from="setpoint" to="/setpoint_z" />
<remap from="state" to="/ardrone/odometry/pose/pose/position/z" />
<remap from="/pid_z/control_effort" to="/publicador_intermedio_z" />
</node>
</launch>
I was just checking how it works using just the second controller, so please don't mind the other ones. The state takes information from the topic pid_y/state that reads the /ardrone/odometry/pose/pose/position and publishes the value of y (if u want to see the node I can post it). Then, pid_controller is publishing in /publicador_intermedio_x that it's a node that works like a conection betweeen the outcome of the controller and the topic /cdm_vel of the drone (i mean, the topic where you need to publish in order to controlling the drone). Finally the last one is the big problem: setpoint. In the pid package we can find an example in order to understand how it works. So I copied the node that publishes the setpoint values in order to make a test. It looks like this:
#include <ros/ros.h>
#include <std_msgs/Float64.h>
int main(int argc, char** argv)
{
//inicio comunicacion con sistema ROS
ros::init(argc, argv, "publicador");
ROS_INFO("Starting setpoint publisher");
ros::NodeHandle nh;
while (ros::ok() && ros::Time(0) == ros::Time::now())
{
ROS_INFO("Setpoint_node spinning, waiting for time to become non-zero");
sleep(1);
}
std_msgs::Float64 contador;
contador.data = 1.0;
//creamos un objeto publicador
ros::Publisher pub = nh.advertise<std_msgs::Float64>("/pid_y/setpoint_y", 1000);
ros::Rate loop_rate(10); // acomodar a frecuencia que no sature, pero q sea mas rapida que publicacion odometria
while (ros::ok())
{
ros::spinOnce();
pub.publish(contador);
contador.data = contador.data + 1;
pub.publish(contador);
ROS_INFO("Valor publicado: [%f]", contador);
loop_rate.sleep(); //duermo hasta proxima iteracion
}
Now that I already explained the code, this is what isn’t working: I run the pid with the nodes that it needs. The launch reads correctly the setpoint and the state (the odometry) but it doesn't publish because:
prev_time is 0, doing nothing
If i understood the code correctly, It’s because prev time uses the time between two consecutive values to calculate the error. That's ok. But when the launch must to read the second setpoint value it never does it. It stays in
Waiting first setpoint value
and never read it, even when the node is publishing the new value. I can't understand what I'm doing wrong.
Can anyone help me?
Related
How to pass multiple parameters into WSO2 MI dataService, nested queries
I search far and wide,
Here how its done:
</query>
<query id="getCampaigns" useConfig="MySQLConnection">
<sql>SELECT NULL</sql>
<param name="param1" sqlType="STRING" />
<param name="param2" sqlType="QUERY_STRING" />
<param name="param3" sqlType="QUERY_STRING" />
<result outputType="json">{
"Campaigns": {
"CampaignsByBanks": {
"SearchedCampaigns": {
"#getCampaignBbank": "$param1->param1, $param2->param2, $param3->param3",
"#getCampaignAbank": "$param1->param1, $param2->param2, $param3->param3"
},
"OtherCampaigns": {
"#getOtherCampaignBbank": "$param1->param1, $param2->param2, $param3->param3",
"#getOtherCampaignAbank": "$param1->param1, $param2->param2, $param3->param3"
}
}
}
}
</result>
</query>
how to pass single parameter into WSO2 MI dataService, nested query
https://docs.wso2.com/display/EI630/Defining+Nested+Queries
I've been looking for hours a solution to my (simple ?) problem but I cannot find anyone who encountered this. I'm using latest version of rapidxml(1.13).
I'm currently trying to create a tile-based engine and I need to read tmx file.
I'm been using rapidxml for a while and so far everything was great. It was able to read every node perfectly and with an expected behavior. But I came across one node it has a problem with.
This is my tmx file :
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.5" tiledversion="1.6.0" orientation="orthogonal" renderorder="right-down" width="100" height="100" tilewidth="32" tileheight="32" infinite="0" nextlayerid="12" nextobjectid="1">
<tileset firstgid="1" source="../../../Tile_engine/Tile_engine/sprite/[Base]BaseChip_pipo.tsx"/>
<tileset firstgid="1065" source="../../../Tile_engine/Tile_engine/sprite/collision.tsx"/>
<layer id="4" name="background" width="100" height="100">
<properties>
<property name="bg" type="bool" value="false"/>
</properties>
<data encoding="csv">
//I've removed the data for clearer view
</data>
</layer>
<layer id="6" name="object" width="100" height="100">
<properties>
<property name="isSolid" type="bool" value="true"/>
</properties>
<data encoding="csv">
//I've removed the data for clearer view
</data>
</layer>
<layer id="9" name="front" width="100" height="100">
<properties>
<property name="isSolid" type="bool" value="false"/>
</properties>
<data encoding="csv">
//I've removed the data for clearer view
</data>
</layer>
<layer id="11" name="collision" width="100" height="100">
<data encoding="csv">
//I've removed the data for clearer view
</data>
</layer>
</map>
In order to debug, I'm using a basic read with rapidxml :
xml_document<> doc;
xml_node<> * root_node;
// Read the xml file into a vector
ifstream theFile ("sprites/map_wtf.tmx");
vector<char> buffer((istreambuf_iterator<char>(theFile)), istreambuf_iterator<char>());
buffer.push_back('\0');
// Parse the buffer using the xml file parsing library into doc
doc.parse<0>(&buffer[0]);
// Find our root node
root_node = doc.first_node("map");
When I try to read (and count) the layer node for example :
int count_node(0);
for(xml_node<> * child = root_node->first_node("layer"); child != nullptr; child = child->next_sibling())
count_node++;
cout << count_node;
The output is correct and gives me 4.
But when I try to read the tileset node, the output gives me 6.
So I've assumed the behavior is link to the /> at the end of the tileset node (<tileset firstgid="1" source="../../../Tile_engine/Tile_engine/sprite/[Base]BaseChip_pipo.tsx"/>).
Since the nested property node has the same pattern (<property name="bg" type="bool" value="false"/>), I've tried this code :
int count_node(0);
for(xml_node<> * child = root_node->first_node("layer")->first_node("properties")->first_node("property"); child != nullptr; child = child->next_sibling())
count_node++;
cout << count_node;
who gives me the correct output aka : 1.
I've tried different parsing options for the line doc.parse<0>(&buffer[0]) but nothing works. I've also read the content of the buffer during theses tests and it was correct.
I must have the wrong way to read the file but I cannot understand why this script reads layer node and property node fine, but not the tileset ones.
Can anyone help me ?
Thanks !
The question is based on a misunderstanding about the result of
xml_node<> * child = root_node->first_node("layer");
child = child->next_sibling();
The child = child->next_sibling() returns the next node on the same level irregardless of the node name or any other constraint that was applied during the root_node->first_node("layer") selection.
However, the next_sibling signature is basically the same as the first_node signature, so it can be used to apply criteria to the next sibling node to be found.
So the (untested) approach would be like
int count_node(0);
for(xml_node<> * child = root_node->first_node("tileset"); child != nullptr; child = child->next_sibling("tileset"))
count_node++;
cout << count_node;
I have searched high and low for an example implementation or blog post on how to use Mass Transit's Quartz integration (https://github.com/MassTransit/MassTransit-Quartz).
At the moment I have to make do with just looking at the unit tests that come with the code base and I'm not making much progress.
Are there any examples or good blog posts out there to help me get started with Mass Transit and Quartz Scheduling?
This example lets you persist a MassTransit scheuled message in a SQL database. Out of the box, MassTransit only persists in memory without some config changes.
First of all you need a subtle change to your app/web.config file to include the following 2 blocks:
<configSections>
<section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<quartz>
<add key="quartz.scheduler.instanceName" value="MassTransit-Quartz" />
<add key="quartz.scheduler.instanceId" value="AUTO" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="4" />
<add key="quartz.threadPool.threadPriority" value="2" />
<add key="quartz.jobStore.misfireThreshold" value="60000" />
<add key="quartz.jobStore.type" value="Quartz.Impl.AdoJobStore.JobStoreTX, Quartz" />
<add key="quartz.jobStore.useProperties" value="false" />
<add key="quartz.jobStore.driverDelegateType" value="Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz" />
<add key="quartz.jobStore.clustered" value="true" />
<add key="quartz.jobStore.tablePrefix" value="QRTZ_" />
<add key="quartz.jobStore.dataSource" value="quartzDS" />
<add key="quartz.dataSource.quartzDS.connectionString" value="Server=(local);Database=Quartz;Integrated Security=SSPI" />
<add key="quartz.dataSource.quartzDS.provider" value="SqlServer-20" />
Then, in your local SQL, create a new database named "Quartz", download the quartz.net source and locate the database script
"tables_sqlServer.sql"
run this against your Quartz local database to create the schema.
Now you have everything ready to persist scheduled messages in the database, you need to subscribe these two consumers from the MassTransit Quartz integration library:
var scheduler = CreateScheduler();
sb.SubscribeConsumer(() => new ScheduleMessageConsumer(scheduler));
sb.SubscribeConsumer(() => new CancelScheduledMessageConsumer(scheduler));
Where scheduler is an IScheduler:
static IScheduler CreateScheduler()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
return schedulerFactory.GetScheduler();
}
and sb is your servicebus of type IServiceBus.
Finally, in your code call:
Bus.ScheduleMessage(SchedulePeriodInSecondsFromNow, MessageToSchedule);
And have a consumer for the "MessageToSchedule" type.
If you open up the database and query the QRTZ_TRIGGERS table, you will see jobs appearing there and in QRTZ_JOB_DETAILS.
Hope this helps!
My Regex:
#\<param name\=\"src\"+.+\"\s\/\>#
The problem is that stops at the second /> but I want just the first <param>.
<param name="example" src="hello.swf" />
<param name="stuff2" />
So how should I get just the first param?
Probably something like this...
#param name="([a-zA-Z0-9]+)" src="(.*?)"#is
Your result should be in $match[2]
Edit2: only regex match solutions, please. thank you!
Edit: I'm looking for regex solution, if it's exist. I have other blocks with the same data that are not XML, and I can't use Perl, I added Perl tag as I'm more familiar with regexes in Perl. Thanks in advance!
I Have list like this:
<Param name="Application #" value="1">
<Param name="app_id" value="32767" />
<Param name="app_name" value="App01" />
<Param name="app_version" value="1.0.0" />
<Param name="app_priority" value="1" />
</Param>
<Param name="Application #" value="2">
<Param name="app_id" value="3221" />
<Param name="app_name" value="App02" />
<Param name="app_version" value="1.0.0" />
<Param name="app_priority" value="5" />
</Param>
<Param name="Application #" value="3">
<Param name="app_id" value="32" />
<Param name="app_name" value="App03" />
<Param name="app_version" value="1.0.0" />
<Param name="app_priority" value="2" />
</Param>
How can I get a block for one app if I only know, say, a value of app_name. For example for App02 I want to get
<Param name="Application #" value="2">
<Param name="app_id" value="3221" />
<Param name="app_name" value="App02" />
<Param name="app_version" value="1.0.0" />
<Param name="app_priority" value="5" />
</Param>
Is it possible to get it, if other "name=" lines are not known (but there's always name="app_name" and Param name="Application #")?
Can it be done in a single regex match? (doesn't have to be, but feels like there's probably a way).
since your content seems to be some XML why don't use a real parser to do the task ?
use XML::XPath;
use XML::XPath::XMLParser;
my $xp = XML::XPath->new(filename => 'test.xhtml');
my $nodeset = $xp->find('/Param[#name=\'Application #\']'); # find all applications
foreach my $node ($nodeset->get_nodelist) {
print "FOUND\n\n",
XML::XPath::XMLParser::as_string($node),
"\n\n";
}
you can read a bit more about XPath here and have full reference at the w3c.
I advise you not to use reg exp to do that task because it's going to be complicate and not maintenable.
note: also possible to use the DOM API just depend the one you like the most.
This seems to be a sad case of bogus XML. A misguided attempt to create enterprisey software at best. The developers could have used a sane configuration file format such as:
[App03]
app_id = 32767
app_version = 1.0.0
...
but they decided to drive everyone insane with meaningless BSXML.
I would say, if this file is less than 10 MB in size, just go ahead and use XML::Simple. If the file indeed consists of nothing but repeated blocks of exactly what you posted, you can use the following solution:
#!/usr/bin/perl
use strict; use warnings;
my %apps;
{
local $/ = "</Param>\n";
while ( my $block = <DATA> ) {
last unless $block =~ /\S/;
my %appinfo = ($block =~ /name="([^"]+?)"\s+value="([^"]+?)"/g);
$apps{ $appinfo{app_name} } = \%appinfo;
}
}
use Data::Dumper;
print Dumper $apps{App03};
Edit: If you cannot use Perl and you won't tell us what you can use, there is not much I can do but point out that
/name="([^"]+?)"\s+value="([^"]+?)"/g
will give you all name-value pairs.
I would prefer a parser solution, too. If you absolutely have to use a regex and understand all the disadvantages of this approach, then the following regex should work:
<Param name="Application #"[^>]*>\s+<Param[^>]*>\s+<Param name="app_name" value="App02" />\s+(?:<Param[^>]*>\s+){2}</Param>
This relies heavily on the structure present in your example. A re-ordering of tags, introduction of additional tags or (shudder) nesting of tags will break the regex.
Seems like it would be more appropriate to use an XML reader library, but I don't know Perl enough to suggest one.
Perl's XML DOM Parser may be appropriate here.
I would suggest using one of XML parsers, but if you cannot do so, then the following quick and dirty code should do:
my ($rez) = $data =~/\<Param\s+name\s*=\s*"Application\s#"\s+value\s*=\s*"2"\>((?:.|\n)*?)^\<\/Param\>/m;
print $rez;
(assuming $data contains your xml as a single string, possibly multiline )