I'm working on a project that uses Kinect for robot navigation. We use ROS Groovy as distro and Gazebo for simulation, and have sensor and model plugins for the robot model. We have manipulated kinect model using the .sdf file and added libgazebo_ros_openni_kinect.so file as plugin. So now, whenever we launch the robot model in Gazebo, it publishes topics like these: /cam3d/depth/image_raw, /cam3d/depth/points, /cam3d/rgb/image_raw ...
Our model.sdf contains this part for the kinect model:
<plugin name="kinect" filename="libgazebo_ros_openni_kinect.so" >
<alwaysOn>true</alwaysOn>
<updateRate>10</updateRate>
<pointCloudCutoff>0.001</pointCloudCutoff>
<imageTopicName>/cam3d/rgb/image_raw</imageTopicName>
<pointCloudTopicName>/cam3d/depth/points</pointCloudTopicName>
<cameraInfoTopicName>/cam3d/camera_info</cameraInfoTopicName>
<depthImageTopicName>/cam3d/depth/image_raw</depthImageTopicName>
<depthImageInfoTopicName>/cam3d/depth/camera_info</depthImageInfoTopicName>
<frameName>kinect</frameName>
<distortion_k1>0.00000001</distortion_k1>
<distortion_k2>0.00000001</distortion_k2>
<distortion_k3>0.00000001</distortion_k3>
<distortion_t1>0.00000001</distortion_t1>
<distortion_t2>0.00000001</distortion_t2>
<imageTopicName>kinectimage</imageTopicName>
<pointCloudTopicName>pcloud</pointCloudTopicName>
<depthImageTopicName>depth</depthImageTopicName>
<depthImageCameraInfoTopicName>depthcamerainfo</depthImageCameraInfoTopicName>
</plugin>
We intend to use pcl_to_scan package in order to convert the point cloud data into LaserScan. I've done a little research about it. People say that I have to create a launch file to use the pcl_to_scan package. I took a look at the example launch files and realized that they use openni.launch and openni_manager in order to convert /camera/depth/points into laserscan data. I need to manipulate that launch file in order to work with the model that we have created, since we're not using openni at the moment.
The launch file that they offer is like this:
<launch>
<!-- kinect nodes -->
<include file="$(find openni_launch)/launch/openni.launch"/>
<!-- openni_manager -->
<node pkg="nodelet" type="nodelet" name="openni_manager" output="screen" respawn="true" args="manager"/>
<!-- throttling -->
<node pkg="nodelet" type="nodelet" name="pointcloud_throttle" args="load pointcloud_to_laserscan/CloudThrottle openni_manager">
<param name="max_rate" value="2"/>
<remap from="cloud_in" to="/camera/depth/points"/>
<remap from="cloud_out" to="cloud_throttled"/>
</node>
<!-- fake laser -->
<node pkg="nodelet" type="nodelet" name="kinect_laser" args="load pointcloud_to_laserscan/CloudToScan openni_manager">
<!--Setting the parameters for obtaining scan data within desired ranges-->
<param name="max_height" value="0.30"/>
<param name="min_height" value="-0.15"/>
<param name="angle_min" value="-0.5233"/>
<param name="angle_max" value="0.5233"/>
<param name="range_min" value="0.50"/>
<param name="range_max" value="6.0"/>
<param name="output_frame_id" value="/camera_depth_frame"/>
<remap from="cloud" to="cloud_throttled"/>
</node>
</launch>
I've also stumbled into depthimage_to_laserscan and pointcloud_to_laserscan packages, that can also be useful for dealing with this issue. Any help regarding the pcl_to_scan issue, or any other easier methods to deal with this situation will be greately appreciated. Thanks in advance.
Related
I am working on a .Net example where I define my own data type using RTI Connext DDS.
Instead of creating the application from the beginning, I got help from the source code of the hello_world_xml_dynamic example in rti_workspace directory. I have made several changes to the USER_QOS_PROFILES.xml file to create my own data type and changes its name to MY_PROFILES.xml
But when I compile the application and run it from the command line, I get the following error:
DDS_DomainParticipantFactory_create_participant_from_config_w_paramsI:ERROR: Profile library 'MyParticipantLibrary::PublicationParticipant' not found
! Unable to create DDS domain participant
The line of code that catching the error:
if (this.participant == null)
{
this.participant = DDS.DomainParticipantFactory.get_instance().
create_participant_from_config(
"MyParticipantLibrary::PublicationParticipant");
if (this.participant == null)
{
Console.Error.WriteLine("! Unable to create DDS domain participant");
return;
}
}
this is the configuration file MY_PROFILES.xml :
<!--
RTI Data Distribution Service Deployment
-->
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/6.0.1/rti_dds_profiles.xsd">
<!-- Qos Library -->
<qos_library name="qosLibrary">
<qos_profile name="DefaultProfile">
</qos_profile>
</qos_library>
<!-- types -->
<types>
<struct name="FlightData">
<member name="Latitude" type="double"/>
<member name="Longitude" type="double"/>
<member name="Altitude" type="double"/>
</struct>
</types>
<!-- Domain Library -->
<domain_library name="MyDomainLibrary" >
<domain name="FlightDataDomain" domain_id="0">
<register_type name="FlightDataType"
type_ref="FlightData" />
<topic name="FlightDataTopic"
register_type_ref="FlightDataType">
<topic_qos name="FlightData_qos"
base_name="qosLibrary::DefaultProfile"/>
</topic>
</domain>
</domain_library>
<!-- Participant library -->
<domain_participant_library name="MyParticipantLibrary">
<domain_participant name="PublicationParticipant"
domain_ref="MyDomainLibrary::FlightDataDomain">
<publisher name="MyPublisher">
<data_writer name="FlightDataWriter"
topic_ref="FlightDataTopic"/>
</publisher>
</domain_participant>
<domain_participant name="SubscriptionParticipant"
domain_ref="MyDomainLibrary::FlightDataDomain">
<subscriber name="MySubscriber">
<data_reader name="FlightDataReader"
topic_ref="FlightDataTopic">
<datareader_qos name="FlightData_reader_qos"
base_name="qosLibrary::DefaultProfile"/>
</data_reader>
</subscriber>
</domain_participant>
</domain_participant_library>
</dds>
where am i making a mistake?
Your XML file looks correct. From the 'not found' error message, it seems that you may not have taken the right steps to instruct your application to load that profiles-file MY_PROFILES.xml to actually learn about your desired Participant. You can easily verify that this is the case by introducing an error in your XML file (for example by incorrectly renaming one tag) and rerun your application. If it does not complain about the syntax or schema of the XML, then your file did not get loaded and this hypothesis is correct.
If that turns out to be your problem indeed, then you have several options to fix that. They are listed in the User's Manual section 18.5 How to Load XML-Specified QoS Settings.
Sitecore CMS+DMS 6.6.0 rev.130404 => 7.0 rev.130424
In our project we have been using AdvancedDatabaseCrawler (ADC) for our indexes (specially because of it's dynamic fields feature). Here's a sample index configuration:
<index id="GeoIndex" type="Sitecore.Search.Index, Sitecore.Kernel">
<param desc="name">$(id)</param>
<param desc="folder">$(id)</param>
<analyzer ref="search/analyzer" />
<locations hint="list:AddCrawler">
<web type="scSearchContrib.Crawler.Crawlers.AdvancedDatabaseCrawler, scSearchContrib.Crawler">
<database>web</database>
<root>/sitecore/content/Globals/Locations</root>
<IndexAllFields>true</IndexAllFields>
<include hint="list:IncludeTemplate">
<!--Suburb Template-->
<suburb>{FF0D64AA-DCB4-467A-A310-FF905F9393C0}</suburb>
</include>
<dynamicFields hint="raw:AddDynamicFields">
<dynamicField type="OurApp.CustomSearchFields.SearchTextField,OurApp" name="search text" storageType="NO" indexType="TOKENIZED" vectorType="NO" />
<dynamicField type="OurApp.CustomSearchFields.LongNameField,OurApp" name="display name" storageType="YES" indexType="UN_TOKENIZED" vectorType="NO" />
</dynamicFields>
</web>
</locations>
</index>
As you can see, we use scSearchContrib.Crawler.Crawlers.AdvancedDatabaseCrawler as the crawler and it uses the fields defined inside <dynamicFields hint="raw:AddDynamicFields"> section to inject custom fields into the index.
Now we are upgrading our project to sitecore 7. In Sitecore 7, they have ported the DynamicFields functionality from ADC into sitecore. I found out some articles on this and converted our custom search field classes to implement sitecore 7 IComputedIndexField interface instead of inheriting from BaseDynamicField class in ADC. Now my problem is how to change the index configuration to match with new sitecore 7 APIs. There were bits and pieces on the web but couldn't find all the examples I needed to convert my configuration. Can anybody help me on this?
While I'm doing this I'm under the impression that we won't have to rebuild our indexes since it still uses Lucene internally. I don't want to change the index structure. Just want to upgrade the code and configuration from AdvancedDatabaseCrawler to Sitecore 7. Should I be worried about breaking our existing indexes? Please shed some light on this as well.
Thanks
A few quick clarifications :)
We have not merged ADC into Sitecore 7, the ContentSearch layer is a complete rewrite of the old search layer for Sitecore. We have taken some of the core concepts from ADC, such as dynamic fields, and put them in the new implementation (as ComputedFields). They are not 1:1 compatible and you will have to do some work on your indexes.
The version of Lucene has also been upgraded from 2.* to 3.0.3 so all indexes will need to be re-created anyway as they are a very different version of Lucene.
There are two options here, the old Lucene search (Sitecore.Search namespace) (which ADC was built upon) has not been touched and will still work in the same way, although I am not sure about ADC compatibility with SItecore 7 as in theory this has now been superseded.
The next option is to update your index to take advantage of the new search features of Sitecore 7. The configuration you have will not be directly compatible but, while you will need to rework your index into the new configuration, the basic concepts should be familiar to you. The dynamic fields you have should map logically to ComputedFields (fields that are calculated when an item is indexed) and everything else is straightforward.
While it looks like a lot of extra config for ContentSearch a lot of it is default config that you will not need to touch, you will just need to override the configuration parts for the computed fields you want to add and the template you want to include.
An example of creating your own configuration override can be found here : http://www.mikkelhm.dk/post/2013/10/12/Defining-a-custom-index-in-Sitecore-7-and-utilizing-it.aspx
I would also recommend making sure you upgrade to 7.0 rev. 131127 (7.0 Update-3) as this fixes a bug in the IncludeTemplates logic in the version you currently have.
I managed to convert the index configuration for sitecore ContentSearch API. Looking at Sitecore default index configurations was a great help for this.
Note: As also mentioned by Stephen, <include hint="list:IncludeTemplate"> does not work in Sitecore 7.0 initial release. It's fixed in Sitecore 7.0 rev. 131127 (7.0 Update-3) and I'm planning to upgrade to it.
Here's a good article on sitecore 7 index update strategies by John West. It'll help you in configuration your indexes the way you want.
Converted configuration:
<sitecore>
<contentSearch>
<configuration type="Sitecore.ContentSearch.LuceneProvider.LuceneSearchConfiguration, Sitecore.ContentSearch.LuceneProvider">
<DefaultIndexConfiguration type="Sitecore.ContentSearch.LuceneProvider.LuceneIndexConfiguration, Sitecore.ContentSearch.LuceneProvider">
<IndexAllFields>true</IndexAllFields>
<include hint="list:IncludeTemplate">
<!--Suburb Template-->
<suburb>{FF0D64AA-DCB4-467A-A310-FF905F9393C0}</suburb>
</include>
<fields hint="raw:AddComputedIndexField">
<field fieldName="search text" storageType="NO" indexType="TOKENIZED" vectorType="NO">OurApp.CustomSearchFields.SearchTextField,OurApp</field>
<field fieldName="display name" storageType="YES" indexType="UN_TOKENIZED" vectorType="NO">OurApp.CustomSearchFields.LongNameField,OurApp</field>
</fields>
</DefaultIndexConfiguration>
<indexes hint="list:AddIndex">
<index id="GeoIndex" type="Sitecore.ContentSearch.LuceneProvider.LuceneIndex, Sitecore.ContentSearch.LuceneProvider">
<param desc="name">$(id)</param>
<param desc="folder">$(id)</param>
<!-- This initializes index property store. Id has to be set to the index id -->
<param desc="propertyStore" ref="contentSearch/databasePropertyStore" param1="$(id)" />
<strategies hint="list:AddStrategy">
<!-- NOTE: order of these is controls the execution order -->
<strategy ref="contentSearch/indexUpdateStrategies/onPublishEndAsync" />
</strategies>
<commitPolicy hint="raw:SetCommitPolicy">
<policy type="Sitecore.ContentSearch.TimeIntervalCommitPolicy, Sitecore.ContentSearch" />
</commitPolicy>
<commitPolicyExecutor hint="raw:SetCommitPolicyExecutor">
<policyExecutor type="Sitecore.ContentSearch.CommitPolicyExecutor, Sitecore.ContentSearch" />
</commitPolicyExecutor>
<locations hint="list:AddCrawler">
<crawler type="Sitecore.ContentSearch.LuceneProvider.Crawlers.DefaultCrawler, Sitecore.ContentSearch.LuceneProvider">
<Database>web</Database>
<Root>/sitecore/content/Globals/Countries</Root>
</crawler>
</locations>
</index>
</indexes>
</configuration>
</contentSearch>
</sitecore>
I would love to add support for Working Sets for my Eclipse plugin that used the Common Navigator framework.
In Eclipse bugzilla there is mention that this is supported
None of the online manuals for the Common Navigator explain how to do it
I do not know where to start even since there is no extension point for it, and the Working Set implementation classes are all "internal". I have a very basic navigator setup showing default project resources and some additional IFileSystem stuff implementing ITreeContentProvider.
You can get the working set manager using:
IWorkingSetManager manager = PlatformUI.getWorkbench().getWorkingSetManager();
and from that get the visible working sets with:
IWorkingSet [] workingSets = manager.getWorkingSets();
the members of a working set can be accessed with:
IAdaptable [] elements = workingSet.getElements();
so you could use the working sets list as the input for the tree viewer and adjust your tree content provider to deal with this.
In retrospect the following is a better solution. Instead of implementing ITreeContentProvider and traversing the working sets ourselves, we can reuse existing standard providers for the same content, which might work better.
You can use them like so:
<extension
point="org.eclipse.ui.navigator.viewer">
<viewerContentBinding
viewerId="rascal.navigator">
<includes>
<contentExtension pattern="org.eclipse.ui.navigator.resourceContent" />
<contentExtension pattern="org.eclipse.ui.navigator.resources.filters.*"/>
<contentExtension pattern="org.eclipse.ui.navigator.resources.linkHelper"/>
<contentExtension pattern="org.eclipse.ui.navigator.resources.workingSets"/>
</includes>
</viewerContentBinding>
In particular the org.eclipse.ui.navigator.resources.workingSets is what adds working sets capabilities to your navigator.
Adding your own content then becomes an issue of adding another content provider which ignores workingsets and projects and other kinds of resources which are already taken care of, e.g. like so:
<extension
point="org.eclipse.ui.navigator.navigatorContent">
<navigatorContent
activeByDefault="true"
contentProvider="org.rascalmpl.eclipse.navigator.NavigatorContentProvider"
id="org.rascalmpl.navigator.searchPathContent"
labelProvider="org.rascalmpl.eclipse.navigator.NavigatorContentLabelProvider"
name="Rascal search path"
priority="normal">
<triggerPoints>
<or>
<instanceof value="org.eclipse.core.resources.IResource"/>
</or>
</triggerPoints>
<possibleChildren>
<or>
<instanceof value="java.lang.Object"/>
</or>
</possibleChildren>
<actionProvider
class="org.rascalmpl.eclipse.navigator.NavigatorActionProvider"
id="org.rascalmpl.navigator.actions">
</actionProvider>
<commonSorter
class="org.rascalmpl.eclipse.navigator.Sorter">
</commonSorter>
</navigatorContent>
<commonWizard
type="new"
wizardId="rascal_eclipse.wizards.NewRascalFile">
<enablement></enablement>
</commonWizard>
<commonWizard
type="new"
wizardId="rascal_eclipse.projectwizard">
<enablement></enablement>
</commonWizard>
</extension>
and in the NavigatorContentProvider class we implement getElements and getChildren but only for our own additional content.
When I perform a jackrabbit (version 2.2.9) search and I call get row.getValue("rep:excerpt()") the returned string is just all the properties (excluding jcr: properties) concatenated. How do I control this? eg. If I have a property called "description" containing "bla foo bla" when I search for "foo" I would like to see rep:excerpt() return part of just the description.
I tried creating an index config (and I deleted my repository between tests) in an attempt to control what properties were indexed, to no avail.
Workspace.xml...
<SearchIndex class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
<param name="path" value="${wsp.home}/index"/>
<param name="supportHighlighting" value="true"/>
<param name="excerptProviderClass" value="org.apache.jackrabbit.core.query.lucene.DefaultHTMLExcerpt"/>
<param name="indexingConfiguration" value="${wsp.home}/indexing_configuration.xml"/>
</SearchIndex>
indexing_configuration.xml
<?xml version="1.0"?>
<!DOCTYPE configuration SYSTEM "http://jackrabbit.apache.org/dtd/indexing-configuration-1.0.dtd">
<configuration xmlns:nt="http://www.jcp.org/jcr/nt/1.0">
<index-rule nodeType="nt:teneoNode">
<property>description</property>
<property>input</property>
<property>key</property>
<property>comment</property>
</index-rule>
</configuration>
Thanks.
Ted.
You can configure the ExcerptProvider (Javadoc) implementation which is responsible for the rep:excerpt() functionality in the SearchIndex element of you workspace.xml file:
<param name="excerptProviderClass" value="org.apache.jackrabbit.core.query.lucene.DefaultHTMLExcerpt"/>
You might need to plugin in your own implementation for you specific needs.
There is also some - unfortunately rather old - information on the Jackrabbit Wiki.
I have a properties file, let say my-file.properties.
In addition to that, I have several configuration files for my application where some information must be filled regarding the content of my-file.properties file.
my-file.properties:
application.version=1.0
application.build=42
user.name=foo
user.password=bar
Thus, in my configuration files, I will find some ${application.version}, ${user.name} that will be replaced by their value taken in the properties file...
When I build my application using Maven2, I only need to specify the properties file and say that my resources files are filtered (as in this answer to another problem). However, I need to achieve the same thing by using only Ant.
I've seen that Ant offers a filter task. However, it forces me to use the pattern #property.key# (i.e. #user.name# instead of #{user.name}) in my configuration files, which is not acceptable in my case.
How can I solve my problem?
I think expandproperties is what you are looking for. This acts just like Maven2's resource filters.
INPUT
For instance, if you have src directory (one of many files):
<link href="${css.files.remote}/css1.css"/>
src/test.txt
PROCESS
And in my ANT build file we have this:
<project default="default">
<!-- The remote location of any CSS files -->
<property name="css.files.remote" value="/css/theCSSFiles" />
...
<target name="ExpandPropertiesTest">
<mkdir dir="./filtered"/>
<copy todir="./filtered">
<filterchain>
<expandproperties/>
</filterchain>
<fileset dir="./src" />
</copy>
</target>
</project>
build.xml
OUTPUT
*When you run the ExpandPropertiesTest target you will have the following in your filtered directory: *
<link href="/css/theCSSFiles/css1.css"/>
filtered/test.txt
You can define a custom FilterReader. So you have a couple of choices:
Extend/copy the org.apache.tools.ant.filters.ReplaceTokens class and define a Map property that references another properties file containing all the replacements. This is still a bit of a chore as you have to define all the replacements.
Extend/copy the org.apache.tools.ant.filters.ReplaceTokens class with additional processing that just substitutes the matched token with a version with the correct garnish. Of course you'd have to be really careful where you use this type as it will match anything with the begin and end token.
So in the read() method of ReplaceTokens, replace:
final String replaceWith = (String) hash.get(key.toString());
with a call to a getReplacement() method:
...
final String replaceWith = getReplacement(key.toString);
...
private String getReplacement(String key) {
//first check if we have a replacement defined
if(has.containsKey(key)) {
return (String)hash.get(key);
}
//now use our built in rule, use a StringBuilder if you want to be tidy
return "$" + key + "}";
}
To use this, you'd ensure your class is packaged and on Ant's path and modify your filter:
<filterreader classname="my.custom.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!--Can still define explicit tokens, any not
defined explicitly will be replaced by the generic rule -->
</filterreader>
One hooooooorible way to make this work, inspired by the solution of Mnementh, is with the following code:
<!-- Read the property file -->
<property file="my-file.properties"/>
<copy todir="${dist-files}" overwrite="true">
<fileset dir="${src-files}">
<include name="*.properties"/>
</fileset>
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.ReplaceTokens">
<!-- Define the begin and end tokens -->
<param type="tokenchar" name="begintoken" value="$"/>
<param type="tokenchar" name="endtoken" value="}"/>
<!-- Define one token per entry in the my-file.properties. Arggh -->
<param type="token" name="{application.version" value="${application.version}"/>
<param type="token" name="{user.name" value="${user.name}"/>
...
</filterreader>
</filterchain>
</copy>
Explanations:
I am using the ReplaceTokens reader to look for all $...} pattern. I cannot search for ${...} patterns, as the begintoken is a char and not a String. Then, I set the list of tokens starting with a { (i.e. I see {user.name instead of user.name). Hopefully, I have "only" about 20 lines in my-file.properties, so I need to define "only" 20 tokens in my Ant file...
Is there any simple and stupid solution to solve this simple and stupid problem??
Ant knows a concept named Filterchains, that is useful here. Use the ReplaceTokens-filter and specify the begintoken and endtoken as empty (normally that's '#'). That should do the trick.